diff options
Diffstat (limited to 'libX11')
105 files changed, 109276 insertions, 108200 deletions
diff --git a/libX11/configure.ac b/libX11/configure.ac index 44c9afc12..a0af80baa 100644 --- a/libX11/configure.ac +++ b/libX11/configure.ac @@ -1,493 +1,493 @@ - -# Initialize Autoconf -AC_PREREQ([2.60]) -AC_INIT([libX11], [1.4.4], - [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libX11]) -AC_CONFIG_SRCDIR([Makefile.am]) -AC_CONFIG_HEADERS([src/config.h include/X11/XlibConf.h]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CANONICAL_BUILD -AC_CANONICAL_HOST -# Set common system defines for POSIX extensions, such as _GNU_SOURCE -# Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL) -# to avoid autoconf errors. -AC_USE_SYSTEM_EXTENSIONS - -# Initialize Automake -AM_INIT_AUTOMAKE([foreign dist-bzip2]) -AM_MAINTAINER_MODE - -# Initialize libtool -AC_PROG_LIBTOOL - -# Require xorg-macros minimum of 1.15 for fop minimum version -m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.15 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.15) -XORG_DEFAULT_OPTIONS -XORG_ENABLE_SPECS -XORG_WITH_XMLTO(0.0.22) -XORG_WITH_FOP([],[no]) -XORG_WITH_XSLTPROC -XORG_CHECK_SGML_DOCTOOLS(1.9) -XORG_PROG_RAWCPP -XORG_WITH_PERL - -# Required when PKG_CHECK_MODULES called within an if statement -PKG_PROG_PKG_CONFIG - -if test x"$CC_FOR_BUILD" = x; then - if test x"$cross_compiling" = xyes; then - AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc) - else - CC_FOR_BUILD="$CC" - fi -fi -AC_SUBST([CC_FOR_BUILD]) - -if test x"$CPPFLAGS_FOR_BUILD" = x; then - if test ! x"$cross_compiling" = xyes; then - CPPFLAGS_FOR_BUILD=${CPPFLAGS} - fi -fi -AC_SUBST(CPPFLAGS_FOR_BUILD) - -if test x"$CFLAGS_FOR_BUILD" = x; then - if test ! x"$cross_compiling" = xyes; then - CFLAGS_FOR_BUILD=${CFLAGS} - fi -fi -AC_SUBST(CFLAGS_FOR_BUILD) - -if test x"$LDFLAGS_FOR_BUILD" = x; then - if test ! x"$cross_compiling" = xyes; then - LDFLAGS_FOR_BUILD=${LDFLAGS} - fi -fi -AC_SUBST(LDFLAGS_FOR_BUILD) - -# Checks for pkg-config packages - -# Always required -X11_REQUIRES='xproto >= 7.0.17 xextproto xtrans xcb >= 1.1.92' -X11_EXTRA_DEPS="xcb >= 1.1.92" - -PKG_PROG_PKG_CONFIG() - -AC_SUBST(X11_EXTRA_DEPS) - -# Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro -# was not expanded, since libX11 with no transport types is rather useless. -# -# If you're seeing an error here, be sure you installed the lib/xtrans module -# first and if it's not in the default location, that you set the ACLOCAL -# environment variable to find it, such as: -# ACLOCAL="aclocal -I ${PREFIX}/share/aclocal" -m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$]) - -# Transport selection macro from xtrans.m4 -XTRANS_CONNECTION_FLAGS - -# Secure RPC detection macro from xtrans.m4 -XTRANS_SECURE_RPC_FLAGS - -# Preferred order to try transports for local connections -AC_MSG_CHECKING([what order to try transports in for local connections]) -DEFAULT_LOCAL_TRANS="" -case $host_os in - solaris*) - # On Solaris 2.6 through 9, named pipes (LOCAL_TRANS) were - # faster than Unix domain sockets, but on Solaris 10 & later, - # Unix domain sockets are faster now. - if test "$UNIXCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}UNIX_TRANS" - fi - if test "$LOCALCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS" - fi - if test "$TCPCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS" - fi - ;; - linux*) - # LOCAL_TRANS is used for abstract sockets. - if test "$UNIXCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS,UNIX_TRANS" - fi - if test "$TCPCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS" - fi - ;; - *) - if test "$LOCALCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS" - fi - if test "$UNIXCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}UNIX_TRANS" - fi - if test "$TCPCONN" = "yes" ; then - if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}," - fi - DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS" - fi - ;; -esac - -AC_ARG_WITH(local-transport-order, - AS_HELP_STRING([--with-local-transport-order=LIST], [preference sorted list of transport types to try for local connections]), - [LOCAL_TRANSPORT_LIST=$withval], - [LOCAL_TRANSPORT_LIST=$DEFAULT_LOCAL_TRANS]) -AC_DEFINE_UNQUOTED([LOCAL_TRANSPORT_LIST], [$LOCAL_TRANSPORT_LIST], - [preference sorted list of transport types to try for local connections]) -AC_MSG_RESULT([$LOCAL_TRANSPORT_LIST]) - -# Check for dlopen -AC_MSG_CHECKING([if run-time linking is supported]) -AC_SEARCH_LIBS(dlopen,[dl svld]) -if test "x$ac_cv_search_dlopen" = xno; then - AC_SEARCH_LIBS(shl_load,[dld]) - if test "x$ac_cv_search_shl_load" != xno; then - AC_DEFINE(HAVE_SHL_LOAD,1, - [Use shl_load to load shared libraries]) - AC_CHECK_HEADERS([dl.h]) - fi -else - AC_DEFINE(HAVE_DLOPEN,1,[Use dlopen to load shared libraries]) - AC_CHECK_HEADERS([dlfcn.h]) -fi -if test x$ac_cv_header_dlcfn_h -o x$ac_cv_header_dl_h; then - HAVE_LOADABLE_MODULES=yes -else - HAVE_LOADABLE_MODULES=no -fi -AC_MSG_RESULT($HAVE_LOADABLE_MODULES) - -AC_MSG_CHECKING([if loadable i18n module support should be enabled]) -AC_ARG_ENABLE(loadable-i18n, - AS_HELP_STRING([--enable-loadable-i18n], - [Controls loadable i18n module support]), - [XLIB_LOADABLE_I18N=$enableval], - [XLIB_LOADABLE_I18N="no"]) -if test x$XLIB_LOADABLE_I18N = xyes; then - if test x$HAVE_LOADABLE_MODULES = xno; then - AC_MSG_ERROR([Loadable module support is required to enable loadable i18n module support]) - fi - AC_DEFINE(USE_DYNAMIC_LC,1, - [Split some i18n functions into loadable modules]) - AC_SUBST(I18N_MODULE_LIBS,'${top_builddir}/src/libX11.la') -fi -AC_MSG_RESULT($XLIB_LOADABLE_I18N) - -AM_CONDITIONAL(XLIB_LOADABLE_I18N, test x$XLIB_LOADABLE_I18N = xyes) - -AC_MSG_CHECKING([if loadable Xcursor library support should be enabled]) -AC_ARG_ENABLE(loadable-xcursor, - AS_HELP_STRING([--disable-loadable-xcursor], - [Controls loadable xcursor library support]), - [XLIB_LOADABLE_XCURSOR=$enableval], - [XLIB_LOADABLE_XCURSOR=$HAVE_LOADABLE_MODULES]) -if test x$XLIB_LOADABLE_XCURSOR = xyes; then - AC_DEFINE(USE_DYNAMIC_XCURSOR,1, - [Use the X cursor library to load cursors]) -fi -AC_MSG_RESULT($XLIB_LOADABLE_XCURSOR) - -# Checks for header files. -AC_CHECK_HEADERS([sys/select.h]) - -# Checks for typedefs, structures, and compiler characteristics. - -# Checks for library functions. -AC_CHECK_FUNCS([strtol]) -# Used in lcFile.c (see also --enable-xlocaledir settings below) -XLOCALEDIR_IS_SAFE="no" -AC_CHECK_FUNC([issetugid], [XLOCALEDIR_IS_SAFE="yes"] - AC_DEFINE(HASSETUGID,1,[Has issetugid() function])) -AC_CHECK_FUNC([getresuid], [XLOCALEDIR_IS_SAFE="yes"] - AC_DEFINE(HASGETRESUID,1,[Has getresuid() & getresgid() functions])) -# Used in Font.c -AC_CHECK_FUNC([shmat], AC_DEFINE(HAS_SHM,1,[Has shm*() functions])) - -# Checks for system services -# AC_PATH_XTRA - -# arch specific things -WCHAR32="1" -case $host_os in - os2*) os2="true" ; WCHAR32="0" ;; - *) ;; -esac -AC_SUBST(WCHAR32) - -AM_CONDITIONAL(OS2, test x$os2 = xtrue) - -AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto]) -if test "x$LAUNCHD" = xauto; then - unset LAUNCHD - AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin]) -fi - -if test "x$LAUNCHD" = xyes ; then - AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available]) - AC_DEFINE(TRANS_REOPEN, 1, [launchd support available]) -fi - -AC_ARG_ENABLE(xthreads, - AS_HELP_STRING([--disable-xthreads], - [Disable Xlib support for Multithreading]), - [xthreads=$enableval],[xthreads=yes]) - -AC_CHECK_LIB(c, getpwuid_r, [mtsafeapi="yes"], [mtsafeapi="no"]) - -case x$xthreads in -xyes) - AC_DEFINE(XTHREADS,1,[Whether libX11 is compiled with thread support]) - if test x$mtsafeapi = xyes - then - AC_DEFINE(XUSE_MTSAFE_API,1,[Whether libX11 needs to use MT safe API's]) - fi - ;; -*) - ;; -esac - -AC_CHECK_LIB(c, pthread_self, [thrstubs="no"], [thrstubs="yes"]) -AM_CONDITIONAL(THRSTUBS, test x$thrstubs = xyes) - -# XXX incomplete, please fill this in -if test x$xthreads = xyes ; then - case $host_os in - linux*|gnu*|k*bsd*-gnu) - XTHREADLIB=-lpthread ;; - netbsd*) - XTHREAD_CFLAGS="-D_POSIX_THREAD_SAFE_FUNCTIONS" - XTHREADLIB="-lpthread" ;; - freebsd*) - XTHREAD_CFLAGS="-D_THREAD_SAFE" - XTHREADLIB="-pthread" ;; - dragonfly*|openbsd*) - XTHREADLIB="-pthread" ;; - solaris*) - XTHREAD_CFLAGS="-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS" ;; - esac -fi -AC_SUBST(XTHREADLIB) -AC_SUBST(XTHREAD_CFLAGS) - -AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], ) - -# -# Find keysymdef.h -# -AC_MSG_CHECKING([keysym definitions]) -KEYSYMDEFDIR=`$PKG_CONFIG --variable=includedir xproto`/X11 -FILES="keysymdef.h XF86keysym.h Sunkeysym.h DECkeysym.h HPkeysym.h" -for i in $FILES; do - if test -f "$KEYSYMDEFDIR/$i"; then - KEYSYMDEFS="$KEYSYMDEFS $KEYSYMDEFDIR/$i" - elif test "x$i" = "xkeysymdef.h"; then - AC_MSG_ERROR([Cannot find keysymdef.h]) - fi -done -AC_MSG_RESULT([$KEYSYMDEFS]) -AC_SUBST(KEYSYMDEFS) - -AM_CONDITIONAL(UDC, test xfalse = xtrue) - -AC_ARG_ENABLE(xcms, - AS_HELP_STRING([--disable-xcms], - [Disable Xlib support for CMS *EXPERIMENTAL*]), - [XCMS=$enableval],[XCMS=yes]) -AM_CONDITIONAL(XCMS, [test x$XCMS = xyes ]) -if test x"$XCMS" = "xyes"; then - AC_DEFINE(XCMS,1,[Include support for XCMS]) -fi - -AC_ARG_ENABLE(xlocale, - AS_HELP_STRING([--disable-xlocale], - [Disable Xlib locale implementation *EXPERIMENTAL*]), - [XLOCALE=$enableval],[XLOCALE=yes]) - -AM_CONDITIONAL(XLOCALE, [ test x$XLOCALE = xyes ]) -if test x"$XLOCALE" = "xyes"; then - AC_DEFINE(XLOCALE,1,[support for X Locales]) -fi - -# This disables XLOCALEDIR. Set it if you're using BuildLoadableXlibI18n, -# don't have either issetugid() or getresuid(), and you need to protect -# clients that are setgid or setuid to an id other than 0. -AC_MSG_CHECKING([if XLOCALEDIR support should be enabled]) -AC_ARG_ENABLE(xlocaledir, - AS_HELP_STRING([--enable-xlocaledir], - [Enable XLOCALEDIR environment variable support]), - [ENABLE_XLOCALEDIR=$enableval],[ENABLE_XLOCALEDIR=$XLOCALEDIR_IS_SAFE]) -if test "x$ENABLE_XLOCALEDIR" = "xno"; then - AC_DEFINE(NO_XLOCALEDIR,1,[Disable XLOCALEDIR environment variable]) -fi -AC_MSG_RESULT($ENABLE_XLOCALEDIR) - -AC_ARG_ENABLE(xf86bigfont, - AS_HELP_STRING([--disable-xf86bigfont], - [Disable XF86BigFont extension support]), - [XF86BIGFONT=$enableval],[XF86BIGFONT="yes"]) -if test "x$XF86BIGFONT" = "xyes"; then - PKG_CHECK_MODULES(BIGFONT, [xf86bigfontproto >= 1.2.0], - AC_DEFINE(XF86BIGFONT,1,[Enable XF86BIGFONT extension]),XF86BIGFONT="no") -fi - -AC_ARG_ENABLE(xkb, - AS_HELP_STRING([--disable-xkb], - [Disable XKB support *EXPERIMENTAL*]), - [XKB=$enableval],[XKB=yes]) - -AM_CONDITIONAL(XKB, [ test x$XKB = xyes ]) -if test x"$XKB" = "xyes"; then - XKBPROTO_REQUIRES="kbproto" - X11_REQUIRES="${X11_REQUIRES} kbproto inputproto" - AC_DEFINE(XKB,1,[Use XKB]) -else - XKBPROTO_REQUIRES="" -fi -AC_SUBST(XKBPROTO_REQUIRES) - -AC_FUNC_MMAP() -composecache_default=$ac_cv_func_mmap_fixed_mapped -AC_CHECK_FUNC(nl_langinfo, , [composecache_default=no]) -AC_ARG_ENABLE(composecache, - AS_HELP_STRING([--disable-composecache], - [Disable compose table cache support]), - [COMPOSECACHE=$enableval],[COMPOSECACHE=$composecache_default]) -if test x"$COMPOSECACHE" = "xyes"; then - AC_DEFINE(COMPOSECACHE,1,[Include compose table cache support]) -fi - -# Allow checking code with lint, sparse, etc. -XORG_WITH_LINT -XORG_LINT_LIBRARY([X11]) - -X11_DATADIR="${datadir}/X11" -AX_DEFINE_DIR(X11_DATADIR, X11_DATADIR, [Location of libX11 data]) -AC_SUBST(X11_DATADIR) - -X11_LIBDIR="${libdir}/X11" -AX_DEFINE_DIR(X11_LIBDIR, X11_LIBDIR, [Location of libX11 library data]) -AC_SUBST(X11_LIBDIR) - -PKG_CHECK_MODULES(X11, [$X11_REQUIRES]) -X11_CFLAGS="$X11_CFLAGS $XTHREAD_CFLAGS" - -# -# Yes, it would be nice to put the locale data in -# /usr/share, but the locale stuff includes loadable -# libraries which must be located in the same directory -# as the other locale data, so for now, everything lives -# in ${libdir} -# - -X11_LOCALEDATADIR="${X11_DATADIR}/locale" -AX_DEFINE_DIR(XLOCALEDATADIR, X11_LOCALEDATADIR, [Location of libX11 locale data]) -AC_SUBST(X11_LOCALEDATADIR) - -AC_ARG_WITH(locale-lib-dir, AS_HELP_STRING([--with-locale-lib-dir=DIR], - [Directory where locale libraries files are installed (default: $libdir/X11/locale)]), - [ X11_LOCALELIBDIR="$withval" ], - [ X11_LOCALELIBDIR="${X11_LIBDIR}/locale" ]) -AX_DEFINE_DIR(XLOCALELIBDIR, X11_LOCALELIBDIR, [Location of libX11 locale libraries]) -AC_SUBST(X11_LOCALELIBDIR) - -X11_LOCALEDIR="${X11_LOCALEDATADIR}" -AX_DEFINE_DIR(XLOCALEDIR, X11_LOCALEDIR, [Location of libX11 locale data]) -AC_SUBST(X11_LOCALEDIR) - -locales="\ - am_ET.UTF-8 armscii-8 C el_GR.UTF-8 en_US.UTF-8 fi_FI.UTF-8 \ - georgian-academy georgian-ps ibm-cp1133 iscii-dev isiri-3342 \ - iso8859-1 iso8859-10 iso8859-11 iso8859-13 iso8859-14 iso8859-15 \ - iso8859-2 iso8859-3 iso8859-4 iso8859-5 iso8859-6 iso8859-7 \ - iso8859-8 iso8859-9 iso8859-9e ja ja.JIS ja_JP.UTF-8\ - ja.S90 ja.SJIS ja.U90 ko koi8-c koi8-r \ - koi8-u ko_KR.UTF-8 microsoft-cp1251 microsoft-cp1255 \ - microsoft-cp1256 mulelao-1 nokhchi-1 pt_BR.UTF-8 ru_RU.UTF-8 \ - tatar-cyr th_TH th_TH.UTF-8 tscii-0 vi_VN.tcvn vi_VN.viscii \ - zh_CN zh_CN.gb18030 zh_CN.gbk zh_CN.UTF-8 zh_HK.big5 \ - zh_HK.big5hkscs zh_HK.UTF-8 zh_TW zh_TW.big5 zh_TW.UTF-8" -AC_SUBST(locales) - -XKEYSYMDB="${X11_DATADIR}/XKeysymDB" -AX_DEFINE_DIR(XKEYSYMDB, XKEYSYMDB, [Location of keysym database]) - -XERRORDB="${X11_DATADIR}/XErrorDB" -AX_DEFINE_DIR(XERRORDB, XERRORDB, [Location of error message database]) - -XORG_CHECK_MALLOC_ZERO - -AC_CONFIG_FILES([Makefile - include/Makefile - man/Makefile - man/xkb/Makefile - src/Makefile - src/util/Makefile - src/xcms/Makefile - src/xlibi18n/Makefile - modules/Makefile - modules/im/Makefile - modules/im/ximcp/Makefile - modules/lc/Makefile - modules/lc/def/Makefile - modules/lc/gen/Makefile - modules/lc/Utf8/Makefile - modules/lc/xlocale/Makefile - modules/om/Makefile - modules/om/generic/Makefile - src/xkb/Makefile - nls/Makefile - specs/Makefile - specs/i18n/Makefile - specs/i18n/compose/Makefile - specs/i18n/framework/Makefile - specs/i18n/localedb/Makefile - specs/i18n/trans/Makefile - specs/libX11/Makefile - specs/XIM/Makefile - specs/XKB/Makefile - x11.pc - x11-xcb.pc]) -AC_OUTPUT - -echo "" -echo "X11 will be built with the following settings:" -echo " Loadable i18n module support: "$XLIB_LOADABLE_I18N -echo " Loadable xcursor library support: "$XLIB_LOADABLE_XCURSOR -echo " Threading support: "$xthreads -echo " Use Threads safe API: "$mtsafeapi -echo " Threads stubs in libX11: "$thrstubs -echo " XCMS: "$XCMS -echo " Internationalization support: "$XLOCALE -echo " XF86BigFont support: "$XF86BIGFONT -echo " XKB support: "$XKB -echo " XLOCALEDIR environment variable support: "$ENABLE_XLOCALEDIR -echo " Compose table cache enabled: "$COMPOSECACHE -echo " Functional specs building enabled: "$build_specs -echo "" +
+# Initialize Autoconf
+AC_PREREQ([2.60])
+AC_INIT([libX11], [1.4.4],
+ [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libX11])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([src/config.h include/X11/XlibConf.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+# Set common system defines for POSIX extensions, such as _GNU_SOURCE
+# Must be called before any macros that run the compiler (like AC_PROG_LIBTOOL)
+# to avoid autoconf errors.
+AC_USE_SYSTEM_EXTENSIONS
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require xorg-macros minimum of 1.15 for fop minimum version
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.15 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.15)
+XORG_DEFAULT_OPTIONS
+XORG_ENABLE_SPECS
+XORG_WITH_XMLTO(0.0.22)
+XORG_WITH_FOP([],[no])
+XORG_WITH_XSLTPROC
+XORG_CHECK_SGML_DOCTOOLS(1.9)
+XORG_PROG_RAWCPP
+XORG_WITH_PERL
+
+# Required when PKG_CHECK_MODULES called within an if statement
+PKG_PROG_PKG_CONFIG
+
+if test x"$CC_FOR_BUILD" = x; then
+ if test x"$cross_compiling" = xyes; then
+ AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc)
+ else
+ CC_FOR_BUILD="$CC"
+ fi
+fi
+AC_SUBST([CC_FOR_BUILD])
+
+if test x"$CPPFLAGS_FOR_BUILD" = x; then
+ if test ! x"$cross_compiling" = xyes; then
+ CPPFLAGS_FOR_BUILD=${CPPFLAGS}
+ fi
+fi
+AC_SUBST(CPPFLAGS_FOR_BUILD)
+
+if test x"$CFLAGS_FOR_BUILD" = x; then
+ if test ! x"$cross_compiling" = xyes; then
+ CFLAGS_FOR_BUILD=${CFLAGS}
+ fi
+fi
+AC_SUBST(CFLAGS_FOR_BUILD)
+
+if test x"$LDFLAGS_FOR_BUILD" = x; then
+ if test ! x"$cross_compiling" = xyes; then
+ LDFLAGS_FOR_BUILD=${LDFLAGS}
+ fi
+fi
+AC_SUBST(LDFLAGS_FOR_BUILD)
+
+# Checks for pkg-config packages
+
+# Always required
+X11_REQUIRES='xproto >= 7.0.17 xextproto xtrans xcb >= 1.1.92'
+X11_EXTRA_DEPS="xcb >= 1.1.92"
+
+PKG_PROG_PKG_CONFIG()
+
+AC_SUBST(X11_EXTRA_DEPS)
+
+# Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
+# was not expanded, since libX11 with no transport types is rather useless.
+#
+# If you're seeing an error here, be sure you installed the lib/xtrans module
+# first and if it's not in the default location, that you set the ACLOCAL
+# environment variable to find it, such as:
+# ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
+m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$])
+
+# Transport selection macro from xtrans.m4
+XTRANS_CONNECTION_FLAGS
+
+# Secure RPC detection macro from xtrans.m4
+XTRANS_SECURE_RPC_FLAGS
+
+# Preferred order to try transports for local connections
+AC_MSG_CHECKING([what order to try transports in for local connections])
+DEFAULT_LOCAL_TRANS=""
+case $host_os in
+ solaris*)
+ # On Solaris 2.6 through 9, named pipes (LOCAL_TRANS) were
+ # faster than Unix domain sockets, but on Solaris 10 & later,
+ # Unix domain sockets are faster now.
+ if test "$UNIXCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}UNIX_TRANS"
+ fi
+ if test "$LOCALCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS"
+ fi
+ if test "$TCPCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS"
+ fi
+ ;;
+ linux*)
+ # LOCAL_TRANS is used for abstract sockets.
+ if test "$UNIXCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS,UNIX_TRANS"
+ fi
+ if test "$TCPCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS"
+ fi
+ ;;
+ *)
+ if test "$LOCALCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}LOCAL_TRANS"
+ fi
+ if test "$UNIXCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}UNIX_TRANS"
+ fi
+ if test "$TCPCONN" = "yes" ; then
+ if test ! "x$DEFAULT_LOCAL_TRANS" = "x" ; then
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS},"
+ fi
+ DEFAULT_LOCAL_TRANS="${DEFAULT_LOCAL_TRANS}TCP_TRANS"
+ fi
+ ;;
+esac
+
+AC_ARG_WITH(local-transport-order,
+ AS_HELP_STRING([--with-local-transport-order=LIST], [preference sorted list of transport types to try for local connections]),
+ [LOCAL_TRANSPORT_LIST=$withval],
+ [LOCAL_TRANSPORT_LIST=$DEFAULT_LOCAL_TRANS])
+AC_DEFINE_UNQUOTED([LOCAL_TRANSPORT_LIST], [$LOCAL_TRANSPORT_LIST],
+ [preference sorted list of transport types to try for local connections])
+AC_MSG_RESULT([$LOCAL_TRANSPORT_LIST])
+
+# Check for dlopen
+AC_MSG_CHECKING([if run-time linking is supported])
+AC_SEARCH_LIBS(dlopen,[dl svld])
+if test "x$ac_cv_search_dlopen" = xno; then
+ AC_SEARCH_LIBS(shl_load,[dld])
+ if test "x$ac_cv_search_shl_load" != xno; then
+ AC_DEFINE(HAVE_SHL_LOAD,1,
+ [Use shl_load to load shared libraries])
+ AC_CHECK_HEADERS([dl.h])
+ fi
+else
+ AC_DEFINE(HAVE_DLOPEN,1,[Use dlopen to load shared libraries])
+ AC_CHECK_HEADERS([dlfcn.h])
+fi
+if test x$ac_cv_header_dlcfn_h -o x$ac_cv_header_dl_h; then
+ HAVE_LOADABLE_MODULES=yes
+else
+ HAVE_LOADABLE_MODULES=no
+fi
+AC_MSG_RESULT($HAVE_LOADABLE_MODULES)
+
+AC_MSG_CHECKING([if loadable i18n module support should be enabled])
+AC_ARG_ENABLE(loadable-i18n,
+ AS_HELP_STRING([--enable-loadable-i18n],
+ [Controls loadable i18n module support]),
+ [XLIB_LOADABLE_I18N=$enableval],
+ [XLIB_LOADABLE_I18N="no"])
+if test x$XLIB_LOADABLE_I18N = xyes; then
+ if test x$HAVE_LOADABLE_MODULES = xno; then
+ AC_MSG_ERROR([Loadable module support is required to enable loadable i18n module support])
+ fi
+ AC_DEFINE(USE_DYNAMIC_LC,1,
+ [Split some i18n functions into loadable modules])
+ AC_SUBST(I18N_MODULE_LIBS,'${top_builddir}/src/libX11.la')
+fi
+AC_MSG_RESULT($XLIB_LOADABLE_I18N)
+
+AM_CONDITIONAL(XLIB_LOADABLE_I18N, test x$XLIB_LOADABLE_I18N = xyes)
+
+AC_MSG_CHECKING([if loadable Xcursor library support should be enabled])
+AC_ARG_ENABLE(loadable-xcursor,
+ AS_HELP_STRING([--disable-loadable-xcursor],
+ [Controls loadable xcursor library support]),
+ [XLIB_LOADABLE_XCURSOR=$enableval],
+ [XLIB_LOADABLE_XCURSOR=$HAVE_LOADABLE_MODULES])
+if test x$XLIB_LOADABLE_XCURSOR = xyes; then
+ AC_DEFINE(USE_DYNAMIC_XCURSOR,1,
+ [Use the X cursor library to load cursors])
+fi
+AC_MSG_RESULT($XLIB_LOADABLE_XCURSOR)
+
+# Checks for header files.
+AC_CHECK_HEADERS([sys/select.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+
+# Checks for library functions.
+AC_CHECK_FUNCS([strtol])
+# Used in lcFile.c (see also --enable-xlocaledir settings below)
+XLOCALEDIR_IS_SAFE="no"
+AC_CHECK_FUNC([issetugid], [XLOCALEDIR_IS_SAFE="yes"]
+ AC_DEFINE(HASSETUGID,1,[Has issetugid() function]))
+AC_CHECK_FUNC([getresuid], [XLOCALEDIR_IS_SAFE="yes"]
+ AC_DEFINE(HASGETRESUID,1,[Has getresuid() & getresgid() functions]))
+# Used in Font.c
+AC_CHECK_FUNC([shmat], AC_DEFINE(HAS_SHM,1,[Has shm*() functions]))
+
+# Checks for system services
+# AC_PATH_XTRA
+
+# arch specific things
+WCHAR32="1"
+case $host_os in
+ os2*) os2="true" ; WCHAR32="0" ;;
+ *) ;;
+esac
+AC_SUBST(WCHAR32)
+
+AM_CONDITIONAL(OS2, test x$os2 = xtrue)
+
+AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
+if test "x$LAUNCHD" = xauto; then
+ unset LAUNCHD
+ AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
+fi
+
+if test "x$LAUNCHD" = xyes ; then
+ AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
+ AC_DEFINE(TRANS_REOPEN, 1, [launchd support available])
+fi
+
+AC_ARG_ENABLE(xthreads,
+ AS_HELP_STRING([--disable-xthreads],
+ [Disable Xlib support for Multithreading]),
+ [xthreads=$enableval],[xthreads=yes])
+
+AC_CHECK_LIB(c, getpwuid_r, [mtsafeapi="yes"], [mtsafeapi="no"])
+
+case x$xthreads in
+xyes)
+ AC_DEFINE(XTHREADS,1,[Whether libX11 is compiled with thread support])
+ if test x$mtsafeapi = xyes
+ then
+ AC_DEFINE(XUSE_MTSAFE_API,1,[Whether libX11 needs to use MT safe API's])
+ fi
+ ;;
+*)
+ ;;
+esac
+
+AC_CHECK_LIB(c, pthread_self, [thrstubs="no"], [thrstubs="yes"])
+AM_CONDITIONAL(THRSTUBS, test x$thrstubs = xyes)
+
+# XXX incomplete, please fill this in
+if test x$xthreads = xyes ; then
+ case $host_os in
+ linux*|gnu*|k*bsd*-gnu)
+ XTHREADLIB=-lpthread ;;
+ netbsd*)
+ XTHREAD_CFLAGS="-D_POSIX_THREAD_SAFE_FUNCTIONS"
+ XTHREADLIB="-lpthread" ;;
+ freebsd*)
+ XTHREAD_CFLAGS="-D_THREAD_SAFE"
+ XTHREADLIB="-pthread" ;;
+ dragonfly*|openbsd*)
+ XTHREADLIB="-pthread" ;;
+ solaris*)
+ XTHREAD_CFLAGS="-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS" ;;
+ esac
+fi
+AC_SUBST(XTHREADLIB)
+AC_SUBST(XTHREAD_CFLAGS)
+
+AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+
+#
+# Find keysymdef.h
+#
+AC_MSG_CHECKING([keysym definitions])
+KEYSYMDEFDIR=`$PKG_CONFIG --variable=includedir xproto`/X11
+FILES="keysymdef.h XF86keysym.h Sunkeysym.h DECkeysym.h HPkeysym.h"
+for i in $FILES; do
+ if test -f "$KEYSYMDEFDIR/$i"; then
+ KEYSYMDEFS="$KEYSYMDEFS $KEYSYMDEFDIR/$i"
+ elif test "x$i" = "xkeysymdef.h"; then
+ AC_MSG_ERROR([Cannot find keysymdef.h])
+ fi
+done
+AC_MSG_RESULT([$KEYSYMDEFS])
+AC_SUBST(KEYSYMDEFS)
+
+AM_CONDITIONAL(UDC, test xfalse = xtrue)
+
+AC_ARG_ENABLE(xcms,
+ AS_HELP_STRING([--disable-xcms],
+ [Disable Xlib support for CMS *EXPERIMENTAL*]),
+ [XCMS=$enableval],[XCMS=yes])
+AM_CONDITIONAL(XCMS, [test x$XCMS = xyes ])
+if test x"$XCMS" = "xyes"; then
+ AC_DEFINE(XCMS,1,[Include support for XCMS])
+fi
+
+AC_ARG_ENABLE(xlocale,
+ AS_HELP_STRING([--disable-xlocale],
+ [Disable Xlib locale implementation *EXPERIMENTAL*]),
+ [XLOCALE=$enableval],[XLOCALE=yes])
+
+AM_CONDITIONAL(XLOCALE, [ test x$XLOCALE = xyes ])
+if test x"$XLOCALE" = "xyes"; then
+ AC_DEFINE(XLOCALE,1,[support for X Locales])
+fi
+
+# This disables XLOCALEDIR. Set it if you're using BuildLoadableXlibI18n,
+# don't have either issetugid() or getresuid(), and you need to protect
+# clients that are setgid or setuid to an id other than 0.
+AC_MSG_CHECKING([if XLOCALEDIR support should be enabled])
+AC_ARG_ENABLE(xlocaledir,
+ AS_HELP_STRING([--enable-xlocaledir],
+ [Enable XLOCALEDIR environment variable support]),
+ [ENABLE_XLOCALEDIR=$enableval],[ENABLE_XLOCALEDIR=$XLOCALEDIR_IS_SAFE])
+if test "x$ENABLE_XLOCALEDIR" = "xno"; then
+ AC_DEFINE(NO_XLOCALEDIR,1,[Disable XLOCALEDIR environment variable])
+fi
+AC_MSG_RESULT($ENABLE_XLOCALEDIR)
+
+AC_ARG_ENABLE(xf86bigfont,
+ AS_HELP_STRING([--disable-xf86bigfont],
+ [Disable XF86BigFont extension support]),
+ [XF86BIGFONT=$enableval],[XF86BIGFONT="yes"])
+if test "x$XF86BIGFONT" = "xyes"; then
+ PKG_CHECK_MODULES(BIGFONT, [xf86bigfontproto >= 1.2.0],
+ AC_DEFINE(XF86BIGFONT,1,[Enable XF86BIGFONT extension]),XF86BIGFONT="no")
+fi
+
+AC_ARG_ENABLE(xkb,
+ AS_HELP_STRING([--disable-xkb],
+ [Disable XKB support *EXPERIMENTAL*]),
+ [XKB=$enableval],[XKB=yes])
+
+AM_CONDITIONAL(XKB, [ test x$XKB = xyes ])
+if test x"$XKB" = "xyes"; then
+ XKBPROTO_REQUIRES="kbproto"
+ X11_REQUIRES="${X11_REQUIRES} kbproto inputproto"
+ AC_DEFINE(XKB,1,[Use XKB])
+else
+ XKBPROTO_REQUIRES=""
+fi
+AC_SUBST(XKBPROTO_REQUIRES)
+
+AC_FUNC_MMAP()
+composecache_default=$ac_cv_func_mmap_fixed_mapped
+AC_CHECK_FUNC(nl_langinfo, , [composecache_default=no])
+AC_ARG_ENABLE(composecache,
+ AS_HELP_STRING([--disable-composecache],
+ [Disable compose table cache support]),
+ [COMPOSECACHE=$enableval],[COMPOSECACHE=$composecache_default])
+if test x"$COMPOSECACHE" = "xyes"; then
+ AC_DEFINE(COMPOSECACHE,1,[Include compose table cache support])
+fi
+
+# Allow checking code with lint, sparse, etc.
+XORG_WITH_LINT
+XORG_LINT_LIBRARY([X11])
+
+X11_DATADIR="${datadir}/X11"
+AX_DEFINE_DIR(X11_DATADIR, X11_DATADIR, [Location of libX11 data])
+AC_SUBST(X11_DATADIR)
+
+X11_LIBDIR="${libdir}/X11"
+AX_DEFINE_DIR(X11_LIBDIR, X11_LIBDIR, [Location of libX11 library data])
+AC_SUBST(X11_LIBDIR)
+
+PKG_CHECK_MODULES(X11, [$X11_REQUIRES])
+X11_CFLAGS="$X11_CFLAGS $XTHREAD_CFLAGS"
+
+#
+# Yes, it would be nice to put the locale data in
+# /usr/share, but the locale stuff includes loadable
+# libraries which must be located in the same directory
+# as the other locale data, so for now, everything lives
+# in ${libdir}
+#
+
+X11_LOCALEDATADIR="${X11_DATADIR}/locale"
+AX_DEFINE_DIR(XLOCALEDATADIR, X11_LOCALEDATADIR, [Location of libX11 locale data])
+AC_SUBST(X11_LOCALEDATADIR)
+
+AC_ARG_WITH(locale-lib-dir, AS_HELP_STRING([--with-locale-lib-dir=DIR],
+ [Directory where locale libraries files are installed (default: $libdir/X11/locale)]),
+ [ X11_LOCALELIBDIR="$withval" ],
+ [ X11_LOCALELIBDIR="${X11_LIBDIR}/locale" ])
+AX_DEFINE_DIR(XLOCALELIBDIR, X11_LOCALELIBDIR, [Location of libX11 locale libraries])
+AC_SUBST(X11_LOCALELIBDIR)
+
+X11_LOCALEDIR="${X11_LOCALEDATADIR}"
+AX_DEFINE_DIR(XLOCALEDIR, X11_LOCALEDIR, [Location of libX11 locale data])
+AC_SUBST(X11_LOCALEDIR)
+
+locales="\
+ am_ET.UTF-8 armscii-8 C el_GR.UTF-8 en_US.UTF-8 fi_FI.UTF-8 \
+ georgian-academy georgian-ps ibm-cp1133 iscii-dev isiri-3342 \
+ iso8859-1 iso8859-10 iso8859-11 iso8859-13 iso8859-14 iso8859-15 \
+ iso8859-2 iso8859-3 iso8859-4 iso8859-5 iso8859-6 iso8859-7 \
+ iso8859-8 iso8859-9 iso8859-9e ja ja.JIS ja_JP.UTF-8\
+ ja.S90 ja.SJIS ja.U90 ko koi8-c koi8-r \
+ koi8-u ko_KR.UTF-8 microsoft-cp1251 microsoft-cp1255 \
+ microsoft-cp1256 mulelao-1 nokhchi-1 pt_BR.UTF-8 ru_RU.UTF-8 \
+ tatar-cyr th_TH th_TH.UTF-8 tscii-0 vi_VN.tcvn vi_VN.viscii \
+ zh_CN zh_CN.gb18030 zh_CN.gbk zh_CN.UTF-8 zh_HK.big5 \
+ zh_HK.big5hkscs zh_HK.UTF-8 zh_TW zh_TW.big5 zh_TW.UTF-8"
+AC_SUBST(locales)
+
+XKEYSYMDB="${X11_DATADIR}/XKeysymDB"
+AX_DEFINE_DIR(XKEYSYMDB, XKEYSYMDB, [Location of keysym database])
+
+XERRORDB="${X11_DATADIR}/XErrorDB"
+AX_DEFINE_DIR(XERRORDB, XERRORDB, [Location of error message database])
+
+XORG_CHECK_MALLOC_ZERO
+
+AC_CONFIG_FILES([Makefile
+ include/Makefile
+ man/Makefile
+ man/xkb/Makefile
+ src/Makefile
+ src/util/Makefile
+ src/xcms/Makefile
+ src/xlibi18n/Makefile
+ modules/Makefile
+ modules/im/Makefile
+ modules/im/ximcp/Makefile
+ modules/lc/Makefile
+ modules/lc/def/Makefile
+ modules/lc/gen/Makefile
+ modules/lc/Utf8/Makefile
+ modules/lc/xlocale/Makefile
+ modules/om/Makefile
+ modules/om/generic/Makefile
+ src/xkb/Makefile
+ nls/Makefile
+ specs/Makefile
+ specs/i18n/Makefile
+ specs/i18n/compose/Makefile
+ specs/i18n/framework/Makefile
+ specs/i18n/localedb/Makefile
+ specs/i18n/trans/Makefile
+ specs/libX11/Makefile
+ specs/XIM/Makefile
+ specs/XKB/Makefile
+ x11.pc
+ x11-xcb.pc])
+AC_OUTPUT
+
+echo ""
+echo "X11 will be built with the following settings:"
+echo " Loadable i18n module support: "$XLIB_LOADABLE_I18N
+echo " Loadable xcursor library support: "$XLIB_LOADABLE_XCURSOR
+echo " Threading support: "$xthreads
+echo " Use Threads safe API: "$mtsafeapi
+echo " Threads stubs in libX11: "$thrstubs
+echo " XCMS: "$XCMS
+echo " Internationalization support: "$XLOCALE
+echo " XF86BigFont support: "$XF86BIGFONT
+echo " XKB support: "$XKB
+echo " XLOCALEDIR environment variable support: "$ENABLE_XLOCALEDIR
+echo " Compose table cache enabled: "$COMPOSECACHE
+echo " Functional specs building enabled: "$build_specs
+echo ""
diff --git a/libX11/cpprules.mak b/libX11/cpprules.mak new file mode 100644 index 000000000..9f485ac0d --- /dev/null +++ b/libX11/cpprules.mak @@ -0,0 +1,19 @@ +
+ifdef x11thislocaledir
+
+$(x11thislocaledir)\%: %.pre
+ cl /nologo /EP $< -DXCOMM\#\# > $@
+
+$(x11thislocaledir):
+ $(CREATEDIR)
+
+all: $(x11thislocaledir)
+endif
+
+$(eval $(locales:%=$(X11_LOCALEDATADIR)\%\XLC_LOCALE : %\XLC_LOCALE.pre$n cl /nologo /EP $$< -DXCOMM\#\# > $$@$n))
+
+$(eval $(locales:%=$(X11_LOCALEDATADIR)\%\Compose : %\Compose.pre$n cl /nologo /EP $$< -DXCOMM\#\# > $$@$n))
+
+$(eval $(locales:%=$(X11_LOCALEDATADIR)\%\XI18N_OBJS : $(X11_LOCALEDATADIR)\% %\XI18N_OBJS$n copy %\XI18N_OBJS $$@$n))
+
+$(eval $(locales:%=$(X11_LOCALEDATADIR)\% :$n mkdir $$@$n ))
diff --git a/libX11/docbook.am b/libX11/docbook.am index 2ffb7e60a..e94e975f6 100644 --- a/libX11/docbook.am +++ b/libX11/docbook.am @@ -1,97 +1,97 @@ -# -# Generate output formats for a single DocBook/XML with/without chapters -# -# Variables set by the calling Makefile: -# shelfdir: the location where the docs/specs are installed. Typically $(docdir) -# docbook: the main DocBook/XML file, no chapters, appendix or image files -# chapters: all files pulled in by an XInclude statement and images. -# - -# -# This makefile is intended for Users Documentation and Functional Specifications. -# Do not use for Developer Documentation which is not installed and does not require olink. -# Refer to http://www.x.org/releases/X11R7.6/doc/xorg-docs/ReleaseNotes.html#id2584393 -# for an explanation on documents classification. -# - -# DocBook/XML generated output formats to be installed -shelf_DATA = - -# DocBook/XML file with chapters, appendix and images it includes -dist_shelf_DATA = $(docbook) $(chapters) - -if HAVE_XMLTO -# -# Generate DocBook/XML output formats with or without stylesheets -# - -# Stylesheets are available if the package xorg-sgml-doctools is installed -if HAVE_STYLESHEETS - -# The location where all cross reference databases are installed -sgmldbsdir = $(XORG_SGML_PATH)/X11/dbs -masterdb = "$(sgmldbsdir)/masterdb$(suffix $@).xml" -XMLTO_FLAGS = \ - --searchpath "$(XORG_SGML_PATH)/X11" \ - --stringparam target.database.document=$(masterdb) \ - --stringparam current.docid="$(<:.xml=)" \ - --stringparam collect.xref.targets="no" - -XMLTO_XHTML_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl \ - --stringparam html.stylesheet=$(STYLESHEET_SRCDIR)/xorg.css - -XMLTO_FO_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl -endif HAVE_STYLESHEETS - -shelf_DATA += $(docbook:.xml=.html) -%.html: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) xhtml-nochunks $< - -if HAVE_FOP -shelf_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps) -%.pdf: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop pdf $< -%.ps: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop ps $< -endif HAVE_FOP - -if HAVE_XMLTO_TEXT -shelf_DATA += $(docbook:.xml=.txt) -%.txt: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) txt $< -endif HAVE_XMLTO_TEXT - -# -# Generate documents cross-reference target databases -# - -# This is only possible if the xorg-sgml-doctools package is installed -if HAVE_STYLESHEETS -if HAVE_XSLTPROC - -# DocBook/XML generated document cross-reference database -shelf_DATA += $(docbook:.xml=.html.db) $(docbook:.xml=.fo.db) - -# Generate DocBook/XML document cross-reference database -# Flags for the XSL Transformation processor generating xref target databases -XSLTPROC_FLAGS = \ - --path "$(XORG_SGML_PATH)/X11" \ - --stringparam targets.filename "$@" \ - --stringparam collect.xref.targets "only" \ - --nonet --xinclude - -%.html.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $< - -%.fo.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< - -endif HAVE_XSLTPROC -endif HAVE_STYLESHEETS -endif HAVE_XMLTO - -CLEANFILES = $(shelf_DATA) +#
+# Generate output formats for a single DocBook/XML with/without chapters
+#
+# Variables set by the calling Makefile:
+# shelfdir: the location where the docs/specs are installed. Typically $(docdir)
+# docbook: the main DocBook/XML file, no chapters, appendix or image files
+# chapters: all files pulled in by an XInclude statement and images.
+#
+
+#
+# This makefile is intended for Users Documentation and Functional Specifications.
+# Do not use for Developer Documentation which is not installed and does not require olink.
+# Refer to http://www.x.org/releases/X11R7.6/doc/xorg-docs/ReleaseNotes.html#id2584393
+# for an explanation on documents classification.
+#
+
+# DocBook/XML generated output formats to be installed
+shelf_DATA =
+
+# DocBook/XML file with chapters, appendix and images it includes
+dist_shelf_DATA = $(docbook) $(chapters)
+
+if HAVE_XMLTO
+#
+# Generate DocBook/XML output formats with or without stylesheets
+#
+
+# Stylesheets are available if the package xorg-sgml-doctools is installed
+if HAVE_STYLESHEETS
+
+# The location where all cross reference databases are installed
+sgmldbsdir = $(XORG_SGML_PATH)/X11/dbs
+masterdb = "$(sgmldbsdir)/masterdb$(suffix $@).xml"
+XMLTO_FLAGS = \
+ --searchpath "$(XORG_SGML_PATH)/X11" \
+ --stringparam target.database.document=$(masterdb) \
+ --stringparam current.docid="$(<:.xml=)" \
+ --stringparam collect.xref.targets="no"
+
+XMLTO_XHTML_FLAGS = \
+ -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl \
+ --stringparam html.stylesheet=$(STYLESHEET_SRCDIR)/xorg.css
+
+XMLTO_FO_FLAGS = \
+ -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl
+endif HAVE_STYLESHEETS
+
+shelf_DATA += $(docbook:.xml=.html)
+%.html: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) xhtml-nochunks $<
+
+if HAVE_FOP
+shelf_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps)
+%.pdf: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop pdf $<
+%.ps: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop ps $<
+endif HAVE_FOP
+
+if HAVE_XMLTO_TEXT
+shelf_DATA += $(docbook:.xml=.txt)
+%.txt: %.xml $(chapters)
+ $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) txt $<
+endif HAVE_XMLTO_TEXT
+
+#
+# Generate documents cross-reference target databases
+#
+
+# This is only possible if the xorg-sgml-doctools package is installed
+if HAVE_STYLESHEETS
+if HAVE_XSLTPROC
+
+# DocBook/XML generated document cross-reference database
+shelf_DATA += $(docbook:.xml=.html.db) $(docbook:.xml=.fo.db)
+
+# Generate DocBook/XML document cross-reference database
+# Flags for the XSL Transformation processor generating xref target databases
+XSLTPROC_FLAGS = \
+ --path "$(XORG_SGML_PATH)/X11" \
+ --stringparam targets.filename "$@" \
+ --stringparam collect.xref.targets "only" \
+ --nonet --xinclude
+
+%.html.db: %.xml $(chapters)
+ $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \
+ http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $<
+
+%.fo.db: %.xml $(chapters)
+ $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \
+ http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $<
+
+endif HAVE_XSLTPROC
+endif HAVE_STYLESHEETS
+endif HAVE_XMLTO
+
+CLEANFILES = $(shelf_DATA)
diff --git a/libX11/include/X11/Xlib.h b/libX11/include/X11/Xlib.h index 5c6c77077..b32390894 100644 --- a/libX11/include/X11/Xlib.h +++ b/libX11/include/X11/Xlib.h @@ -83,8 +83,8 @@ _Xmblen( typedef char *XPointer; -#define Bool int -#define Status int +typedef int Bool; +typedef int Status; #define True 1 #define False 0 diff --git a/libX11/include/X11/Xlibint.h b/libX11/include/X11/Xlibint.h index 2ce356d15..a55938b5b 100644 --- a/libX11/include/X11/Xlibint.h +++ b/libX11/include/X11/Xlibint.h @@ -1,1402 +1,1402 @@ - -/* - -Copyright 1984, 1985, 1987, 1989, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifndef _X11_XLIBINT_H_ -#define _X11_XLIBINT_H_ 1 - -/* - * Xlibint.h - Header definition and support file for the internal - * support routines used by the C subroutine interface - * library (Xlib) to the X Window System. - * - * Warning, there be dragons here.... - */ - -#include <X11/Xlib.h> -#include <X11/Xproto.h> /* to declare xEvent */ -#include <X11/XlibConf.h> /* for configured options like XTHREADS */ - -#ifdef WIN32 -#define _XFlush _XFlushIt -#endif - -/* - * If your BytesReadable correctly detects broken connections, then - * you should NOT define XCONN_CHECK_FREQ. - */ -#ifndef XCONN_CHECK_FREQ -#define XCONN_CHECK_FREQ 256 -#endif - -struct _XGC -{ - XExtData *ext_data; /* hook for extension to hang data */ - GContext gid; /* protocol ID for graphics context */ - Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ - Bool dashes; /* boolean: TRUE if dash-list is really a list */ - unsigned long dirty;/* cache dirty bits */ - XGCValues values; /* shadow structure of values */ -}; - -struct _XDisplay -{ - XExtData *ext_data; /* hook for extension to hang data */ - struct _XFreeFuncs *free_funcs; /* internal free functions */ - int fd; /* Network socket. */ - int conn_checker; /* ugly thing used by _XEventsQueued */ - int proto_major_version;/* maj. version of server's X protocol */ - int proto_minor_version;/* minor version of server's X protocol */ - char *vendor; /* vendor of the server hardware */ - XID resource_base; /* resource ID base */ - XID resource_mask; /* resource ID mask bits */ - XID resource_id; /* allocator current ID */ - int resource_shift; /* allocator shift to correct bits */ - XID (*resource_alloc)( /* allocator function */ - struct _XDisplay* - ); - int byte_order; /* screen byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* padding and data requirements */ - int bitmap_pad; /* padding requirements on bitmaps */ - int bitmap_bit_order; /* LeastSignificant or MostSignificant */ - int nformats; /* number of pixmap formats in list */ - ScreenFormat *pixmap_format; /* pixmap format list */ - int vnumber; /* Xlib's X protocol version number. */ - int release; /* release of the server */ - struct _XSQEvent *head, *tail; /* Input event queue. */ - int qlen; /* Length of input event queue */ - unsigned long last_request_read; /* seq number of last event read */ - unsigned long request; /* sequence number of last request. */ - char *last_req; /* beginning of last request, or dummy */ - char *buffer; /* Output buffer starting address. */ - char *bufptr; /* Output buffer index pointer. */ - char *bufmax; /* Output buffer maximum+1 address. */ - unsigned max_request_size; /* maximum number 32 bit words in request*/ - struct _XrmHashBucketRec *db; - int (*synchandler)( /* Synchronization handler */ - struct _XDisplay* - ); - char *display_name; /* "host:display" string used on this connect*/ - int default_screen; /* default screen for operations */ - int nscreens; /* number of screens on this server*/ - Screen *screens; /* pointer to list of screens */ - unsigned long motion_buffer; /* size of motion buffer */ - volatile unsigned long flags; /* internal connection flags */ - int min_keycode; /* minimum defined keycode */ - int max_keycode; /* maximum defined keycode */ - KeySym *keysyms; /* This server's keysyms */ - XModifierKeymap *modifiermap; /* This server's modifier keymap */ - int keysyms_per_keycode;/* number of rows */ - char *xdefaults; /* contents of defaults from server */ - char *scratch_buffer; /* place to hang scratch buffer */ - unsigned long scratch_length; /* length of scratch buffer */ - int ext_number; /* extension number on this display */ - struct _XExten *ext_procs; /* extensions initialized on this display */ - /* - * the following can be fixed size, as the protocol defines how - * much address space is available. - * While this could be done using the extension vector, there - * may be MANY events processed, so a search through the extension - * list to find the right procedure for each event might be - * expensive if many extensions are being used. - */ - Bool (*event_vec[128])( /* vector for wire to event */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - Status (*wire_vec[128])( /* vector for event to wire */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - KeySym lock_meaning; /* for XLookupString */ - struct _XLockInfo *lock; /* multi-thread state, display lock */ - struct _XInternalAsync *async_handlers; /* for internal async */ - unsigned long bigreq_size; /* max size of big requests */ - struct _XLockPtrs *lock_fns; /* pointers to threads functions */ - void (*idlist_alloc)( /* XID list allocator function */ - Display * /* dpy */, - XID * /* ids */, - int /* count */ - ); - /* things above this line should not move, for binary compatibility */ - struct _XKeytrans *key_bindings; /* for XLookupString */ - Font cursor_font; /* for XCreateFontCursor */ - struct _XDisplayAtoms *atoms; /* for XInternAtom */ - unsigned int mode_switch; /* keyboard group modifiers */ - unsigned int num_lock; /* keyboard numlock modifiers */ - struct _XContextDB *context_db; /* context database */ - Bool (**error_vec)( /* vector for wire to error */ - Display * /* display */, - XErrorEvent * /* he */, - xError * /* we */ - ); - /* - * Xcms information - */ - struct { - XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ - XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ - XPointer perVisualIntensityMaps; - /* linked list of XcmsIntensityMap */ - } cms; - struct _XIMFilter *im_filters; - struct _XSQEvent *qfree; /* unallocated event queue elements */ - unsigned long next_event_serial_num; /* inserted into next queue elt */ - struct _XExten *flushes; /* Flush hooks */ - struct _XConnectionInfo *im_fd_info; /* _XRegisterInternalConnection */ - int im_fd_length; /* number of im_fd_info */ - struct _XConnWatchInfo *conn_watchers; /* XAddConnectionWatch */ - int watcher_count; /* number of conn_watchers */ - XPointer filedes; /* struct pollfd cache for _XWaitForReadable */ - int (*savedsynchandler)( /* user synchandler when Xlib usurps */ - Display * /* dpy */ - ); - XID resource_max; /* allocator max ID */ - int xcmisc_opcode; /* major opcode for XC-MISC */ - struct _XkbInfoRec *xkb_info; /* XKB info */ - struct _XtransConnInfo *trans_conn; /* transport connection object */ - struct _X11XCBPrivate *xcb; /* XCB glue private data */ - - /* Generic event cookie handling */ - unsigned int next_cookie; /* next event cookie */ - /* vector for wire to generic event, index is (extension - 128) */ - Bool (*generic_event_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* Xlib event */, - xEvent * /* wire event */); - /* vector for event copy, index is (extension - 128) */ - Bool (*generic_event_copy_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* in */, - XGenericEventCookie * /* out*/); - void *cookiejar; /* cookie events returned but not claimed */ -}; - -#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) - -/* - * define the following if you want the Data macro to be a procedure instead - */ -#ifdef CRAY -#define DataRoutineIsProcedure -#endif /* CRAY */ - -#ifndef _XEVENT_ -/* - * _QEvent datatype for use in input queueing. - */ -typedef struct _XSQEvent -{ - struct _XSQEvent *next; - XEvent event; - unsigned long qserial_num; /* so multi-threaded code can find new ones */ -} _XQEvent; -#endif - -#include <X11/Xproto.h> -#ifdef __sgi -#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ -#endif -#include <errno.h> -#define _XBCOPYFUNC _Xbcopy -#include <X11/Xfuncs.h> -#include <X11/Xosdefs.h> - -/* Utek leaves kernel macros around in include files (bleah) */ -#ifdef dirty -#undef dirty -#endif - -#include <stdlib.h> -#include <string.h> - -#include <X11/Xfuncproto.h> - -_XFUNCPROTOBEGIN - -/* - * The following definitions can be used for locking requests in multi-threaded - * address spaces. - */ -#ifdef XTHREADS -/* Author: Stephen Gildea, MIT X Consortium - * - * declarations for C Threads locking - */ - -typedef struct _LockInfoRec *LockInfoPtr; - -/* interfaces for locking.c */ -struct _XLockPtrs { - /* used by all, including extensions; do not move */ - void (*lock_display)( - Display *dpy -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line -#endif - ); - void (*unlock_display)( - Display *dpy -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line -#endif - ); -}; - -#if defined(WIN32) && !defined(_XLIBINT_) -#define _XCreateMutex_fn (*_XCreateMutex_fn_p) -#define _XFreeMutex_fn (*_XFreeMutex_fn_p) -#define _XLockMutex_fn (*_XLockMutex_fn_p) -#define _XUnlockMutex_fn (*_XUnlockMutex_fn_p) -#define _Xglobal_lock (*_Xglobal_lock_p) -#endif - -/* in XlibInt.c */ -extern void (*_XCreateMutex_fn)( - LockInfoPtr /* lock */ -); -extern void (*_XFreeMutex_fn)( - LockInfoPtr /* lock */ -); -extern void (*_XLockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif -); -extern void (*_XUnlockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif -); - -extern LockInfoPtr _Xglobal_lock; - -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d),__FILE__,__LINE__) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d),__FILE__,__LINE__) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock,__FILE__,__LINE__) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock,__FILE__,__LINE__) -#else -/* used everywhere, so must be fast if not using threads */ -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock) -#endif -#define _XCreateMutex(lock) if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock); -#define _XFreeMutex(lock) if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock); - -#else /* XTHREADS */ -#define LockDisplay(dis) -#define _XLockMutex(lock) -#define _XUnlockMutex(lock) -#define UnlockDisplay(dis) -#define _XCreateMutex(lock) -#define _XFreeMutex(lock) -#endif - -#define Xfree(ptr) free((ptr)) - -/* - * Note that some machines do not return a valid pointer for malloc(0), in - * which case we provide an alternate under the control of the - * define MALLOC_0_RETURNS_NULL. This is necessary because some - * Xlib code expects malloc(0) to return a valid pointer to storage. - */ -#if defined(MALLOC_0_RETURNS_NULL) || defined(__clang_analyzer__) - -# define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) -# define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) -# define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) - -#else - -# define Xmalloc(size) malloc((size)) -# define Xrealloc(ptr, size) realloc((ptr), (size)) -# define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) - -#endif - -#include <stddef.h> - -#define LOCKED 1 -#define UNLOCKED 0 - -#ifndef BUFSIZE -#define BUFSIZE 2048 /* X output buffer size. */ -#endif -#ifndef PTSPERBATCH -#define PTSPERBATCH 1024 /* point batching */ -#endif -#ifndef WLNSPERBATCH -#define WLNSPERBATCH 50 /* wide line batching */ -#endif -#ifndef ZLNSPERBATCH -#define ZLNSPERBATCH 1024 /* thin line batching */ -#endif -#ifndef WRCTSPERBATCH -#define WRCTSPERBATCH 10 /* wide line rectangle batching */ -#endif -#ifndef ZRCTSPERBATCH -#define ZRCTSPERBATCH 256 /* thin line rectangle batching */ -#endif -#ifndef FRCTSPERBATCH -#define FRCTSPERBATCH 256 /* filled rectangle batching */ -#endif -#ifndef FARCSPERBATCH -#define FARCSPERBATCH 256 /* filled arc batching */ -#endif -#ifndef CURSORFONT -#define CURSORFONT "cursor" /* standard cursor fonts */ -#endif - -/* - * Display flags - */ -#define XlibDisplayIOError (1L << 0) -#define XlibDisplayClosing (1L << 1) -#define XlibDisplayNoXkb (1L << 2) -#define XlibDisplayPrivSync (1L << 3) -#define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */ -#define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */ -#define XlibDisplayReply (1L << 5) /* in _XReply */ -#define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */ -#define XlibDisplayDfltRMDB (1L << 7) /* mark if RM db from XGetDefault */ - -/* - * X Protocol packetizing macros. - */ - -/* Need to start requests on 64 bit word boundaries - * on a CRAY computer so add a NoOp (127) if needed. - * A character pointer on a CRAY computer will be non-zero - * after shifting right 61 bits of it is not pointing to - * a word boundary. - */ -#ifdef WORD64 -#define WORD64ALIGN if ((long)dpy->bufptr >> 61) {\ - dpy->last_req = dpy->bufptr;\ - *(dpy->bufptr) = X_NoOperation;\ - *(dpy->bufptr+1) = 0;\ - *(dpy->bufptr+2) = 0;\ - *(dpy->bufptr+3) = 1;\ - dpy->request++;\ - dpy->bufptr += 4;\ - } -#else /* else does not require alignment on 64-bit boundaries */ -#define WORD64ALIGN -#endif /* WORD64 */ - - -/* - * GetReq - Get the next available X request packet in the buffer and - * return it. - * - * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc. - * "req" is the name of the request pointer. - * - */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetReq(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ - req->reqType = X_##name;\ - req->length = (SIZEOF(x##name##Req))>>2;\ - dpy->bufptr += SIZEOF(x##name##Req);\ - dpy->request++ - -#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ -#define GetReq(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ - req->reqType = X_/**/name;\ - req->length = (SIZEOF(x/**/name/**/Req))>>2;\ - dpy->bufptr += SIZEOF(x/**/name/**/Req);\ - dpy->request++ -#endif - -/* GetReqExtra is the same as GetReq, but allocates "n" additional - bytes after the request. "n" must be a multiple of 4! */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetReqExtra(name, n, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ - req->reqType = X_##name;\ - req->length = (SIZEOF(x##name##Req) + n)>>2;\ - dpy->bufptr += SIZEOF(x##name##Req) + n;\ - dpy->request++ -#else -#define GetReqExtra(name, n, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ - req->reqType = X_/**/name;\ - req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\ - dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\ - dpy->request++ -#endif - - -/* - * GetResReq is for those requests that have a resource ID - * (Window, Pixmap, GContext, etc.) as their single argument. - * "rid" is the name of the resource. - */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetResReq(name, rid, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ - req->reqType = X_##name;\ - req->length = 2;\ - req->id = (rid);\ - dpy->bufptr += SIZEOF(xResourceReq);\ - dpy->request++ -#else -#define GetResReq(name, rid, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ - req->reqType = X_/**/name;\ - req->length = 2;\ - req->id = (rid);\ - dpy->bufptr += SIZEOF(xResourceReq);\ - dpy->request++ -#endif - -/* - * GetEmptyReq is for those requests that have no arguments - * at all. - */ -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetEmptyReq(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (xReq *) (dpy->last_req = dpy->bufptr);\ - req->reqType = X_##name;\ - req->length = 1;\ - dpy->bufptr += SIZEOF(xReq);\ - dpy->request++ -#else -#define GetEmptyReq(name, req) \ - WORD64ALIGN\ - if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ - _XFlush(dpy);\ - req = (xReq *) (dpy->last_req = dpy->bufptr);\ - req->reqType = X_/**/name;\ - req->length = 1;\ - dpy->bufptr += SIZEOF(xReq);\ - dpy->request++ -#endif - -#ifdef WORD64 -#define MakeBigReq(req,n) \ - { \ - char _BRdat[4]; \ - unsigned long _BRlen = req->length - 1; \ - req->length = 0; \ - memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - memcpy(((char *)req) + 4, _BRdat, 4); \ - Data32(dpy, (long *)&_BRdat, 4); \ - } -#else -#ifdef LONG64 -#define MakeBigReq(req,n) \ - { \ - CARD64 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } -#else -#define MakeBigReq(req,n) \ - { \ - CARD32 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } -#endif -#endif - -#ifndef __clang_analyzer__ -#define SetReqLen(req,n,badlen) \ - if ((req->length + n) > (unsigned)65535) { \ - if (dpy->bigreq_size) { \ - MakeBigReq(req,n) \ - } else { \ - n = badlen; \ - req->length += n; \ - } \ - } else \ - req->length += n -#else -#define SetReqLen(req,n,badlen) \ - req->length += n -#endif - -#define SyncHandle() \ - if (dpy->synchandler) (*dpy->synchandler)(dpy) - -extern void _XFlushGCCache(Display *dpy, GC gc); -#define FlushGC(dpy, gc) \ - if ((gc)->dirty) _XFlushGCCache((dpy), (gc)) -/* - * Data - Place data in the buffer and pad the end to provide - * 32 bit word alignment. Transmit if the buffer fills. - * - * "dpy" is a pointer to a Display. - * "data" is a pinter to a data buffer. - * "len" is the length of the data buffer. - */ -#ifndef DataRoutineIsProcedure -#define Data(dpy, data, len) {\ - if (dpy->bufptr + (len) <= dpy->bufmax) {\ - memcpy(dpy->bufptr, data, (int)len);\ - dpy->bufptr += ((len) + 3) & ~3;\ - } else\ - _XSend(dpy, data, len);\ - } -#endif /* DataRoutineIsProcedure */ - - -/* Allocate bytes from the buffer. No padding is done, so if - * the length is not a multiple of 4, the caller must be - * careful to leave the buffer aligned after sending the - * current request. - * - * "type" is the type of the pointer being assigned to. - * "ptr" is the pointer being assigned to. - * "n" is the number of bytes to allocate. - * - * Example: - * xTextElt *elt; - * BufAlloc (xTextElt *, elt, nbytes) - */ - -#define BufAlloc(type, ptr, n) \ - if (dpy->bufptr + (n) > dpy->bufmax) \ - _XFlush (dpy); \ - ptr = (type) dpy->bufptr; \ - memset(ptr, '\0', n); \ - dpy->bufptr += (n); - -#ifdef WORD64 -#define Data16(dpy, data, len) _XData16(dpy, (short *)data, len) -#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) -#else -#define Data16(dpy, data, len) Data((dpy), (char *)(data), (len)) -#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) -#define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) -#ifdef LONG64 -#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) -extern int _XData32( - Display *dpy, - register long *data, - unsigned len -); -extern void _XRead32( - Display *dpy, - register long *data, - long len -); -#else -#define Data32(dpy, data, len) Data((dpy), (char *)(data), (len)) -#define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) -#endif -#endif /* not WORD64 */ - -#define PackData16(dpy,data,len) Data16 (dpy, data, len) -#define PackData32(dpy,data,len) Data32 (dpy, data, len) - -/* Xlib manual is bogus */ -#define PackData(dpy,data,len) PackData16 (dpy, data, len) - -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ - (((cs)->rbearing|(cs)->lbearing| \ - (cs)->ascent|(cs)->descent) == 0)) - -/* - * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit - * character. If the character is in the column and exists, then return the - * appropriate metrics (note that fonts with common per-character metrics will - * return min_bounds). If none of these hold true, try again with the default - * char. - */ -#define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \ -{ \ - cs = def; \ - if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_1D(fs,cs) \ - CI_GET_CHAR_INFO_1D (fs, fs->default_char, NULL, cs) - - - -/* - * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and - * column. This is used for fonts that have more than row zero. - */ -#define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ -{ \ - cs = def; \ - if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ - col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[((row - fs->min_byte1) * \ - (fs->max_char_or_byte2 - \ - fs->min_char_or_byte2 + 1)) + \ - (col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_2D(fs,cs) \ -{ \ - unsigned int r = (fs->default_char >> 8); \ - unsigned int c = (fs->default_char & 0xff); \ - CI_GET_CHAR_INFO_2D (fs, r, c, NULL, cs); \ -} - - -#ifdef MUSTCOPY - -/* for when 32-bit alignment is not good enough */ -#define OneDataCard32(dpy,dstaddr,srcvar) \ - { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); } - -#else - -/* srcvar must be a variable for large architecture version */ -#define OneDataCard32(dpy,dstaddr,srcvar) \ - { *(CARD32 *)(dstaddr) = (srcvar); } - -#endif /* MUSTCOPY */ - -typedef struct _XInternalAsync { - struct _XInternalAsync *next; - /* - * handler arguments: - * rep is the generic reply that caused this handler - * to be invoked. It must also be passed to _XGetAsyncReply. - * buf and len are opaque values that must be passed to - * _XGetAsyncReply or _XGetAsyncData. - * data is the closure stored in this struct. - * The handler returns True iff it handled this reply. - */ - Bool (*handler)( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ - ); - XPointer data; -} _XAsyncHandler; - -typedef struct _XAsyncEState { - unsigned long min_sequence_number; - unsigned long max_sequence_number; - unsigned char error_code; - unsigned char major_opcode; - unsigned short minor_opcode; - unsigned char last_error_received; - int error_count; -} _XAsyncErrorState; - -extern void _XDeqAsyncHandler(Display *dpy, _XAsyncHandler *handler); -#define DeqAsyncHandler(dpy,handler) { \ - if (dpy->async_handlers == (handler)) \ - dpy->async_handlers = (handler)->next; \ - else \ - _XDeqAsyncHandler(dpy, handler); \ - } - -typedef void (*FreeFuncType) ( - Display* /* display */ -); - -typedef int (*FreeModmapType) ( - XModifierKeymap* /* modmap */ -); - -/* - * This structure is private to the library. - */ -typedef struct _XFreeFuncs { - FreeFuncType atoms; /* _XFreeAtomTable */ - FreeModmapType modifiermap; /* XFreeModifiermap */ - FreeFuncType key_bindings; /* _XFreeKeyBindings */ - FreeFuncType context_db; /* _XFreeContextDB */ - FreeFuncType defaultCCCs; /* _XcmsFreeDefaultCCCs */ - FreeFuncType clientCmaps; /* _XcmsFreeClientCmaps */ - FreeFuncType intensityMaps; /* _XcmsFreeIntensityMaps */ - FreeFuncType im_filters; /* _XFreeIMFilters */ - FreeFuncType xkb; /* _XkbFreeInfo */ -} _XFreeFuncRec; - -/* types for InitExt.c */ -typedef int (*CreateGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*CopyGCType)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*FlushGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*FreeGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*CreateFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - -typedef int (*FreeFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - -typedef int (*CloseDisplayType) ( - Display* /* display */, - XExtCodes* /* codes */ -); - -typedef int (*ErrorType) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ -); - -typedef char* (*ErrorStringType) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ -); - -typedef void (*PrintErrorType)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ -); - -typedef void (*BeforeFlushType)( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ -); - -/* - * This structure is private to the library. - */ -typedef struct _XExten { /* private to extension mechanism */ - struct _XExten *next; /* next in list */ - XExtCodes codes; /* public information, all extension told */ - CreateGCType create_GC; /* routine to call when GC created */ - CopyGCType copy_GC; /* routine to call when GC copied */ - FlushGCType flush_GC; /* routine to call when GC flushed */ - FreeGCType free_GC; /* routine to call when GC freed */ - CreateFontType create_Font; /* routine to call when Font created */ - FreeFontType free_Font; /* routine to call when Font freed */ - CloseDisplayType close_display; /* routine to call when connection closed */ - ErrorType error; /* who to call when an error occurs */ - ErrorStringType error_string; /* routine to supply error string */ - char *name; /* name of this extension */ - PrintErrorType error_values; /* routine to supply error values */ - BeforeFlushType before_flush; /* routine to call when sending data */ - struct _XExten *next_flush; /* next in list of those with flushes */ -} _XExtension; - -/* extension hooks */ - -#ifdef DataRoutineIsProcedure -extern void Data(Display *dpy, char *data, long len); -#endif -extern int _XError( - Display* /* dpy */, - xError* /* rep */ -); -extern int _XIOError( - Display* /* dpy */ -) _X_NORETURN; -extern int (*_XIOErrorFunction)( - Display* /* dpy */ -); -extern int (*_XErrorFunction)( - Display* /* dpy */, - XErrorEvent* /* error_event */ -); -extern void _XEatData( - Display* /* dpy */, - unsigned long /* n */ -); -extern char *_XAllocScratch( - Display* /* dpy */, - unsigned long /* nbytes */ -); -extern char *_XAllocTemp( - Display* /* dpy */, - unsigned long /* nbytes */ -); -extern void _XFreeTemp( - Display* /* dpy */, - char* /* buf */, - unsigned long /* nbytes */ -); -extern Visual *_XVIDtoVisual( - Display* /* dpy */, - VisualID /* id */ -); -extern unsigned long _XSetLastRequestRead( - Display* /* dpy */, - xGenericReply* /* rep */ -); -extern int _XGetHostname( - char* /* buf */, - int /* maxlen */ -); -extern Screen *_XScreenOfWindow( - Display* /* dpy */, - Window /* w */ -); -extern Bool _XAsyncErrorHandler( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ -); -extern char *_XGetAsyncReply( - Display* /* dpy */, - char* /* replbuf */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - int /* extra */, - Bool /* discard */ -); -extern void _XGetAsyncData( - Display* /* dpy */, - char * /* data */, - char * /* buf */, - int /* len */, - int /* skip */, - int /* datalen */, - int /* discardtotal */ -); -extern void _XFlush( - Display* /* dpy */ -); -extern int _XEventsQueued( - Display* /* dpy */, - int /* mode */ -); -extern void _XReadEvents( - Display* /* dpy */ -); -extern int _XRead( - Display* /* dpy */, - char* /* data */, - long /* size */ -); -extern void _XReadPad( - Display* /* dpy */, - char* /* data */, - long /* size */ -); -extern void _XSend( - Display* /* dpy */, - _Xconst char* /* data */, - long /* size */ -); -extern Status _XReply( - Display* /* dpy */, - xReply* /* rep */, - int /* extra */, - Bool /* discard */ -); -extern void _XEnq( - Display* /* dpy */, - xEvent* /* event */ -); -extern void _XDeq( - Display* /* dpy */, - _XQEvent* /* prev */, - _XQEvent* /* qelt */ -); - -extern Bool _XUnknownWireEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ -); - -extern Bool _XUnknownWireEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* re */, - xEvent* /* event */ -); - -extern Bool _XUnknownCopyEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ -); - -extern Status _XUnknownNativeEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ -); - -extern Bool _XWireToEvent(Display *dpy, XEvent *re, xEvent *event); -extern Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we); -extern Bool _XPollfdCacheInit(Display *dpy); -extern void _XPollfdCacheAdd(Display *dpy, int fd); -extern void _XPollfdCacheDel(Display *dpy, int fd); -extern XID _XAllocID(Display *dpy); -extern void _XAllocIDs(Display *dpy, XID *ids, int count); - -extern int _XFreeExtData( - XExtData* /* extension */ -); - -extern int (*XESetCreateGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetCopyGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetFlushGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetFreeGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetCreateFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); - -extern int (*XESetFreeFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); - -extern int (*XESetCloseDisplay( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XExtCodes* -); - -extern int (*XESetError( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ - ) /* proc */ -))( - Display*, xError*, XExtCodes*, int* -); - -extern char* (*XESetErrorString( - Display* /* display */, - int /* extension */, - char* (*) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ - ) /* proc */ -))( - Display*, int, XExtCodes*, char*, int -); - -extern void (*XESetPrintErrorValues ( - Display* /* display */, - int /* extension */, - void (*)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ - ) /* proc */ -))( - Display*, XErrorEvent*, void* -); - -extern Bool (*XESetWireToEvent( - Display* /* display */, - int /* event_number */, - Bool (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); - -extern Bool (*XESetWireToEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, xEvent* -); - -extern Bool (*XESetCopyEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, XGenericEventCookie* -); - - -extern Status (*XESetEventToWire( - Display* /* display */, - int /* event_number */, - Status (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); - -extern Bool (*XESetWireToError( - Display* /* display */, - int /* error_number */, - Bool (*) ( - Display* /* display */, - XErrorEvent* /* he */, - xError* /* we */ - ) /* proc */ -))( - Display*, XErrorEvent*, xError* -); - -extern void (*XESetBeforeFlush( - Display* /* display */, - int /* error_number */, - void (*) ( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ - ) /* proc */ -))( - Display*, XExtCodes*, _Xconst char*, long -); - -/* internal connections for IMs */ - -typedef void (*_XInternalConnectionProc)( - Display* /* dpy */, - int /* fd */, - XPointer /* call_data */ -); - - -extern Status _XRegisterInternalConnection( - Display* /* dpy */, - int /* fd */, - _XInternalConnectionProc /* callback */, - XPointer /* call_data */ -); - -extern void _XUnregisterInternalConnection( - Display* /* dpy */, - int /* fd */ -); - -extern void _XProcessInternalConnection( - Display* /* dpy */, - struct _XConnectionInfo* /* conn_info */ -); - -/* Display structure has pointers to these */ - -struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ - int fd; - _XInternalConnectionProc read_callback; - XPointer call_data; - XPointer *watch_data; /* set/used by XConnectionWatchProc */ - struct _XConnectionInfo *next; -}; - -struct _XConnWatchInfo { /* info from XAddConnectionWatch */ - XConnectionWatchProc fn; - XPointer client_data; - struct _XConnWatchInfo *next; -}; - -#ifdef __UNIXOS2__ -extern char* __XOS2RedirRoot( - char* -); -#endif - -extern int _XTextHeight( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* count */ -); - -extern int _XTextHeight16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* count */ -); - -#if defined(WIN32) - -extern int _XOpenFile( - _Xconst char* /* path */, - int /* flags */ -); - -extern int _XOpenFileMode( - _Xconst char* /* path */, - int /* flags */, - mode_t /* mode */ -); - -extern void* _XFopenFile( - _Xconst char* /* path */, - _Xconst char* /* mode */ -); - -extern int _XAccessFile( - _Xconst char* /* path */ -); -#else -#define _XOpenFile(path,flags) open(path,flags) -#define _XOpenFileMode(path,flags,mode) open(path,flags,mode) -#define _XFopenFile(path,mode) fopen(path,mode) -#endif - -/* EvToWire.c */ -extern Status _XEventToWire(Display *dpy, XEvent *re, xEvent *event); - -extern int _XF86LoadQueryLocaleFont( - Display* /* dpy */, - _Xconst char* /* name*/, - XFontStruct** /* xfp*/, - Font* /* fidp */ -); - -extern void _XProcessWindowAttributes ( - register Display *dpy, - xChangeWindowAttributesReq *req, - register unsigned long valuemask, - register XSetWindowAttributes *attributes); - -extern int _XDefaultError( - Display *dpy, - XErrorEvent *event); - -extern int _XDefaultIOError( - Display *dpy); - -extern void _XSetClipRectangles ( - register Display *dpy, - GC gc, - int clip_x_origin, int clip_y_origin, - XRectangle *rectangles, - int n, - int ordering); - -Status _XGetWindowAttributes( - register Display *dpy, - Window w, - XWindowAttributes *attr); - -int _XPutBackEvent ( - register Display *dpy, - register XEvent *event); - -extern Bool _XIsEventCookie( - Display *dpy, - XEvent *ev); - -extern void _XFreeEventCookies( - Display *dpy); - -extern void _XStoreEventCookie( - Display *dpy, - XEvent *ev); - -extern Bool _XFetchEventCookie( - Display *dpy, - XGenericEventCookie *ev); - -extern Bool _XCopyEventCookie( - Display *dpy, - XGenericEventCookie *in, - XGenericEventCookie *out); - -/* lcFile.c */ - -extern void xlocaledir( - char *buf, - int buf_len -); - -_XFUNCPROTOEND - -#endif /* _X11_XLIBINT_H_ */ +
+/*
+
+Copyright 1984, 1985, 1987, 1989, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifndef _X11_XLIBINT_H_
+#define _X11_XLIBINT_H_ 1
+
+/*
+ * Xlibint.h - Header definition and support file for the internal
+ * support routines used by the C subroutine interface
+ * library (Xlib) to the X Window System.
+ *
+ * Warning, there be dragons here....
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xproto.h> /* to declare xEvent */
+#include <X11/XlibConf.h> /* for configured options like XTHREADS */
+
+#ifdef WIN32
+#define _XFlush _XFlushIt
+#endif
+
+/*
+ * If your BytesReadable correctly detects broken connections, then
+ * you should NOT define XCONN_CHECK_FREQ.
+ */
+#ifndef XCONN_CHECK_FREQ
+#define XCONN_CHECK_FREQ 256
+#endif
+
+struct _XGC
+{
+ XExtData *ext_data; /* hook for extension to hang data */
+ GContext gid; /* protocol ID for graphics context */
+ Bool rects; /* boolean: TRUE if clipmask is list of rectangles */
+ Bool dashes; /* boolean: TRUE if dash-list is really a list */
+ unsigned long dirty;/* cache dirty bits */
+ XGCValues values; /* shadow structure of values */
+};
+
+struct _XDisplay
+{
+ XExtData *ext_data; /* hook for extension to hang data */
+ struct _XFreeFuncs *free_funcs; /* internal free functions */
+ int fd; /* Network socket. */
+ int conn_checker; /* ugly thing used by _XEventsQueued */
+ int proto_major_version;/* maj. version of server's X protocol */
+ int proto_minor_version;/* minor version of server's X protocol */
+ char *vendor; /* vendor of the server hardware */
+ XID resource_base; /* resource ID base */
+ XID resource_mask; /* resource ID mask bits */
+ XID resource_id; /* allocator current ID */
+ int resource_shift; /* allocator shift to correct bits */
+ XID (*resource_alloc)( /* allocator function */
+ struct _XDisplay*
+ );
+ int byte_order; /* screen byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* padding and data requirements */
+ int bitmap_pad; /* padding requirements on bitmaps */
+ int bitmap_bit_order; /* LeastSignificant or MostSignificant */
+ int nformats; /* number of pixmap formats in list */
+ ScreenFormat *pixmap_format; /* pixmap format list */
+ int vnumber; /* Xlib's X protocol version number. */
+ int release; /* release of the server */
+ struct _XSQEvent *head, *tail; /* Input event queue. */
+ int qlen; /* Length of input event queue */
+ unsigned long last_request_read; /* seq number of last event read */
+ unsigned long request; /* sequence number of last request. */
+ char *last_req; /* beginning of last request, or dummy */
+ char *buffer; /* Output buffer starting address. */
+ char *bufptr; /* Output buffer index pointer. */
+ char *bufmax; /* Output buffer maximum+1 address. */
+ unsigned max_request_size; /* maximum number 32 bit words in request*/
+ struct _XrmHashBucketRec *db;
+ int (*synchandler)( /* Synchronization handler */
+ struct _XDisplay*
+ );
+ char *display_name; /* "host:display" string used on this connect*/
+ int default_screen; /* default screen for operations */
+ int nscreens; /* number of screens on this server*/
+ Screen *screens; /* pointer to list of screens */
+ unsigned long motion_buffer; /* size of motion buffer */
+ volatile unsigned long flags; /* internal connection flags */
+ int min_keycode; /* minimum defined keycode */
+ int max_keycode; /* maximum defined keycode */
+ KeySym *keysyms; /* This server's keysyms */
+ XModifierKeymap *modifiermap; /* This server's modifier keymap */
+ int keysyms_per_keycode;/* number of rows */
+ char *xdefaults; /* contents of defaults from server */
+ char *scratch_buffer; /* place to hang scratch buffer */
+ unsigned long scratch_length; /* length of scratch buffer */
+ int ext_number; /* extension number on this display */
+ struct _XExten *ext_procs; /* extensions initialized on this display */
+ /*
+ * the following can be fixed size, as the protocol defines how
+ * much address space is available.
+ * While this could be done using the extension vector, there
+ * may be MANY events processed, so a search through the extension
+ * list to find the right procedure for each event might be
+ * expensive if many extensions are being used.
+ */
+ Bool (*event_vec[128])( /* vector for wire to event */
+ Display * /* dpy */,
+ XEvent * /* re */,
+ xEvent * /* event */
+ );
+ Status (*wire_vec[128])( /* vector for event to wire */
+ Display * /* dpy */,
+ XEvent * /* re */,
+ xEvent * /* event */
+ );
+ KeySym lock_meaning; /* for XLookupString */
+ struct _XLockInfo *lock; /* multi-thread state, display lock */
+ struct _XInternalAsync *async_handlers; /* for internal async */
+ unsigned long bigreq_size; /* max size of big requests */
+ struct _XLockPtrs *lock_fns; /* pointers to threads functions */
+ void (*idlist_alloc)( /* XID list allocator function */
+ Display * /* dpy */,
+ XID * /* ids */,
+ int /* count */
+ );
+ /* things above this line should not move, for binary compatibility */
+ struct _XKeytrans *key_bindings; /* for XLookupString */
+ Font cursor_font; /* for XCreateFontCursor */
+ struct _XDisplayAtoms *atoms; /* for XInternAtom */
+ unsigned int mode_switch; /* keyboard group modifiers */
+ unsigned int num_lock; /* keyboard numlock modifiers */
+ struct _XContextDB *context_db; /* context database */
+ Bool (**error_vec)( /* vector for wire to error */
+ Display * /* display */,
+ XErrorEvent * /* he */,
+ xError * /* we */
+ );
+ /*
+ * Xcms information
+ */
+ struct {
+ XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */
+ XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */
+ XPointer perVisualIntensityMaps;
+ /* linked list of XcmsIntensityMap */
+ } cms;
+ struct _XIMFilter *im_filters;
+ struct _XSQEvent *qfree; /* unallocated event queue elements */
+ unsigned long next_event_serial_num; /* inserted into next queue elt */
+ struct _XExten *flushes; /* Flush hooks */
+ struct _XConnectionInfo *im_fd_info; /* _XRegisterInternalConnection */
+ int im_fd_length; /* number of im_fd_info */
+ struct _XConnWatchInfo *conn_watchers; /* XAddConnectionWatch */
+ int watcher_count; /* number of conn_watchers */
+ XPointer filedes; /* struct pollfd cache for _XWaitForReadable */
+ int (*savedsynchandler)( /* user synchandler when Xlib usurps */
+ Display * /* dpy */
+ );
+ XID resource_max; /* allocator max ID */
+ int xcmisc_opcode; /* major opcode for XC-MISC */
+ struct _XkbInfoRec *xkb_info; /* XKB info */
+ struct _XtransConnInfo *trans_conn; /* transport connection object */
+ struct _X11XCBPrivate *xcb; /* XCB glue private data */
+
+ /* Generic event cookie handling */
+ unsigned int next_cookie; /* next event cookie */
+ /* vector for wire to generic event, index is (extension - 128) */
+ Bool (*generic_event_vec[128])(
+ Display * /* dpy */,
+ XGenericEventCookie * /* Xlib event */,
+ xEvent * /* wire event */);
+ /* vector for event copy, index is (extension - 128) */
+ Bool (*generic_event_copy_vec[128])(
+ Display * /* dpy */,
+ XGenericEventCookie * /* in */,
+ XGenericEventCookie * /* out*/);
+ void *cookiejar; /* cookie events returned but not claimed */
+};
+
+#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
+
+/*
+ * define the following if you want the Data macro to be a procedure instead
+ */
+#ifdef CRAY
+#define DataRoutineIsProcedure
+#endif /* CRAY */
+
+#ifndef _XEVENT_
+/*
+ * _QEvent datatype for use in input queueing.
+ */
+typedef struct _XSQEvent
+{
+ struct _XSQEvent *next;
+ XEvent event;
+ unsigned long qserial_num; /* so multi-threaded code can find new ones */
+} _XQEvent;
+#endif
+
+#include <X11/Xproto.h>
+#ifdef __sgi
+#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */
+#endif
+#include <errno.h>
+#define _XBCOPYFUNC _Xbcopy
+#include <X11/Xfuncs.h>
+#include <X11/Xosdefs.h>
+
+/* Utek leaves kernel macros around in include files (bleah) */
+#ifdef dirty
+#undef dirty
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+/*
+ * The following definitions can be used for locking requests in multi-threaded
+ * address spaces.
+ */
+#ifdef XTHREADS
+/* Author: Stephen Gildea, MIT X Consortium
+ *
+ * declarations for C Threads locking
+ */
+
+typedef struct _LockInfoRec *LockInfoPtr;
+
+/* interfaces for locking.c */
+struct _XLockPtrs {
+ /* used by all, including extensions; do not move */
+ void (*lock_display)(
+ Display *dpy
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char *file
+ , int line
+#endif
+ );
+ void (*unlock_display)(
+ Display *dpy
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char *file
+ , int line
+#endif
+ );
+};
+
+#if defined(WIN32) && !defined(_XLIBINT_)
+#define _XCreateMutex_fn (*_XCreateMutex_fn_p)
+#define _XFreeMutex_fn (*_XFreeMutex_fn_p)
+#define _XLockMutex_fn (*_XLockMutex_fn_p)
+#define _XUnlockMutex_fn (*_XUnlockMutex_fn_p)
+#define _Xglobal_lock (*_Xglobal_lock_p)
+#endif
+
+/* in XlibInt.c */
+extern void (*_XCreateMutex_fn)(
+ LockInfoPtr /* lock */
+);
+extern void (*_XFreeMutex_fn)(
+ LockInfoPtr /* lock */
+);
+extern void (*_XLockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+);
+extern void (*_XUnlockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+);
+
+extern LockInfoPtr _Xglobal_lock;
+
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d),__FILE__,__LINE__)
+#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d),__FILE__,__LINE__)
+#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock,__FILE__,__LINE__)
+#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock,__FILE__,__LINE__)
+#else
+/* used everywhere, so must be fast if not using threads */
+#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d)
+#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d)
+#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock)
+#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock)
+#endif
+#define _XCreateMutex(lock) if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock);
+#define _XFreeMutex(lock) if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock);
+
+#else /* XTHREADS */
+#define LockDisplay(dis)
+#define _XLockMutex(lock)
+#define _XUnlockMutex(lock)
+#define UnlockDisplay(dis)
+#define _XCreateMutex(lock)
+#define _XFreeMutex(lock)
+#endif
+
+#define Xfree(ptr) free((ptr))
+
+/*
+ * Note that some machines do not return a valid pointer for malloc(0), in
+ * which case we provide an alternate under the control of the
+ * define MALLOC_0_RETURNS_NULL. This is necessary because some
+ * Xlib code expects malloc(0) to return a valid pointer to storage.
+ */
+#if defined(MALLOC_0_RETURNS_NULL) || defined(__clang_analyzer__)
+
+# define Xmalloc(size) malloc(((size) == 0 ? 1 : (size)))
+# define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size)))
+# define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize))
+
+#else
+
+# define Xmalloc(size) malloc((size))
+# define Xrealloc(ptr, size) realloc((ptr), (size))
+# define Xcalloc(nelem, elsize) calloc((nelem), (elsize))
+
+#endif
+
+#include <stddef.h>
+
+#define LOCKED 1
+#define UNLOCKED 0
+
+#ifndef BUFSIZE
+#define BUFSIZE 2048 /* X output buffer size. */
+#endif
+#ifndef PTSPERBATCH
+#define PTSPERBATCH 1024 /* point batching */
+#endif
+#ifndef WLNSPERBATCH
+#define WLNSPERBATCH 50 /* wide line batching */
+#endif
+#ifndef ZLNSPERBATCH
+#define ZLNSPERBATCH 1024 /* thin line batching */
+#endif
+#ifndef WRCTSPERBATCH
+#define WRCTSPERBATCH 10 /* wide line rectangle batching */
+#endif
+#ifndef ZRCTSPERBATCH
+#define ZRCTSPERBATCH 256 /* thin line rectangle batching */
+#endif
+#ifndef FRCTSPERBATCH
+#define FRCTSPERBATCH 256 /* filled rectangle batching */
+#endif
+#ifndef FARCSPERBATCH
+#define FARCSPERBATCH 256 /* filled arc batching */
+#endif
+#ifndef CURSORFONT
+#define CURSORFONT "cursor" /* standard cursor fonts */
+#endif
+
+/*
+ * Display flags
+ */
+#define XlibDisplayIOError (1L << 0)
+#define XlibDisplayClosing (1L << 1)
+#define XlibDisplayNoXkb (1L << 2)
+#define XlibDisplayPrivSync (1L << 3)
+#define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */
+#define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */
+#define XlibDisplayReply (1L << 5) /* in _XReply */
+#define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */
+#define XlibDisplayDfltRMDB (1L << 7) /* mark if RM db from XGetDefault */
+
+/*
+ * X Protocol packetizing macros.
+ */
+
+/* Need to start requests on 64 bit word boundaries
+ * on a CRAY computer so add a NoOp (127) if needed.
+ * A character pointer on a CRAY computer will be non-zero
+ * after shifting right 61 bits of it is not pointing to
+ * a word boundary.
+ */
+#ifdef WORD64
+#define WORD64ALIGN if ((long)dpy->bufptr >> 61) {\
+ dpy->last_req = dpy->bufptr;\
+ *(dpy->bufptr) = X_NoOperation;\
+ *(dpy->bufptr+1) = 0;\
+ *(dpy->bufptr+2) = 0;\
+ *(dpy->bufptr+3) = 1;\
+ dpy->request++;\
+ dpy->bufptr += 4;\
+ }
+#else /* else does not require alignment on 64-bit boundaries */
+#define WORD64ALIGN
+#endif /* WORD64 */
+
+
+/*
+ * GetReq - Get the next available X request packet in the buffer and
+ * return it.
+ *
+ * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc.
+ * "req" is the name of the request pointer.
+ *
+ */
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define GetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = (SIZEOF(x##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(x##name##Req);\
+ dpy->request++
+
+#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
+#define GetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = (SIZEOF(x/**/name/**/Req))>>2;\
+ dpy->bufptr += SIZEOF(x/**/name/**/Req);\
+ dpy->request++
+#endif
+
+/* GetReqExtra is the same as GetReq, but allocates "n" additional
+ bytes after the request. "n" must be a multiple of 4! */
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define GetReqExtra(name, n, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = (SIZEOF(x##name##Req) + n)>>2;\
+ dpy->bufptr += SIZEOF(x##name##Req) + n;\
+ dpy->request++
+#else
+#define GetReqExtra(name, n, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\
+ dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\
+ dpy->request++
+#endif
+
+
+/*
+ * GetResReq is for those requests that have a resource ID
+ * (Window, Pixmap, GContext, etc.) as their single argument.
+ * "rid" is the name of the resource.
+ */
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define GetResReq(name, rid, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = 2;\
+ req->id = (rid);\
+ dpy->bufptr += SIZEOF(xResourceReq);\
+ dpy->request++
+#else
+#define GetResReq(name, rid, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = 2;\
+ req->id = (rid);\
+ dpy->bufptr += SIZEOF(xResourceReq);\
+ dpy->request++
+#endif
+
+/*
+ * GetEmptyReq is for those requests that have no arguments
+ * at all.
+ */
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define GetEmptyReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xReq *) (dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = 1;\
+ dpy->bufptr += SIZEOF(xReq);\
+ dpy->request++
+#else
+#define GetEmptyReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xReq *) (dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = 1;\
+ dpy->bufptr += SIZEOF(xReq);\
+ dpy->request++
+#endif
+
+#ifdef WORD64
+#define MakeBigReq(req,n) \
+ { \
+ char _BRdat[4]; \
+ unsigned long _BRlen = req->length - 1; \
+ req->length = 0; \
+ memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \
+ memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
+ memcpy(((char *)req) + 4, _BRdat, 4); \
+ Data32(dpy, (long *)&_BRdat, 4); \
+ }
+#else
+#ifdef LONG64
+#define MakeBigReq(req,n) \
+ { \
+ CARD64 _BRdat; \
+ CARD32 _BRlen = req->length - 1; \
+ req->length = 0; \
+ _BRdat = ((CARD32 *)req)[_BRlen]; \
+ memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
+ ((CARD32 *)req)[1] = _BRlen + n + 2; \
+ Data32(dpy, &_BRdat, 4); \
+ }
+#else
+#define MakeBigReq(req,n) \
+ { \
+ CARD32 _BRdat; \
+ CARD32 _BRlen = req->length - 1; \
+ req->length = 0; \
+ _BRdat = ((CARD32 *)req)[_BRlen]; \
+ memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
+ ((CARD32 *)req)[1] = _BRlen + n + 2; \
+ Data32(dpy, &_BRdat, 4); \
+ }
+#endif
+#endif
+
+#ifndef __clang_analyzer__
+#define SetReqLen(req,n,badlen) \
+ if ((req->length + n) > (unsigned)65535) { \
+ if (dpy->bigreq_size) { \
+ MakeBigReq(req,n) \
+ } else { \
+ n = badlen; \
+ req->length += n; \
+ } \
+ } else \
+ req->length += n
+#else
+#define SetReqLen(req,n,badlen) \
+ req->length += n
+#endif
+
+#define SyncHandle() \
+ if (dpy->synchandler) (*dpy->synchandler)(dpy)
+
+extern void _XFlushGCCache(Display *dpy, GC gc);
+#define FlushGC(dpy, gc) \
+ if ((gc)->dirty) _XFlushGCCache((dpy), (gc))
+/*
+ * Data - Place data in the buffer and pad the end to provide
+ * 32 bit word alignment. Transmit if the buffer fills.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pinter to a data buffer.
+ * "len" is the length of the data buffer.
+ */
+#ifndef DataRoutineIsProcedure
+#define Data(dpy, data, len) {\
+ if (dpy->bufptr + (len) <= dpy->bufmax) {\
+ memcpy(dpy->bufptr, data, (int)len);\
+ dpy->bufptr += ((len) + 3) & ~3;\
+ } else\
+ _XSend(dpy, data, len);\
+ }
+#endif /* DataRoutineIsProcedure */
+
+
+/* Allocate bytes from the buffer. No padding is done, so if
+ * the length is not a multiple of 4, the caller must be
+ * careful to leave the buffer aligned after sending the
+ * current request.
+ *
+ * "type" is the type of the pointer being assigned to.
+ * "ptr" is the pointer being assigned to.
+ * "n" is the number of bytes to allocate.
+ *
+ * Example:
+ * xTextElt *elt;
+ * BufAlloc (xTextElt *, elt, nbytes)
+ */
+
+#define BufAlloc(type, ptr, n) \
+ if (dpy->bufptr + (n) > dpy->bufmax) \
+ _XFlush (dpy); \
+ ptr = (type) dpy->bufptr; \
+ memset(ptr, '\0', n); \
+ dpy->bufptr += (n);
+
+#ifdef WORD64
+#define Data16(dpy, data, len) _XData16(dpy, (short *)data, len)
+#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len)
+#else
+#define Data16(dpy, data, len) Data((dpy), (char *)(data), (len))
+#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len))
+#define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len))
+#ifdef LONG64
+#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len)
+extern int _XData32(
+ Display *dpy,
+ register long *data,
+ unsigned len
+);
+extern void _XRead32(
+ Display *dpy,
+ register long *data,
+ long len
+);
+#else
+#define Data32(dpy, data, len) Data((dpy), (char *)(data), (len))
+#define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len))
+#endif
+#endif /* not WORD64 */
+
+#define PackData16(dpy,data,len) Data16 (dpy, data, len)
+#define PackData32(dpy,data,len) Data32 (dpy, data, len)
+
+/* Xlib manual is bogus */
+#define PackData(dpy,data,len) PackData16 (dpy, data, len)
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
+ (((cs)->rbearing|(cs)->lbearing| \
+ (cs)->ascent|(cs)->descent) == 0))
+
+/*
+ * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit
+ * character. If the character is in the column and exists, then return the
+ * appropriate metrics (note that fonts with common per-character metrics will
+ * return min_bounds). If none of these hold true, try again with the default
+ * char.
+ */
+#define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \
+{ \
+ cs = def; \
+ if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
+ if (fs->per_char == NULL) { \
+ cs = &fs->min_bounds; \
+ } else { \
+ cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
+ if (CI_NONEXISTCHAR(cs)) cs = def; \
+ } \
+ } \
+}
+
+#define CI_GET_DEFAULT_INFO_1D(fs,cs) \
+ CI_GET_CHAR_INFO_1D (fs, fs->default_char, NULL, cs)
+
+
+
+/*
+ * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and
+ * column. This is used for fonts that have more than row zero.
+ */
+#define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \
+{ \
+ cs = def; \
+ if (row >= fs->min_byte1 && row <= fs->max_byte1 && \
+ col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
+ if (fs->per_char == NULL) { \
+ cs = &fs->min_bounds; \
+ } else { \
+ cs = &fs->per_char[((row - fs->min_byte1) * \
+ (fs->max_char_or_byte2 - \
+ fs->min_char_or_byte2 + 1)) + \
+ (col - fs->min_char_or_byte2)]; \
+ if (CI_NONEXISTCHAR(cs)) cs = def; \
+ } \
+ } \
+}
+
+#define CI_GET_DEFAULT_INFO_2D(fs,cs) \
+{ \
+ unsigned int r = (fs->default_char >> 8); \
+ unsigned int c = (fs->default_char & 0xff); \
+ CI_GET_CHAR_INFO_2D (fs, r, c, NULL, cs); \
+}
+
+
+#ifdef MUSTCOPY
+
+/* for when 32-bit alignment is not good enough */
+#define OneDataCard32(dpy,dstaddr,srcvar) \
+ { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); }
+
+#else
+
+/* srcvar must be a variable for large architecture version */
+#define OneDataCard32(dpy,dstaddr,srcvar) \
+ { *(CARD32 *)(dstaddr) = (srcvar); }
+
+#endif /* MUSTCOPY */
+
+typedef struct _XInternalAsync {
+ struct _XInternalAsync *next;
+ /*
+ * handler arguments:
+ * rep is the generic reply that caused this handler
+ * to be invoked. It must also be passed to _XGetAsyncReply.
+ * buf and len are opaque values that must be passed to
+ * _XGetAsyncReply or _XGetAsyncData.
+ * data is the closure stored in this struct.
+ * The handler returns True iff it handled this reply.
+ */
+ Bool (*handler)(
+ Display* /* dpy */,
+ xReply* /* rep */,
+ char* /* buf */,
+ int /* len */,
+ XPointer /* data */
+ );
+ XPointer data;
+} _XAsyncHandler;
+
+typedef struct _XAsyncEState {
+ unsigned long min_sequence_number;
+ unsigned long max_sequence_number;
+ unsigned char error_code;
+ unsigned char major_opcode;
+ unsigned short minor_opcode;
+ unsigned char last_error_received;
+ int error_count;
+} _XAsyncErrorState;
+
+extern void _XDeqAsyncHandler(Display *dpy, _XAsyncHandler *handler);
+#define DeqAsyncHandler(dpy,handler) { \
+ if (dpy->async_handlers == (handler)) \
+ dpy->async_handlers = (handler)->next; \
+ else \
+ _XDeqAsyncHandler(dpy, handler); \
+ }
+
+typedef void (*FreeFuncType) (
+ Display* /* display */
+);
+
+typedef int (*FreeModmapType) (
+ XModifierKeymap* /* modmap */
+);
+
+/*
+ * This structure is private to the library.
+ */
+typedef struct _XFreeFuncs {
+ FreeFuncType atoms; /* _XFreeAtomTable */
+ FreeModmapType modifiermap; /* XFreeModifiermap */
+ FreeFuncType key_bindings; /* _XFreeKeyBindings */
+ FreeFuncType context_db; /* _XFreeContextDB */
+ FreeFuncType defaultCCCs; /* _XcmsFreeDefaultCCCs */
+ FreeFuncType clientCmaps; /* _XcmsFreeClientCmaps */
+ FreeFuncType intensityMaps; /* _XcmsFreeIntensityMaps */
+ FreeFuncType im_filters; /* _XFreeIMFilters */
+ FreeFuncType xkb; /* _XkbFreeInfo */
+} _XFreeFuncRec;
+
+/* types for InitExt.c */
+typedef int (*CreateGCType) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*CopyGCType)(
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*FlushGCType) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*FreeGCType) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*CreateFontType) (
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*FreeFontType) (
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*CloseDisplayType) (
+ Display* /* display */,
+ XExtCodes* /* codes */
+);
+
+typedef int (*ErrorType) (
+ Display* /* display */,
+ xError* /* err */,
+ XExtCodes* /* codes */,
+ int* /* ret_code */
+);
+
+typedef char* (*ErrorStringType) (
+ Display* /* display */,
+ int /* code */,
+ XExtCodes* /* codes */,
+ char* /* buffer */,
+ int /* nbytes */
+);
+
+typedef void (*PrintErrorType)(
+ Display* /* display */,
+ XErrorEvent* /* ev */,
+ void* /* fp */
+);
+
+typedef void (*BeforeFlushType)(
+ Display* /* display */,
+ XExtCodes* /* codes */,
+ _Xconst char* /* data */,
+ long /* len */
+);
+
+/*
+ * This structure is private to the library.
+ */
+typedef struct _XExten { /* private to extension mechanism */
+ struct _XExten *next; /* next in list */
+ XExtCodes codes; /* public information, all extension told */
+ CreateGCType create_GC; /* routine to call when GC created */
+ CopyGCType copy_GC; /* routine to call when GC copied */
+ FlushGCType flush_GC; /* routine to call when GC flushed */
+ FreeGCType free_GC; /* routine to call when GC freed */
+ CreateFontType create_Font; /* routine to call when Font created */
+ FreeFontType free_Font; /* routine to call when Font freed */
+ CloseDisplayType close_display; /* routine to call when connection closed */
+ ErrorType error; /* who to call when an error occurs */
+ ErrorStringType error_string; /* routine to supply error string */
+ char *name; /* name of this extension */
+ PrintErrorType error_values; /* routine to supply error values */
+ BeforeFlushType before_flush; /* routine to call when sending data */
+ struct _XExten *next_flush; /* next in list of those with flushes */
+} _XExtension;
+
+/* extension hooks */
+
+#ifdef DataRoutineIsProcedure
+extern void Data(Display *dpy, char *data, long len);
+#endif
+extern int _XError(
+ Display* /* dpy */,
+ xError* /* rep */
+);
+extern int _XIOError(
+ Display* /* dpy */
+) _X_NORETURN;
+extern int (*_XIOErrorFunction)(
+ Display* /* dpy */
+);
+extern int (*_XErrorFunction)(
+ Display* /* dpy */,
+ XErrorEvent* /* error_event */
+);
+extern void _XEatData(
+ Display* /* dpy */,
+ unsigned long /* n */
+);
+extern char *_XAllocScratch(
+ Display* /* dpy */,
+ unsigned long /* nbytes */
+);
+extern char *_XAllocTemp(
+ Display* /* dpy */,
+ unsigned long /* nbytes */
+);
+extern void _XFreeTemp(
+ Display* /* dpy */,
+ char* /* buf */,
+ unsigned long /* nbytes */
+);
+extern Visual *_XVIDtoVisual(
+ Display* /* dpy */,
+ VisualID /* id */
+);
+extern unsigned long _XSetLastRequestRead(
+ Display* /* dpy */,
+ xGenericReply* /* rep */
+);
+extern int _XGetHostname(
+ char* /* buf */,
+ int /* maxlen */
+);
+extern Screen *_XScreenOfWindow(
+ Display* /* dpy */,
+ Window /* w */
+);
+extern Bool _XAsyncErrorHandler(
+ Display* /* dpy */,
+ xReply* /* rep */,
+ char* /* buf */,
+ int /* len */,
+ XPointer /* data */
+);
+extern char *_XGetAsyncReply(
+ Display* /* dpy */,
+ char* /* replbuf */,
+ xReply* /* rep */,
+ char* /* buf */,
+ int /* len */,
+ int /* extra */,
+ Bool /* discard */
+);
+extern void _XGetAsyncData(
+ Display* /* dpy */,
+ char * /* data */,
+ char * /* buf */,
+ int /* len */,
+ int /* skip */,
+ int /* datalen */,
+ int /* discardtotal */
+);
+extern void _XFlush(
+ Display* /* dpy */
+);
+extern int _XEventsQueued(
+ Display* /* dpy */,
+ int /* mode */
+);
+extern void _XReadEvents(
+ Display* /* dpy */
+);
+extern int _XRead(
+ Display* /* dpy */,
+ char* /* data */,
+ long /* size */
+);
+extern void _XReadPad(
+ Display* /* dpy */,
+ char* /* data */,
+ long /* size */
+);
+extern void _XSend(
+ Display* /* dpy */,
+ _Xconst char* /* data */,
+ long /* size */
+);
+extern Status _XReply(
+ Display* /* dpy */,
+ xReply* /* rep */,
+ int /* extra */,
+ Bool /* discard */
+);
+extern void _XEnq(
+ Display* /* dpy */,
+ xEvent* /* event */
+);
+extern void _XDeq(
+ Display* /* dpy */,
+ _XQEvent* /* prev */,
+ _XQEvent* /* qelt */
+);
+
+extern Bool _XUnknownWireEvent(
+ Display* /* dpy */,
+ XEvent* /* re */,
+ xEvent* /* event */
+);
+
+extern Bool _XUnknownWireEventCookie(
+ Display* /* dpy */,
+ XGenericEventCookie* /* re */,
+ xEvent* /* event */
+);
+
+extern Bool _XUnknownCopyEventCookie(
+ Display* /* dpy */,
+ XGenericEventCookie* /* in */,
+ XGenericEventCookie* /* out */
+);
+
+extern Status _XUnknownNativeEvent(
+ Display* /* dpy */,
+ XEvent* /* re */,
+ xEvent* /* event */
+);
+
+extern Bool _XWireToEvent(Display *dpy, XEvent *re, xEvent *event);
+extern Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we);
+extern Bool _XPollfdCacheInit(Display *dpy);
+extern void _XPollfdCacheAdd(Display *dpy, int fd);
+extern void _XPollfdCacheDel(Display *dpy, int fd);
+extern XID _XAllocID(Display *dpy);
+extern void _XAllocIDs(Display *dpy, XID *ids, int count);
+
+extern int _XFreeExtData(
+ XExtData* /* extension */
+);
+
+extern int (*XESetCreateGC(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, GC, XExtCodes*
+);
+
+extern int (*XESetCopyGC(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, GC, XExtCodes*
+);
+
+extern int (*XESetFlushGC(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, GC, XExtCodes*
+);
+
+extern int (*XESetFreeGC(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, GC, XExtCodes*
+);
+
+extern int (*XESetCreateFont(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, XFontStruct*, XExtCodes*
+);
+
+extern int (*XESetFreeFont(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, XFontStruct*, XExtCodes*
+);
+
+extern int (*XESetCloseDisplay(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ XExtCodes* /* codes */
+ ) /* proc */
+))(
+ Display*, XExtCodes*
+);
+
+extern int (*XESetError(
+ Display* /* display */,
+ int /* extension */,
+ int (*) (
+ Display* /* display */,
+ xError* /* err */,
+ XExtCodes* /* codes */,
+ int* /* ret_code */
+ ) /* proc */
+))(
+ Display*, xError*, XExtCodes*, int*
+);
+
+extern char* (*XESetErrorString(
+ Display* /* display */,
+ int /* extension */,
+ char* (*) (
+ Display* /* display */,
+ int /* code */,
+ XExtCodes* /* codes */,
+ char* /* buffer */,
+ int /* nbytes */
+ ) /* proc */
+))(
+ Display*, int, XExtCodes*, char*, int
+);
+
+extern void (*XESetPrintErrorValues (
+ Display* /* display */,
+ int /* extension */,
+ void (*)(
+ Display* /* display */,
+ XErrorEvent* /* ev */,
+ void* /* fp */
+ ) /* proc */
+))(
+ Display*, XErrorEvent*, void*
+);
+
+extern Bool (*XESetWireToEvent(
+ Display* /* display */,
+ int /* event_number */,
+ Bool (*) (
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+ ) /* proc */
+))(
+ Display*, XEvent*, xEvent*
+);
+
+extern Bool (*XESetWireToEventCookie(
+ Display* /* display */,
+ int /* extension */,
+ Bool (*) (
+ Display* /* display */,
+ XGenericEventCookie* /* re */,
+ xEvent* /* event */
+ ) /* proc */
+))(
+ Display*, XGenericEventCookie*, xEvent*
+);
+
+extern Bool (*XESetCopyEventCookie(
+ Display* /* display */,
+ int /* extension */,
+ Bool (*) (
+ Display* /* display */,
+ XGenericEventCookie* /* in */,
+ XGenericEventCookie* /* out */
+ ) /* proc */
+))(
+ Display*, XGenericEventCookie*, XGenericEventCookie*
+);
+
+
+extern Status (*XESetEventToWire(
+ Display* /* display */,
+ int /* event_number */,
+ Status (*) (
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+ ) /* proc */
+))(
+ Display*, XEvent*, xEvent*
+);
+
+extern Bool (*XESetWireToError(
+ Display* /* display */,
+ int /* error_number */,
+ Bool (*) (
+ Display* /* display */,
+ XErrorEvent* /* he */,
+ xError* /* we */
+ ) /* proc */
+))(
+ Display*, XErrorEvent*, xError*
+);
+
+extern void (*XESetBeforeFlush(
+ Display* /* display */,
+ int /* error_number */,
+ void (*) (
+ Display* /* display */,
+ XExtCodes* /* codes */,
+ _Xconst char* /* data */,
+ long /* len */
+ ) /* proc */
+))(
+ Display*, XExtCodes*, _Xconst char*, long
+);
+
+/* internal connections for IMs */
+
+typedef void (*_XInternalConnectionProc)(
+ Display* /* dpy */,
+ int /* fd */,
+ XPointer /* call_data */
+);
+
+
+extern Status _XRegisterInternalConnection(
+ Display* /* dpy */,
+ int /* fd */,
+ _XInternalConnectionProc /* callback */,
+ XPointer /* call_data */
+);
+
+extern void _XUnregisterInternalConnection(
+ Display* /* dpy */,
+ int /* fd */
+);
+
+extern void _XProcessInternalConnection(
+ Display* /* dpy */,
+ struct _XConnectionInfo* /* conn_info */
+);
+
+/* Display structure has pointers to these */
+
+struct _XConnectionInfo { /* info from _XRegisterInternalConnection */
+ int fd;
+ _XInternalConnectionProc read_callback;
+ XPointer call_data;
+ XPointer *watch_data; /* set/used by XConnectionWatchProc */
+ struct _XConnectionInfo *next;
+};
+
+struct _XConnWatchInfo { /* info from XAddConnectionWatch */
+ XConnectionWatchProc fn;
+ XPointer client_data;
+ struct _XConnWatchInfo *next;
+};
+
+#ifdef __UNIXOS2__
+extern char* __XOS2RedirRoot(
+ char*
+);
+#endif
+
+extern int _XTextHeight(
+ XFontStruct* /* font_struct */,
+ _Xconst char* /* string */,
+ int /* count */
+);
+
+extern int _XTextHeight16(
+ XFontStruct* /* font_struct */,
+ _Xconst XChar2b* /* string */,
+ int /* count */
+);
+
+#if defined(WIN32)
+
+extern int _XOpenFile(
+ _Xconst char* /* path */,
+ int /* flags */
+);
+
+extern int _XOpenFileMode(
+ _Xconst char* /* path */,
+ int /* flags */,
+ mode_t /* mode */
+);
+
+extern void* _XFopenFile(
+ _Xconst char* /* path */,
+ _Xconst char* /* mode */
+);
+
+extern int _XAccessFile(
+ _Xconst char* /* path */
+);
+#else
+#define _XOpenFile(path,flags) open(path,flags)
+#define _XOpenFileMode(path,flags,mode) open(path,flags,mode)
+#define _XFopenFile(path,mode) fopen(path,mode)
+#endif
+
+/* EvToWire.c */
+extern Status _XEventToWire(Display *dpy, XEvent *re, xEvent *event);
+
+extern int _XF86LoadQueryLocaleFont(
+ Display* /* dpy */,
+ _Xconst char* /* name*/,
+ XFontStruct** /* xfp*/,
+ Font* /* fidp */
+);
+
+extern void _XProcessWindowAttributes (
+ register Display *dpy,
+ xChangeWindowAttributesReq *req,
+ register unsigned long valuemask,
+ register XSetWindowAttributes *attributes);
+
+extern int _XDefaultError(
+ Display *dpy,
+ XErrorEvent *event);
+
+extern int _XDefaultIOError(
+ Display *dpy);
+
+extern void _XSetClipRectangles (
+ register Display *dpy,
+ GC gc,
+ int clip_x_origin, int clip_y_origin,
+ XRectangle *rectangles,
+ int n,
+ int ordering);
+
+Status _XGetWindowAttributes(
+ register Display *dpy,
+ Window w,
+ XWindowAttributes *attr);
+
+int _XPutBackEvent (
+ register Display *dpy,
+ register XEvent *event);
+
+extern Bool _XIsEventCookie(
+ Display *dpy,
+ XEvent *ev);
+
+extern void _XFreeEventCookies(
+ Display *dpy);
+
+extern void _XStoreEventCookie(
+ Display *dpy,
+ XEvent *ev);
+
+extern Bool _XFetchEventCookie(
+ Display *dpy,
+ XGenericEventCookie *ev);
+
+extern Bool _XCopyEventCookie(
+ Display *dpy,
+ XGenericEventCookie *in,
+ XGenericEventCookie *out);
+
+/* lcFile.c */
+
+extern void xlocaledir(
+ char *buf,
+ int buf_len
+);
+
+_XFUNCPROTOEND
+
+#endif /* _X11_XLIBINT_H_ */
diff --git a/libX11/include/X11/Xregion.h b/libX11/include/X11/Xregion.h index b441312dc..1ae16c487 100644 --- a/libX11/include/X11/Xregion.h +++ b/libX11/include/X11/Xregion.h @@ -58,8 +58,10 @@ typedef struct { #define TRUE 1
#define FALSE 0
+#ifndef MAXSHORT
#define MAXSHORT 32767
#define MINSHORT -MAXSHORT
+#endif
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
diff --git a/libX11/man/DisplayOfCCC.man b/libX11/man/DisplayOfCCC.man index 160eeb57f..fef9fb919 100644 --- a/libX11/man/DisplayOfCCC.man +++ b/libX11/man/DisplayOfCCC.man @@ -1,188 +1,188 @@ -.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 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 CONNECTION 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 dealings in this Software without prior written authorization -.\" from the X Consortium. -.\" -.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991 by -.\" Digital Equipment Corporation -.\" -.\" Portions Copyright \(co 1990, 1991 by -.\" Tektronix, Inc. -.\" -.\" Permission to use, copy, modify and distribute this documentation for -.\" any purpose and without fee is hereby granted, provided that the above -.\" copyright notice appears in all copies and that both that copyright notice -.\" and this permission notice appear in all copies, and that the names of -.\" Digital and Tektronix not be used in in advertising or publicity pertaining -.\" to this documentation without specific, written prior permission. -.\" Digital and Tektronix makes no representations about the suitability -.\" of this documentation for any purpose. -.\" It is provided ``as is'' without express or implied warranty. -.\" -.\" -.ds xT X Toolkit Intrinsics \- C Language Interface -.ds xW Athena X Widgets \- C Language X Toolkit Interface -.ds xL Xlib \- C Language X Interface -.ds xC Inter-Client Communication Conventions Manual -.na -.de Ds -.nf -.\\$1D \\$2 \\$1 -.ft 1 -.\".ps \\n(PS -.\".if \\n(VS>=40 .vs \\n(VSu -.\".if \\n(VS<=39 .vs \\n(VSp -.. -.de De -.ce 0 -.if \\n(BD .DF -.nr BD 0 -.in \\n(OIu -.if \\n(TM .ls 2 -.sp \\n(DDu -.fi -.. -.de FD -.LP -.KS -.TA .5i 3i -.ta .5i 3i -.nf -.. -.de FN -.fi -.KE -.LP -.. -.de IN \" send an index entry to the stderr -.. -.de C{ -.KS -.nf -.D -.\" -.\" choose appropriate monospace font -.\" the imagen conditional, 480, -.\" may be changed to L if LB is too -.\" heavy for your eyes... -.\" -.ie "\\*(.T"480" .ft L -.el .ie "\\*(.T"300" .ft L -.el .ie "\\*(.T"202" .ft PO -.el .ie "\\*(.T"aps" .ft CW -.el .ft R -.ps \\n(PS -.ie \\n(VS>40 .vs \\n(VSu -.el .vs \\n(VSp -.. -.de C} -.DE -.R -.. -.de Pn -.ie t \\$1\fB\^\\$2\^\fR\\$3 -.el \\$1\fI\^\\$2\^\fP\\$3 -.. -.de ZN -.ie t \fB\^\\$1\^\fR\\$2 -.el \fI\^\\$1\^\fP\\$2 -.. -.de hN -.ie t <\fB\\$1\fR>\\$2 -.el <\fI\\$1\fP>\\$2 -.. -.de NT -.ne 7 -.ds NO Note -.if \\n(.$>$1 .if !'\\$2'C' .ds NO \\$2 -.if \\n(.$ .if !'\\$1'C' .ds NO \\$1 -.ie n .sp -.el .sp 10p -.TB -.ce -\\*(NO -.ie n .sp -.el .sp 5p -.if '\\$1'C' .ce 99 -.if '\\$2'C' .ce 99 -.in +5n -.ll -5n -.R -.. -. \" Note End -- doug kraft 3/85 -.de NE -.ce 0 -.in -5n -.ll +5n -.ie n .sp -.el .sp 10p -.. -.ny0 -.TH DisplayOfCCC __libmansuffix__ __xorgversion__ "XLIB FUNCTIONS" -.SH NAME -DisplayOfCCC, VisualOfCCC, ScreenNumberOfCCC, ScreenWhitePointOfCCC, ClientWhitePointOfCCC \- Color Conversion Context macros -.SH SYNTAX -.HP -Display *DisplayOfCCC\^(\^XcmsCCC \fIccc\fP\^); -.HP -Visual *VisualOfCCC\^(\^XcmsCCC \fIccc\fP\^); -.HP -int ScreenNumberOfCCC\^(\^XcmsCCC \fIccc\fP\^); -.HP -XcmsColor *ScreenWhitePointOfCCC\^(\^XcmsCCC \fIccc\fP\^); -.HP -XcmsColor *ClientWhitePointOfCCC\^(\^XcmsCCC \fIccc\fP\^); -.SH ARGUMENTS -.IP \fIccc\fP 1i -Specifies the CCC. -.SH DESCRIPTION -The -.ZN DisplayOfCCC -macro returns the display associated with the specified CCC. -.LP -The -.ZN VisualOfCCC -macro returns the visual associated with the specified CCC. -.LP -The -.ZN ScreenNumberOfCCC -macro returns the number of the screen associated with the specified CCC. -.LP -The -.ZN ScreenWhitePointOfCCC -macro returns the screen white point of the screen associated with -the specified CCC. -.LP -The -.ZN ClientWhitePointOfCCC -macro returns the client white point of the screen associated with -the specified CCC. -.SH "SEE ALSO" -XcmsCCCOfColormap(__libmansuffix__), -XcmsConvertColors(__libmansuffix__), -XcmsCreateCCC(__libmansuffix__), -XcmsDefaultCCC(__libmansuffix__), -XcmsSetWhitePoint(__libmansuffix__) -.br -\fI\*(xL\fP +.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 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 CONNECTION 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 dealings in this Software without prior written authorization
+.\" from the X Consortium.
+.\"
+.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
+.\" Digital Equipment Corporation
+.\"
+.\" Portions Copyright \(co 1990, 1991 by
+.\" Tektronix, Inc.
+.\"
+.\" Permission to use, copy, modify and distribute this documentation for
+.\" any purpose and without fee is hereby granted, provided that the above
+.\" copyright notice appears in all copies and that both that copyright notice
+.\" and this permission notice appear in all copies, and that the names of
+.\" Digital and Tektronix not be used in in advertising or publicity pertaining
+.\" to this documentation without specific, written prior permission.
+.\" Digital and Tektronix makes no representations about the suitability
+.\" of this documentation for any purpose.
+.\" It is provided ``as is'' without express or implied warranty.
+.\"
+.\"
+.ds xT X Toolkit Intrinsics \- C Language Interface
+.ds xW Athena X Widgets \- C Language X Toolkit Interface
+.ds xL Xlib \- C Language X Interface
+.ds xC Inter-Client Communication Conventions Manual
+.na
+.de Ds
+.nf
+.\\$1D \\$2 \\$1
+.ft 1
+.\".ps \\n(PS
+.\".if \\n(VS>=40 .vs \\n(VSu
+.\".if \\n(VS<=39 .vs \\n(VSp
+..
+.de De
+.ce 0
+.if \\n(BD .DF
+.nr BD 0
+.in \\n(OIu
+.if \\n(TM .ls 2
+.sp \\n(DDu
+.fi
+..
+.de FD
+.LP
+.KS
+.TA .5i 3i
+.ta .5i 3i
+.nf
+..
+.de FN
+.fi
+.KE
+.LP
+..
+.de IN \" send an index entry to the stderr
+..
+.de C{
+.KS
+.nf
+.D
+.\"
+.\" choose appropriate monospace font
+.\" the imagen conditional, 480,
+.\" may be changed to L if LB is too
+.\" heavy for your eyes...
+.\"
+.ie "\\*(.T"480" .ft L
+.el .ie "\\*(.T"300" .ft L
+.el .ie "\\*(.T"202" .ft PO
+.el .ie "\\*(.T"aps" .ft CW
+.el .ft R
+.ps \\n(PS
+.ie \\n(VS>40 .vs \\n(VSu
+.el .vs \\n(VSp
+..
+.de C}
+.DE
+.R
+..
+.de Pn
+.ie t \\$1\fB\^\\$2\^\fR\\$3
+.el \\$1\fI\^\\$2\^\fP\\$3
+..
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.de hN
+.ie t <\fB\\$1\fR>\\$2
+.el <\fI\\$1\fP>\\$2
+..
+.de NT
+.ne 7
+.ds NO Note
+.if \\n(.$>$1 .if !'\\$2'C' .ds NO \\$2
+.if \\n(.$ .if !'\\$1'C' .ds NO \\$1
+.ie n .sp
+.el .sp 10p
+.TB
+.ce
+\\*(NO
+.ie n .sp
+.el .sp 5p
+.if '\\$1'C' .ce 99
+.if '\\$2'C' .ce 99
+.in +5n
+.ll -5n
+.R
+..
+. \" Note End -- doug kraft 3/85
+.de NE
+.ce 0
+.in -5n
+.ll +5n
+.ie n .sp
+.el .sp 10p
+..
+.ny0
+.TH DisplayOfCCC __libmansuffix__ __xorgversion__ "XLIB FUNCTIONS"
+.SH NAME
+DisplayOfCCC, VisualOfCCC, ScreenNumberOfCCC, ScreenWhitePointOfCCC, ClientWhitePointOfCCC \- Color Conversion Context macros
+.SH SYNTAX
+.HP
+Display *DisplayOfCCC\^(\^XcmsCCC \fIccc\fP\^);
+.HP
+Visual *VisualOfCCC\^(\^XcmsCCC \fIccc\fP\^);
+.HP
+int ScreenNumberOfCCC\^(\^XcmsCCC \fIccc\fP\^);
+.HP
+XcmsColor *ScreenWhitePointOfCCC\^(\^XcmsCCC \fIccc\fP\^);
+.HP
+XcmsColor *ClientWhitePointOfCCC\^(\^XcmsCCC \fIccc\fP\^);
+.SH ARGUMENTS
+.IP \fIccc\fP 1i
+Specifies the CCC.
+.SH DESCRIPTION
+The
+.ZN DisplayOfCCC
+macro returns the display associated with the specified CCC.
+.LP
+The
+.ZN VisualOfCCC
+macro returns the visual associated with the specified CCC.
+.LP
+The
+.ZN ScreenNumberOfCCC
+macro returns the number of the screen associated with the specified CCC.
+.LP
+The
+.ZN ScreenWhitePointOfCCC
+macro returns the screen white point of the screen associated with
+the specified CCC.
+.LP
+The
+.ZN ClientWhitePointOfCCC
+macro returns the client white point of the screen associated with
+the specified CCC.
+.SH "SEE ALSO"
+XcmsCCCOfColormap(__libmansuffix__),
+XcmsConvertColors(__libmansuffix__),
+XcmsCreateCCC(__libmansuffix__),
+XcmsDefaultCCC(__libmansuffix__),
+XcmsSetWhitePoint(__libmansuffix__)
+.br
+\fI\*(xL\fP
diff --git a/libX11/man/Makefile.am b/libX11/man/Makefile.am index ef1a7453f..da08e230d 100644 --- a/libX11/man/Makefile.am +++ b/libX11/man/Makefile.am @@ -1,1081 +1,1081 @@ -SUBDIRS = xkb - -libmandir = $(LIB_MAN_DIR) - -libman_PRE = \ - $(all_shadows:=.man) \ - $(file_shadows:=.man) \ - AllPlanes.man \ - BlackPixelOfScreen.man \ - DisplayOfCCC.man \ - ImageByteOrder.man \ - IsCursorKey.man \ - XAddConnectionWatch.man \ - XAddHost.man \ - XAllocClassHint.man \ - XAllocColor.man \ - XAllocIconSize.man \ - XAllocSizeHints.man \ - XAllocStandardColormap.man \ - XAllocWMHints.man \ - XAllowEvents.man \ - XAnyEvent.man \ - XButtonEvent.man \ - XChangeKeyboardControl.man \ - XChangeKeyboardMapping.man \ - XChangePointerControl.man \ - XChangeSaveSet.man \ - XChangeWindowAttributes.man \ - XCirculateEvent.man \ - XCirculateRequestEvent.man \ - XClearArea.man \ - XClientMessageEvent.man \ - XcmsAllocColor.man \ - XcmsCCCOfColormap.man \ - XcmsCIELabQueryMaxC.man \ - XcmsCIELuvQueryMaxC.man \ - XcmsColor.man \ - XcmsConvertColors.man \ - XcmsCreateCCC.man \ - XcmsDefaultCCC.man \ - XcmsQueryBlack.man \ - XcmsQueryColor.man \ - XcmsSetWhitePoint.man \ - XcmsStoreColor.man \ - XcmsTekHVCQueryMaxC.man \ - XColormapEvent.man \ - XConfigureEvent.man \ - XConfigureRequestEvent.man \ - XConfigureWindow.man \ - XCopyArea.man \ - XCreateColormap.man \ - XCreateFontCursor.man \ - XCreateFontSet.man \ - XCreateGC.man \ - XCreateIC.man \ - XCreateOC.man \ - XCreatePixmap.man \ - XCreateRegion.man \ - XCreateWindowEvent.man \ - XCreateWindow.man \ - XCrossingEvent.man \ - XDefineCursor.man \ - XDestroyWindowEvent.man \ - XDestroyWindow.man \ - XDrawArc.man \ - XDrawImageString.man \ - XDrawLine.man \ - XDrawPoint.man \ - XDrawRectangle.man \ - XDrawString.man \ - XDrawText.man \ - XEmptyRegion.man \ - XErrorEvent.man \ - XExposeEvent.man \ - XExtentsOfFontSet.man \ - XFillRectangle.man \ - XFilterEvent.man \ - XFlush.man \ - XFocusChangeEvent.man \ - XFontSetExtents.man \ - XFontsOfFontSet.man \ - XFree.man \ - XGetEventData.man \ - XGetVisualInfo.man \ - XGetWindowAttributes.man \ - XGetWindowProperty.man \ - XGetXCBConnection.man \ - XGrabButton.man \ - XGrabKeyboard.man \ - XGrabKey.man \ - XGrabPointer.man \ - XGrabServer.man \ - XGraphicsExposeEvent.man \ - XGravityEvent.man \ - XIconifyWindow.man \ - XIfEvent.man \ - XInitImage.man \ - XInitThreads.man \ - XInstallColormap.man \ - XInternAtom.man \ - XIntersectRegion.man \ - XKeymapEvent.man \ - XListFonts.man \ - XLoadFont.man \ - XLookupKeysym.man \ - XMapEvent.man \ - XMapRequestEvent.man \ - XMapWindow.man \ - XmbDrawImageString.man \ - XmbDrawString.man \ - XmbDrawText.man \ - XmbLookupString.man \ - XmbResetIC.man \ - XmbTextEscapement.man \ - XmbTextExtents.man \ - XmbTextListToTextProperty.man \ - XmbTextPerCharExtents.man \ - XNextEvent.man \ - XNoOp.man \ - XOpenDisplay.man \ - XOpenIM.man \ - XOpenOM.man \ - XParseGeometry.man \ - XPolygonRegion.man \ - XPropertyEvent.man \ - XPutBackEvent.man \ - XPutImage.man \ - XQueryBestSize.man \ - XQueryColor.man \ - XQueryExtension.man \ - XQueryPointer.man \ - XQueryTree.man \ - XRaiseWindow.man \ - XReadBitmapFile.man \ - XRecolorCursor.man \ - XReparentEvent.man \ - XReparentWindow.man \ - XResizeRequestEvent.man \ - XResourceManagerString.man \ - XrmEnumerateDatabase.man \ - XrmGetFileDatabase.man \ - XrmGetResource.man \ - XrmInitialize.man \ - XrmMergeDatabases.man \ - XrmPutResource.man \ - XrmUniqueQuark.man \ - XSaveContext.man \ - XSelectInput.man \ - XSelectionClearEvent.man \ - XSelectionEvent.man \ - XSelectionRequestEvent.man \ - XSendEvent.man \ - XSetArcMode.man \ - XSetClipOrigin.man \ - XSetCloseDownMode.man \ - XSetCommand.man \ - XSetErrorHandler.man \ - XSetEventQueueOwner.man \ - XSetFillStyle.man \ - XSetFont.man \ - XSetFontPath.man \ - XSetICFocus.man \ - XSetICValues.man \ - XSetInputFocus.man \ - XSetLineAttributes.man \ - XSetPointerMapping.man \ - XSetScreenSaver.man \ - XSetSelectionOwner.man \ - XSetState.man \ - XSetTextProperty.man \ - XSetTile.man \ - XSetTransientForHint.man \ - XSetWMClientMachine.man \ - XSetWMColormapWindows.man \ - XSetWMIconName.man \ - XSetWMName.man \ - XSetWMProperties.man \ - XSetWMProtocols.man \ - XStoreBytes.man \ - XStoreColors.man \ - XStringListToTextProperty.man \ - XStringToKeysym.man \ - XSupportsLocale.man \ - XSynchronize.man \ - XTextExtents.man \ - XTextWidth.man \ - XTranslateCoordinates.man \ - XUnmapEvent.man \ - XUnmapWindow.man \ - XVaCreateNestedList.man \ - XVisibilityEvent.man \ - XWarpPointer.man - -filemandir = $(FILE_MAN_DIR) -fileman_PRE = Compose.man - -libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@) \ - $(all_shadows:=.@LIB_MAN_SUFFIX@) - -fileman_DATA = $(fileman_PRE:man=@FILE_MAN_SUFFIX@) \ - $(file_shadows:=.@FILE_MAN_SUFFIX@) - -EXTRA_DIST = $(libman_PRE) $(fileman_PRE) - -CLEANFILES = $(libman_DATA) $(fileman_DATA) - -SUFFIXES = .$(LIB_MAN_SUFFIX) .$(FILE_MAN_SUFFIX) .man - -MAN_SUBSTS += -e 's|__xlocaledir__|$(X11_LOCALEDATADIR)|g' - -# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure -.man.$(LIB_MAN_SUFFIX) .man.$(FILE_MAN_SUFFIX): - $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ - -# Generate man page shadow files (Replaces InstallManPageAliases from Imake) -all_shadows = \ - $(AllPlanes_shadows) \ - $(BlackPixelOfScreen_shadows) \ - $(DisplayOfCCC_shadows) \ - $(ImageByteOrder_shadows) \ - $(IsCursorKey_shadows) \ - $(XAllocClassHint_shadows) \ - $(XAllocIconSize_shadows) \ - $(XAllocStandardColormap_shadows) \ - $(XAllocSizeHints_shadows) \ - $(XAllocWMHints_shadows) \ - $(XAddHost_shadows) \ - $(XAllocColor_shadows) \ - $(XAnyEvent_shadows) \ - $(XButtonEvent_shadows) \ - $(XChangeKeyboardControl_shadows) \ - $(XChangeKeyboardMapping_shadows) \ - $(XChangePointerControl_shadows) \ - $(XChangeSaveSet_shadows) \ - $(XChangeWindowAttributes_shadows) \ - $(XClearArea_shadows) \ - $(XConfigureWindow_shadows) \ - $(XCopyArea_shadows) \ - $(XCreateColormap_shadows) \ - $(XCreateFontCursor_shadows) \ - $(XCreateFontSet_shadows) \ - $(XCreateGC_shadows) \ - $(XCreateIC_shadows) \ - $(XInitImage_shadows) \ - $(XCreateOC_shadows) \ - $(XCreatePixmap_shadows) \ - $(XCreateRegion_shadows) \ - $(XCreateWindow_shadows) \ - $(XDefineCursor_shadows) \ - $(XDestroyWindow_shadows) \ - $(XDrawArc_shadows) \ - $(XDrawImageString_shadows) \ - $(XDrawLine_shadows) \ - $(XDrawPoint_shadows) \ - $(XDrawRectangle_shadows) \ - $(XDrawString_shadows) \ - $(XDrawText_shadows) \ - $(XEmptyRegion_shadows) \ - $(XFillRectangle_shadows) \ - $(XFlush_shadows) \ - $(XFontsOfFontSet_shadows) \ - $(XGraphicsExposeEvent_shadows) \ - $(XrmGetFileDatabase_shadows) \ - $(XrmGetResource_shadows) \ - $(XGetEventData_shadows) \ - $(XGetVisualInfo_shadows) \ - $(XGetWindowAttributes_shadows) \ - $(XGetWindowProperty_shadows) \ - $(XGrabButton_shadows) \ - $(XGrabKey_shadows) \ - $(XGrabKeyboard_shadows) \ - $(XGrabPointer_shadows) \ - $(XGrabServer_shadows) \ - $(XIconifyWindow_shadows) \ - $(XIfEvent_shadows) \ - $(XrmInitialize_shadows) \ - $(XInstallColormap_shadows) \ - $(XAddConnectionWatch_shadows) \ - $(XIntersectRegion_shadows) \ - $(XInternAtom_shadows) \ - $(XListFonts_shadows) \ - $(XLoadFont_shadows) \ - $(XLookupKeysym_shadows) \ - $(XrmMergeDatabases_shadows) \ - $(XMapEvent_shadows) \ - $(XMapWindow_shadows) \ - $(XNextEvent_shadows) \ - $(XOpenDisplay_shadows) \ - $(XOpenIM_shadows) \ - $(XOpenOM_shadows) \ - $(XParseGeometry_shadows) \ - $(XPolygonRegion_shadows) \ - $(XPutImage_shadows) \ - $(XrmPutResource_shadows) \ - $(XQueryBestSize_shadows) \ - $(XQueryColor_shadows) \ - $(XQueryExtension_shadows) \ - $(XResourceManagerString_shadows) \ - $(XRaiseWindow_shadows) \ - $(XReadBitmapFile_shadows) \ - $(XRecolorCursor_shadows) \ - $(XSaveContext_shadows) \ - $(XSetICFocus_shadows) \ - $(XSetICValues_shadows) \ - $(XStringListToTextProperty_shadows) \ - $(XSetArcMode_shadows) \ - $(XSetClipOrigin_shadows) \ - $(XSetCloseDownMode_shadows) \ - $(XSetCommand_shadows) \ - $(XSetErrorHandler_shadows) \ - $(XSendEvent_shadows) \ - $(XSetFillStyle_shadows) \ - $(XSetFontPath_shadows) \ - $(XSetInputFocus_shadows) \ - $(XSetLineAttributes_shadows) \ - $(XSetPointerMapping_shadows) \ - $(XSetScreenSaver_shadows) \ - $(XSetSelectionOwner_shadows) \ - $(XSetState_shadows) \ - $(XSetTransientForHint_shadows) \ - $(XSetTextProperty_shadows) \ - $(XSetTile_shadows) \ - $(XSetWMClientMachine_shadows) \ - $(XSetWMColormapWindows_shadows) \ - $(XSetWMIconName_shadows) \ - $(XSetWMName_shadows) \ - $(XSetWMProperties_shadows) \ - $(XSetWMProtocols_shadows) \ - $(XStoreBytes_shadows) \ - $(XStoreColors_shadows) \ - $(XStringToKeysym_shadows) \ - $(XSupportsLocale_shadows) \ - $(XSynchronize_shadows) \ - $(XmbTextListToTextProperty_shadows) \ - $(XTextExtents_shadows) \ - $(XTextWidth_shadows) \ - $(XInitThreads_shadows) \ - $(XrmUniqueQuark_shadows) \ - $(XUnmapWindow_shadows) \ - $(XcmsCCCOfColormap_shadows) \ - $(XcmsAllocColor_shadows) \ - $(XcmsColor_shadows) \ - $(XcmsCreateCCC_shadows) \ - $(XcmsCIELabQueryMaxC_shadows) \ - $(XcmsCIELuvQueryMaxC_shadows) \ - $(XcmsQueryBlack_shadows) \ - $(XcmsQueryColor_shadows) \ - $(XcmsStoreColor_shadows) \ - $(XcmsSetWhitePoint_shadows) \ - $(XcmsTekHVCQueryMaxC_shadows) \ - $(XmbDrawImageString_shadows) \ - $(XmbDrawString_shadows) \ - $(XmbDrawText_shadows) \ - $(XmbLookupString_shadows) \ - $(XmbResetIC_shadows) \ - $(XmbTextEscapement_shadows) \ - $(XmbTextExtents_shadows) \ - $(XmbTextPerCharExtents_shadows) - - -AllPlanes_shadows = \ - BlackPixel \ - WhitePixel \ - ConnectionNumber \ - DefaultColormap \ - DefaultDepth \ - XListDepths \ - DefaultGC \ - DefaultRootWindow \ - DefaultScreenOfDisplay \ - DefaultScreen \ - DefaultVisual \ - DisplayCells \ - DisplayPlanes \ - DisplayString \ - XMaxRequestSize \ - XExtendedMaxRequestSize \ - LastKnownRequestProcessed \ - NextRequest \ - ProtocolVersion \ - ProtocolRevision \ - QLength \ - RootWindow \ - ScreenCount \ - ScreenOfDisplay \ - ServerVendor \ - VendorRelease - -BlackPixelOfScreen_shadows = \ - WhitePixelOfScreen \ - CellsOfScreen \ - DefaultColormapOfScreen \ - DefaultDepthOfScreen \ - DefaultGCOfScreen \ - DefaultVisualOfScreen \ - DoesBackingStore \ - DoesSaveUnders \ - DisplayOfScreen \ - XScreenNumberOfScreen \ - EventMaskOfScreen \ - HeightOfScreen \ - HeightMMOfScreen \ - MaxCmapsOfScreen \ - MinCmapsOfScreen \ - PlanesOfScreen \ - RootWindowOfScreen \ - WidthOfScreen \ - WidthMMOfScreen - -DisplayOfCCC_shadows = \ - VisualOfCCC \ - ScreenNumberOfCCC \ - ScreenWhitePointOfCCC \ - ClientWhitePointOfCCC - -ImageByteOrder_shadows = \ - BitmapBitOrder \ - BitmapPad \ - BitmapUnit \ - DisplayHeight \ - DisplayHeightMM \ - DisplayWidth \ - DisplayWidthMM \ - XListPixmapFormats \ - XPixmapFormatValues - -IsCursorKey_shadows = \ - IsFunctionKey \ - IsKeypadKey \ - IsMiscFunctionKey \ - IsModifierKey \ - IsPFKey \ - IsPrivateKeypadKey - -XAllocClassHint_shadows = \ - XSetClassHint \ - XGetClassHint \ - XClassHint - -XAllocIconSize_shadows = \ - XSetIconSizes \ - XGetIconSizes \ - XIconSize - -XAllocStandardColormap_shadows = \ - XSetRGBColormaps \ - XGetRGBColormaps \ - XStandardColormap - -XAllocSizeHints_shadows = \ - XSetWMNormalHints \ - XGetWMNormalHints \ - XSetWMSizeHints \ - XGetWMSizeHints \ - XSizeHints - -XAllocWMHints_shadows = \ - XSetWMHints \ - XGetWMHints \ - XWMHints - -XAddHost_shadows = \ - XAddHosts \ - XListHosts \ - XRemoveHost \ - XRemoveHosts \ - XSetAccessControl \ - XEnableAccessControl \ - XDisableAccessControl \ - XHostAddress - -XAllocColor_shadows = \ - XAllocNamedColor \ - XAllocColorCells \ - XAllocColorPlanes \ - XFreeColors - -XAnyEvent_shadows = \ - XEvent - -XButtonEvent_shadows = \ - XKeyEvent \ - XMotionEvent - -XChangeKeyboardControl_shadows = \ - XGetKeyboardControl \ - XAutoRepeatOn \ - XAutoRepeatOff \ - XBell \ - XQueryKeymap \ - XKeyboardControl - -XChangeKeyboardMapping_shadows = \ - XGetKeyboardMapping \ - XDisplayKeycodes \ - XSetModifierMapping \ - XGetModifierMapping \ - XNewModifiermap \ - XInsertModifiermapEntry \ - XDeleteModifiermapEntry \ - XFreeModifiermap \ - XModifierKeymap - -XChangePointerControl_shadows = \ - XGetPointerControl - -XChangeSaveSet_shadows = \ - XAddToSaveSet \ - XRemoveFromSaveSet - -XChangeWindowAttributes_shadows = \ - XSetWindowBackground \ - XSetWindowBackgroundPixmap \ - XSetWindowBorder \ - XSetWindowBorderPixmap \ - XSetWindowColormap - -XClearArea_shadows = \ - XClearWindow - -XConfigureWindow_shadows = \ - XMoveWindow \ - XResizeWindow \ - XMoveResizeWindow \ - XSetWindowBorderWidth \ - XWindowChanges - -XCopyArea_shadows = \ - XCopyPlane - -XCreateColormap_shadows = \ - XCopyColormapAndFree \ - XFreeColormap \ - XColor - -XCreateFontCursor_shadows = \ - XCreatePixmapCursor \ - XCreateGlyphCursor - -XCreateFontSet_shadows = \ - XFreeFontSet - -XCreateGC_shadows = \ - XCopyGC \ - XChangeGC \ - XGetGCValues \ - XFreeGC \ - XGContextFromGC \ - XGCValues - -XCreateIC_shadows = \ - XDestroyIC \ - XIMOfIC - -XInitImage_shadows = \ - XCreateImage \ - XGetPixel \ - XPutPixel \ - XSubImage \ - XAddPixel \ - XDestroyImage - -XCreateOC_shadows = \ - XDestroyOC \ - XSetOCValues \ - XGetOCValues \ - XOMOfOC - -XCreatePixmap_shadows = \ - XFreePixmap - -XCreateRegion_shadows = \ - XSetRegion \ - XDestroyRegion - -XCreateWindow_shadows = \ - XCreateSimpleWindow \ - XSetWindowAttributes - -XDefineCursor_shadows = \ - XUndefineCursor - -XDestroyWindow_shadows = \ - XDestroySubwindows - -XDrawArc_shadows = \ - XDrawArcs \ - XArc - -XDrawImageString_shadows = \ - XDrawImageString16 - -XDrawLine_shadows = \ - XDrawLines \ - XDrawSegments \ - XSegment - -XDrawPoint_shadows = \ - XDrawPoints \ - XPoint - -XDrawRectangle_shadows = \ - XDrawRectangles \ - XRectangle - -XDrawString_shadows = \ - XDrawString16 - -XDrawText_shadows = \ - XDrawText16 \ - XTextItem \ - XTextItem16 - -XEmptyRegion_shadows = \ - XEqualRegion \ - XPointInRegion \ - XRectInRegion - -XFillRectangle_shadows = \ - XFillRectangles \ - XFillPolygon \ - XFillArc \ - XFillArcs - -XFlush_shadows = \ - XSync \ - XEventsQueued \ - XPending - -XFontsOfFontSet_shadows = \ - XBaseFontNameListOfFontSet \ - XLocaleOfFontSet \ - XContextDependentDrawing \ - XContextualDrawing \ - XDirectionalDependentDrawing - -XGraphicsExposeEvent_shadows = \ - XNoExposeEvent - -XrmGetFileDatabase_shadows = \ - XrmPutFileDatabase \ - XrmGetStringDatabase \ - XrmLocaleOfDatabase \ - XrmGetDatabase \ - XrmSetDatabase \ - XrmDestroyDatabase - -XrmGetResource_shadows = \ - XrmQGetResource \ - XrmQGetSearchList \ - XrmQGetSearchResource - -XGetEventData_shadows = \ - XFreeEventData \ - XGenericEventCookie - -XGetVisualInfo_shadows = \ - XMatchVisualInfo \ - XVisualIDFromVisual \ - XVisualInfo - -XGetWindowAttributes_shadows = \ - XGetGeometry \ - XWindowAttributes - -XGetWindowProperty_shadows = \ - XListProperties \ - XChangeProperty \ - XRotateWindowProperties \ - XDeleteProperty - -XGrabButton_shadows = \ - XUngrabButton - -XGrabKey_shadows = \ - XUngrabKey - -XGrabKeyboard_shadows = \ - XUngrabKeyboard - -XGrabPointer_shadows = \ - XUngrabPointer \ - XChangeActivePointerGrab - -XGrabServer_shadows = \ - XUngrabServer - -XIconifyWindow_shadows = \ - XWithdrawWindow \ - XReconfigureWMWindow - -XIfEvent_shadows = \ - XCheckIfEvent \ - XPeekIfEvent - -XrmInitialize_shadows = \ - XrmParseCommand \ - XrmValue \ - XrmOptionKind \ - XrmOptionDescRec - -XInstallColormap_shadows = \ - XUninstallColormap \ - XListInstalledColormaps - -XAddConnectionWatch_shadows = \ - XRemoveConnectionWatch \ - XProcessInternalConnection \ - XInternalConnectionNumbers - -XIntersectRegion_shadows = \ - XUnionRegion \ - XUnionRectWithRegion \ - XSubtractRegion \ - XXorRegion \ - XOffsetRegion \ - XShrinkRegion - -XInternAtom_shadows = \ - XInternAtoms \ - XGetAtomName \ - XGetAtomNames - -XListFonts_shadows = \ - XFreeFontNames \ - XListFontsWithInfo \ - XFreeFontInfo - -XLoadFont_shadows = \ - XQueryFont \ - XLoadQueryFont \ - XFreeFont \ - XGetFontProperty \ - XUnloadFont \ - XCharStruct \ - XFontProp \ - XChar2b \ - XFontStruct - -XLookupKeysym_shadows = \ - XRefreshKeyboardMapping \ - XLookupString \ - XRebindKeysym - -XrmMergeDatabases_shadows = \ - XrmCombineDatabase \ - XrmCombineFileDatabase - -XMapEvent_shadows = \ - XMappingEvent - -XMapWindow_shadows = \ - XMapRaised \ - XMapSubwindows - -XNextEvent_shadows = \ - XPeekEvent \ - XWindowEvent \ - XCheckWindowEvent \ - XMaskEvent \ - XCheckMaskEvent \ - XCheckTypedEvent \ - XCheckTypedWindowEvent - -XOpenDisplay_shadows = \ - XCloseDisplay - -XOpenIM_shadows = \ - XCloseIM \ - XSetIMValues \ - XGetIMValues \ - XDisplayOfIM \ - XLocaleOfIM \ - XRegisterIMInstantiateCallback \ - XUnregisterIMInstantiateCallback - -XOpenOM_shadows = \ - XCloseOM \ - XSetOMValues \ - XGetOMValues \ - XDisplayOfOM \ - XLocaleOfOM - -XParseGeometry_shadows = \ - XWMGeometry - -XPolygonRegion_shadows = \ - XClipBox - -XPutImage_shadows = \ - XGetImage \ - XGetSubImage - -XrmPutResource_shadows = \ - XrmQPutResource \ - XrmPutStringResource \ - XrmQPutStringResource \ - XrmPutLineResource - -XQueryBestSize_shadows = \ - XQueryBestTile \ - XQueryBestStipple - -XQueryColor_shadows = \ - XQueryColors \ - XLookupColor \ - XParseColor - -XQueryExtension_shadows = \ - XListExtensions \ - XFreeExtensionList - -XResourceManagerString_shadows = \ - XScreenResourceString - -XRaiseWindow_shadows = \ - XLowerWindow \ - XCirculateSubwindows \ - XCirculateSubwindowsUp \ - XCirculateSubwindowsDown \ - XRestackWindows - -XReadBitmapFile_shadows = \ - XReadBitmapFileData \ - XWriteBitmapFile \ - XCreatePixmapFromBitmapData \ - XCreateBitmapFromData - -XRecolorCursor_shadows = \ - XFreeCursor \ - XQueryBestCursor - -XSaveContext_shadows = \ - XFindContext \ - XDeleteContext \ - XUniqueContext - -XSetICFocus_shadows = \ - XUnsetICFocus - -XSetICValues_shadows = \ - XGetICValues - -XStringListToTextProperty_shadows = \ - XTextPropertyToStringList \ - XFreeStringList \ - XTextProperty - -XSetArcMode_shadows = \ - XSetSubwindowMode \ - XSetGraphicsExposure - -XSetClipOrigin_shadows = \ - XSetClipMask \ - XSetClipRectangles - -XSetCloseDownMode_shadows = \ - XKillClient - -XSetCommand_shadows = \ - XGetCommand - -XSetErrorHandler_shadows = \ - XGetErrorText \ - XDisplayName \ - XSetIOErrorHandler \ - XGetErrorDatabaseText - -XSendEvent_shadows = \ - XDisplayMotionBufferSize \ - XGetMotionEvents \ - XTimeCoord - -XSetFillStyle_shadows = \ - XSetFillRule - -XSetFontPath_shadows = \ - XGetFontPath \ - XFreeFontPath - -XSetInputFocus_shadows = \ - XGetInputFocus - -XSetLineAttributes_shadows = \ - XSetDashes - -XSetPointerMapping_shadows = \ - XGetPointerMapping - -XSetScreenSaver_shadows = \ - XForceScreenSaver \ - XActivateScreenSaver \ - XResetScreenSaver \ - XGetScreenSaver - -XSetSelectionOwner_shadows = \ - XGetSelectionOwner \ - XConvertSelection - -XSetState_shadows = \ - XSetFunction \ - XSetPlaneMask \ - XSetForeground \ - XSetBackground - -XSetTransientForHint_shadows = \ - XGetTransientForHint - -XSetTextProperty_shadows = \ - XGetTextProperty - -XSetTile_shadows = \ - XSetStipple \ - XSetTSOrigin - -XSetWMClientMachine_shadows = \ - XGetWMClientMachine - -XSetWMColormapWindows_shadows = \ - XGetWMColormapWindows - -XSetWMIconName_shadows = \ - XGetWMIconName \ - XSetIconName \ - XGetIconName - -XSetWMName_shadows = \ - XGetWMName \ - XStoreName \ - XFetchName - -XSetWMProperties_shadows = \ - XmbSetWMProperties \ - Xutf8SetWMProperties - -XSetWMProtocols_shadows = \ - XGetWMProtocols - -XStoreBytes_shadows = \ - XStoreBuffer \ - XFetchBytes \ - XFetchBuffer \ - XRotateBuffers - -XStoreColors_shadows = \ - XStoreColor \ - XStoreNamedColor - -XStringToKeysym_shadows = \ - XKeysymToString \ - XKeycodeToKeysym \ - XKeysymToKeycode \ - XConvertCase - -XSupportsLocale_shadows = \ - XSetLocaleModifiers - -XSynchronize_shadows = \ - XSetAfterFunction - -XmbTextListToTextProperty_shadows = \ - XwcTextListToTextProperty \ - Xutf8TextListToTextProperty \ - XmbTextPropertyToTextList \ - XwcTextPropertyToTextList \ - Xutf8TextPropertyToTextList \ - XwcFreeStringList \ - XDefaultString - -XTextExtents_shadows = \ - XTextExtents16 \ - XQueryTextExtents \ - XQueryTextExtents16 - -XTextWidth_shadows = \ - XTextWidth16 - -XInitThreads_shadows = \ - XLockDisplay \ - XUnlockDisplay - -XrmUniqueQuark_shadows = \ - XrmStringToQuark \ - XrmPermStringToQuark \ - XrmQuarkToString \ - XrmStringToQuarkList \ - XrmStringToBindingQuarkList - -XUnmapWindow_shadows = \ - XUnmapSubwindows - -XcmsCCCOfColormap_shadows = \ - XcmsSetCCCOfColormap - -XcmsAllocColor_shadows = \ - XcmsAllocNamedColor - -XcmsColor_shadows = \ - XcmsRGB \ - XcmsRGBi \ - XcmsCIEXYZ \ - XcmsCIEuvY \ - XcmsCIExyY \ - XcmsCIELab \ - XcmsCIELuv \ - XcmsTekHVC \ - XcmsPad - -XcmsCreateCCC_shadows = \ - XcmsFreeCCC - -XcmsCIELabQueryMaxC_shadows = \ - XcmsCIELabQueryMaxL \ - XcmsCIELabQueryMaxLC \ - XcmsCIELabQueryMinL - -XcmsCIELuvQueryMaxC_shadows = \ - XcmsCIELuvQueryMaxL \ - XcmsCIELuvQueryMaxLC \ - XcmsCIELuvQueryMinL - -XcmsQueryBlack_shadows = \ - XcmsQueryBlue \ - XcmsQueryGreen \ - XcmsQueryRed \ - XcmsQueryWhite - -XcmsQueryColor_shadows = \ - XcmsQueryColors \ - XcmsLookupColor - -XcmsStoreColor_shadows = \ - XcmsStoreColors - -XcmsSetWhitePoint_shadows = \ - XcmsSetWhiteAdjustProc - -XcmsTekHVCQueryMaxC_shadows = \ - XcmsTekHVCQueryMaxV \ - XcmsTekHVCQueryMaxVC \ - XcmsTekHVCQueryMaxVSamples \ - XcmsTekHVCQueryMinV - -XmbDrawImageString_shadows = \ - XwcDrawImageString \ - Xutf8DrawImageString - -XmbDrawString_shadows = \ - XwcDrawString \ - Xutf8DrawString - -XmbDrawText_shadows = \ - XwcDrawText \ - Xutf8DrawText - -XmbLookupString_shadows = \ - XwcLookupString \ - Xutf8LookupString - -XmbResetIC_shadows = \ - XwcResetIC \ - Xutf8ResetIC - -XmbTextEscapement_shadows = \ - XwcTextEscapement \ - Xutf8TextEscapement - -XmbTextExtents_shadows = \ - XwcTextExtents \ - Xutf8TextExtents - -XmbTextPerCharExtents_shadows = \ - XwcTextPerCharExtents \ - Xutf8TextPerCharExtents - -file_shadows = \ - $(Compose_shadows) - -Compose_shadows = \ - XCompose - +SUBDIRS = xkb
+
+libmandir = $(LIB_MAN_DIR)
+
+libman_PRE = \
+ $(all_shadows:=.man) \
+ $(file_shadows:=.man) \
+ AllPlanes.man \
+ BlackPixelOfScreen.man \
+ DisplayOfCCC.man \
+ ImageByteOrder.man \
+ IsCursorKey.man \
+ XAddConnectionWatch.man \
+ XAddHost.man \
+ XAllocClassHint.man \
+ XAllocColor.man \
+ XAllocIconSize.man \
+ XAllocSizeHints.man \
+ XAllocStandardColormap.man \
+ XAllocWMHints.man \
+ XAllowEvents.man \
+ XAnyEvent.man \
+ XButtonEvent.man \
+ XChangeKeyboardControl.man \
+ XChangeKeyboardMapping.man \
+ XChangePointerControl.man \
+ XChangeSaveSet.man \
+ XChangeWindowAttributes.man \
+ XCirculateEvent.man \
+ XCirculateRequestEvent.man \
+ XClearArea.man \
+ XClientMessageEvent.man \
+ XcmsAllocColor.man \
+ XcmsCCCOfColormap.man \
+ XcmsCIELabQueryMaxC.man \
+ XcmsCIELuvQueryMaxC.man \
+ XcmsColor.man \
+ XcmsConvertColors.man \
+ XcmsCreateCCC.man \
+ XcmsDefaultCCC.man \
+ XcmsQueryBlack.man \
+ XcmsQueryColor.man \
+ XcmsSetWhitePoint.man \
+ XcmsStoreColor.man \
+ XcmsTekHVCQueryMaxC.man \
+ XColormapEvent.man \
+ XConfigureEvent.man \
+ XConfigureRequestEvent.man \
+ XConfigureWindow.man \
+ XCopyArea.man \
+ XCreateColormap.man \
+ XCreateFontCursor.man \
+ XCreateFontSet.man \
+ XCreateGC.man \
+ XCreateIC.man \
+ XCreateOC.man \
+ XCreatePixmap.man \
+ XCreateRegion.man \
+ XCreateWindowEvent.man \
+ XCreateWindow.man \
+ XCrossingEvent.man \
+ XDefineCursor.man \
+ XDestroyWindowEvent.man \
+ XDestroyWindow.man \
+ XDrawArc.man \
+ XDrawImageString.man \
+ XDrawLine.man \
+ XDrawPoint.man \
+ XDrawRectangle.man \
+ XDrawString.man \
+ XDrawText.man \
+ XEmptyRegion.man \
+ XErrorEvent.man \
+ XExposeEvent.man \
+ XExtentsOfFontSet.man \
+ XFillRectangle.man \
+ XFilterEvent.man \
+ XFlush.man \
+ XFocusChangeEvent.man \
+ XFontSetExtents.man \
+ XFontsOfFontSet.man \
+ XFree.man \
+ XGetEventData.man \
+ XGetVisualInfo.man \
+ XGetWindowAttributes.man \
+ XGetWindowProperty.man \
+ XGetXCBConnection.man \
+ XGrabButton.man \
+ XGrabKeyboard.man \
+ XGrabKey.man \
+ XGrabPointer.man \
+ XGrabServer.man \
+ XGraphicsExposeEvent.man \
+ XGravityEvent.man \
+ XIconifyWindow.man \
+ XIfEvent.man \
+ XInitImage.man \
+ XInitThreads.man \
+ XInstallColormap.man \
+ XInternAtom.man \
+ XIntersectRegion.man \
+ XKeymapEvent.man \
+ XListFonts.man \
+ XLoadFont.man \
+ XLookupKeysym.man \
+ XMapEvent.man \
+ XMapRequestEvent.man \
+ XMapWindow.man \
+ XmbDrawImageString.man \
+ XmbDrawString.man \
+ XmbDrawText.man \
+ XmbLookupString.man \
+ XmbResetIC.man \
+ XmbTextEscapement.man \
+ XmbTextExtents.man \
+ XmbTextListToTextProperty.man \
+ XmbTextPerCharExtents.man \
+ XNextEvent.man \
+ XNoOp.man \
+ XOpenDisplay.man \
+ XOpenIM.man \
+ XOpenOM.man \
+ XParseGeometry.man \
+ XPolygonRegion.man \
+ XPropertyEvent.man \
+ XPutBackEvent.man \
+ XPutImage.man \
+ XQueryBestSize.man \
+ XQueryColor.man \
+ XQueryExtension.man \
+ XQueryPointer.man \
+ XQueryTree.man \
+ XRaiseWindow.man \
+ XReadBitmapFile.man \
+ XRecolorCursor.man \
+ XReparentEvent.man \
+ XReparentWindow.man \
+ XResizeRequestEvent.man \
+ XResourceManagerString.man \
+ XrmEnumerateDatabase.man \
+ XrmGetFileDatabase.man \
+ XrmGetResource.man \
+ XrmInitialize.man \
+ XrmMergeDatabases.man \
+ XrmPutResource.man \
+ XrmUniqueQuark.man \
+ XSaveContext.man \
+ XSelectInput.man \
+ XSelectionClearEvent.man \
+ XSelectionEvent.man \
+ XSelectionRequestEvent.man \
+ XSendEvent.man \
+ XSetArcMode.man \
+ XSetClipOrigin.man \
+ XSetCloseDownMode.man \
+ XSetCommand.man \
+ XSetErrorHandler.man \
+ XSetEventQueueOwner.man \
+ XSetFillStyle.man \
+ XSetFont.man \
+ XSetFontPath.man \
+ XSetICFocus.man \
+ XSetICValues.man \
+ XSetInputFocus.man \
+ XSetLineAttributes.man \
+ XSetPointerMapping.man \
+ XSetScreenSaver.man \
+ XSetSelectionOwner.man \
+ XSetState.man \
+ XSetTextProperty.man \
+ XSetTile.man \
+ XSetTransientForHint.man \
+ XSetWMClientMachine.man \
+ XSetWMColormapWindows.man \
+ XSetWMIconName.man \
+ XSetWMName.man \
+ XSetWMProperties.man \
+ XSetWMProtocols.man \
+ XStoreBytes.man \
+ XStoreColors.man \
+ XStringListToTextProperty.man \
+ XStringToKeysym.man \
+ XSupportsLocale.man \
+ XSynchronize.man \
+ XTextExtents.man \
+ XTextWidth.man \
+ XTranslateCoordinates.man \
+ XUnmapEvent.man \
+ XUnmapWindow.man \
+ XVaCreateNestedList.man \
+ XVisibilityEvent.man \
+ XWarpPointer.man
+
+filemandir = $(FILE_MAN_DIR)
+fileman_PRE = Compose.man
+
+libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@) \
+ $(all_shadows:=.@LIB_MAN_SUFFIX@)
+
+fileman_DATA = $(fileman_PRE:man=@FILE_MAN_SUFFIX@) \
+ $(file_shadows:=.@FILE_MAN_SUFFIX@)
+
+EXTRA_DIST = $(libman_PRE) $(fileman_PRE)
+
+CLEANFILES = $(libman_DATA) $(fileman_DATA)
+
+SUFFIXES = .$(LIB_MAN_SUFFIX) .$(FILE_MAN_SUFFIX) .man
+
+MAN_SUBSTS += -e 's|__xlocaledir__|$(X11_LOCALEDATADIR)|g'
+
+# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
+.man.$(LIB_MAN_SUFFIX) .man.$(FILE_MAN_SUFFIX):
+ $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
+
+# Generate man page shadow files (Replaces InstallManPageAliases from Imake)
+all_shadows = \
+ $(AllPlanes_shadows) \
+ $(BlackPixelOfScreen_shadows) \
+ $(DisplayOfCCC_shadows) \
+ $(ImageByteOrder_shadows) \
+ $(IsCursorKey_shadows) \
+ $(XAllocClassHint_shadows) \
+ $(XAllocIconSize_shadows) \
+ $(XAllocStandardColormap_shadows) \
+ $(XAllocSizeHints_shadows) \
+ $(XAllocWMHints_shadows) \
+ $(XAddHost_shadows) \
+ $(XAllocColor_shadows) \
+ $(XAnyEvent_shadows) \
+ $(XButtonEvent_shadows) \
+ $(XChangeKeyboardControl_shadows) \
+ $(XChangeKeyboardMapping_shadows) \
+ $(XChangePointerControl_shadows) \
+ $(XChangeSaveSet_shadows) \
+ $(XChangeWindowAttributes_shadows) \
+ $(XClearArea_shadows) \
+ $(XConfigureWindow_shadows) \
+ $(XCopyArea_shadows) \
+ $(XCreateColormap_shadows) \
+ $(XCreateFontCursor_shadows) \
+ $(XCreateFontSet_shadows) \
+ $(XCreateGC_shadows) \
+ $(XCreateIC_shadows) \
+ $(XInitImage_shadows) \
+ $(XCreateOC_shadows) \
+ $(XCreatePixmap_shadows) \
+ $(XCreateRegion_shadows) \
+ $(XCreateWindow_shadows) \
+ $(XDefineCursor_shadows) \
+ $(XDestroyWindow_shadows) \
+ $(XDrawArc_shadows) \
+ $(XDrawImageString_shadows) \
+ $(XDrawLine_shadows) \
+ $(XDrawPoint_shadows) \
+ $(XDrawRectangle_shadows) \
+ $(XDrawString_shadows) \
+ $(XDrawText_shadows) \
+ $(XEmptyRegion_shadows) \
+ $(XFillRectangle_shadows) \
+ $(XFlush_shadows) \
+ $(XFontsOfFontSet_shadows) \
+ $(XGraphicsExposeEvent_shadows) \
+ $(XrmGetFileDatabase_shadows) \
+ $(XrmGetResource_shadows) \
+ $(XGetEventData_shadows) \
+ $(XGetVisualInfo_shadows) \
+ $(XGetWindowAttributes_shadows) \
+ $(XGetWindowProperty_shadows) \
+ $(XGrabButton_shadows) \
+ $(XGrabKey_shadows) \
+ $(XGrabKeyboard_shadows) \
+ $(XGrabPointer_shadows) \
+ $(XGrabServer_shadows) \
+ $(XIconifyWindow_shadows) \
+ $(XIfEvent_shadows) \
+ $(XrmInitialize_shadows) \
+ $(XInstallColormap_shadows) \
+ $(XAddConnectionWatch_shadows) \
+ $(XIntersectRegion_shadows) \
+ $(XInternAtom_shadows) \
+ $(XListFonts_shadows) \
+ $(XLoadFont_shadows) \
+ $(XLookupKeysym_shadows) \
+ $(XrmMergeDatabases_shadows) \
+ $(XMapEvent_shadows) \
+ $(XMapWindow_shadows) \
+ $(XNextEvent_shadows) \
+ $(XOpenDisplay_shadows) \
+ $(XOpenIM_shadows) \
+ $(XOpenOM_shadows) \
+ $(XParseGeometry_shadows) \
+ $(XPolygonRegion_shadows) \
+ $(XPutImage_shadows) \
+ $(XrmPutResource_shadows) \
+ $(XQueryBestSize_shadows) \
+ $(XQueryColor_shadows) \
+ $(XQueryExtension_shadows) \
+ $(XResourceManagerString_shadows) \
+ $(XRaiseWindow_shadows) \
+ $(XReadBitmapFile_shadows) \
+ $(XRecolorCursor_shadows) \
+ $(XSaveContext_shadows) \
+ $(XSetICFocus_shadows) \
+ $(XSetICValues_shadows) \
+ $(XStringListToTextProperty_shadows) \
+ $(XSetArcMode_shadows) \
+ $(XSetClipOrigin_shadows) \
+ $(XSetCloseDownMode_shadows) \
+ $(XSetCommand_shadows) \
+ $(XSetErrorHandler_shadows) \
+ $(XSendEvent_shadows) \
+ $(XSetFillStyle_shadows) \
+ $(XSetFontPath_shadows) \
+ $(XSetInputFocus_shadows) \
+ $(XSetLineAttributes_shadows) \
+ $(XSetPointerMapping_shadows) \
+ $(XSetScreenSaver_shadows) \
+ $(XSetSelectionOwner_shadows) \
+ $(XSetState_shadows) \
+ $(XSetTransientForHint_shadows) \
+ $(XSetTextProperty_shadows) \
+ $(XSetTile_shadows) \
+ $(XSetWMClientMachine_shadows) \
+ $(XSetWMColormapWindows_shadows) \
+ $(XSetWMIconName_shadows) \
+ $(XSetWMName_shadows) \
+ $(XSetWMProperties_shadows) \
+ $(XSetWMProtocols_shadows) \
+ $(XStoreBytes_shadows) \
+ $(XStoreColors_shadows) \
+ $(XStringToKeysym_shadows) \
+ $(XSupportsLocale_shadows) \
+ $(XSynchronize_shadows) \
+ $(XmbTextListToTextProperty_shadows) \
+ $(XTextExtents_shadows) \
+ $(XTextWidth_shadows) \
+ $(XInitThreads_shadows) \
+ $(XrmUniqueQuark_shadows) \
+ $(XUnmapWindow_shadows) \
+ $(XcmsCCCOfColormap_shadows) \
+ $(XcmsAllocColor_shadows) \
+ $(XcmsColor_shadows) \
+ $(XcmsCreateCCC_shadows) \
+ $(XcmsCIELabQueryMaxC_shadows) \
+ $(XcmsCIELuvQueryMaxC_shadows) \
+ $(XcmsQueryBlack_shadows) \
+ $(XcmsQueryColor_shadows) \
+ $(XcmsStoreColor_shadows) \
+ $(XcmsSetWhitePoint_shadows) \
+ $(XcmsTekHVCQueryMaxC_shadows) \
+ $(XmbDrawImageString_shadows) \
+ $(XmbDrawString_shadows) \
+ $(XmbDrawText_shadows) \
+ $(XmbLookupString_shadows) \
+ $(XmbResetIC_shadows) \
+ $(XmbTextEscapement_shadows) \
+ $(XmbTextExtents_shadows) \
+ $(XmbTextPerCharExtents_shadows)
+
+
+AllPlanes_shadows = \
+ BlackPixel \
+ WhitePixel \
+ ConnectionNumber \
+ DefaultColormap \
+ DefaultDepth \
+ XListDepths \
+ DefaultGC \
+ DefaultRootWindow \
+ DefaultScreenOfDisplay \
+ DefaultScreen \
+ DefaultVisual \
+ DisplayCells \
+ DisplayPlanes \
+ DisplayString \
+ XMaxRequestSize \
+ XExtendedMaxRequestSize \
+ LastKnownRequestProcessed \
+ NextRequest \
+ ProtocolVersion \
+ ProtocolRevision \
+ QLength \
+ RootWindow \
+ ScreenCount \
+ ScreenOfDisplay \
+ ServerVendor \
+ VendorRelease
+
+BlackPixelOfScreen_shadows = \
+ WhitePixelOfScreen \
+ CellsOfScreen \
+ DefaultColormapOfScreen \
+ DefaultDepthOfScreen \
+ DefaultGCOfScreen \
+ DefaultVisualOfScreen \
+ DoesBackingStore \
+ DoesSaveUnders \
+ DisplayOfScreen \
+ XScreenNumberOfScreen \
+ EventMaskOfScreen \
+ HeightOfScreen \
+ HeightMMOfScreen \
+ MaxCmapsOfScreen \
+ MinCmapsOfScreen \
+ PlanesOfScreen \
+ RootWindowOfScreen \
+ WidthOfScreen \
+ WidthMMOfScreen
+
+DisplayOfCCC_shadows = \
+ VisualOfCCC \
+ ScreenNumberOfCCC \
+ ScreenWhitePointOfCCC \
+ ClientWhitePointOfCCC
+
+ImageByteOrder_shadows = \
+ BitmapBitOrder \
+ BitmapPad \
+ BitmapUnit \
+ DisplayHeight \
+ DisplayHeightMM \
+ DisplayWidth \
+ DisplayWidthMM \
+ XListPixmapFormats \
+ XPixmapFormatValues
+
+IsCursorKey_shadows = \
+ IsFunctionKey \
+ IsKeypadKey \
+ IsMiscFunctionKey \
+ IsModifierKey \
+ IsPFKey \
+ IsPrivateKeypadKey
+
+XAllocClassHint_shadows = \
+ XSetClassHint \
+ XGetClassHint \
+ XClassHint
+
+XAllocIconSize_shadows = \
+ XSetIconSizes \
+ XGetIconSizes \
+ XIconSize
+
+XAllocStandardColormap_shadows = \
+ XSetRGBColormaps \
+ XGetRGBColormaps \
+ XStandardColormap
+
+XAllocSizeHints_shadows = \
+ XSetWMNormalHints \
+ XGetWMNormalHints \
+ XSetWMSizeHints \
+ XGetWMSizeHints \
+ XSizeHints
+
+XAllocWMHints_shadows = \
+ XSetWMHints \
+ XGetWMHints \
+ XWMHints
+
+XAddHost_shadows = \
+ XAddHosts \
+ XListHosts \
+ XRemoveHost \
+ XRemoveHosts \
+ XSetAccessControl \
+ XEnableAccessControl \
+ XDisableAccessControl \
+ XHostAddress
+
+XAllocColor_shadows = \
+ XAllocNamedColor \
+ XAllocColorCells \
+ XAllocColorPlanes \
+ XFreeColors
+
+XAnyEvent_shadows = \
+ XEvent
+
+XButtonEvent_shadows = \
+ XKeyEvent \
+ XMotionEvent
+
+XChangeKeyboardControl_shadows = \
+ XGetKeyboardControl \
+ XAutoRepeatOn \
+ XAutoRepeatOff \
+ XBell \
+ XQueryKeymap \
+ XKeyboardControl
+
+XChangeKeyboardMapping_shadows = \
+ XGetKeyboardMapping \
+ XDisplayKeycodes \
+ XSetModifierMapping \
+ XGetModifierMapping \
+ XNewModifiermap \
+ XInsertModifiermapEntry \
+ XDeleteModifiermapEntry \
+ XFreeModifiermap \
+ XModifierKeymap
+
+XChangePointerControl_shadows = \
+ XGetPointerControl
+
+XChangeSaveSet_shadows = \
+ XAddToSaveSet \
+ XRemoveFromSaveSet
+
+XChangeWindowAttributes_shadows = \
+ XSetWindowBackground \
+ XSetWindowBackgroundPixmap \
+ XSetWindowBorder \
+ XSetWindowBorderPixmap \
+ XSetWindowColormap
+
+XClearArea_shadows = \
+ XClearWindow
+
+XConfigureWindow_shadows = \
+ XMoveWindow \
+ XResizeWindow \
+ XMoveResizeWindow \
+ XSetWindowBorderWidth \
+ XWindowChanges
+
+XCopyArea_shadows = \
+ XCopyPlane
+
+XCreateColormap_shadows = \
+ XCopyColormapAndFree \
+ XFreeColormap \
+ XColor
+
+XCreateFontCursor_shadows = \
+ XCreatePixmapCursor \
+ XCreateGlyphCursor
+
+XCreateFontSet_shadows = \
+ XFreeFontSet
+
+XCreateGC_shadows = \
+ XCopyGC \
+ XChangeGC \
+ XGetGCValues \
+ XFreeGC \
+ XGContextFromGC \
+ XGCValues
+
+XCreateIC_shadows = \
+ XDestroyIC \
+ XIMOfIC
+
+XInitImage_shadows = \
+ XCreateImage \
+ XGetPixel \
+ XPutPixel \
+ XSubImage \
+ XAddPixel \
+ XDestroyImage
+
+XCreateOC_shadows = \
+ XDestroyOC \
+ XSetOCValues \
+ XGetOCValues \
+ XOMOfOC
+
+XCreatePixmap_shadows = \
+ XFreePixmap
+
+XCreateRegion_shadows = \
+ XSetRegion \
+ XDestroyRegion
+
+XCreateWindow_shadows = \
+ XCreateSimpleWindow \
+ XSetWindowAttributes
+
+XDefineCursor_shadows = \
+ XUndefineCursor
+
+XDestroyWindow_shadows = \
+ XDestroySubwindows
+
+XDrawArc_shadows = \
+ XDrawArcs \
+ XArc
+
+XDrawImageString_shadows = \
+ XDrawImageString16
+
+XDrawLine_shadows = \
+ XDrawLines \
+ XDrawSegments \
+ XSegment
+
+XDrawPoint_shadows = \
+ XDrawPoints \
+ XPoint
+
+XDrawRectangle_shadows = \
+ XDrawRectangles \
+ XRectangle
+
+XDrawString_shadows = \
+ XDrawString16
+
+XDrawText_shadows = \
+ XDrawText16 \
+ XTextItem \
+ XTextItem16
+
+XEmptyRegion_shadows = \
+ XEqualRegion \
+ XPointInRegion \
+ XRectInRegion
+
+XFillRectangle_shadows = \
+ XFillRectangles \
+ XFillPolygon \
+ XFillArc \
+ XFillArcs
+
+XFlush_shadows = \
+ XSync \
+ XEventsQueued \
+ XPending
+
+XFontsOfFontSet_shadows = \
+ XBaseFontNameListOfFontSet \
+ XLocaleOfFontSet \
+ XContextDependentDrawing \
+ XContextualDrawing \
+ XDirectionalDependentDrawing
+
+XGraphicsExposeEvent_shadows = \
+ XNoExposeEvent
+
+XrmGetFileDatabase_shadows = \
+ XrmPutFileDatabase \
+ XrmGetStringDatabase \
+ XrmLocaleOfDatabase \
+ XrmGetDatabase \
+ XrmSetDatabase \
+ XrmDestroyDatabase
+
+XrmGetResource_shadows = \
+ XrmQGetResource \
+ XrmQGetSearchList \
+ XrmQGetSearchResource
+
+XGetEventData_shadows = \
+ XFreeEventData \
+ XGenericEventCookie
+
+XGetVisualInfo_shadows = \
+ XMatchVisualInfo \
+ XVisualIDFromVisual \
+ XVisualInfo
+
+XGetWindowAttributes_shadows = \
+ XGetGeometry \
+ XWindowAttributes
+
+XGetWindowProperty_shadows = \
+ XListProperties \
+ XChangeProperty \
+ XRotateWindowProperties \
+ XDeleteProperty
+
+XGrabButton_shadows = \
+ XUngrabButton
+
+XGrabKey_shadows = \
+ XUngrabKey
+
+XGrabKeyboard_shadows = \
+ XUngrabKeyboard
+
+XGrabPointer_shadows = \
+ XUngrabPointer \
+ XChangeActivePointerGrab
+
+XGrabServer_shadows = \
+ XUngrabServer
+
+XIconifyWindow_shadows = \
+ XWithdrawWindow \
+ XReconfigureWMWindow
+
+XIfEvent_shadows = \
+ XCheckIfEvent \
+ XPeekIfEvent
+
+XrmInitialize_shadows = \
+ XrmParseCommand \
+ XrmValue \
+ XrmOptionKind \
+ XrmOptionDescRec
+
+XInstallColormap_shadows = \
+ XUninstallColormap \
+ XListInstalledColormaps
+
+XAddConnectionWatch_shadows = \
+ XRemoveConnectionWatch \
+ XProcessInternalConnection \
+ XInternalConnectionNumbers
+
+XIntersectRegion_shadows = \
+ XUnionRegion \
+ XUnionRectWithRegion \
+ XSubtractRegion \
+ XXorRegion \
+ XOffsetRegion \
+ XShrinkRegion
+
+XInternAtom_shadows = \
+ XInternAtoms \
+ XGetAtomName \
+ XGetAtomNames
+
+XListFonts_shadows = \
+ XFreeFontNames \
+ XListFontsWithInfo \
+ XFreeFontInfo
+
+XLoadFont_shadows = \
+ XQueryFont \
+ XLoadQueryFont \
+ XFreeFont \
+ XGetFontProperty \
+ XUnloadFont \
+ XCharStruct \
+ XFontProp \
+ XChar2b \
+ XFontStruct
+
+XLookupKeysym_shadows = \
+ XRefreshKeyboardMapping \
+ XLookupString \
+ XRebindKeysym
+
+XrmMergeDatabases_shadows = \
+ XrmCombineDatabase \
+ XrmCombineFileDatabase
+
+XMapEvent_shadows = \
+ XMappingEvent
+
+XMapWindow_shadows = \
+ XMapRaised \
+ XMapSubwindows
+
+XNextEvent_shadows = \
+ XPeekEvent \
+ XWindowEvent \
+ XCheckWindowEvent \
+ XMaskEvent \
+ XCheckMaskEvent \
+ XCheckTypedEvent \
+ XCheckTypedWindowEvent
+
+XOpenDisplay_shadows = \
+ XCloseDisplay
+
+XOpenIM_shadows = \
+ XCloseIM \
+ XSetIMValues \
+ XGetIMValues \
+ XDisplayOfIM \
+ XLocaleOfIM \
+ XRegisterIMInstantiateCallback \
+ XUnregisterIMInstantiateCallback
+
+XOpenOM_shadows = \
+ XCloseOM \
+ XSetOMValues \
+ XGetOMValues \
+ XDisplayOfOM \
+ XLocaleOfOM
+
+XParseGeometry_shadows = \
+ XWMGeometry
+
+XPolygonRegion_shadows = \
+ XClipBox
+
+XPutImage_shadows = \
+ XGetImage \
+ XGetSubImage
+
+XrmPutResource_shadows = \
+ XrmQPutResource \
+ XrmPutStringResource \
+ XrmQPutStringResource \
+ XrmPutLineResource
+
+XQueryBestSize_shadows = \
+ XQueryBestTile \
+ XQueryBestStipple
+
+XQueryColor_shadows = \
+ XQueryColors \
+ XLookupColor \
+ XParseColor
+
+XQueryExtension_shadows = \
+ XListExtensions \
+ XFreeExtensionList
+
+XResourceManagerString_shadows = \
+ XScreenResourceString
+
+XRaiseWindow_shadows = \
+ XLowerWindow \
+ XCirculateSubwindows \
+ XCirculateSubwindowsUp \
+ XCirculateSubwindowsDown \
+ XRestackWindows
+
+XReadBitmapFile_shadows = \
+ XReadBitmapFileData \
+ XWriteBitmapFile \
+ XCreatePixmapFromBitmapData \
+ XCreateBitmapFromData
+
+XRecolorCursor_shadows = \
+ XFreeCursor \
+ XQueryBestCursor
+
+XSaveContext_shadows = \
+ XFindContext \
+ XDeleteContext \
+ XUniqueContext
+
+XSetICFocus_shadows = \
+ XUnsetICFocus
+
+XSetICValues_shadows = \
+ XGetICValues
+
+XStringListToTextProperty_shadows = \
+ XTextPropertyToStringList \
+ XFreeStringList \
+ XTextProperty
+
+XSetArcMode_shadows = \
+ XSetSubwindowMode \
+ XSetGraphicsExposure
+
+XSetClipOrigin_shadows = \
+ XSetClipMask \
+ XSetClipRectangles
+
+XSetCloseDownMode_shadows = \
+ XKillClient
+
+XSetCommand_shadows = \
+ XGetCommand
+
+XSetErrorHandler_shadows = \
+ XGetErrorText \
+ XDisplayName \
+ XSetIOErrorHandler \
+ XGetErrorDatabaseText
+
+XSendEvent_shadows = \
+ XDisplayMotionBufferSize \
+ XGetMotionEvents \
+ XTimeCoord
+
+XSetFillStyle_shadows = \
+ XSetFillRule
+
+XSetFontPath_shadows = \
+ XGetFontPath \
+ XFreeFontPath
+
+XSetInputFocus_shadows = \
+ XGetInputFocus
+
+XSetLineAttributes_shadows = \
+ XSetDashes
+
+XSetPointerMapping_shadows = \
+ XGetPointerMapping
+
+XSetScreenSaver_shadows = \
+ XForceScreenSaver \
+ XActivateScreenSaver \
+ XResetScreenSaver \
+ XGetScreenSaver
+
+XSetSelectionOwner_shadows = \
+ XGetSelectionOwner \
+ XConvertSelection
+
+XSetState_shadows = \
+ XSetFunction \
+ XSetPlaneMask \
+ XSetForeground \
+ XSetBackground
+
+XSetTransientForHint_shadows = \
+ XGetTransientForHint
+
+XSetTextProperty_shadows = \
+ XGetTextProperty
+
+XSetTile_shadows = \
+ XSetStipple \
+ XSetTSOrigin
+
+XSetWMClientMachine_shadows = \
+ XGetWMClientMachine
+
+XSetWMColormapWindows_shadows = \
+ XGetWMColormapWindows
+
+XSetWMIconName_shadows = \
+ XGetWMIconName \
+ XSetIconName \
+ XGetIconName
+
+XSetWMName_shadows = \
+ XGetWMName \
+ XStoreName \
+ XFetchName
+
+XSetWMProperties_shadows = \
+ XmbSetWMProperties \
+ Xutf8SetWMProperties
+
+XSetWMProtocols_shadows = \
+ XGetWMProtocols
+
+XStoreBytes_shadows = \
+ XStoreBuffer \
+ XFetchBytes \
+ XFetchBuffer \
+ XRotateBuffers
+
+XStoreColors_shadows = \
+ XStoreColor \
+ XStoreNamedColor
+
+XStringToKeysym_shadows = \
+ XKeysymToString \
+ XKeycodeToKeysym \
+ XKeysymToKeycode \
+ XConvertCase
+
+XSupportsLocale_shadows = \
+ XSetLocaleModifiers
+
+XSynchronize_shadows = \
+ XSetAfterFunction
+
+XmbTextListToTextProperty_shadows = \
+ XwcTextListToTextProperty \
+ Xutf8TextListToTextProperty \
+ XmbTextPropertyToTextList \
+ XwcTextPropertyToTextList \
+ Xutf8TextPropertyToTextList \
+ XwcFreeStringList \
+ XDefaultString
+
+XTextExtents_shadows = \
+ XTextExtents16 \
+ XQueryTextExtents \
+ XQueryTextExtents16
+
+XTextWidth_shadows = \
+ XTextWidth16
+
+XInitThreads_shadows = \
+ XLockDisplay \
+ XUnlockDisplay
+
+XrmUniqueQuark_shadows = \
+ XrmStringToQuark \
+ XrmPermStringToQuark \
+ XrmQuarkToString \
+ XrmStringToQuarkList \
+ XrmStringToBindingQuarkList
+
+XUnmapWindow_shadows = \
+ XUnmapSubwindows
+
+XcmsCCCOfColormap_shadows = \
+ XcmsSetCCCOfColormap
+
+XcmsAllocColor_shadows = \
+ XcmsAllocNamedColor
+
+XcmsColor_shadows = \
+ XcmsRGB \
+ XcmsRGBi \
+ XcmsCIEXYZ \
+ XcmsCIEuvY \
+ XcmsCIExyY \
+ XcmsCIELab \
+ XcmsCIELuv \
+ XcmsTekHVC \
+ XcmsPad
+
+XcmsCreateCCC_shadows = \
+ XcmsFreeCCC
+
+XcmsCIELabQueryMaxC_shadows = \
+ XcmsCIELabQueryMaxL \
+ XcmsCIELabQueryMaxLC \
+ XcmsCIELabQueryMinL
+
+XcmsCIELuvQueryMaxC_shadows = \
+ XcmsCIELuvQueryMaxL \
+ XcmsCIELuvQueryMaxLC \
+ XcmsCIELuvQueryMinL
+
+XcmsQueryBlack_shadows = \
+ XcmsQueryBlue \
+ XcmsQueryGreen \
+ XcmsQueryRed \
+ XcmsQueryWhite
+
+XcmsQueryColor_shadows = \
+ XcmsQueryColors \
+ XcmsLookupColor
+
+XcmsStoreColor_shadows = \
+ XcmsStoreColors
+
+XcmsSetWhitePoint_shadows = \
+ XcmsSetWhiteAdjustProc
+
+XcmsTekHVCQueryMaxC_shadows = \
+ XcmsTekHVCQueryMaxV \
+ XcmsTekHVCQueryMaxVC \
+ XcmsTekHVCQueryMaxVSamples \
+ XcmsTekHVCQueryMinV
+
+XmbDrawImageString_shadows = \
+ XwcDrawImageString \
+ Xutf8DrawImageString
+
+XmbDrawString_shadows = \
+ XwcDrawString \
+ Xutf8DrawString
+
+XmbDrawText_shadows = \
+ XwcDrawText \
+ Xutf8DrawText
+
+XmbLookupString_shadows = \
+ XwcLookupString \
+ Xutf8LookupString
+
+XmbResetIC_shadows = \
+ XwcResetIC \
+ Xutf8ResetIC
+
+XmbTextEscapement_shadows = \
+ XwcTextEscapement \
+ Xutf8TextEscapement
+
+XmbTextExtents_shadows = \
+ XwcTextExtents \
+ Xutf8TextExtents
+
+XmbTextPerCharExtents_shadows = \
+ XwcTextPerCharExtents \
+ Xutf8TextPerCharExtents
+
+file_shadows = \
+ $(Compose_shadows)
+
+Compose_shadows = \
+ XCompose
+
diff --git a/libX11/man/XChangeKeyboardMapping.man b/libX11/man/XChangeKeyboardMapping.man index 71b7a9142..37ee0ba43 100644 --- a/libX11/man/XChangeKeyboardMapping.man +++ b/libX11/man/XChangeKeyboardMapping.man @@ -1,447 +1,447 @@ -.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 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 CONNECTION 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 dealings in this Software without prior written authorization -.\" from the X Consortium. -.\" -.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991 by -.\" Digital Equipment Corporation -.\" -.\" Portions Copyright \(co 1990, 1991 by -.\" Tektronix, Inc. -.\" -.\" Permission to use, copy, modify and distribute this documentation for -.\" any purpose and without fee is hereby granted, provided that the above -.\" copyright notice appears in all copies and that both that copyright notice -.\" and this permission notice appear in all copies, and that the names of -.\" Digital and Tektronix not be used in in advertising or publicity pertaining -.\" to this documentation without specific, written prior permission. -.\" Digital and Tektronix makes no representations about the suitability -.\" of this documentation for any purpose. -.\" It is provided ``as is'' without express or implied warranty. -.\" -.\" -.ds xT X Toolkit Intrinsics \- C Language Interface -.ds xW Athena X Widgets \- C Language X Toolkit Interface -.ds xL Xlib \- C Language X Interface -.ds xC Inter-Client Communication Conventions Manual -.na -.de Ds -.nf -.\\$1D \\$2 \\$1 -.ft 1 -.\".ps \\n(PS -.\".if \\n(VS>=40 .vs \\n(VSu -.\".if \\n(VS<=39 .vs \\n(VSp -.. -.de De -.ce 0 -.if \\n(BD .DF -.nr BD 0 -.in \\n(OIu -.if \\n(TM .ls 2 -.sp \\n(DDu -.fi -.. -.de FD -.LP -.KS -.TA .5i 3i -.ta .5i 3i -.nf -.. -.de FN -.fi -.KE -.LP -.. -.de IN \" send an index entry to the stderr -.. -.de C{ -.KS -.nf -.D -.\" -.\" choose appropriate monospace font -.\" the imagen conditional, 480, -.\" may be changed to L if LB is too -.\" heavy for your eyes... -.\" -.ie "\\*(.T"480" .ft L -.el .ie "\\*(.T"300" .ft L -.el .ie "\\*(.T"202" .ft PO -.el .ie "\\*(.T"aps" .ft CW -.el .ft R -.ps \\n(PS -.ie \\n(VS>40 .vs \\n(VSu -.el .vs \\n(VSp -.. -.de C} -.DE -.R -.. -.de Pn -.ie t \\$1\fB\^\\$2\^\fR\\$3 -.el \\$1\fI\^\\$2\^\fP\\$3 -.. -.de ZN -.ie t \fB\^\\$1\^\fR\\$2 -.el \fI\^\\$1\^\fP\\$2 -.. -.de hN -.ie t <\fB\\$1\fR>\\$2 -.el <\fI\\$1\fP>\\$2 -.. -.de NT -.ne 7 -.ds NO Note -.if \\n(.$>$1 .if !'\\$2'C' .ds NO \\$2 -.if \\n(.$ .if !'\\$1'C' .ds NO \\$1 -.ie n .sp -.el .sp 10p -.TB -.ce -\\*(NO -.ie n .sp -.el .sp 5p -.if '\\$1'C' .ce 99 -.if '\\$2'C' .ce 99 -.in +5n -.ll -5n -.R -.. -. \" Note End -- doug kraft 3/85 -.de NE -.ce 0 -.in -5n -.ll +5n -.ie n .sp -.el .sp 10p -.. -.ny0 -.TH XChangeKeyboardMapping __libmansuffix__ __xorgversion__ "XLIB FUNCTIONS" -.SH NAME -XChangeKeyboardMapping, XGetKeyboardMapping, XDisplayKeycodes, XSetModifierMapping, XGetModifierMapping, XNewModifiermap, XInsertModifiermapEntry, XDeleteModifiermapEntry, XFreeModifiermap, XModifierKeymap \- manipulate keyboard encoding and keyboard encoding structure -.SH SYNTAX -.HP -int XChangeKeyboardMapping(\^Display *\fIdisplay\fP, int \fIfirst_keycode\fP, -int \fIkeysyms_per_keycode\fP, KeySym *\fIkeysyms\fP, int \fInum_codes\fP\^); -.HP -KeySym *XGetKeyboardMapping(\^Display *\fIdisplay\fP, KeyCode -\fIfirst_keycode\fP, int \fIkeycode_count\fP, int -*\fIkeysyms_per_keycode_return\fP\^); -.HP -int XDisplayKeycodes\^(\^Display *\fIdisplay\fP\^, int -*\fImin_keycodes_return\fP\^, int *\fImax_keycodes_return\fP\^); -.HP -int XSetModifierMapping(\^Display *\fIdisplay\fP, XModifierKeymap -*\fImodmap\fP\^); -.HP -XModifierKeymap *XGetModifierMapping(\^Display *\fIdisplay\fP\^); -.HP -XModifierKeymap *XNewModifiermap(\^int \fImax_keys_per_mod\fP\^); -.HP -XModifierKeymap *XInsertModifiermapEntry\^(\^XModifierKeymap *\fImodmap\fP, -KeyCode \fIkeycode_entry\fP, int \fImodifier\fP\^); -.HP -XModifierKeymap *XDeleteModifiermapEntry\^(\^XModifierKeymap *\fImodmap\fP, -KeyCode \fIkeycode_entry\fP, int \fImodifier\fP\^); -.HP -int XFreeModifiermap(\^XModifierKeymap *\fImodmap\fP\^); -.SH ARGUMENTS -.IP \fIdisplay\fP 1i -Specifies the connection to the X server. -.ds Kc changed or returned -.IP \fIfirst_keycode\fP 1i -Specifies the first KeyCode that is to be \*(Kc. -.IP \fIkeycode_count\fP 1i -Specifies the number of KeyCodes that are to be returned. -.IP \fIkeycode_entry\fP 1i -Specifies the KeyCode. -.IP \fIkeysyms\fP 1i -Specifies an array of KeySyms. -.IP \fIkeysyms_per_keycode\fP 1i -Specifies the number of KeySyms per KeyCode. -.IP \fIkeysyms_per_keycode_return\fP 1i -Returns the number of KeySyms per KeyCode. -.IP \fImax_keys_per_mod\fP 1i -Specifies the number of KeyCode entries preallocated to the modifiers -in the map. -.IP \fImax_keycodes_return\fP 1i -Returns the maximum number of KeyCodes. -.IP \fImin_keycodes_return\fP 1i -Returns the minimum number of KeyCodes. -.IP \fImodifier\fP 1i -Specifies the modifier. -.IP \fImodmap\fP 1i -Specifies the -.ZN XModifierKeymap -structure. -.IP \fInum_codes\fP 1i -Specifies the number of KeyCodes that are to be changed. -.SH DESCRIPTION -The -.ZN XChangeKeyboardMapping -function defines the symbols for the specified number of KeyCodes -starting with first_keycode. -The symbols for KeyCodes outside this range remain unchanged. -The number of elements in keysyms must be: -.LP -.Ds -num_codes * keysyms_per_keycode -.De -.LP -The specified first_keycode must be greater than or equal to min_keycode -returned by -.ZN XDisplayKeycodes , -or a -.ZN BadValue -error results. -In addition, the following expression must be less than or equal to -max_keycode as returned by -.ZN XDisplayKeycodes , -or a -.ZN BadValue -error results: -.LP -.Ds -first_keycode + num_codes \- 1 -.De -.LP -KeySym number N, counting from zero, for KeyCode K has the following index -in keysyms, counting from zero: -.LP -.Ds -(K \- first_keycode) * keysyms_per_keycode + N -.De -.LP -The specified keysyms_per_keycode can be chosen arbitrarily by the client -to be large enough to hold all desired symbols. -A special KeySym value of -.ZN NoSymbol -should be used to fill in unused elements -for individual KeyCodes. -It is legal for -.ZN NoSymbol -to appear in nontrailing positions -of the effective list for a KeyCode. -.ZN XChangeKeyboardMapping -generates a -.ZN MappingNotify -event. -.LP -There is no requirement that the X server interpret this mapping. -It is merely stored for reading and writing by clients. -.LP -.ZN XChangeKeyboardMapping -can generate -.ZN BadAlloc -and -.ZN BadValue -errors. -.LP -The -.ZN XGetKeyboardMapping -function returns the symbols for the specified number of KeyCodes -starting with first_keycode. -The value specified in first_keycode must be greater than -or equal to min_keycode as returned by -.ZN XDisplayKeycodes , -or a -.ZN BadValue -error results. -In addition, the following expression must be less than or equal -to max_keycode as returned by -.ZN XDisplayKeycodes : -.LP -.Ds -first_keycode + keycode_count \- 1 -.De -.LP -If this is not the case, a -.ZN BadValue -error results. -The number of elements in the KeySyms list is: -.LP -.Ds -keycode_count * keysyms_per_keycode_return -.De -.LP -KeySym number N, counting from zero, for KeyCode K has the following index -in the list, counting from zero: -.Ds -(K \- first_code) * keysyms_per_code_return + N -.De -.LP -The X server arbitrarily chooses the keysyms_per_keycode_return value -to be large enough to report all requested symbols. -A special KeySym value of -.ZN NoSymbol -is used to fill in unused elements for -individual KeyCodes. -To free the storage returned by -.ZN XGetKeyboardMapping , -use -.ZN XFree . -.LP -.ZN XGetKeyboardMapping -can generate a -.ZN BadValue -error. -.LP -The -.ZN XDisplayKeycodes -function returns the min-keycodes and max-keycodes supported by the -specified display. -The minimum number of KeyCodes returned is never less than 8, -and the maximum number of KeyCodes returned is never greater than 255. -Not all KeyCodes in this range are required to have corresponding keys. -.LP -The -.ZN XSetModifierMapping -function specifies the KeyCodes of the keys (if any) that are to be used -as modifiers. -If it succeeds, -the X server generates a -.ZN MappingNotify -event, and -.ZN XSetModifierMapping -returns -.ZN MappingSuccess . -X permits at most 8 modifier keys. -If more than 8 are specified in the -.ZN XModifierKeymap -structure, a -.ZN BadLength -error results. -.LP -The modifiermap member of the -.ZN XModifierKeymap -structure contains 8 sets of max_keypermod KeyCodes, -one for each modifier in the order -.ZN Shift , -.ZN Lock , -.ZN Control , -.ZN Mod1 , -.ZN Mod2 , -.ZN Mod3 , -.ZN Mod4 , -and -.ZN Mod5 . -Only nonzero KeyCodes have meaning in each set, -and zero KeyCodes are ignored. -In addition, all of the nonzero KeyCodes must be in the range specified by -min_keycode and max_keycode in the -.ZN Display -structure, -or a -.ZN BadValue -error results. -.LP -An X server can impose restrictions on how modifiers can be changed, -for example, -if certain keys do not generate up transitions in hardware, -if auto-repeat cannot be disabled on certain keys, -or if multiple modifier keys are not supported. -If some such restriction is violated, -the status reply is -.ZN MappingFailed , -and none of the modifiers are changed. -If the new KeyCodes specified for a modifier differ from those -currently defined and any (current or new) keys for that modifier are -in the logically down state, -.ZN XSetModifierMapping -returns -.ZN MappingBusy , -and none of the modifiers is changed. -.LP -.ZN XSetModifierMapping -can generate -.ZN BadAlloc -and -.ZN BadValue -errors. -.LP -The -.ZN XGetModifierMapping -function returns a pointer to a newly created -.ZN XModifierKeymap -structure that contains the keys being used as modifiers. -The structure should be freed after use by calling -.ZN XFreeModifiermap . -If only zero values appear in the set for any modifier, -that modifier is disabled. -.LP -The -.ZN XNewModifiermap -function returns a pointer to -.ZN XModifierKeymap -structure for later use. -.LP -The -.ZN XInsertModifiermapEntry -function adds the specified KeyCode to the set that controls the specified -modifier and returns the resulting -.ZN XModifierKeymap -structure (expanded as needed). -.LP -The -.ZN XDeleteModifiermapEntry -function deletes the specified KeyCode from the set that controls the -specified modifier and returns a pointer to the resulting -.ZN XModifierKeymap -structure. -.LP -The -.ZN XFreeModifiermap -function frees the specified -.ZN XModifierKeymap -structure. -.SH STRUCTURES -The -.ZN XModifierKeymap -structure contains: -.LP -.Ds 0 -.TA .5i 2.5i -.ta .5i 2.5i -typedef struct { - int max_keypermod; /\&* This server's max number of keys per modifier */ - KeyCode *modifiermap; /\&* An 8 by max_keypermod array of the modifiers */ -} XModifierKeymap; -.De -.SH DIAGNOSTICS -.TP 1i -.ZN BadAlloc -The server failed to allocate the requested resource or server memory. -.TP 1i -.ZN BadValue -Some numeric value falls outside the range of values accepted by the request. -Unless a specific range is specified for an argument, the full range defined -by the argument's type is accepted. Any argument defined as a set of -alternatives can generate this error. -.SH "SEE ALSO" -XFree(__libmansuffix__), -XSetPointerMapping(__libmansuffix__) -.br -\fI\*(xL\fP +.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 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 CONNECTION 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 dealings in this Software without prior written authorization
+.\" from the X Consortium.
+.\"
+.\" Copyright \(co 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
+.\" Digital Equipment Corporation
+.\"
+.\" Portions Copyright \(co 1990, 1991 by
+.\" Tektronix, Inc.
+.\"
+.\" Permission to use, copy, modify and distribute this documentation for
+.\" any purpose and without fee is hereby granted, provided that the above
+.\" copyright notice appears in all copies and that both that copyright notice
+.\" and this permission notice appear in all copies, and that the names of
+.\" Digital and Tektronix not be used in in advertising or publicity pertaining
+.\" to this documentation without specific, written prior permission.
+.\" Digital and Tektronix makes no representations about the suitability
+.\" of this documentation for any purpose.
+.\" It is provided ``as is'' without express or implied warranty.
+.\"
+.\"
+.ds xT X Toolkit Intrinsics \- C Language Interface
+.ds xW Athena X Widgets \- C Language X Toolkit Interface
+.ds xL Xlib \- C Language X Interface
+.ds xC Inter-Client Communication Conventions Manual
+.na
+.de Ds
+.nf
+.\\$1D \\$2 \\$1
+.ft 1
+.\".ps \\n(PS
+.\".if \\n(VS>=40 .vs \\n(VSu
+.\".if \\n(VS<=39 .vs \\n(VSp
+..
+.de De
+.ce 0
+.if \\n(BD .DF
+.nr BD 0
+.in \\n(OIu
+.if \\n(TM .ls 2
+.sp \\n(DDu
+.fi
+..
+.de FD
+.LP
+.KS
+.TA .5i 3i
+.ta .5i 3i
+.nf
+..
+.de FN
+.fi
+.KE
+.LP
+..
+.de IN \" send an index entry to the stderr
+..
+.de C{
+.KS
+.nf
+.D
+.\"
+.\" choose appropriate monospace font
+.\" the imagen conditional, 480,
+.\" may be changed to L if LB is too
+.\" heavy for your eyes...
+.\"
+.ie "\\*(.T"480" .ft L
+.el .ie "\\*(.T"300" .ft L
+.el .ie "\\*(.T"202" .ft PO
+.el .ie "\\*(.T"aps" .ft CW
+.el .ft R
+.ps \\n(PS
+.ie \\n(VS>40 .vs \\n(VSu
+.el .vs \\n(VSp
+..
+.de C}
+.DE
+.R
+..
+.de Pn
+.ie t \\$1\fB\^\\$2\^\fR\\$3
+.el \\$1\fI\^\\$2\^\fP\\$3
+..
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.de hN
+.ie t <\fB\\$1\fR>\\$2
+.el <\fI\\$1\fP>\\$2
+..
+.de NT
+.ne 7
+.ds NO Note
+.if \\n(.$>$1 .if !'\\$2'C' .ds NO \\$2
+.if \\n(.$ .if !'\\$1'C' .ds NO \\$1
+.ie n .sp
+.el .sp 10p
+.TB
+.ce
+\\*(NO
+.ie n .sp
+.el .sp 5p
+.if '\\$1'C' .ce 99
+.if '\\$2'C' .ce 99
+.in +5n
+.ll -5n
+.R
+..
+. \" Note End -- doug kraft 3/85
+.de NE
+.ce 0
+.in -5n
+.ll +5n
+.ie n .sp
+.el .sp 10p
+..
+.ny0
+.TH XChangeKeyboardMapping __libmansuffix__ __xorgversion__ "XLIB FUNCTIONS"
+.SH NAME
+XChangeKeyboardMapping, XGetKeyboardMapping, XDisplayKeycodes, XSetModifierMapping, XGetModifierMapping, XNewModifiermap, XInsertModifiermapEntry, XDeleteModifiermapEntry, XFreeModifiermap, XModifierKeymap \- manipulate keyboard encoding and keyboard encoding structure
+.SH SYNTAX
+.HP
+int XChangeKeyboardMapping(\^Display *\fIdisplay\fP, int \fIfirst_keycode\fP,
+int \fIkeysyms_per_keycode\fP, KeySym *\fIkeysyms\fP, int \fInum_codes\fP\^);
+.HP
+KeySym *XGetKeyboardMapping(\^Display *\fIdisplay\fP, KeyCode
+\fIfirst_keycode\fP, int \fIkeycode_count\fP, int
+*\fIkeysyms_per_keycode_return\fP\^);
+.HP
+int XDisplayKeycodes\^(\^Display *\fIdisplay\fP\^, int
+*\fImin_keycodes_return\fP\^, int *\fImax_keycodes_return\fP\^);
+.HP
+int XSetModifierMapping(\^Display *\fIdisplay\fP, XModifierKeymap
+*\fImodmap\fP\^);
+.HP
+XModifierKeymap *XGetModifierMapping(\^Display *\fIdisplay\fP\^);
+.HP
+XModifierKeymap *XNewModifiermap(\^int \fImax_keys_per_mod\fP\^);
+.HP
+XModifierKeymap *XInsertModifiermapEntry\^(\^XModifierKeymap *\fImodmap\fP,
+KeyCode \fIkeycode_entry\fP, int \fImodifier\fP\^);
+.HP
+XModifierKeymap *XDeleteModifiermapEntry\^(\^XModifierKeymap *\fImodmap\fP,
+KeyCode \fIkeycode_entry\fP, int \fImodifier\fP\^);
+.HP
+int XFreeModifiermap(\^XModifierKeymap *\fImodmap\fP\^);
+.SH ARGUMENTS
+.IP \fIdisplay\fP 1i
+Specifies the connection to the X server.
+.ds Kc changed or returned
+.IP \fIfirst_keycode\fP 1i
+Specifies the first KeyCode that is to be \*(Kc.
+.IP \fIkeycode_count\fP 1i
+Specifies the number of KeyCodes that are to be returned.
+.IP \fIkeycode_entry\fP 1i
+Specifies the KeyCode.
+.IP \fIkeysyms\fP 1i
+Specifies an array of KeySyms.
+.IP \fIkeysyms_per_keycode\fP 1i
+Specifies the number of KeySyms per KeyCode.
+.IP \fIkeysyms_per_keycode_return\fP 1i
+Returns the number of KeySyms per KeyCode.
+.IP \fImax_keys_per_mod\fP 1i
+Specifies the number of KeyCode entries preallocated to the modifiers
+in the map.
+.IP \fImax_keycodes_return\fP 1i
+Returns the maximum number of KeyCodes.
+.IP \fImin_keycodes_return\fP 1i
+Returns the minimum number of KeyCodes.
+.IP \fImodifier\fP 1i
+Specifies the modifier.
+.IP \fImodmap\fP 1i
+Specifies the
+.ZN XModifierKeymap
+structure.
+.IP \fInum_codes\fP 1i
+Specifies the number of KeyCodes that are to be changed.
+.SH DESCRIPTION
+The
+.ZN XChangeKeyboardMapping
+function defines the symbols for the specified number of KeyCodes
+starting with first_keycode.
+The symbols for KeyCodes outside this range remain unchanged.
+The number of elements in keysyms must be:
+.LP
+.Ds
+num_codes * keysyms_per_keycode
+.De
+.LP
+The specified first_keycode must be greater than or equal to min_keycode
+returned by
+.ZN XDisplayKeycodes ,
+or a
+.ZN BadValue
+error results.
+In addition, the following expression must be less than or equal to
+max_keycode as returned by
+.ZN XDisplayKeycodes ,
+or a
+.ZN BadValue
+error results:
+.LP
+.Ds
+first_keycode + num_codes \- 1
+.De
+.LP
+KeySym number N, counting from zero, for KeyCode K has the following index
+in keysyms, counting from zero:
+.LP
+.Ds
+(K \- first_keycode) * keysyms_per_keycode + N
+.De
+.LP
+The specified keysyms_per_keycode can be chosen arbitrarily by the client
+to be large enough to hold all desired symbols.
+A special KeySym value of
+.ZN NoSymbol
+should be used to fill in unused elements
+for individual KeyCodes.
+It is legal for
+.ZN NoSymbol
+to appear in nontrailing positions
+of the effective list for a KeyCode.
+.ZN XChangeKeyboardMapping
+generates a
+.ZN MappingNotify
+event.
+.LP
+There is no requirement that the X server interpret this mapping.
+It is merely stored for reading and writing by clients.
+.LP
+.ZN XChangeKeyboardMapping
+can generate
+.ZN BadAlloc
+and
+.ZN BadValue
+errors.
+.LP
+The
+.ZN XGetKeyboardMapping
+function returns the symbols for the specified number of KeyCodes
+starting with first_keycode.
+The value specified in first_keycode must be greater than
+or equal to min_keycode as returned by
+.ZN XDisplayKeycodes ,
+or a
+.ZN BadValue
+error results.
+In addition, the following expression must be less than or equal
+to max_keycode as returned by
+.ZN XDisplayKeycodes :
+.LP
+.Ds
+first_keycode + keycode_count \- 1
+.De
+.LP
+If this is not the case, a
+.ZN BadValue
+error results.
+The number of elements in the KeySyms list is:
+.LP
+.Ds
+keycode_count * keysyms_per_keycode_return
+.De
+.LP
+KeySym number N, counting from zero, for KeyCode K has the following index
+in the list, counting from zero:
+.Ds
+(K \- first_code) * keysyms_per_code_return + N
+.De
+.LP
+The X server arbitrarily chooses the keysyms_per_keycode_return value
+to be large enough to report all requested symbols.
+A special KeySym value of
+.ZN NoSymbol
+is used to fill in unused elements for
+individual KeyCodes.
+To free the storage returned by
+.ZN XGetKeyboardMapping ,
+use
+.ZN XFree .
+.LP
+.ZN XGetKeyboardMapping
+can generate a
+.ZN BadValue
+error.
+.LP
+The
+.ZN XDisplayKeycodes
+function returns the min-keycodes and max-keycodes supported by the
+specified display.
+The minimum number of KeyCodes returned is never less than 8,
+and the maximum number of KeyCodes returned is never greater than 255.
+Not all KeyCodes in this range are required to have corresponding keys.
+.LP
+The
+.ZN XSetModifierMapping
+function specifies the KeyCodes of the keys (if any) that are to be used
+as modifiers.
+If it succeeds,
+the X server generates a
+.ZN MappingNotify
+event, and
+.ZN XSetModifierMapping
+returns
+.ZN MappingSuccess .
+X permits at most 8 modifier keys.
+If more than 8 are specified in the
+.ZN XModifierKeymap
+structure, a
+.ZN BadLength
+error results.
+.LP
+The modifiermap member of the
+.ZN XModifierKeymap
+structure contains 8 sets of max_keypermod KeyCodes,
+one for each modifier in the order
+.ZN Shift ,
+.ZN Lock ,
+.ZN Control ,
+.ZN Mod1 ,
+.ZN Mod2 ,
+.ZN Mod3 ,
+.ZN Mod4 ,
+and
+.ZN Mod5 .
+Only nonzero KeyCodes have meaning in each set,
+and zero KeyCodes are ignored.
+In addition, all of the nonzero KeyCodes must be in the range specified by
+min_keycode and max_keycode in the
+.ZN Display
+structure,
+or a
+.ZN BadValue
+error results.
+.LP
+An X server can impose restrictions on how modifiers can be changed,
+for example,
+if certain keys do not generate up transitions in hardware,
+if auto-repeat cannot be disabled on certain keys,
+or if multiple modifier keys are not supported.
+If some such restriction is violated,
+the status reply is
+.ZN MappingFailed ,
+and none of the modifiers are changed.
+If the new KeyCodes specified for a modifier differ from those
+currently defined and any (current or new) keys for that modifier are
+in the logically down state,
+.ZN XSetModifierMapping
+returns
+.ZN MappingBusy ,
+and none of the modifiers is changed.
+.LP
+.ZN XSetModifierMapping
+can generate
+.ZN BadAlloc
+and
+.ZN BadValue
+errors.
+.LP
+The
+.ZN XGetModifierMapping
+function returns a pointer to a newly created
+.ZN XModifierKeymap
+structure that contains the keys being used as modifiers.
+The structure should be freed after use by calling
+.ZN XFreeModifiermap .
+If only zero values appear in the set for any modifier,
+that modifier is disabled.
+.LP
+The
+.ZN XNewModifiermap
+function returns a pointer to
+.ZN XModifierKeymap
+structure for later use.
+.LP
+The
+.ZN XInsertModifiermapEntry
+function adds the specified KeyCode to the set that controls the specified
+modifier and returns the resulting
+.ZN XModifierKeymap
+structure (expanded as needed).
+.LP
+The
+.ZN XDeleteModifiermapEntry
+function deletes the specified KeyCode from the set that controls the
+specified modifier and returns a pointer to the resulting
+.ZN XModifierKeymap
+structure.
+.LP
+The
+.ZN XFreeModifiermap
+function frees the specified
+.ZN XModifierKeymap
+structure.
+.SH STRUCTURES
+The
+.ZN XModifierKeymap
+structure contains:
+.LP
+.Ds 0
+.TA .5i 2.5i
+.ta .5i 2.5i
+typedef struct {
+ int max_keypermod; /\&* This server's max number of keys per modifier */
+ KeyCode *modifiermap; /\&* An 8 by max_keypermod array of the modifiers */
+} XModifierKeymap;
+.De
+.SH DIAGNOSTICS
+.TP 1i
+.ZN BadAlloc
+The server failed to allocate the requested resource or server memory.
+.TP 1i
+.ZN BadValue
+Some numeric value falls outside the range of values accepted by the request.
+Unless a specific range is specified for an argument, the full range defined
+by the argument's type is accepted. Any argument defined as a set of
+alternatives can generate this error.
+.SH "SEE ALSO"
+XFree(__libmansuffix__),
+XSetPointerMapping(__libmansuffix__)
+.br
+\fI\*(xL\fP
diff --git a/libX11/man/xkb/XkbPtrActionX.man b/libX11/man/xkb/XkbPtrActionX.man index 7116185c4..f821245f6 100644 --- a/libX11/man/xkb/XkbPtrActionX.man +++ b/libX11/man/xkb/XkbPtrActionX.man @@ -1,104 +1,104 @@ -'\" t -.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved. -.\" -.\" 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 (including the next -.\" paragraph) 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 OR COPYRIGHT HOLDERS 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. -.\" -.TH XkbPtrActionX __libmansuffix__ __xorgversion__ "XKB FUNCTIONS" -.SH NAME -XkbPtrActionX \- Returns the high_XXX and low_XXX fields of act converted to a -signed int -.SH SYNOPSIS -.HP -.B int XkbPtrActionX -.BI "(\^XkbPtrAction " "act" "\^);" -.if n .ti +5n -.if t .ti +.5i -.SH ARGUMENTS -.TP -.I \- act -action from which to extract X -.SH DESCRIPTION -.LP -Actions associated with the XkbPtrAction structure move the pointer when keys -are pressed and released. - -If the MouseKeys control is not enabled, KeyPress and KeyRelease events are -treated as though the action is XkbSA_NoAction. - -If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr -instructs the server to generate core pointer MotionNotify events rather than -the usual KeyPress event, and the corresponding KeyRelease event disables any -mouse keys timers that were created as a result of handling the XkbSA_MovePtr -action. - -The -.I type -field of the XkbPtrAction structure is always XkbSA_MovePtr. - -The -.I flags -field is a bitwise inclusive OR of the masks shown in Table 1. - -.TS -c s -l l -l lw(4i). -Table 1 Pointer Action Types -_ -Action Type Meaning -_ -XkbSA_NoAcceleration T{ -If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a -mouse keys timer for this key; every time the timer expires, the cursor moves. -T} -XkbSA_MoveAbsoluteX T{ -If set, the X portion of the structure specifies the new pointer X coordinate. -Otherwise, the X portion is added to the current pointer X coordinate to -determine the new pointer X coordinate. -T} -XkbSA_MoveAbsoluteY T{ -If set, the Y portion of the structure specifies the new pointer Y coordinate. -Otherwise, the Y portion is added to the current pointer Y coordinate to -determine the new pointer Y coordinate. -T} -.TE - -Each of the X and Y coordinates of the XkbPtrAction structure is composed of -two signed 16-bit values, that is, the X coordinate is composed of -.I high_XXX -and -.I low_XXX, -and similarly for the Y coordinate. Xkb provides the following macros, to -convert between a signed integer and two signed 16-bit values in XkbPtrAction -structures. -.SH STRUCTURES -.LP -.nf - - typedef struct _XkbPtrAction { - unsigned char type; /\(** XkbSA_MovePtr */ - unsigned char flags; /\(** determines type of pointer motion */ - unsigned char high_XXX; /\(** x coordinate, high bits*/ - unsigned char low_XXX; /\(** y coordinate, low bits */ - unsigned char high_YYY; /\(** x coordinate, high bits */ - unsigned char low_YYY; /\(** y coordinate, low bits */ - } XkbPtrAction; - -.fi +'\" t
+.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved.
+.\"
+.\" 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 (including the next
+.\" paragraph) 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 OR COPYRIGHT HOLDERS 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.
+.\"
+.TH XkbPtrActionX __libmansuffix__ __xorgversion__ "XKB FUNCTIONS"
+.SH NAME
+XkbPtrActionX \- Returns the high_XXX and low_XXX fields of act converted to a
+signed int
+.SH SYNOPSIS
+.HP
+.B int XkbPtrActionX
+.BI "(\^XkbPtrAction " "act" "\^);"
+.if n .ti +5n
+.if t .ti +.5i
+.SH ARGUMENTS
+.TP
+.I \- act
+action from which to extract X
+.SH DESCRIPTION
+.LP
+Actions associated with the XkbPtrAction structure move the pointer when keys
+are pressed and released.
+
+If the MouseKeys control is not enabled, KeyPress and KeyRelease events are
+treated as though the action is XkbSA_NoAction.
+
+If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr
+instructs the server to generate core pointer MotionNotify events rather than
+the usual KeyPress event, and the corresponding KeyRelease event disables any
+mouse keys timers that were created as a result of handling the XkbSA_MovePtr
+action.
+
+The
+.I type
+field of the XkbPtrAction structure is always XkbSA_MovePtr.
+
+The
+.I flags
+field is a bitwise inclusive OR of the masks shown in Table 1.
+
+.TS
+c s
+l l
+l lw(4i).
+Table 1 Pointer Action Types
+_
+Action Type Meaning
+_
+XkbSA_NoAcceleration T{
+If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a
+mouse keys timer for this key; every time the timer expires, the cursor moves.
+T}
+XkbSA_MoveAbsoluteX T{
+If set, the X portion of the structure specifies the new pointer X coordinate.
+Otherwise, the X portion is added to the current pointer X coordinate to
+determine the new pointer X coordinate.
+T}
+XkbSA_MoveAbsoluteY T{
+If set, the Y portion of the structure specifies the new pointer Y coordinate.
+Otherwise, the Y portion is added to the current pointer Y coordinate to
+determine the new pointer Y coordinate.
+T}
+.TE
+
+Each of the X and Y coordinates of the XkbPtrAction structure is composed of
+two signed 16-bit values, that is, the X coordinate is composed of
+.I high_XXX
+and
+.I low_XXX,
+and similarly for the Y coordinate. Xkb provides the following macros, to
+convert between a signed integer and two signed 16-bit values in XkbPtrAction
+structures.
+.SH STRUCTURES
+.LP
+.nf
+
+ typedef struct _XkbPtrAction {
+ unsigned char type; /\(** XkbSA_MovePtr */
+ unsigned char flags; /\(** determines type of pointer motion */
+ unsigned char high_XXX; /\(** x coordinate, high bits*/
+ unsigned char low_XXX; /\(** y coordinate, low bits */
+ unsigned char high_YYY; /\(** x coordinate, high bits */
+ unsigned char low_YYY; /\(** y coordinate, low bits */
+ } XkbPtrAction;
+
+.fi
diff --git a/libX11/man/xkb/XkbPtrActionY.man b/libX11/man/xkb/XkbPtrActionY.man index ad10214ea..f4afc180c 100644 --- a/libX11/man/xkb/XkbPtrActionY.man +++ b/libX11/man/xkb/XkbPtrActionY.man @@ -1,104 +1,104 @@ -'\" t -.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved. -.\" -.\" 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 (including the next -.\" paragraph) 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 OR COPYRIGHT HOLDERS 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. -.\" -.TH XkbPtrActionY __libmansuffix__ __xorgversion__ "XKB FUNCTIONS" -.SH NAME -XkbPtrActionY \- Returns the high_YYY and low_YYY fields of act converted to a -signed int -.SH SYNOPSIS -.HP -.B int XkbPtrActionY -.BI "(\^XkbPtrAction " "act" "\^);" -.if n .ti +5n -.if t .ti +.5i -.SH ARGUMENTS -.TP -.I \- act -action from which to extract Y -.SH DESCRIPTION -.LP -Actions associated with the XkbPtrAction structure move the pointer when keys -are pressed and released. - -If the MouseKeys control is not enabled, KeyPress and KeyRelease events are -treated as though the action is XkbSA_NoAction. - -If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr -instructs the server to generate core pointer MotionNotify events rather than -the usual KeyPress event, and the corresponding KeyRelease event disables any -mouse keys timers that were created as a result of handling the XkbSA_MovePtr -action. - -The -.I type -field of the XkbPtrAction structure is always XkbSA_MovePtr. - -The -.I flags -field is a bitwise inclusive OR of the masks shown in Table 1. - -.TS -c s -l l -l lw(4i). -Table 1 Pointer Action Types -_ -Action Type Meaning -_ -XkbSA_NoAcceleration T{ -If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a -mouse keys timer for this key; every time the timer expires, the cursor moves. -T} -XkbSA_MoveAbsoluteX T{ -If set, the X portion of the structure specifies the new pointer X coordinate. -Otherwise, the X portion is added to the current pointer X coordinate to -determine the new pointer X coordinate. -T} -XkbSA_MoveAbsoluteY T{ -If set, the Y portion of the structure specifies the new pointer Y coordinate. -Otherwise, the Y portion is added to the current pointer Y coordinate to -determine the new pointer Y coordinate. -T} -.TE - -Each of the X and Y coordinates of the XkbPtrAction structure is composed of -two signed 16-bit values, that is, the X coordinate is composed of -.I high_XXX -and -.I low_XXX, -and similarly for the Y coordinate. Xkb provides the following macros, to -convert between a signed integer and two signed 16-bit values in XkbPtrAction -structures. -.SH STRUCTURES -.LP -.nf - - typedef struct _XkbPtrAction { - unsigned char type; /\(** XkbSA_MovePtr */ - unsigned char flags; /\(** determines type of pointer motion */ - unsigned char high_XXX; /\(** x coordinate, high bits*/ - unsigned char low_XXX; /\(** y coordinate, low bits */ - unsigned char high_YYY; /\(** x coordinate, high bits */ - unsigned char low_YYY; /\(** y coordinate, low bits */ - } XkbPtrAction; - -.fi +'\" t
+.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved.
+.\"
+.\" 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 (including the next
+.\" paragraph) 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 OR COPYRIGHT HOLDERS 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.
+.\"
+.TH XkbPtrActionY __libmansuffix__ __xorgversion__ "XKB FUNCTIONS"
+.SH NAME
+XkbPtrActionY \- Returns the high_YYY and low_YYY fields of act converted to a
+signed int
+.SH SYNOPSIS
+.HP
+.B int XkbPtrActionY
+.BI "(\^XkbPtrAction " "act" "\^);"
+.if n .ti +5n
+.if t .ti +.5i
+.SH ARGUMENTS
+.TP
+.I \- act
+action from which to extract Y
+.SH DESCRIPTION
+.LP
+Actions associated with the XkbPtrAction structure move the pointer when keys
+are pressed and released.
+
+If the MouseKeys control is not enabled, KeyPress and KeyRelease events are
+treated as though the action is XkbSA_NoAction.
+
+If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr
+instructs the server to generate core pointer MotionNotify events rather than
+the usual KeyPress event, and the corresponding KeyRelease event disables any
+mouse keys timers that were created as a result of handling the XkbSA_MovePtr
+action.
+
+The
+.I type
+field of the XkbPtrAction structure is always XkbSA_MovePtr.
+
+The
+.I flags
+field is a bitwise inclusive OR of the masks shown in Table 1.
+
+.TS
+c s
+l l
+l lw(4i).
+Table 1 Pointer Action Types
+_
+Action Type Meaning
+_
+XkbSA_NoAcceleration T{
+If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a
+mouse keys timer for this key; every time the timer expires, the cursor moves.
+T}
+XkbSA_MoveAbsoluteX T{
+If set, the X portion of the structure specifies the new pointer X coordinate.
+Otherwise, the X portion is added to the current pointer X coordinate to
+determine the new pointer X coordinate.
+T}
+XkbSA_MoveAbsoluteY T{
+If set, the Y portion of the structure specifies the new pointer Y coordinate.
+Otherwise, the Y portion is added to the current pointer Y coordinate to
+determine the new pointer Y coordinate.
+T}
+.TE
+
+Each of the X and Y coordinates of the XkbPtrAction structure is composed of
+two signed 16-bit values, that is, the X coordinate is composed of
+.I high_XXX
+and
+.I low_XXX,
+and similarly for the Y coordinate. Xkb provides the following macros, to
+convert between a signed integer and two signed 16-bit values in XkbPtrAction
+structures.
+.SH STRUCTURES
+.LP
+.nf
+
+ typedef struct _XkbPtrAction {
+ unsigned char type; /\(** XkbSA_MovePtr */
+ unsigned char flags; /\(** determines type of pointer motion */
+ unsigned char high_XXX; /\(** x coordinate, high bits*/
+ unsigned char low_XXX; /\(** y coordinate, low bits */
+ unsigned char high_YYY; /\(** x coordinate, high bits */
+ unsigned char low_YYY; /\(** y coordinate, low bits */
+ } XkbPtrAction;
+
+.fi
diff --git a/libX11/man/xkb/XkbSetPtrActionX.man b/libX11/man/xkb/XkbSetPtrActionX.man index 2bd56b255..9b13cd402 100644 --- a/libX11/man/xkb/XkbSetPtrActionX.man +++ b/libX11/man/xkb/XkbSetPtrActionX.man @@ -1,108 +1,108 @@ -'\" t -.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved. -.\" -.\" 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 (including the next -.\" paragraph) 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 OR COPYRIGHT HOLDERS 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. -.\" -.TH XkbSetPtrActionX __libmansuffix__ __xorgversion__ "XKB FUNCTIONS" -.SH NAME -XkbSetPtrActionX \- Sets the high_XXX and low_XXX fields of act from the signed -integer value x -.SH SYNOPSIS -.HP -.B void XkbSetPtrActionX -.BI "(\^XkbPtrAction " "act" "\^," -.BI "int " "x" "\^);" -.if n .ti +5n -.if t .ti +.5i -.SH ARGUMENTS -.TP -.I \- act -action in which to set X -.TP -.I \- x -new value to set -.SH DESCRIPTION -.LP -Actions associated with the XkbPtrAction structure move the pointer when keys -are pressed and released. - -If the MouseKeys control is not enabled, KeyPress and KeyRelease events are -treated as though the action is XkbSA_NoAction. - -If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr -instructs the server to generate core pointer MotionNotify events rather than -the usual KeyPress event, and the corresponding KeyRelease event disables any -mouse keys timers that were created as a result of handling the XkbSA_MovePtr -action. - -The -.I type -field of the XkbPtrAction structure is always XkbSA_MovePtr. - -The -.I flags -field is a bitwise inclusive OR of the masks shown in Table 1. - -.TS -c s -l l -l lw(4i). -Table 1 Pointer Action Types -_ -Action Type Meaning -_ -XkbSA_NoAcceleration T{ -If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a -mouse keys timer for this key; every time the timer expires, the cursor moves. -T} -XkbSA_MoveAbsoluteX T{ -If set, the X portion of the structure specifies the new pointer X coordinate. -Otherwise, the X portion is added to the current pointer X coordinate to -determine the new pointer X coordinate. -T} -XkbSA_MoveAbsoluteY T{ -If set, the Y portion of the structure specifies the new pointer Y coordinate. -Otherwise, the Y portion is added to the current pointer Y coordinate to -determine the new pointer Y coordinate. -T} -.TE - -Each of the X and Y coordinates of the XkbPtrAction structure is composed of -two signed 16-bit values, that is, the X coordinate is composed of -.I high_XXX -and -.I low_XXX, -and similarly for the Y coordinate. Xkb provides the following macros, to -convert between a signed integer and two signed 16-bit values in XkbPtrAction -structures. -.SH STRUCTURES -.LP -.nf - - typedef struct _XkbPtrAction { - unsigned char type; /\(** XkbSA_MovePtr */ - unsigned char flags; /\(** determines type of pointer motion */ - unsigned char high_XXX; /\(** x coordinate, high bits*/ - unsigned char low_XXX; /\(** y coordinate, low bits */ - unsigned char high_YYY; /\(** x coordinate, high bits */ - unsigned char low_YYY; /\(** y coordinate, low bits */ - } XkbPtrAction; - -.fi +'\" t
+.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved.
+.\"
+.\" 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 (including the next
+.\" paragraph) 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 OR COPYRIGHT HOLDERS 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.
+.\"
+.TH XkbSetPtrActionX __libmansuffix__ __xorgversion__ "XKB FUNCTIONS"
+.SH NAME
+XkbSetPtrActionX \- Sets the high_XXX and low_XXX fields of act from the signed
+integer value x
+.SH SYNOPSIS
+.HP
+.B void XkbSetPtrActionX
+.BI "(\^XkbPtrAction " "act" "\^,"
+.BI "int " "x" "\^);"
+.if n .ti +5n
+.if t .ti +.5i
+.SH ARGUMENTS
+.TP
+.I \- act
+action in which to set X
+.TP
+.I \- x
+new value to set
+.SH DESCRIPTION
+.LP
+Actions associated with the XkbPtrAction structure move the pointer when keys
+are pressed and released.
+
+If the MouseKeys control is not enabled, KeyPress and KeyRelease events are
+treated as though the action is XkbSA_NoAction.
+
+If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr
+instructs the server to generate core pointer MotionNotify events rather than
+the usual KeyPress event, and the corresponding KeyRelease event disables any
+mouse keys timers that were created as a result of handling the XkbSA_MovePtr
+action.
+
+The
+.I type
+field of the XkbPtrAction structure is always XkbSA_MovePtr.
+
+The
+.I flags
+field is a bitwise inclusive OR of the masks shown in Table 1.
+
+.TS
+c s
+l l
+l lw(4i).
+Table 1 Pointer Action Types
+_
+Action Type Meaning
+_
+XkbSA_NoAcceleration T{
+If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a
+mouse keys timer for this key; every time the timer expires, the cursor moves.
+T}
+XkbSA_MoveAbsoluteX T{
+If set, the X portion of the structure specifies the new pointer X coordinate.
+Otherwise, the X portion is added to the current pointer X coordinate to
+determine the new pointer X coordinate.
+T}
+XkbSA_MoveAbsoluteY T{
+If set, the Y portion of the structure specifies the new pointer Y coordinate.
+Otherwise, the Y portion is added to the current pointer Y coordinate to
+determine the new pointer Y coordinate.
+T}
+.TE
+
+Each of the X and Y coordinates of the XkbPtrAction structure is composed of
+two signed 16-bit values, that is, the X coordinate is composed of
+.I high_XXX
+and
+.I low_XXX,
+and similarly for the Y coordinate. Xkb provides the following macros, to
+convert between a signed integer and two signed 16-bit values in XkbPtrAction
+structures.
+.SH STRUCTURES
+.LP
+.nf
+
+ typedef struct _XkbPtrAction {
+ unsigned char type; /\(** XkbSA_MovePtr */
+ unsigned char flags; /\(** determines type of pointer motion */
+ unsigned char high_XXX; /\(** x coordinate, high bits*/
+ unsigned char low_XXX; /\(** y coordinate, low bits */
+ unsigned char high_YYY; /\(** x coordinate, high bits */
+ unsigned char low_YYY; /\(** y coordinate, low bits */
+ } XkbPtrAction;
+
+.fi
diff --git a/libX11/man/xkb/XkbSetPtrActionY.man b/libX11/man/xkb/XkbSetPtrActionY.man index d8da0f20f..308970176 100644 --- a/libX11/man/xkb/XkbSetPtrActionY.man +++ b/libX11/man/xkb/XkbSetPtrActionY.man @@ -1,108 +1,108 @@ -'\" t -.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved. -.\" -.\" 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 (including the next -.\" paragraph) 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 OR COPYRIGHT HOLDERS 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. -.\" -.TH XkbSetPtrActionY __libmansuffix__ __xorgversion__ "XKB FUNCTIONS" -.SH NAME -XkbSetPtrActionY \- Sets the high_YYY and low_YYY fields of act from the signed -integer value y -.SH SYNOPSIS -.HP -.B void XkbSetPtrActionY -.BI "(\^XkbPtrAction " "act" "\^," -.BI "int " "y" "\^);" -.if n .ti +5n -.if t .ti +.5i -.SH ARGUMENTS -.TP -.I \- act -action in which to set Y -.TP -.I \- y -new value to set -.SH DESCRIPTION -.LP -Actions associated with the XkbPtrAction structure move the pointer when keys -are pressed and released. - -If the MouseKeys control is not enabled, KeyPress and KeyRelease events are -treated as though the action is XkbSA_NoAction. - -If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr -instructs the server to generate core pointer MotionNotify events rather than -the usual KeyPress event, and the corresponding KeyRelease event disables any -mouse keys timers that were created as a result of handling the XkbSA_MovePtr -action. - -The -.I type -field of the XkbPtrAction structure is always XkbSA_MovePtr. - -The -.I flags -field is a bitwise inclusive OR of the masks shown in Table 1. - -.TS -c s -l l -l lw(4i). -Table 1 Pointer Action Types -_ -Action Type Meaning -_ -XkbSA_NoAcceleration T{ -If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a -mouse keys timer for this key; every time the timer expires, the cursor moves. -T} -XkbSA_MoveAbsoluteX T{ -If set, the X portion of the structure specifies the new pointer X coordinate. -Otherwise, the X portion is added to the current pointer X coordinate to -determine the new pointer X coordinate. -T} -XkbSA_MoveAbsoluteY T{ -If set, the Y portion of the structure specifies the new pointer Y coordinate. -Otherwise, the Y portion is added to the current pointer Y coordinate to -determine the new pointer Y coordinate. -T} -.TE - -Each of the X and Y coordinates of the XkbPtrAction structure is composed of -two signed 16-bit values, that is, the X coordinate is composed of -.I high_XXX -and -.I low_XXX, -and similarly for the Y coordinate. Xkb provides the following macros, to -convert between a signed integer and two signed 16-bit values in XkbPtrAction -structures. -.SH STRUCTURES -.LP -.nf - - typedef struct _XkbPtrAction { - unsigned char type; /\(** XkbSA_MovePtr */ - unsigned char flags; /\(** determines type of pointer motion */ - unsigned char high_XXX; /\(** x coordinate, high bits*/ - unsigned char low_XXX; /\(** y coordinate, low bits */ - unsigned char high_YYY; /\(** x coordinate, high bits */ - unsigned char low_YYY; /\(** y coordinate, low bits */ - } XkbPtrAction; - -.fi +'\" t
+.\" Copyright 1999 Oracle and/or its affiliates. All rights reserved.
+.\"
+.\" 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 (including the next
+.\" paragraph) 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 OR COPYRIGHT HOLDERS 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.
+.\"
+.TH XkbSetPtrActionY __libmansuffix__ __xorgversion__ "XKB FUNCTIONS"
+.SH NAME
+XkbSetPtrActionY \- Sets the high_YYY and low_YYY fields of act from the signed
+integer value y
+.SH SYNOPSIS
+.HP
+.B void XkbSetPtrActionY
+.BI "(\^XkbPtrAction " "act" "\^,"
+.BI "int " "y" "\^);"
+.if n .ti +5n
+.if t .ti +.5i
+.SH ARGUMENTS
+.TP
+.I \- act
+action in which to set Y
+.TP
+.I \- y
+new value to set
+.SH DESCRIPTION
+.LP
+Actions associated with the XkbPtrAction structure move the pointer when keys
+are pressed and released.
+
+If the MouseKeys control is not enabled, KeyPress and KeyRelease events are
+treated as though the action is XkbSA_NoAction.
+
+If the MouseKeys control is enabled, a server action of type XkbSA_MovePtr
+instructs the server to generate core pointer MotionNotify events rather than
+the usual KeyPress event, and the corresponding KeyRelease event disables any
+mouse keys timers that were created as a result of handling the XkbSA_MovePtr
+action.
+
+The
+.I type
+field of the XkbPtrAction structure is always XkbSA_MovePtr.
+
+The
+.I flags
+field is a bitwise inclusive OR of the masks shown in Table 1.
+
+.TS
+c s
+l l
+l lw(4i).
+Table 1 Pointer Action Types
+_
+Action Type Meaning
+_
+XkbSA_NoAcceleration T{
+If not set, and the MouseKeysAccel control is enabled, the KeyPress initiates a
+mouse keys timer for this key; every time the timer expires, the cursor moves.
+T}
+XkbSA_MoveAbsoluteX T{
+If set, the X portion of the structure specifies the new pointer X coordinate.
+Otherwise, the X portion is added to the current pointer X coordinate to
+determine the new pointer X coordinate.
+T}
+XkbSA_MoveAbsoluteY T{
+If set, the Y portion of the structure specifies the new pointer Y coordinate.
+Otherwise, the Y portion is added to the current pointer Y coordinate to
+determine the new pointer Y coordinate.
+T}
+.TE
+
+Each of the X and Y coordinates of the XkbPtrAction structure is composed of
+two signed 16-bit values, that is, the X coordinate is composed of
+.I high_XXX
+and
+.I low_XXX,
+and similarly for the Y coordinate. Xkb provides the following macros, to
+convert between a signed integer and two signed 16-bit values in XkbPtrAction
+structures.
+.SH STRUCTURES
+.LP
+.nf
+
+ typedef struct _XkbPtrAction {
+ unsigned char type; /\(** XkbSA_MovePtr */
+ unsigned char flags; /\(** determines type of pointer motion */
+ unsigned char high_XXX; /\(** x coordinate, high bits*/
+ unsigned char low_XXX; /\(** y coordinate, low bits */
+ unsigned char high_YYY; /\(** x coordinate, high bits */
+ unsigned char low_YYY; /\(** y coordinate, low bits */
+ } XkbPtrAction;
+
+.fi
diff --git a/libX11/modules/im/ximcp/imCallbk.c b/libX11/modules/im/ximcp/imCallbk.c index 6275bbf00..761021354 100644 --- a/libX11/modules/im/ximcp/imCallbk.c +++ b/libX11/modules/im/ximcp/imCallbk.c @@ -1,754 +1,754 @@ -/*********************************************************************** -Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts, -Copyright 1994 by FUJITSU LIMITED -Copyright 1994 by Sony Corporation - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 names of Digital, FUJITSU -LIMITED and Sony Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED -AND SONY CORPORATION 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. - - Author: Hiroyuki Miyamoto Digital Equipment Corporation - miyamoto@jrd.dec.com - Modifier: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Makoto Wakamatsu Sony Corporation - makoto@sm.sony.co.jp - -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" -#include "XlcPubI.h" -#ifdef X_LOCALE -#define mblen(a,b) _Xmblen(a,b) -extern int _Xmblen (); -#endif - -#define sz_CARD8 1 -#define sz_INT8 1 -#define sz_CARD16 2 -#define sz_INT16 2 -#define sz_BITMASK16 sz_CARD16 -#define sz_CARD32 4 -#define sz_INT32 4 -#define sz_BITMASK32 sz_CARD32 -#define sz_XIMID sizeof(XIMID) -#define sz_XICID sizeof(XICID) -#define sz_XIMATTRID sizeof(XIMATTRID) -#define sz_XICATTRID sizeof(XICATTRID) -#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID) -#define sz_ximGeometry 0 -#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32) -#define sz_ximPreeditStart 0 -#define sz_ximPreeditStartReply sz_INT32 -#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32) -#define sz_ximPreeditCaretReply sz_CARD32 -#define sz_ximPreeditDone 0 -#define sz_ximStatusStart 0 -#define sz_ximStatusDone 0 - -typedef enum { - XimCbSuccess, - XimCbNoCallback, - XimCbError, - XimCbQueued, - XimCbBadContextID, - XimCbBadOpcode -} XimCbStatus; - -typedef XimCbStatus (*XimCb)( - Xim, Xic, char*, int - ); - -#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p))) -#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8)) -#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8)) -#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE)) -#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID)) - -#define _XimWriteData(im,len,data) \ - (im->private.proto.write((im),(len),(XPointer)(data))) -#define _XimReadData(im,buf,buf_len,len) \ - (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len))) -#define _XimFlushData(im) im->private.proto.flush((im)) - -Private XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int); -Private void _free_memory_for_text(XIMText*); -Private XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int); - -#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) -#define RConst /**/ -#else -#define RConst const -#endif - -/* NOTE: - * the table below depends on the protocol number - * defined in the IM Protocol document. - */ -static RConst XimCb callback_table[] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */ - _XimGeometryCallback, /* #070 */ - _XimStrConversionCallback, /* #071 */ - NULL, /* #072 */ - _XimPreeditStartCallback, /* #073 */ - NULL, /* #074 */ - _XimPreeditDrawCallback, /* #075 */ - _XimPreeditCaretCallback, /* #076 */ - NULL, /* #077 */ - _XimPreeditDoneCallback, /* #078 */ - _XimStatusStartCallback, /* #079 */ - _XimStatusDrawCallback, /* #080 */ - _XimStatusDoneCallback, /* #081 */ - _XimPreeditStateNotifyCallback /* #082 */ - }; - - -Private Bool -_XimIsReadyForProcess(Xic ic) -{ - return(!ic->private.proto.waitCallback); /* check HM */ -} - -Private void -_XimProcessPendingCallbacks(Xic ic) -{ - XimPendingCallback pcbq; - - while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL) - && _XimIsReadyForProcess(ic)) { - (void) (*callback_table[pcbq->major_opcode])(pcbq->im, - pcbq->ic, - pcbq->proto, - pcbq->proto_len); - ic->private.proto.pend_cb_que = pcbq->next; - Xfree(pcbq->proto); /* free memory of XimPendingCallback */ - Xfree(pcbq); - } -} - -Private void -_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data) -{ - XimPendingCallback pcbq = ic->private.proto.pend_cb_que; - - /* Queuing is FIFO - */ - while (pcbq != (XimPendingCallback)NULL) { - if (pcbq->next == (XimPendingCallback)NULL) { - break; - } - pcbq = pcbq->next; - } - if (pcbq == (XimPendingCallback)NULL) { - ic->private.proto.pend_cb_que = call_data; - } - else { - pcbq->next = call_data; - } -} - -Public Bool -_XimCbDispatch(Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - /* `data' points to the beginning of the packet defined in IM Protocol doc. - */ - int major_opcode = PACKET_TO_MAJOROPCODE(data); - XIMID imid = PACKET_TO_IMID(data); - XICID icid = PACKET_TO_ICID(data); - Xim im = (Xim)call_data; /* check HM */ - Xic ic = _XimICOfXICID(im, icid); - char* proto; - int proto_len; - - /* check validity of im/ic - */ - if ((imid != im->private.proto.imid) || !ic) { - return False; /* status = XimCbBadContextID; */ - } - - /* process pending callbacks - */ - _XimProcessPendingCallbacks(ic); - - /* check if the protocol should be processed here - */ - if (major_opcode > 82) { - return False; /* status = XimCbBadOpcode; */ - } - if (!callback_table[major_opcode]) { - return False; /* status = XimCbBadOpcode; */ - } - - /* move the pointer ahead by the IM Protocol packet header size - */ - proto = (char*)data + sz_ximPacketHeader; - proto_len = (int)len - sz_ximPacketHeader; - - /* check if it can be processed right away - * and if no, queue the protocol, otherwise invoke a callback - */ - if (!_XimIsReadyForProcess(ic)) { - - /* queue the protocol - */ - XimPendingCallback pcb; - char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL; - - pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec)); - if (pcb && (proto_len <= 0 || proto_buf)) { - if (proto_len > 0) - memcpy(proto_buf, proto, proto_len); - - pcb->major_opcode = major_opcode; - pcb->im = im; - pcb->ic = ic; - pcb->proto = proto_buf; - pcb->proto_len = proto_len; - pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */ - _XimPutCbIntoQueue(ic, pcb); - /* status = XimCbQueued; */ - } else { - /* status = XimCbError; */ - Xfree(pcb); - Xfree(proto_buf); - } - } - else { - /* invoke each callback according to the major opcode. - * `proto' points to the next address of IM-ID and IC-ID. - * `proto_len' specifies the packet length. - */ - (void) (*callback_table[major_opcode])(im, ic, proto, proto_len); - } - return True; -} - -Private XimCbStatus -_XimGeometryCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.geometry_callback; - - /* invoke the callack - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStrConversionCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */ - XIMStringConversionCallbackStruct cbrec; - - /* invoke the callback - */ - if (cb && cb->callback) { - int p = XIM_HEADER_SIZE; - cbrec.position = (XIMStringConversionPosition) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.direction = (XIMCaretDirection) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.operation = (XIMStringConversionOperation) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.factor = (unsigned short) - *(CARD32*)&proto[p]; - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_STR_CONVERSION, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* send a reply - */ - { - CARD8 *buf; - INT16 buf_len; - int p, length_in_bytes, i; - - /* Assumption: - * `cbrec.text->length' means the string length in characters - */ - { - length_in_bytes = (cbrec.text->encoding_is_wchar)? - sizeof(wchar_t) * cbrec.text->length: /* wchar */ - strlen(cbrec.text->string.mbs); /* mb */ - buf_len = XIM_HEADER_SIZE + - sz_CARD16 + - 2 + length_in_bytes + - XIM_PAD(2 + length_in_bytes) + - 2 + 2 + sz_CARD32 * cbrec.text->length; - buf = (CARD8*)Xmalloc(buf_len); - } - _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); - buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; - memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); - p += length_in_bytes; - *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); - p += XIM_PAD(2); - for (i = 0; i < (int)cbrec.text->length; i++) { - *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; - p += sz_CARD32; - } - - if (!(_XimWriteData(im, buf_len, buf))) { - return XimCbError; - } - _XimFlushData(im); - - Xfree(buf); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditStartCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.start_callback; - int ret; - - /* invoke the callback - */ - if (cb && cb->callback){ - ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_PREEDIT_START, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* send a reply - */ - { - CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; - CARD8 *buf = (CARD8 *)buf32; - INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; - int p; - - _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(INT32*)&buf[p] = (INT32)ret; - - if (!(_XimWriteData(im, buf_len, buf))) { - return XimCbError; - } - _XimFlushData(im); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditDoneCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.done_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private void -_read_text_from_packet(Xim im, - char* buf, - XIMText** text_ptr) -{ - int status; - XIMText* text; - int tmp_len; - char* tmp_buf; - Status s = 0; - - status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; - - /* string part - */ - if (status & 0x00000001) /* "no string" bit on */ { - buf += sz_CARD16; /* skip "length of preedit string" */ - buf += 2; /* pad */ - *text_ptr = (XIMText*)NULL; - return; - } - - *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText)); - if (text == (XIMText*)NULL) return; - - tmp_len = (int)*(CARD16*)buf; - buf += sz_CARD16; - if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) { - memcpy(tmp_buf, buf, tmp_len); - tmp_buf[tmp_len] = '\0'; - - text->encoding_is_wchar = False; - text->length = im->methods->ctstombs((XIM)im, - tmp_buf, tmp_len, - NULL, 0, &s); /* CT? HM */ - if (s != XLookupNone) { -#ifndef NO_DEC_I18N_FIX - /* Allow for NULL-terminated */ - if ((text->string.multi_byte = - (char*)Xmalloc(text->length * - XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { -#else - if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) { -#endif - int tmp; -#ifndef NO_DEC_I18N_FIX - char *char_tmp; - int char_len; -#endif - tmp = im->methods->ctstombs((XIM)im, - tmp_buf, tmp_len, -#ifndef NO_DEC_I18N_FIX - text->string.multi_byte, - text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, -#else - text->string.multi_byte, text->length, -#endif - &s); - text->string.multi_byte[tmp] = '\0'; -#ifndef NO_DEC_I18N_FIX - text->length = 0; - char_tmp = text->string.multi_byte; - while (*char_tmp != '\0') { - char_len = mblen(char_tmp, strlen(char_tmp)); - char_tmp = char_tmp + char_len; - (text->length)++; - } -#endif - } - } - else { - text->length = 0; - text->string.multi_byte = NULL; - } - - Xfree(tmp_buf); - } - buf += tmp_len; - - buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ - - /* feedback part - */ - if (status & 0x00000002) /* "no feedback" bit on */ { - text->feedback = (XIMFeedback*)NULL; - } - else { - int i, j; - - i = (int)*(CARD16*)buf; buf += sz_CARD16; - buf += sz_CARD16; /* skip `unused' */ - text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); - j = 0; - while (i > 0) { - text->feedback[j] = (XIMFeedback)*(CARD32*)buf; - buf += sz_CARD32; - i -= sz_CARD32; - j++; - } - /* - * text->length tells how long both the status string and - * the feedback array are. If there's "no string" the - * text->length was set to zero previously. See above. - * But if there is feedback (i.e. not "no feedback") then - * we need to convey the length of the feedback array. - * It might have been better if the protocol sent two - * different values, one for the length of the status - * string and one for the length of the feedback array. - */ - if (status & 0x00000001) /* "no string" bit on */ { - text->length = j; - } - } -} - -Private void -_free_memory_for_text(XIMText* text) -{ - if (text) { - if (text->string.multi_byte) - Xfree(text->string.multi_byte); - if (text->feedback) - Xfree(text->feedback); - Xfree(text); - } -} - -Private XimCbStatus -_XimPreeditDrawCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.draw_callback; - XIMPreeditDrawCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; - cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; - cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; - _read_text_from_packet(im, proto, &cbs.text); - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - - _free_memory_for_text((XIMText*)cbs.text); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditCaretCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.caret_callback; - XIMPreeditCaretCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.position = (int)*(INT32*)proto; proto += sz_INT32; - cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; - cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_PREEDIT_CARET, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* Send a reply - */ - { - CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; - INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; - int p; - - _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len); - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(CARD32*)&buf[p] = (CARD32)cbs.position; - - if (!(_XimWriteData(im, len, buf))) { - return XimCbError; - } - _XimFlushData(im); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusStartCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.start_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusDoneCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.done_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusDrawCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.draw_callback; - XIMStatusDrawCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; - if (cbs.type == XIMTextType) { - _read_text_from_packet(im, proto, &cbs.data.text); - } - else if (cbs.type == XIMBitmapType) { - cbs.data.bitmap = (Pixmap)*(CARD32*)proto; - } - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - - if (cbs.type == XIMTextType) - _free_memory_for_text((XIMText *)cbs.data.text); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) -{ - XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; - - /* invoke the callack - */ - if( cb && cb->callback ) { - XIMPreeditStateNotifyCallbackStruct cbrec; - - cbrec.state = *(BITMASK32 *)proto; - (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); - } - else { - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - +/***********************************************************************
+Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 by FUJITSU LIMITED
+Copyright 1994 by Sony Corporation
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Digital, FUJITSU
+LIMITED and Sony Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
+AND SONY CORPORATION 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.
+
+ Author: Hiroyuki Miyamoto Digital Equipment Corporation
+ miyamoto@jrd.dec.com
+ Modifier: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Makoto Wakamatsu Sony Corporation
+ makoto@sm.sony.co.jp
+
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XlcPubI.h"
+#ifdef X_LOCALE
+#define mblen(a,b) _Xmblen(a,b)
+extern int _Xmblen ();
+#endif
+
+#define sz_CARD8 1
+#define sz_INT8 1
+#define sz_CARD16 2
+#define sz_INT16 2
+#define sz_BITMASK16 sz_CARD16
+#define sz_CARD32 4
+#define sz_INT32 4
+#define sz_BITMASK32 sz_CARD32
+#define sz_XIMID sizeof(XIMID)
+#define sz_XICID sizeof(XICID)
+#define sz_XIMATTRID sizeof(XIMATTRID)
+#define sz_XICATTRID sizeof(XICATTRID)
+#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID)
+#define sz_ximGeometry 0
+#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32)
+#define sz_ximPreeditStart 0
+#define sz_ximPreeditStartReply sz_INT32
+#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32)
+#define sz_ximPreeditCaretReply sz_CARD32
+#define sz_ximPreeditDone 0
+#define sz_ximStatusStart 0
+#define sz_ximStatusDone 0
+
+typedef enum {
+ XimCbSuccess,
+ XimCbNoCallback,
+ XimCbError,
+ XimCbQueued,
+ XimCbBadContextID,
+ XimCbBadOpcode
+} XimCbStatus;
+
+typedef XimCbStatus (*XimCb)(
+ Xim, Xic, char*, int
+ );
+
+#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p)))
+#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8))
+#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8))
+#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE))
+#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID))
+
+#define _XimWriteData(im,len,data) \
+ (im->private.proto.write((im),(len),(XPointer)(data)))
+#define _XimReadData(im,buf,buf_len,len) \
+ (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len)))
+#define _XimFlushData(im) im->private.proto.flush((im))
+
+Private XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int);
+Private void _free_memory_for_text(XIMText*);
+Private XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int);
+
+#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32))
+#define RConst /**/
+#else
+#define RConst const
+#endif
+
+/* NOTE:
+ * the table below depends on the protocol number
+ * defined in the IM Protocol document.
+ */
+static RConst XimCb callback_table[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */
+ _XimGeometryCallback, /* #070 */
+ _XimStrConversionCallback, /* #071 */
+ NULL, /* #072 */
+ _XimPreeditStartCallback, /* #073 */
+ NULL, /* #074 */
+ _XimPreeditDrawCallback, /* #075 */
+ _XimPreeditCaretCallback, /* #076 */
+ NULL, /* #077 */
+ _XimPreeditDoneCallback, /* #078 */
+ _XimStatusStartCallback, /* #079 */
+ _XimStatusDrawCallback, /* #080 */
+ _XimStatusDoneCallback, /* #081 */
+ _XimPreeditStateNotifyCallback /* #082 */
+ };
+
+
+Private Bool
+_XimIsReadyForProcess(Xic ic)
+{
+ return(!ic->private.proto.waitCallback); /* check HM */
+}
+
+Private void
+_XimProcessPendingCallbacks(Xic ic)
+{
+ XimPendingCallback pcbq;
+
+ while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL)
+ && _XimIsReadyForProcess(ic)) {
+ (void) (*callback_table[pcbq->major_opcode])(pcbq->im,
+ pcbq->ic,
+ pcbq->proto,
+ pcbq->proto_len);
+ ic->private.proto.pend_cb_que = pcbq->next;
+ Xfree(pcbq->proto); /* free memory of XimPendingCallback */
+ Xfree(pcbq);
+ }
+}
+
+Private void
+_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data)
+{
+ XimPendingCallback pcbq = ic->private.proto.pend_cb_que;
+
+ /* Queuing is FIFO
+ */
+ while (pcbq != (XimPendingCallback)NULL) {
+ if (pcbq->next == (XimPendingCallback)NULL) {
+ break;
+ }
+ pcbq = pcbq->next;
+ }
+ if (pcbq == (XimPendingCallback)NULL) {
+ ic->private.proto.pend_cb_que = call_data;
+ }
+ else {
+ pcbq->next = call_data;
+ }
+}
+
+Public Bool
+_XimCbDispatch(Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ /* `data' points to the beginning of the packet defined in IM Protocol doc.
+ */
+ int major_opcode = PACKET_TO_MAJOROPCODE(data);
+ XIMID imid = PACKET_TO_IMID(data);
+ XICID icid = PACKET_TO_ICID(data);
+ Xim im = (Xim)call_data; /* check HM */
+ Xic ic = _XimICOfXICID(im, icid);
+ char* proto;
+ int proto_len;
+
+ /* check validity of im/ic
+ */
+ if ((imid != im->private.proto.imid) || !ic) {
+ return False; /* status = XimCbBadContextID; */
+ }
+
+ /* process pending callbacks
+ */
+ _XimProcessPendingCallbacks(ic);
+
+ /* check if the protocol should be processed here
+ */
+ if (major_opcode > 82) {
+ return False; /* status = XimCbBadOpcode; */
+ }
+ if (!callback_table[major_opcode]) {
+ return False; /* status = XimCbBadOpcode; */
+ }
+
+ /* move the pointer ahead by the IM Protocol packet header size
+ */
+ proto = (char*)data + sz_ximPacketHeader;
+ proto_len = (int)len - sz_ximPacketHeader;
+
+ /* check if it can be processed right away
+ * and if no, queue the protocol, otherwise invoke a callback
+ */
+ if (!_XimIsReadyForProcess(ic)) {
+
+ /* queue the protocol
+ */
+ XimPendingCallback pcb;
+ char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL;
+
+ pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec));
+ if (pcb && (proto_len <= 0 || proto_buf)) {
+ if (proto_len > 0)
+ memcpy(proto_buf, proto, proto_len);
+
+ pcb->major_opcode = major_opcode;
+ pcb->im = im;
+ pcb->ic = ic;
+ pcb->proto = proto_buf;
+ pcb->proto_len = proto_len;
+ pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */
+ _XimPutCbIntoQueue(ic, pcb);
+ /* status = XimCbQueued; */
+ } else {
+ /* status = XimCbError; */
+ Xfree(pcb);
+ Xfree(proto_buf);
+ }
+ }
+ else {
+ /* invoke each callback according to the major opcode.
+ * `proto' points to the next address of IM-ID and IC-ID.
+ * `proto_len' specifies the packet length.
+ */
+ (void) (*callback_table[major_opcode])(im, ic, proto, proto_len);
+ }
+ return True;
+}
+
+Private XimCbStatus
+_XimGeometryCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.geometry_callback;
+
+ /* invoke the callack
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStrConversionCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */
+ XIMStringConversionCallbackStruct cbrec;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ int p = XIM_HEADER_SIZE;
+ cbrec.position = (XIMStringConversionPosition)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.direction = (XIMCaretDirection)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.operation = (XIMStringConversionOperation)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.factor = (unsigned short)
+ *(CARD32*)&proto[p];
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_STR_CONVERSION,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* send a reply
+ */
+ {
+ CARD8 *buf;
+ INT16 buf_len;
+ int p, length_in_bytes, i;
+
+ /* Assumption:
+ * `cbrec.text->length' means the string length in characters
+ */
+ {
+ length_in_bytes = (cbrec.text->encoding_is_wchar)?
+ sizeof(wchar_t) * cbrec.text->length: /* wchar */
+ strlen(cbrec.text->string.mbs); /* mb */
+ buf_len = XIM_HEADER_SIZE +
+ sz_CARD16 +
+ 2 + length_in_bytes +
+ XIM_PAD(2 + length_in_bytes) +
+ 2 + 2 + sz_CARD32 * cbrec.text->length;
+ buf = (CARD8*)Xmalloc(buf_len);
+ }
+ _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len);
+ buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16;
+ memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes);
+ p += length_in_bytes;
+ *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length);
+ p += XIM_PAD(2);
+ for (i = 0; i < (int)cbrec.text->length; i++) {
+ *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i];
+ p += sz_CARD32;
+ }
+
+ if (!(_XimWriteData(im, buf_len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+
+ Xfree(buf);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditStartCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.start_callback;
+ int ret;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback){
+ ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_PREEDIT_START,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* send a reply
+ */
+ {
+ CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4];
+ CARD8 *buf = (CARD8 *)buf32;
+ INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply;
+ int p;
+
+ _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len);
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(INT32*)&buf[p] = (INT32)ret;
+
+ if (!(_XimWriteData(im, buf_len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditDoneCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.done_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private void
+_read_text_from_packet(Xim im,
+ char* buf,
+ XIMText** text_ptr)
+{
+ int status;
+ XIMText* text;
+ int tmp_len;
+ char* tmp_buf;
+ Status s = 0;
+
+ status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32;
+
+ /* string part
+ */
+ if (status & 0x00000001) /* "no string" bit on */ {
+ buf += sz_CARD16; /* skip "length of preedit string" */
+ buf += 2; /* pad */
+ *text_ptr = (XIMText*)NULL;
+ return;
+ }
+
+ *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText));
+ if (text == (XIMText*)NULL) return;
+
+ tmp_len = (int)*(CARD16*)buf;
+ buf += sz_CARD16;
+ if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) {
+ memcpy(tmp_buf, buf, tmp_len);
+ tmp_buf[tmp_len] = '\0';
+
+ text->encoding_is_wchar = False;
+ text->length = im->methods->ctstombs((XIM)im,
+ tmp_buf, tmp_len,
+ NULL, 0, &s); /* CT? HM */
+ if (s != XLookupNone) {
+#ifndef NO_DEC_I18N_FIX
+ /* Allow for NULL-terminated */
+ if ((text->string.multi_byte =
+ (char*)Xmalloc(text->length *
+ XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) {
+#else
+ if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) {
+#endif
+ int tmp;
+#ifndef NO_DEC_I18N_FIX
+ char *char_tmp;
+ int char_len;
+#endif
+ tmp = im->methods->ctstombs((XIM)im,
+ tmp_buf, tmp_len,
+#ifndef NO_DEC_I18N_FIX
+ text->string.multi_byte,
+ text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1,
+#else
+ text->string.multi_byte, text->length,
+#endif
+ &s);
+ text->string.multi_byte[tmp] = '\0';
+#ifndef NO_DEC_I18N_FIX
+ text->length = 0;
+ char_tmp = text->string.multi_byte;
+ while (*char_tmp != '\0') {
+ char_len = mblen(char_tmp, strlen(char_tmp));
+ char_tmp = char_tmp + char_len;
+ (text->length)++;
+ }
+#endif
+ }
+ }
+ else {
+ text->length = 0;
+ text->string.multi_byte = NULL;
+ }
+
+ Xfree(tmp_buf);
+ }
+ buf += tmp_len;
+
+ buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */
+
+ /* feedback part
+ */
+ if (status & 0x00000002) /* "no feedback" bit on */ {
+ text->feedback = (XIMFeedback*)NULL;
+ }
+ else {
+ int i, j;
+
+ i = (int)*(CARD16*)buf; buf += sz_CARD16;
+ buf += sz_CARD16; /* skip `unused' */
+ text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32)));
+ j = 0;
+ while (i > 0) {
+ text->feedback[j] = (XIMFeedback)*(CARD32*)buf;
+ buf += sz_CARD32;
+ i -= sz_CARD32;
+ j++;
+ }
+ /*
+ * text->length tells how long both the status string and
+ * the feedback array are. If there's "no string" the
+ * text->length was set to zero previously. See above.
+ * But if there is feedback (i.e. not "no feedback") then
+ * we need to convey the length of the feedback array.
+ * It might have been better if the protocol sent two
+ * different values, one for the length of the status
+ * string and one for the length of the feedback array.
+ */
+ if (status & 0x00000001) /* "no string" bit on */ {
+ text->length = j;
+ }
+ }
+}
+
+Private void
+_free_memory_for_text(XIMText* text)
+{
+ if (text) {
+ if (text->string.multi_byte)
+ Xfree(text->string.multi_byte);
+ if (text->feedback)
+ Xfree(text->feedback);
+ Xfree(text);
+ }
+}
+
+Private XimCbStatus
+_XimPreeditDrawCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.draw_callback;
+ XIMPreeditDrawCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.caret = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32;
+ _read_text_from_packet(im, proto, &cbs.text);
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+
+ _free_memory_for_text((XIMText*)cbs.text);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditCaretCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.caret_callback;
+ XIMPreeditCaretCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.position = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32;
+ cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32;
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_PREEDIT_CARET,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* Send a reply
+ */
+ {
+ CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply];
+ INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply;
+ int p;
+
+ _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len);
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(CARD32*)&buf[p] = (CARD32)cbs.position;
+
+ if (!(_XimWriteData(im, len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusStartCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.start_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusDoneCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.done_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusDrawCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.draw_callback;
+ XIMStatusDrawCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32;
+ if (cbs.type == XIMTextType) {
+ _read_text_from_packet(im, proto, &cbs.data.text);
+ }
+ else if (cbs.type == XIMBitmapType) {
+ cbs.data.bitmap = (Pixmap)*(CARD32*)proto;
+ }
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+
+ if (cbs.type == XIMTextType)
+ _free_memory_for_text((XIMText *)cbs.data.text);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len )
+{
+ XICCallback *cb = &ic->core.preedit_attr.state_notify_callback;
+
+ /* invoke the callack
+ */
+ if( cb && cb->callback ) {
+ XIMPreeditStateNotifyCallbackStruct cbrec;
+
+ cbrec.state = *(BITMASK32 *)proto;
+ (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec );
+ }
+ else {
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
diff --git a/libX11/modules/im/ximcp/imDefIc.c b/libX11/modules/im/ximcp/imDefIc.c index a962c1b0f..cd3ed5854 100644 --- a/libX11/modules/im/ximcp/imDefIc.c +++ b/libX11/modules/im/ximcp/imDefIc.c @@ -1,1581 +1,1581 @@ -/* - * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. - Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" - -Private Bool -_XimCreateICCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - - if ((major_opcode == XIM_CREATE_IC_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid)) - return True; - return False; -} - -#ifdef XIM_CONNECTABLE -Public Bool -_XimReCreateIC(ic) - Xic ic; -{ - Xim im = (Xim)ic->core.im; - Xic save_ic; - XIMResourceList res; - unsigned int num; - XIMStyle input_style = ic->core.input_style; - XimDefICValues ic_values; - INT16 len; - CARD16 *buf_s; - char *tmp; - CARD32 tmp_buf32[BUFSIZE/4]; - char *tmp_buf = (char *)tmp_buf32; - char *buf; - int buf_size; - char *data; - int data_len; - int ret_len; - int total; - int idx; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int ret_code; - - if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec)))) - return False; - memcpy((char *)save_ic, (char *)ic, sizeof(XicRec)); - - ic->core.filter_events = im->private.proto.forward_event_mask; - ic->private.proto.forward_event_mask = - im->private.proto.forward_event_mask; - ic->private.proto.synchronous_event_mask = - im->private.proto.synchronous_event_mask; - - num = im->core.ic_num_resources; - buf_size = sizeof(XIMResource) * num; - if (!(res = (XIMResourceList)Xmalloc(buf_size))) - goto ErrorOnReCreateIC; - (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size); - ic->private.proto.ic_resources = res; - ic->private.proto.ic_num_resources = num; - - num = im->private.proto.ic_num_inner_resources; - buf_size = sizeof(XIMResource) * num; - if (!(res = (XIMResourceList)Xmalloc(buf_size))) - goto ErrorOnReCreateIC; - (void)memcpy((char *)res, - (char *)im->private.proto.ic_inner_resources, buf_size); - ic->private.proto.ic_inner_resources = res; - ic->private.proto.ic_num_inner_resources = num; - - _XimSetICMode(ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, input_style); - - _XimSetICMode(ic->private.proto.ic_inner_resources, - ic->private.proto.ic_num_inner_resources, input_style); - - _XimGetCurrentICValues(ic, &ic_values); - buf = tmp_buf; - buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); - data_len = BUFSIZE - buf_size; - total = 0; - idx = 0; - for (;;) { - data = &buf[buf_size]; - if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, &idx, data, data_len, - &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) { - if (buf != tmp_buf) - Xfree(buf); - goto ErrorOnReCreateIC; - } - - total += ret_len; - if (idx == -1) { - break; - } - - buf_size += ret_len; - if (buf == tmp_buf) { - if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { - goto ErrorOnReCreateIC; - } - memcpy(tmp, buf, buf_size); - buf = tmp; - } else { - if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { - Xfree(buf); - goto ErrorOnReCreateIC; - } - buf = tmp; - } - } - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - buf_s[0] = im->private.proto.imid; - buf_s[1] = (INT16)total; - - len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); - _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - if (buf != tmp_buf) - Xfree(buf); - goto ErrorOnReCreateIC; - } - _XimFlush(im); - if (buf != tmp_buf) - Xfree(buf); - ic->private.proto.waitCallback = True; - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimCreateICCheck, 0); - if (ret_code == XIM_TRUE) { - preply = reply; - } else if (ret_code == XIM_OVERFLOW) { - if (len <= 0) { - preply = reply; - } else { - buf_size = (int)len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimCreateICCheck, 0); - if (ret_code != XIM_TRUE) { - Xfree(preply); - ic->private.proto.waitCallback = False; - goto ErrorOnReCreateIC; - } - } - } else { - ic->private.proto.waitCallback = False; - goto ErrorOnReCreateIC; - } - ic->private.proto.waitCallback = False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if (reply != preply) - Xfree(preply); - goto ErrorOnReCreateIC; - } - - ic->private.proto.icid = buf_s[1]; /* icid */ - if (reply != preply) - Xfree(preply); - - _XimRegisterFilter(ic); - MARK_IC_CONNECTED(ic); - if (save_ic->private.proto.ic_resources) - Xfree(save_ic->private.proto.ic_resources); - if (save_ic->private.proto.ic_inner_resources) - Xfree(save_ic->private.proto.ic_inner_resources); - Xfree(save_ic); - return True; - -ErrorOnReCreateIC: - memcpy((char *)ic, (char *)save_ic, sizeof(XicRec)); - Xfree(save_ic); - return False; -} - -Private char * -_XimDelayModeGetICValues(ic, arg) - Xic ic; - XIMArg *arg; -{ - XimDefICValues ic_values; - - _XimGetCurrentICValues(ic, &ic_values); - return _XimGetICValueData(ic, (XPointer)&ic_values, - ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, - arg, XIM_GETICVALUES); -} -#endif /* XIM_CONNECTABLE */ - -Private Bool -_XimGetICValuesCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - - if ((major_opcode == XIM_GET_IC_VALUES_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - return True; - return False; -} - -Private char * -_XimProtoGetICValues( - XIC xic, - XIMArg *arg) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - register XIMArg *p; - register XIMArg *pp; - register int n; - CARD8 *buf; - CARD16 *buf_s; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply = NULL; - int buf_size; - int ret_code; - char *makeid_name; - char *decode_name; - CARD16 *data = NULL; - INT16 data_len = 0; - -#ifndef XIM_CONNECTABLE - if (!IS_IC_CONNECTED(ic)) - return arg->name; -#else - if (!IS_IC_CONNECTED(ic)) { - if (IS_CONNECTABLE(im)) { - if (_XimConnectServer(im)) { - if (!_XimReCreateIC(ic)) { - _XimDelayModeSetAttr(im); - return _XimDelayModeGetICValues(ic, arg); - } - } else { - return _XimDelayModeGetICValues(ic, arg); - } - } else { - return arg->name; - } - } -#endif /* XIM_CONNECTABLE */ - - for (n = 0, p = arg; p && p->name; p++) { - n++; - if ((strcmp(p->name, XNPreeditAttributes) == 0) - || (strcmp(p->name, XNStatusAttributes) == 0)) { - n++; - for (pp = (XIMArg *)p->value; pp && pp->name; pp++) - n++; - } - } - - if (!n) - return (char *)NULL; - - buf_size = sizeof(CARD16) * n; - buf_size += XIM_HEADER_SIZE - + sizeof(CARD16) - + sizeof(CARD16) - + sizeof(INT16) - + XIM_PAD(2 + buf_size); - - if (!(buf = (CARD8 *)Xmalloc(buf_size))) - return arg->name; - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - - makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, arg, - &buf_s[3], &len, XIM_GETICVALUES); - - if (len > 0) { - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - buf_s[2] = len; /* length of ic-attr-id */ - len += sizeof(INT16); /* sizeof length of attr */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - Xfree(buf); - return arg->name; - } - _XimFlush(im); - Xfree(buf); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimGetICValuesCheck, (XPointer)ic); - if (ret_code == XIM_TRUE) { - preply = reply; - } else if (ret_code == XIM_OVERFLOW) { - if (len <= 0) { - preply = reply; - } else { - buf_size = (int)len; - preply = (XPointer)Xmalloc(len); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimGetICValuesCheck, (XPointer)ic); - if (ret_code != XIM_TRUE) { - if (preply != reply) - Xfree(preply); - return arg->name; - } - } - } else { - return arg->name; - } - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if (reply != preply) - Xfree(preply); - return arg->name; - } - data = &buf_s[4]; - data_len = buf_s[2]; - } - else if (len < 0) { - return arg->name; - } - - decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, data, data_len, - arg, XIM_GETICVALUES); - if (reply != preply) - Xfree(preply); - - if (decode_name) - return decode_name; - else - return makeid_name; -} - -#ifdef XIM_CONNECTABLE -Private Bool -_XimCheckNestQuarkList(quark_list, num_quark, quark, separator) - XrmQuark *quark_list; - int num_quark; - XrmQuark quark; - XrmQuark separator; -{ - register int i; - - for (i = 0; i < num_quark; i++) { - if (quark_list[i] == separator) { - break; - } - if (quark_list[i] == quark) { - return True; - } - } - return False; -} - -Private Bool -_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator) - XrmQuark **quark_list; - int idx; - int *num_quark; - XIMArg *arg; - XrmQuark separator; -{ - XrmQuark *q_list = *quark_list; - int n_quark = *num_quark; - register XIMArg *p; - XrmQuark quark; - XrmQuark *tmp; - register int i; - - for (p = arg; p && p->name; p++) { - quark = XrmStringToQuark(p->name); - if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx, - quark, separator)) { - continue; - } - if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) { - *quark_list = q_list; - *num_quark = n_quark; - return False; - } - n_quark++; - for (i = 0; i < idx; i++) { - tmp[i] = q_list[i]; - } - tmp[i] = quark; - for (i = idx + 1; i < n_quark; i++) { - tmp[i] = q_list[i - 1]; - } - q_list = tmp; - } - *quark_list = q_list; - *num_quark = n_quark; - return True; -} - -Private Bool -_XimCheckICQuarkList(quark_list, num_quark, quark, idx) - XrmQuark *quark_list; - int num_quark; - XrmQuark quark; - int *idx; -{ - register int i; - - for (i = 0; i < num_quark; i++) { - if (quark_list[i] == quark) { - *idx = i; - return True; - } - } - return False; -} - -Private Bool -_XimSaveICValues(ic, arg) - Xic ic; - XIMArg *arg; -{ - register XIMArg *p; - register int n; - XrmQuark *quark_list; - XrmQuark *tmp; - XrmQuark quark; - int num_quark; - XrmQuark pre_quark; - XrmQuark sts_quark; - XrmQuark separator; - int idx; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - separator = XrmStringToQuark(XNSeparatorofNestedList); - - if (quark_list = ic->private.proto.saved_icvalues) { - num_quark = ic->private.proto.num_saved_icvalues; - for (p = arg; p && p->name; p++) { - quark = XrmStringToQuark(p->name); - if ((quark == pre_quark) || (quark == sts_quark)) { - if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { - register XIMArg *pp; - int nn; - XrmQuark *q_list; - - for (pp = (XIMArg *)p->value, nn = 0; - pp && pp->name; pp++, nn++); - if (!(tmp = (XrmQuark *)Xrealloc(quark_list, - (sizeof(XrmQuark) * (num_quark + nn + 2))))) { - ic->private.proto.saved_icvalues = quark_list; - ic->private.proto.num_saved_icvalues = num_quark; - return False; - } - quark_list = tmp; - q_list = &quark_list[num_quark]; - num_quark += nn + 2; - *q_list++ = quark; - for (pp = (XIMArg *)p->value; - pp && pp->name; pp++, quark_list++) { - *q_list = XrmStringToQuark(pp->name); - } - *q_list = separator; - } else { - if (!_XimCheckNestedQuarkList(&quark_list, idx + 1, - &num_quark, (XIMArg *)p->value, separator)) { - ic->private.proto.saved_icvalues = quark_list; - ic->private.proto.num_saved_icvalues = num_quark; - return False; - } - } - } else { - if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) { - continue; - } - if (!(tmp = (XrmQuark *)Xrealloc(quark_list, - (sizeof(XrmQuark) * (num_quark + 1))))) { - ic->private.proto.saved_icvalues = quark_list; - ic->private.proto.num_saved_icvalues = num_quark; - return False; - } - quark_list = tmp; - quark_list[num_quark] = quark; - num_quark++; - } - } - ic->private.proto.saved_icvalues = quark_list; - ic->private.proto.num_saved_icvalues = num_quark; - return True; - } - - for (p = arg, n = 0; p && p->name; p++, n++) { - if ((!strcmp(p->name, XNPreeditAttributes)) - || (!strcmp(p->name, XNStatusAttributes))) { - register XIMArg *pp; - int nn; - - for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++); - n += nn + 1; - } - } - - if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { - return False; - } - - ic->private.proto.saved_icvalues = quark_list; - ic->private.proto.num_saved_icvalues = n; - for (p = arg; p && p->name; p++, quark_list++) { - *quark_list = XrmStringToQuark(p->name); - if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) { - register XIMArg *pp; - - quark_list++; - for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) { - *quark_list = XrmStringToQuark(pp->name); - } - *quark_list = separator; - } - } - return True; -} - -Private char * -_XimDelayModeSetICValues(ic, arg) - Xic ic; - XIMArg *arg; -{ - XimDefICValues ic_values; - char *name; - - _XimGetCurrentICValues(ic, &ic_values); - name = _XimSetICValueData(ic, (XPointer)&ic_values, - ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, - arg, XIM_SETICVALUES, False); - _XimSetCurrentICValues(ic, &ic_values); - return name; -} -#endif /* XIM_CONNECTABLE */ - -Private Bool -_XimSetICValuesCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - - if ((major_opcode == XIM_SET_IC_VALUES_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - return True; - return False; -} - -Private char * -_XimProtoSetICValues( - XIC xic, - XIMArg *arg) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - XimDefICValues ic_values; - INT16 len; - CARD16 *buf_s; - char *tmp; - CARD32 tmp_buf32[BUFSIZE/4]; - char *tmp_buf = (char *)tmp_buf32; - char *buf; - int buf_size; - char *data; - int data_len; - int ret_len; - int total; - XIMArg *arg_ret; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply = NULL; - int ret_code; - BITMASK32 flag = 0L; - char *name; - char *tmp_name = (arg) ? arg->name : NULL; - -#ifndef XIM_CONNECTABLE - if (!IS_IC_CONNECTED(ic)) - return tmp_name; -#else - if (!_XimSaveICValues(ic, arg)) - return NULL; - - if (!IS_IC_CONNECTED(ic)) { - if (IS_CONNECTABLE(im)) { - if (_XimConnectServer(im)) { - if (!_XimReCreateIC(ic)) { - _XimDelayModeSetAttr(im); - return _XimDelayModeSetICValues(ic, arg); - } - } else { - return _XimDelayModeSetICValues(ic, arg); - } - } else { - return tmp_name; - } - } -#endif /* XIM_CONNECTABLE */ - - _XimGetCurrentICValues(ic, &ic_values); - buf = tmp_buf; - buf_size = XIM_HEADER_SIZE - + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16); - data_len = BUFSIZE - buf_size; - total = 0; - arg_ret = arg; - for (;;) { - data = &buf[buf_size]; - if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, arg, &arg_ret, - data, data_len, &ret_len, (XPointer)&ic_values, - &flag, XIM_SETICVALUES))) { - break; - } - - total += ret_len; - if (!(arg = arg_ret)) { - break; - } - - buf_size += ret_len; - if (buf == tmp_buf) { - if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { - return tmp_name; - } - memcpy(tmp, buf, buf_size); - buf = tmp; - } else { - if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { - Xfree(buf); - return tmp_name; - } - buf = tmp; - } - } - _XimSetCurrentICValues(ic, &ic_values); - - if (!total) { - return tmp_name; - } - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - -#ifdef EXT_MOVE - if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total)) - return name; -#endif - - buf_s[0] = im->private.proto.imid; - buf_s[1] = ic->private.proto.icid; - buf_s[2] = (INT16)total; - buf_s[3] = 0; - len = (INT16)(sizeof(CARD16) + sizeof(CARD16) - + sizeof(INT16) + sizeof(CARD16) + total); - - _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - if (buf != tmp_buf) - Xfree(buf); - return tmp_name; - } - _XimFlush(im); - if (buf != tmp_buf) - Xfree(buf); - ic->private.proto.waitCallback = True; - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimSetICValuesCheck, (XPointer)ic); - if (ret_code == XIM_TRUE) { - preply = reply; - } else if (ret_code == XIM_OVERFLOW) { - buf_size = (int)len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimSetICValuesCheck, (XPointer)ic); - if (ret_code != XIM_TRUE) { - Xfree(preply); - ic->private.proto.waitCallback = False; - return tmp_name; - } - } else { - ic->private.proto.waitCallback = False; - return tmp_name; - } - ic->private.proto.waitCallback = False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if (reply != preply) - Xfree(preply); - return tmp_name; - } - if (reply != preply) - Xfree(preply); - - return name; -} - -Private Bool -_XimDestroyICCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - Bool ret = False; - - if ((major_opcode == XIM_DESTROY_IC_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - ret = True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - ret = False; - return ret; -} - -Private void -_XimProtoICFree( - Xic ic) -{ -#ifdef XIM_CONNECTABLE - Xim im = (Xim)ic->core.im; -#endif - - if (ic->private.proto.preedit_font) { - Xfree(ic->private.proto.preedit_font); - ic->private.proto.preedit_font = NULL; - } - if (ic->private.proto.status_font) { - Xfree(ic->private.proto.status_font); - ic->private.proto.status_font = NULL; - } - if (ic->private.proto.commit_info) { - _XimFreeCommitInfo(ic); - ic->private.proto.commit_info = NULL; - } - if (ic->private.proto.ic_inner_resources) { - Xfree(ic->private.proto.ic_inner_resources); - ic->private.proto.ic_inner_resources = NULL; - } - -#ifdef XIM_CONNECTABLE - if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { - return; - } -#endif /* XIM_CONNECTABLE */ - - if (ic->private.proto.saved_icvalues) { - Xfree(ic->private.proto.saved_icvalues); - ic->private.proto.saved_icvalues = NULL; - } - if (ic->private.proto.ic_resources) { - Xfree(ic->private.proto.ic_resources); - ic->private.proto.ic_resources = NULL; - } - if (ic->core.hotkey) { - Xfree(ic->core.hotkey); - ic->core.hotkey = NULL; - } - - return; -} - -Private void -_XimProtoDestroyIC( - XIC xic) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - - if (IS_SERVER_CONNECTED(im)) { - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len); - (void)_XimWrite(im, len, (XPointer)buf); - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimDestroyICCheck, (XPointer)ic); - if (ret_code == XIM_OVERFLOW) { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - (void)_XimRead(im, &len, preply, buf_size, - _XimDestroyICCheck, (XPointer)ic); - Xfree(preply); - } - } - UNMARK_IC_CONNECTED(ic); - _XimUnregisterFilter(ic); - _XimProtoICFree(ic); - return; -} - -Private void -_XimProtoSetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - -#ifndef XIM_CONNECTABLE - if (!IS_IC_CONNECTED(ic)) - return; -#else - if (!IS_IC_CONNECTED(ic)) { - if (IS_CONNECTABLE(im)) { - if (_XimConnectServer(im)) { - if (!_XimReCreateIC(ic)) { - _XimDelayModeSetAttr(im); - return; - } - } else { - return; - } - } else { - return; - } - } -#endif /* XIM_CONNECTABLE */ - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len); - (void)_XimWrite(im, len, (XPointer)buf); - _XimFlush(im); - - MARK_FOCUSED(ic); - - _XimRegisterFilter(ic); - return; -} - -Private void -_XimProtoUnsetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - -#ifndef XIM_CONNECTABLE - if (!IS_IC_CONNECTED(ic)) - return; -#else - if (!IS_IC_CONNECTED(ic)) { - if (IS_CONNECTABLE(im)) { - if (_XimConnectServer(im)) { - if (!_XimReCreateIC(ic)) { - _XimDelayModeSetAttr(im); - return; - } - } else { - return; - } - } else { - return; - } - } -#endif /* XIM_CONNECTABLE */ - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len); - (void)_XimWrite(im, len, (XPointer)buf); - _XimFlush(im); - - UNMARK_FOCUSED(ic); - - _XimUnregisterFilter(ic); - return; -} - -Private Bool -_XimResetICCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - - if ((major_opcode == XIM_RESET_IC_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - return True; - return False; -} - -Private char * -_XimProtoReset( - XIC xic, - char * (*retfunc) (Xim im, Xic ic, XPointer buf) ) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - char *commit; - - if (!IS_IC_CONNECTED(ic)) - return (char *)NULL; - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return NULL; - _XimFlush(im); - ic->private.proto.waitCallback = True; - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimResetICCheck, (XPointer)ic); - if (ret_code == XIM_TRUE) { - preply = reply; - } else if (ret_code == XIM_OVERFLOW) { - if (len < 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimResetICCheck, (XPointer)ic); - if (ret_code != XIM_TRUE) { - Xfree(preply); - ic->private.proto.waitCallback = False; - return NULL; - } - } - } else { - ic->private.proto.waitCallback = False; - return NULL; - } - ic->private.proto.waitCallback = False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if (reply != preply) - free(preply); - return NULL; - } - - commit = retfunc(im, ic, (XPointer)&buf_s[2]); - - if (reply != preply) - Xfree(preply); - return commit; -} - -Private char * -_XimCommitedMbString( - Xim im, - Xic ic, - XPointer buf) -{ - CARD16 *buf_s = (CARD16 *)buf; - XimCommitInfo info; - int len; - int new_len; - char *commit; - char *new_commit = NULL; - char *str; - Status status; - - len = 0; - for (info = ic->private.proto.commit_info; info; info = info->next) - len += info->string_len; - len += buf_s[0]; - if ( len == 0 ) - return( NULL ); - - if (!(commit = (char *)Xmalloc(len + 1))) - goto Error_On_Reset; - - str = commit; - for (info = ic->private.proto.commit_info; info; info = info->next) { - (void)memcpy(str, info->string, info->string_len); - str += info->string_len; - } - (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); - commit[len] = '\0'; - - new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status); - if (status != XLookupNone) { - if (!(new_commit = Xmalloc(new_len + 1))) { - Xfree(commit); - goto Error_On_Reset; - } - (void)im->methods->ctstombs((XIM)im, commit, len, - new_commit, new_len, NULL); - new_commit[new_len] = '\0'; - } - Xfree(commit); - -Error_On_Reset: - _XimFreeCommitInfo( ic ); - return new_commit; -} - -Private char * -_XimProtoMbReset( - XIC xic) -{ - return _XimProtoReset(xic, _XimCommitedMbString); -} - -Private wchar_t * -_XimCommitedWcString( - Xim im, - Xic ic, - XPointer buf) -{ - CARD16 *buf_s = (CARD16 *)buf; - XimCommitInfo info; - int len; - int new_len; - char *commit; - wchar_t *new_commit = (wchar_t *)NULL; - char *str; - Status status; - - len = 0; - for (info = ic->private.proto.commit_info; info; info = info->next) - len += info->string_len; - len += buf_s[0]; - if ( len == 0 ) - return( (wchar_t *)NULL ); - - if (!(commit = (char *)Xmalloc(len + 1))) - goto Error_On_Reset; - - str = commit; - for (info = ic->private.proto.commit_info; info; info = info->next) { - (void)memcpy(str, info->string, info->string_len); - str += info->string_len; - } - (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); - commit[len] = '\0'; - - new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status); - if (status != XLookupNone) { - if (!(new_commit = - (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) { - Xfree(commit); - goto Error_On_Reset; - } - (void)im->methods->ctstowcs((XIM)im, commit, len, - new_commit, new_len, NULL); - new_commit[new_len] = (wchar_t)'\0'; - } - Xfree(commit); - -Error_On_Reset: - _XimFreeCommitInfo( ic ); - return new_commit; -} - -Private wchar_t * -_XimProtoWcReset( - XIC xic) -{ - return (wchar_t *) _XimProtoReset(xic, - (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString); -} - -Private char * -_XimCommitedUtf8String( - Xim im, - Xic ic, - XPointer buf) -{ - CARD16 *buf_s = (CARD16 *)buf; - XimCommitInfo info; - int len; - int new_len; - char *commit; - char *new_commit = NULL; - char *str; - Status status; - - len = 0; - for (info = ic->private.proto.commit_info; info; info = info->next) - len += info->string_len; - len += buf_s[0]; - if ( len == 0 ) - return( NULL ); - - if (!(commit = (char *)Xmalloc(len + 1))) - goto Error_On_Reset; - - str = commit; - for (info = ic->private.proto.commit_info; info; info = info->next) { - (void)memcpy(str, info->string, info->string_len); - str += info->string_len; - } - (void)memcpy(str, (char *)&buf_s[1], buf_s[0]); - commit[len] = '\0'; - - new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status); - if (status != XLookupNone) { - if (!(new_commit = Xmalloc(new_len + 1))) { - Xfree(commit); - goto Error_On_Reset; - } - (void)im->methods->ctstoutf8((XIM)im, commit, len, - new_commit, new_len, NULL); - new_commit[new_len] = '\0'; - } - Xfree(commit); - -Error_On_Reset: - _XimFreeCommitInfo( ic ); - return new_commit; -} - -Private char * -_XimProtoUtf8Reset( - XIC xic) -{ - return _XimProtoReset(xic, _XimCommitedUtf8String); -} - -Private XICMethodsRec ic_methods = { - _XimProtoDestroyIC, /* destroy */ - _XimProtoSetFocus, /* set_focus */ - _XimProtoUnsetFocus, /* unset_focus */ - _XimProtoSetICValues, /* set_values */ - _XimProtoGetICValues, /* get_values */ - _XimProtoMbReset, /* mb_reset */ - _XimProtoWcReset, /* wc_reset */ - _XimProtoUtf8Reset, /* utf8_reset */ - _XimProtoMbLookupString, /* mb_lookup_string */ - _XimProtoWcLookupString, /* wc_lookup_string */ - _XimProtoUtf8LookupString /* utf8_lookup_string */ -}; - -Private Bool -_XimGetInputStyle( - XIMArg *arg, - XIMStyle *input_style) -{ - register XIMArg *p; - - for (p = arg; p && p->name; p++) { - if (!(strcmp(p->name, XNInputStyle))) { - *input_style = (XIMStyle)p->value; - return True; - } - } - return False; -} - -#ifdef XIM_CONNECTABLE -Private Bool -_XimDelayModeCreateIC( - Xic ic, - XIMArg *values, - XIMResourceList res, - unsigned int num) -{ - Xim im = (Xim)ic->core.im; - XimDefICValues ic_values; - int len; - XIMStyle input_style; - - bzero((char *)&ic_values, sizeof(XimDefICValues)); - _XimGetCurrentICValues(ic, &ic_values); - if (!(_XimGetInputStyle(values, &input_style))) - return False; - - _XimSetICMode(res, num, input_style); - - if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num, - values, XIM_CREATEIC, False)) { - return False; - } - _XimSetCurrentICValues(ic, &ic_values); - if (!_XimSetICDefaults(ic, (XPointer)&ic_values, - XIM_SETICDEFAULTS, res, num)) { - return False; - } - ic_values.filter_events = KeyPressMask; - _XimSetCurrentICValues(ic, &ic_values); - _XimRegisterFilter(ic); - - return True; -} - -Public Bool -_XimReconnectModeCreateIC(ic) - Xic ic; -{ - Xim im = (Xim)ic->core.im; - int len; - XIMStyle input_style = ic->core.input_style; - XIMResourceList res; - unsigned int num; - - num = im->core.ic_num_resources; - len = sizeof(XIMResource) * num; - if (!(res = (XIMResourceList)Xmalloc(len))) - return False; - (void)memcpy((char *)res, (char *)im->core.ic_resources, len); - ic->private.proto.ic_resources = res; - ic->private.proto.ic_num_resources = num; - - _XimSetICMode(res, num, input_style); - - ic->core.filter_events = KeyPressMask; - - return True; -} -#endif /* XIM_CONNECTABLE */ - -Public XIC -_XimProtoCreateIC( - XIM xim, - XIMArg *arg) -{ - Xim im = (Xim)xim; - Xic ic; - XimDefICValues ic_values; - XIMResourceList res; - unsigned int num; - XIMStyle input_style; - INT16 len; - CARD16 *buf_s; - char *tmp; - CARD32 tmp_buf32[BUFSIZE/4]; - char *tmp_buf = (char *)tmp_buf32; - char *buf; - int buf_size; - char *data; - int data_len; - int ret_len; - int total; - XIMArg *arg_ret; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int ret_code; - -#ifdef XIM_CONNECTABLE - if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im)) - return (XIC)NULL; -#else - if (!IS_SERVER_CONNECTED(im)) - return (XIC)NULL; -#endif /* XIM_CONNECTABLE */ - - if (!(_XimGetInputStyle(arg, &input_style))) - return (XIC)NULL; - - if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) - return (XIC)NULL; - - ic->methods = &ic_methods; - ic->core.im = (XIM)im; - ic->core.input_style = input_style; - - num = im->core.ic_num_resources; - len = sizeof(XIMResource) * num; - if (!(res = (XIMResourceList)Xmalloc(len))) - goto ErrorOnCreatingIC; - (void)memcpy((char *)res, (char *)im->core.ic_resources, len); - ic->private.proto.ic_resources = res; - ic->private.proto.ic_num_resources = num; - -#ifdef XIM_CONNECTABLE - if (!_XimSaveICValues(ic, arg)) - return False; - - if (!IS_SERVER_CONNECTED(im)) { - if (!_XimConnectServer(im)) { - if (_XimDelayModeCreateIC(ic, arg, res, num)) { - return (XIC)ic; - } - goto ErrorOnCreatingIC; - } - } -#endif /* XIM_CONNECTABLE */ - - ic->core.filter_events = im->private.proto.forward_event_mask; - ic->private.proto.forward_event_mask = - im->private.proto.forward_event_mask; - ic->private.proto.synchronous_event_mask = - im->private.proto.synchronous_event_mask; - - num = im->private.proto.ic_num_inner_resources; - len = sizeof(XIMResource) * num; - if (!(res = (XIMResourceList)Xmalloc(len))) - goto ErrorOnCreatingIC; - (void)memcpy((char *)res, - (char *)im->private.proto.ic_inner_resources, len); - ic->private.proto.ic_inner_resources = res; - ic->private.proto.ic_num_inner_resources = num; - - _XimSetICMode(ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, input_style); - - _XimSetICMode(ic->private.proto.ic_inner_resources, - ic->private.proto.ic_num_inner_resources, input_style); - - _XimGetCurrentICValues(ic, &ic_values); - buf = tmp_buf; - buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); - data_len = BUFSIZE - buf_size; - total = 0; - arg_ret = arg; - for (;;) { - data = &buf[buf_size]; - if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources, arg, &arg_ret, data, - data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) { - goto ErrorOnCreatingIC; - } - - total += ret_len; - if (!(arg = arg_ret)) { - break; - } - - buf_size += ret_len; - if (buf == tmp_buf) { - if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { - goto ErrorOnCreatingIC; - } - memcpy(tmp, buf, buf_size); - buf = tmp; - } else { - if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { - Xfree(buf); - goto ErrorOnCreatingIC; - } - buf = tmp; - } - } - _XimSetCurrentICValues(ic, &ic_values); - - if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources, - ic->private.proto.ic_num_resources))) - goto ErrorOnCreatingIC; - - _XimRegisterFilter(ic); - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - buf_s[0] = im->private.proto.imid; - buf_s[1] = (INT16)total; - - len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); - _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - if (buf != tmp_buf) - Xfree(buf); - goto ErrorOnCreatingIC; - } - _XimFlush(im); - if (buf != tmp_buf) - Xfree(buf); - ic->private.proto.waitCallback = True; - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimCreateICCheck, 0); - if (ret_code == XIM_TRUE) { - preply = reply; - } else if (ret_code == XIM_OVERFLOW) { - if (len <= 0) { - preply = reply; - } else { - buf_size = (int)len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimCreateICCheck, 0); - if (ret_code != XIM_TRUE) { - Xfree(preply); - ic->private.proto.waitCallback = False; - goto ErrorOnCreatingIC; - } - } - } else { - ic->private.proto.waitCallback = False; - goto ErrorOnCreatingIC; - } - ic->private.proto.waitCallback = False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if (reply != preply) - Xfree(preply); - goto ErrorOnCreatingIC; - } - - ic->private.proto.icid = buf_s[1]; /* icid */ - if (reply != preply) - Xfree(preply); - MARK_IC_CONNECTED(ic); - return (XIC)ic; - -ErrorOnCreatingIC: - _XimUnregisterFilter(ic); - if (ic->private.proto.ic_resources) - Xfree(ic->private.proto.ic_resources); - if (ic->private.proto.ic_inner_resources) - Xfree(ic->private.proto.ic_inner_resources); - Xfree(ic); - return (XIC)NULL; -} +/*
+ * Copyright 1991, 1992 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
+ Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Private Bool
+_XimCreateICCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+
+ if ((major_opcode == XIM_CREATE_IC_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+#ifdef XIM_CONNECTABLE
+Public Bool
+_XimReCreateIC(ic)
+ Xic ic;
+{
+ Xim im = (Xim)ic->core.im;
+ Xic save_ic;
+ XIMResourceList res;
+ unsigned int num;
+ XIMStyle input_style = ic->core.input_style;
+ XimDefICValues ic_values;
+ INT16 len;
+ CARD16 *buf_s;
+ char *tmp;
+ CARD32 tmp_buf32[BUFSIZE/4];
+ char *tmp_buf = (char *)tmp_buf32;
+ char *buf;
+ int buf_size;
+ char *data;
+ int data_len;
+ int ret_len;
+ int total;
+ int idx;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int ret_code;
+
+ if (!(save_ic = (Xic)Xmalloc(sizeof(XicRec))))
+ return False;
+ memcpy((char *)save_ic, (char *)ic, sizeof(XicRec));
+
+ ic->core.filter_events = im->private.proto.forward_event_mask;
+ ic->private.proto.forward_event_mask =
+ im->private.proto.forward_event_mask;
+ ic->private.proto.synchronous_event_mask =
+ im->private.proto.synchronous_event_mask;
+
+ num = im->core.ic_num_resources;
+ buf_size = sizeof(XIMResource) * num;
+ if (!(res = (XIMResourceList)Xmalloc(buf_size)))
+ goto ErrorOnReCreateIC;
+ (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size);
+ ic->private.proto.ic_resources = res;
+ ic->private.proto.ic_num_resources = num;
+
+ num = im->private.proto.ic_num_inner_resources;
+ buf_size = sizeof(XIMResource) * num;
+ if (!(res = (XIMResourceList)Xmalloc(buf_size)))
+ goto ErrorOnReCreateIC;
+ (void)memcpy((char *)res,
+ (char *)im->private.proto.ic_inner_resources, buf_size);
+ ic->private.proto.ic_inner_resources = res;
+ ic->private.proto.ic_num_inner_resources = num;
+
+ _XimSetICMode(ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, input_style);
+
+ _XimSetICMode(ic->private.proto.ic_inner_resources,
+ ic->private.proto.ic_num_inner_resources, input_style);
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ buf = tmp_buf;
+ buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
+ data_len = BUFSIZE - buf_size;
+ total = 0;
+ idx = 0;
+ for (;;) {
+ data = &buf[buf_size];
+ if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, &idx, data, data_len,
+ &ret_len, (XPointer)&ic_values, XIM_CREATEIC)) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ goto ErrorOnReCreateIC;
+ }
+
+ total += ret_len;
+ if (idx == -1) {
+ break;
+ }
+
+ buf_size += ret_len;
+ if (buf == tmp_buf) {
+ if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
+ goto ErrorOnReCreateIC;
+ }
+ memcpy(tmp, buf, buf_size);
+ buf = tmp;
+ } else {
+ if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
+ Xfree(buf);
+ goto ErrorOnReCreateIC;
+ }
+ buf = tmp;
+ }
+ }
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = (INT16)total;
+
+ len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
+ _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ goto ErrorOnReCreateIC;
+ }
+ _XimFlush(im);
+ if (buf != tmp_buf)
+ Xfree(buf);
+ ic->private.proto.waitCallback = True;
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimCreateICCheck, 0);
+ if (ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if (ret_code == XIM_OVERFLOW) {
+ if (len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimCreateICCheck, 0);
+ if (ret_code != XIM_TRUE) {
+ Xfree(preply);
+ ic->private.proto.waitCallback = False;
+ goto ErrorOnReCreateIC;
+ }
+ }
+ } else {
+ ic->private.proto.waitCallback = False;
+ goto ErrorOnReCreateIC;
+ }
+ ic->private.proto.waitCallback = False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if (reply != preply)
+ Xfree(preply);
+ goto ErrorOnReCreateIC;
+ }
+
+ ic->private.proto.icid = buf_s[1]; /* icid */
+ if (reply != preply)
+ Xfree(preply);
+
+ _XimRegisterFilter(ic);
+ MARK_IC_CONNECTED(ic);
+ if (save_ic->private.proto.ic_resources)
+ Xfree(save_ic->private.proto.ic_resources);
+ if (save_ic->private.proto.ic_inner_resources)
+ Xfree(save_ic->private.proto.ic_inner_resources);
+ Xfree(save_ic);
+ return True;
+
+ErrorOnReCreateIC:
+ memcpy((char *)ic, (char *)save_ic, sizeof(XicRec));
+ Xfree(save_ic);
+ return False;
+}
+
+Private char *
+_XimDelayModeGetICValues(ic, arg)
+ Xic ic;
+ XIMArg *arg;
+{
+ XimDefICValues ic_values;
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ return _XimGetICValueData(ic, (XPointer)&ic_values,
+ ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources,
+ arg, XIM_GETICVALUES);
+}
+#endif /* XIM_CONNECTABLE */
+
+Private Bool
+_XimGetICValuesCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+
+ if ((major_opcode == XIM_GET_IC_VALUES_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ return True;
+ return False;
+}
+
+Private char *
+_XimProtoGetICValues(
+ XIC xic,
+ XIMArg *arg)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ register XIMArg *p;
+ register XIMArg *pp;
+ register int n;
+ CARD8 *buf;
+ CARD16 *buf_s;
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply = NULL;
+ int buf_size;
+ int ret_code;
+ char *makeid_name;
+ char *decode_name;
+ CARD16 *data = NULL;
+ INT16 data_len = 0;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_IC_CONNECTED(ic))
+ return arg->name;
+#else
+ if (!IS_IC_CONNECTED(ic)) {
+ if (IS_CONNECTABLE(im)) {
+ if (_XimConnectServer(im)) {
+ if (!_XimReCreateIC(ic)) {
+ _XimDelayModeSetAttr(im);
+ return _XimDelayModeGetICValues(ic, arg);
+ }
+ } else {
+ return _XimDelayModeGetICValues(ic, arg);
+ }
+ } else {
+ return arg->name;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ for (n = 0, p = arg; p && p->name; p++) {
+ n++;
+ if ((strcmp(p->name, XNPreeditAttributes) == 0)
+ || (strcmp(p->name, XNStatusAttributes) == 0)) {
+ n++;
+ for (pp = (XIMArg *)p->value; pp && pp->name; pp++)
+ n++;
+ }
+ }
+
+ if (!n)
+ return (char *)NULL;
+
+ buf_size = sizeof(CARD16) * n;
+ buf_size += XIM_HEADER_SIZE
+ + sizeof(CARD16)
+ + sizeof(CARD16)
+ + sizeof(INT16)
+ + XIM_PAD(2 + buf_size);
+
+ if (!(buf = (CARD8 *)Xmalloc(buf_size)))
+ return arg->name;
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+
+ makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, arg,
+ &buf_s[3], &len, XIM_GETICVALUES);
+
+ if (len > 0) {
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+ buf_s[2] = len; /* length of ic-attr-id */
+ len += sizeof(INT16); /* sizeof length of attr */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ Xfree(buf);
+ return arg->name;
+ }
+ _XimFlush(im);
+ Xfree(buf);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimGetICValuesCheck, (XPointer)ic);
+ if (ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if (ret_code == XIM_OVERFLOW) {
+ if (len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(len);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimGetICValuesCheck, (XPointer)ic);
+ if (ret_code != XIM_TRUE) {
+ if (preply != reply)
+ Xfree(preply);
+ return arg->name;
+ }
+ }
+ } else {
+ return arg->name;
+ }
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if (reply != preply)
+ Xfree(preply);
+ return arg->name;
+ }
+ data = &buf_s[4];
+ data_len = buf_s[2];
+ }
+ else if (len < 0) {
+ return arg->name;
+ }
+
+ decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, data, data_len,
+ arg, XIM_GETICVALUES);
+ if (reply != preply)
+ Xfree(preply);
+
+ if (decode_name)
+ return decode_name;
+ else
+ return makeid_name;
+}
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimCheckNestQuarkList(quark_list, num_quark, quark, separator)
+ XrmQuark *quark_list;
+ int num_quark;
+ XrmQuark quark;
+ XrmQuark separator;
+{
+ register int i;
+
+ for (i = 0; i < num_quark; i++) {
+ if (quark_list[i] == separator) {
+ break;
+ }
+ if (quark_list[i] == quark) {
+ return True;
+ }
+ }
+ return False;
+}
+
+Private Bool
+_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator)
+ XrmQuark **quark_list;
+ int idx;
+ int *num_quark;
+ XIMArg *arg;
+ XrmQuark separator;
+{
+ XrmQuark *q_list = *quark_list;
+ int n_quark = *num_quark;
+ register XIMArg *p;
+ XrmQuark quark;
+ XrmQuark *tmp;
+ register int i;
+
+ for (p = arg; p && p->name; p++) {
+ quark = XrmStringToQuark(p->name);
+ if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx,
+ quark, separator)) {
+ continue;
+ }
+ if (!(tmp = (XrmQuark *)Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) {
+ *quark_list = q_list;
+ *num_quark = n_quark;
+ return False;
+ }
+ n_quark++;
+ for (i = 0; i < idx; i++) {
+ tmp[i] = q_list[i];
+ }
+ tmp[i] = quark;
+ for (i = idx + 1; i < n_quark; i++) {
+ tmp[i] = q_list[i - 1];
+ }
+ q_list = tmp;
+ }
+ *quark_list = q_list;
+ *num_quark = n_quark;
+ return True;
+}
+
+Private Bool
+_XimCheckICQuarkList(quark_list, num_quark, quark, idx)
+ XrmQuark *quark_list;
+ int num_quark;
+ XrmQuark quark;
+ int *idx;
+{
+ register int i;
+
+ for (i = 0; i < num_quark; i++) {
+ if (quark_list[i] == quark) {
+ *idx = i;
+ return True;
+ }
+ }
+ return False;
+}
+
+Private Bool
+_XimSaveICValues(ic, arg)
+ Xic ic;
+ XIMArg *arg;
+{
+ register XIMArg *p;
+ register int n;
+ XrmQuark *quark_list;
+ XrmQuark *tmp;
+ XrmQuark quark;
+ int num_quark;
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+ XrmQuark separator;
+ int idx;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+ separator = XrmStringToQuark(XNSeparatorofNestedList);
+
+ if (quark_list = ic->private.proto.saved_icvalues) {
+ num_quark = ic->private.proto.num_saved_icvalues;
+ for (p = arg; p && p->name; p++) {
+ quark = XrmStringToQuark(p->name);
+ if ((quark == pre_quark) || (quark == sts_quark)) {
+ if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
+ register XIMArg *pp;
+ int nn;
+ XrmQuark *q_list;
+
+ for (pp = (XIMArg *)p->value, nn = 0;
+ pp && pp->name; pp++, nn++);
+ if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
+ (sizeof(XrmQuark) * (num_quark + nn + 2))))) {
+ ic->private.proto.saved_icvalues = quark_list;
+ ic->private.proto.num_saved_icvalues = num_quark;
+ return False;
+ }
+ quark_list = tmp;
+ q_list = &quark_list[num_quark];
+ num_quark += nn + 2;
+ *q_list++ = quark;
+ for (pp = (XIMArg *)p->value;
+ pp && pp->name; pp++, quark_list++) {
+ *q_list = XrmStringToQuark(pp->name);
+ }
+ *q_list = separator;
+ } else {
+ if (!_XimCheckNestedQuarkList(&quark_list, idx + 1,
+ &num_quark, (XIMArg *)p->value, separator)) {
+ ic->private.proto.saved_icvalues = quark_list;
+ ic->private.proto.num_saved_icvalues = num_quark;
+ return False;
+ }
+ }
+ } else {
+ if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
+ continue;
+ }
+ if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
+ (sizeof(XrmQuark) * (num_quark + 1))))) {
+ ic->private.proto.saved_icvalues = quark_list;
+ ic->private.proto.num_saved_icvalues = num_quark;
+ return False;
+ }
+ quark_list = tmp;
+ quark_list[num_quark] = quark;
+ num_quark++;
+ }
+ }
+ ic->private.proto.saved_icvalues = quark_list;
+ ic->private.proto.num_saved_icvalues = num_quark;
+ return True;
+ }
+
+ for (p = arg, n = 0; p && p->name; p++, n++) {
+ if ((!strcmp(p->name, XNPreeditAttributes))
+ || (!strcmp(p->name, XNStatusAttributes))) {
+ register XIMArg *pp;
+ int nn;
+
+ for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++);
+ n += nn + 1;
+ }
+ }
+
+ if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
+ return False;
+ }
+
+ ic->private.proto.saved_icvalues = quark_list;
+ ic->private.proto.num_saved_icvalues = n;
+ for (p = arg; p && p->name; p++, quark_list++) {
+ *quark_list = XrmStringToQuark(p->name);
+ if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) {
+ register XIMArg *pp;
+
+ quark_list++;
+ for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) {
+ *quark_list = XrmStringToQuark(pp->name);
+ }
+ *quark_list = separator;
+ }
+ }
+ return True;
+}
+
+Private char *
+_XimDelayModeSetICValues(ic, arg)
+ Xic ic;
+ XIMArg *arg;
+{
+ XimDefICValues ic_values;
+ char *name;
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ name = _XimSetICValueData(ic, (XPointer)&ic_values,
+ ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources,
+ arg, XIM_SETICVALUES, False);
+ _XimSetCurrentICValues(ic, &ic_values);
+ return name;
+}
+#endif /* XIM_CONNECTABLE */
+
+Private Bool
+_XimSetICValuesCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+
+ if ((major_opcode == XIM_SET_IC_VALUES_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ return True;
+ return False;
+}
+
+Private char *
+_XimProtoSetICValues(
+ XIC xic,
+ XIMArg *arg)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ XimDefICValues ic_values;
+ INT16 len;
+ CARD16 *buf_s;
+ char *tmp;
+ CARD32 tmp_buf32[BUFSIZE/4];
+ char *tmp_buf = (char *)tmp_buf32;
+ char *buf;
+ int buf_size;
+ char *data;
+ int data_len;
+ int ret_len;
+ int total;
+ XIMArg *arg_ret;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply = NULL;
+ int ret_code;
+ BITMASK32 flag = 0L;
+ char *name;
+ char *tmp_name = (arg) ? arg->name : NULL;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_IC_CONNECTED(ic))
+ return tmp_name;
+#else
+ if (!_XimSaveICValues(ic, arg))
+ return NULL;
+
+ if (!IS_IC_CONNECTED(ic)) {
+ if (IS_CONNECTABLE(im)) {
+ if (_XimConnectServer(im)) {
+ if (!_XimReCreateIC(ic)) {
+ _XimDelayModeSetAttr(im);
+ return _XimDelayModeSetICValues(ic, arg);
+ }
+ } else {
+ return _XimDelayModeSetICValues(ic, arg);
+ }
+ } else {
+ return tmp_name;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ buf = tmp_buf;
+ buf_size = XIM_HEADER_SIZE
+ + sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16);
+ data_len = BUFSIZE - buf_size;
+ total = 0;
+ arg_ret = arg;
+ for (;;) {
+ data = &buf[buf_size];
+ if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, arg, &arg_ret,
+ data, data_len, &ret_len, (XPointer)&ic_values,
+ &flag, XIM_SETICVALUES))) {
+ break;
+ }
+
+ total += ret_len;
+ if (!(arg = arg_ret)) {
+ break;
+ }
+
+ buf_size += ret_len;
+ if (buf == tmp_buf) {
+ if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
+ return tmp_name;
+ }
+ memcpy(tmp, buf, buf_size);
+ buf = tmp;
+ } else {
+ if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
+ Xfree(buf);
+ return tmp_name;
+ }
+ buf = tmp;
+ }
+ }
+ _XimSetCurrentICValues(ic, &ic_values);
+
+ if (!total) {
+ return tmp_name;
+ }
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+
+#ifdef EXT_MOVE
+ if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total))
+ return name;
+#endif
+
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = ic->private.proto.icid;
+ buf_s[2] = (INT16)total;
+ buf_s[3] = 0;
+ len = (INT16)(sizeof(CARD16) + sizeof(CARD16)
+ + sizeof(INT16) + sizeof(CARD16) + total);
+
+ _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ return tmp_name;
+ }
+ _XimFlush(im);
+ if (buf != tmp_buf)
+ Xfree(buf);
+ ic->private.proto.waitCallback = True;
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimSetICValuesCheck, (XPointer)ic);
+ if (ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if (ret_code == XIM_OVERFLOW) {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimSetICValuesCheck, (XPointer)ic);
+ if (ret_code != XIM_TRUE) {
+ Xfree(preply);
+ ic->private.proto.waitCallback = False;
+ return tmp_name;
+ }
+ } else {
+ ic->private.proto.waitCallback = False;
+ return tmp_name;
+ }
+ ic->private.proto.waitCallback = False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if (reply != preply)
+ Xfree(preply);
+ return tmp_name;
+ }
+ if (reply != preply)
+ Xfree(preply);
+
+ return name;
+}
+
+Private Bool
+_XimDestroyICCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+ Bool ret = False;
+
+ if ((major_opcode == XIM_DESTROY_IC_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ ret = True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ ret = False;
+ return ret;
+}
+
+Private void
+_XimProtoICFree(
+ Xic ic)
+{
+#ifdef XIM_CONNECTABLE
+ Xim im = (Xim)ic->core.im;
+#endif
+
+ if (ic->private.proto.preedit_font) {
+ Xfree(ic->private.proto.preedit_font);
+ ic->private.proto.preedit_font = NULL;
+ }
+ if (ic->private.proto.status_font) {
+ Xfree(ic->private.proto.status_font);
+ ic->private.proto.status_font = NULL;
+ }
+ if (ic->private.proto.commit_info) {
+ _XimFreeCommitInfo(ic);
+ ic->private.proto.commit_info = NULL;
+ }
+ if (ic->private.proto.ic_inner_resources) {
+ Xfree(ic->private.proto.ic_inner_resources);
+ ic->private.proto.ic_inner_resources = NULL;
+ }
+
+#ifdef XIM_CONNECTABLE
+ if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
+ return;
+ }
+#endif /* XIM_CONNECTABLE */
+
+ if (ic->private.proto.saved_icvalues) {
+ Xfree(ic->private.proto.saved_icvalues);
+ ic->private.proto.saved_icvalues = NULL;
+ }
+ if (ic->private.proto.ic_resources) {
+ Xfree(ic->private.proto.ic_resources);
+ ic->private.proto.ic_resources = NULL;
+ }
+ if (ic->core.hotkey) {
+ Xfree(ic->core.hotkey);
+ ic->core.hotkey = NULL;
+ }
+
+ return;
+}
+
+Private void
+_XimProtoDestroyIC(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+
+ if (IS_SERVER_CONNECTED(im)) {
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len);
+ (void)_XimWrite(im, len, (XPointer)buf);
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimDestroyICCheck, (XPointer)ic);
+ if (ret_code == XIM_OVERFLOW) {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ (void)_XimRead(im, &len, preply, buf_size,
+ _XimDestroyICCheck, (XPointer)ic);
+ Xfree(preply);
+ }
+ }
+ UNMARK_IC_CONNECTED(ic);
+ _XimUnregisterFilter(ic);
+ _XimProtoICFree(ic);
+ return;
+}
+
+Private void
+_XimProtoSetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_IC_CONNECTED(ic))
+ return;
+#else
+ if (!IS_IC_CONNECTED(ic)) {
+ if (IS_CONNECTABLE(im)) {
+ if (_XimConnectServer(im)) {
+ if (!_XimReCreateIC(ic)) {
+ _XimDelayModeSetAttr(im);
+ return;
+ }
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len);
+ (void)_XimWrite(im, len, (XPointer)buf);
+ _XimFlush(im);
+
+ MARK_FOCUSED(ic);
+
+ _XimRegisterFilter(ic);
+ return;
+}
+
+Private void
+_XimProtoUnsetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_IC_CONNECTED(ic))
+ return;
+#else
+ if (!IS_IC_CONNECTED(ic)) {
+ if (IS_CONNECTABLE(im)) {
+ if (_XimConnectServer(im)) {
+ if (!_XimReCreateIC(ic)) {
+ _XimDelayModeSetAttr(im);
+ return;
+ }
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len);
+ (void)_XimWrite(im, len, (XPointer)buf);
+ _XimFlush(im);
+
+ UNMARK_FOCUSED(ic);
+
+ _XimUnregisterFilter(ic);
+ return;
+}
+
+Private Bool
+_XimResetICCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+
+ if ((major_opcode == XIM_RESET_IC_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ return True;
+ return False;
+}
+
+Private char *
+_XimProtoReset(
+ XIC xic,
+ char * (*retfunc) (Xim im, Xic ic, XPointer buf) )
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ char *commit;
+
+ if (!IS_IC_CONNECTED(ic))
+ return (char *)NULL;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return NULL;
+ _XimFlush(im);
+ ic->private.proto.waitCallback = True;
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimResetICCheck, (XPointer)ic);
+ if (ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if (ret_code == XIM_OVERFLOW) {
+ if (len < 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimResetICCheck, (XPointer)ic);
+ if (ret_code != XIM_TRUE) {
+ Xfree(preply);
+ ic->private.proto.waitCallback = False;
+ return NULL;
+ }
+ }
+ } else {
+ ic->private.proto.waitCallback = False;
+ return NULL;
+ }
+ ic->private.proto.waitCallback = False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if (reply != preply)
+ free(preply);
+ return NULL;
+ }
+
+ commit = retfunc(im, ic, (XPointer)&buf_s[2]);
+
+ if (reply != preply)
+ Xfree(preply);
+ return commit;
+}
+
+Private char *
+_XimCommitedMbString(
+ Xim im,
+ Xic ic,
+ XPointer buf)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+ XimCommitInfo info;
+ int len;
+ int new_len;
+ char *commit;
+ char *new_commit = NULL;
+ char *str;
+ Status status;
+
+ len = 0;
+ for (info = ic->private.proto.commit_info; info; info = info->next)
+ len += info->string_len;
+ len += buf_s[0];
+ if ( len == 0 )
+ return( NULL );
+
+ if (!(commit = (char *)Xmalloc(len + 1)))
+ goto Error_On_Reset;
+
+ str = commit;
+ for (info = ic->private.proto.commit_info; info; info = info->next) {
+ (void)memcpy(str, info->string, info->string_len);
+ str += info->string_len;
+ }
+ (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
+ commit[len] = '\0';
+
+ new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status);
+ if (status != XLookupNone) {
+ if (!(new_commit = Xmalloc(new_len + 1))) {
+ Xfree(commit);
+ goto Error_On_Reset;
+ }
+ (void)im->methods->ctstombs((XIM)im, commit, len,
+ new_commit, new_len, NULL);
+ new_commit[new_len] = '\0';
+ }
+ Xfree(commit);
+
+Error_On_Reset:
+ _XimFreeCommitInfo( ic );
+ return new_commit;
+}
+
+Private char *
+_XimProtoMbReset(
+ XIC xic)
+{
+ return _XimProtoReset(xic, _XimCommitedMbString);
+}
+
+Private wchar_t *
+_XimCommitedWcString(
+ Xim im,
+ Xic ic,
+ XPointer buf)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+ XimCommitInfo info;
+ int len;
+ int new_len;
+ char *commit;
+ wchar_t *new_commit = (wchar_t *)NULL;
+ char *str;
+ Status status;
+
+ len = 0;
+ for (info = ic->private.proto.commit_info; info; info = info->next)
+ len += info->string_len;
+ len += buf_s[0];
+ if ( len == 0 )
+ return( (wchar_t *)NULL );
+
+ if (!(commit = (char *)Xmalloc(len + 1)))
+ goto Error_On_Reset;
+
+ str = commit;
+ for (info = ic->private.proto.commit_info; info; info = info->next) {
+ (void)memcpy(str, info->string, info->string_len);
+ str += info->string_len;
+ }
+ (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
+ commit[len] = '\0';
+
+ new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status);
+ if (status != XLookupNone) {
+ if (!(new_commit =
+ (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) {
+ Xfree(commit);
+ goto Error_On_Reset;
+ }
+ (void)im->methods->ctstowcs((XIM)im, commit, len,
+ new_commit, new_len, NULL);
+ new_commit[new_len] = (wchar_t)'\0';
+ }
+ Xfree(commit);
+
+Error_On_Reset:
+ _XimFreeCommitInfo( ic );
+ return new_commit;
+}
+
+Private wchar_t *
+_XimProtoWcReset(
+ XIC xic)
+{
+ return (wchar_t *) _XimProtoReset(xic,
+ (char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString);
+}
+
+Private char *
+_XimCommitedUtf8String(
+ Xim im,
+ Xic ic,
+ XPointer buf)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+ XimCommitInfo info;
+ int len;
+ int new_len;
+ char *commit;
+ char *new_commit = NULL;
+ char *str;
+ Status status;
+
+ len = 0;
+ for (info = ic->private.proto.commit_info; info; info = info->next)
+ len += info->string_len;
+ len += buf_s[0];
+ if ( len == 0 )
+ return( NULL );
+
+ if (!(commit = (char *)Xmalloc(len + 1)))
+ goto Error_On_Reset;
+
+ str = commit;
+ for (info = ic->private.proto.commit_info; info; info = info->next) {
+ (void)memcpy(str, info->string, info->string_len);
+ str += info->string_len;
+ }
+ (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
+ commit[len] = '\0';
+
+ new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status);
+ if (status != XLookupNone) {
+ if (!(new_commit = Xmalloc(new_len + 1))) {
+ Xfree(commit);
+ goto Error_On_Reset;
+ }
+ (void)im->methods->ctstoutf8((XIM)im, commit, len,
+ new_commit, new_len, NULL);
+ new_commit[new_len] = '\0';
+ }
+ Xfree(commit);
+
+Error_On_Reset:
+ _XimFreeCommitInfo( ic );
+ return new_commit;
+}
+
+Private char *
+_XimProtoUtf8Reset(
+ XIC xic)
+{
+ return _XimProtoReset(xic, _XimCommitedUtf8String);
+}
+
+Private XICMethodsRec ic_methods = {
+ _XimProtoDestroyIC, /* destroy */
+ _XimProtoSetFocus, /* set_focus */
+ _XimProtoUnsetFocus, /* unset_focus */
+ _XimProtoSetICValues, /* set_values */
+ _XimProtoGetICValues, /* get_values */
+ _XimProtoMbReset, /* mb_reset */
+ _XimProtoWcReset, /* wc_reset */
+ _XimProtoUtf8Reset, /* utf8_reset */
+ _XimProtoMbLookupString, /* mb_lookup_string */
+ _XimProtoWcLookupString, /* wc_lookup_string */
+ _XimProtoUtf8LookupString /* utf8_lookup_string */
+};
+
+Private Bool
+_XimGetInputStyle(
+ XIMArg *arg,
+ XIMStyle *input_style)
+{
+ register XIMArg *p;
+
+ for (p = arg; p && p->name; p++) {
+ if (!(strcmp(p->name, XNInputStyle))) {
+ *input_style = (XIMStyle)p->value;
+ return True;
+ }
+ }
+ return False;
+}
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimDelayModeCreateIC(
+ Xic ic,
+ XIMArg *values,
+ XIMResourceList res,
+ unsigned int num)
+{
+ Xim im = (Xim)ic->core.im;
+ XimDefICValues ic_values;
+ int len;
+ XIMStyle input_style;
+
+ bzero((char *)&ic_values, sizeof(XimDefICValues));
+ _XimGetCurrentICValues(ic, &ic_values);
+ if (!(_XimGetInputStyle(values, &input_style)))
+ return False;
+
+ _XimSetICMode(res, num, input_style);
+
+ if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num,
+ values, XIM_CREATEIC, False)) {
+ return False;
+ }
+ _XimSetCurrentICValues(ic, &ic_values);
+ if (!_XimSetICDefaults(ic, (XPointer)&ic_values,
+ XIM_SETICDEFAULTS, res, num)) {
+ return False;
+ }
+ ic_values.filter_events = KeyPressMask;
+ _XimSetCurrentICValues(ic, &ic_values);
+ _XimRegisterFilter(ic);
+
+ return True;
+}
+
+Public Bool
+_XimReconnectModeCreateIC(ic)
+ Xic ic;
+{
+ Xim im = (Xim)ic->core.im;
+ int len;
+ XIMStyle input_style = ic->core.input_style;
+ XIMResourceList res;
+ unsigned int num;
+
+ num = im->core.ic_num_resources;
+ len = sizeof(XIMResource) * num;
+ if (!(res = (XIMResourceList)Xmalloc(len)))
+ return False;
+ (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
+ ic->private.proto.ic_resources = res;
+ ic->private.proto.ic_num_resources = num;
+
+ _XimSetICMode(res, num, input_style);
+
+ ic->core.filter_events = KeyPressMask;
+
+ return True;
+}
+#endif /* XIM_CONNECTABLE */
+
+Public XIC
+_XimProtoCreateIC(
+ XIM xim,
+ XIMArg *arg)
+{
+ Xim im = (Xim)xim;
+ Xic ic;
+ XimDefICValues ic_values;
+ XIMResourceList res;
+ unsigned int num;
+ XIMStyle input_style;
+ INT16 len;
+ CARD16 *buf_s;
+ char *tmp;
+ CARD32 tmp_buf32[BUFSIZE/4];
+ char *tmp_buf = (char *)tmp_buf32;
+ char *buf;
+ int buf_size;
+ char *data;
+ int data_len;
+ int ret_len;
+ int total;
+ XIMArg *arg_ret;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int ret_code;
+
+#ifdef XIM_CONNECTABLE
+ if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im))
+ return (XIC)NULL;
+#else
+ if (!IS_SERVER_CONNECTED(im))
+ return (XIC)NULL;
+#endif /* XIM_CONNECTABLE */
+
+ if (!(_XimGetInputStyle(arg, &input_style)))
+ return (XIC)NULL;
+
+ if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL)
+ return (XIC)NULL;
+
+ ic->methods = &ic_methods;
+ ic->core.im = (XIM)im;
+ ic->core.input_style = input_style;
+
+ num = im->core.ic_num_resources;
+ len = sizeof(XIMResource) * num;
+ if (!(res = (XIMResourceList)Xmalloc(len)))
+ goto ErrorOnCreatingIC;
+ (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
+ ic->private.proto.ic_resources = res;
+ ic->private.proto.ic_num_resources = num;
+
+#ifdef XIM_CONNECTABLE
+ if (!_XimSaveICValues(ic, arg))
+ return False;
+
+ if (!IS_SERVER_CONNECTED(im)) {
+ if (!_XimConnectServer(im)) {
+ if (_XimDelayModeCreateIC(ic, arg, res, num)) {
+ return (XIC)ic;
+ }
+ goto ErrorOnCreatingIC;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ ic->core.filter_events = im->private.proto.forward_event_mask;
+ ic->private.proto.forward_event_mask =
+ im->private.proto.forward_event_mask;
+ ic->private.proto.synchronous_event_mask =
+ im->private.proto.synchronous_event_mask;
+
+ num = im->private.proto.ic_num_inner_resources;
+ len = sizeof(XIMResource) * num;
+ if (!(res = (XIMResourceList)Xmalloc(len)))
+ goto ErrorOnCreatingIC;
+ (void)memcpy((char *)res,
+ (char *)im->private.proto.ic_inner_resources, len);
+ ic->private.proto.ic_inner_resources = res;
+ ic->private.proto.ic_num_inner_resources = num;
+
+ _XimSetICMode(ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, input_style);
+
+ _XimSetICMode(ic->private.proto.ic_inner_resources,
+ ic->private.proto.ic_num_inner_resources, input_style);
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ buf = tmp_buf;
+ buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
+ data_len = BUFSIZE - buf_size;
+ total = 0;
+ arg_ret = arg;
+ for (;;) {
+ data = &buf[buf_size];
+ if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources, arg, &arg_ret, data,
+ data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) {
+ goto ErrorOnCreatingIC;
+ }
+
+ total += ret_len;
+ if (!(arg = arg_ret)) {
+ break;
+ }
+
+ buf_size += ret_len;
+ if (buf == tmp_buf) {
+ if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
+ goto ErrorOnCreatingIC;
+ }
+ memcpy(tmp, buf, buf_size);
+ buf = tmp;
+ } else {
+ if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
+ Xfree(buf);
+ goto ErrorOnCreatingIC;
+ }
+ buf = tmp;
+ }
+ }
+ _XimSetCurrentICValues(ic, &ic_values);
+
+ if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources,
+ ic->private.proto.ic_num_resources)))
+ goto ErrorOnCreatingIC;
+
+ _XimRegisterFilter(ic);
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = (INT16)total;
+
+ len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
+ _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ goto ErrorOnCreatingIC;
+ }
+ _XimFlush(im);
+ if (buf != tmp_buf)
+ Xfree(buf);
+ ic->private.proto.waitCallback = True;
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimCreateICCheck, 0);
+ if (ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if (ret_code == XIM_OVERFLOW) {
+ if (len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimCreateICCheck, 0);
+ if (ret_code != XIM_TRUE) {
+ Xfree(preply);
+ ic->private.proto.waitCallback = False;
+ goto ErrorOnCreatingIC;
+ }
+ }
+ } else {
+ ic->private.proto.waitCallback = False;
+ goto ErrorOnCreatingIC;
+ }
+ ic->private.proto.waitCallback = False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if (reply != preply)
+ Xfree(preply);
+ goto ErrorOnCreatingIC;
+ }
+
+ ic->private.proto.icid = buf_s[1]; /* icid */
+ if (reply != preply)
+ Xfree(preply);
+ MARK_IC_CONNECTED(ic);
+ return (XIC)ic;
+
+ErrorOnCreatingIC:
+ _XimUnregisterFilter(ic);
+ if (ic->private.proto.ic_resources)
+ Xfree(ic->private.proto.ic_resources);
+ if (ic->private.proto.ic_inner_resources)
+ Xfree(ic->private.proto.ic_inner_resources);
+ Xfree(ic);
+ return (XIC)NULL;
+}
diff --git a/libX11/modules/im/ximcp/imDefIm.c b/libX11/modules/im/ximcp/imDefIm.c index 18a3cc85f..2ea4427c3 100644 --- a/libX11/modules/im/ximcp/imDefIm.c +++ b/libX11/modules/im/ximcp/imDefIm.c @@ -1,2044 +1,2044 @@ -/* - * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ - -/****************************************************************** - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - Copyright 1993, 1994 by Sony Corporation - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 names of Digital, FUJITSU -LIMITED and Sony Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED -AND SONY CORPORATION 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. - - Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. - Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Makoto Wakamatsu Sony Corporation - makoto@sm.sony.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "XlcPublic.h" -#include "XlcPubI.h" -#include "XimTrInt.h" -#include "Ximint.h" - - -Public int -_XimCheckDataSize( - XPointer buf, - int len) -{ - CARD16 *buf_s = (CARD16 *)buf; - - if(len < XIM_HEADER_SIZE) - return -1; - return buf_s[1]; -} - -Public void -_XimSetHeader( - XPointer buf, - CARD8 major_opcode, - CARD8 minor_opcode, - INT16 *len -) -{ - CARD8 *buf_b = (CARD8 *)buf; - CARD16 *buf_s = (CARD16 *)buf; - - buf_b[0] = major_opcode; - buf_b[1] = minor_opcode; - buf_s[1] = ((*len) / 4); - *len += XIM_HEADER_SIZE; - return; -} - -Public char -_XimGetMyEndian(void) -{ - CARD16 test_card = 1; - - if(*((char *)&test_card)) - return LITTLEENDIAN; - else - return BIGENDIAN; -} - -Private Bool -_XimCheckServerName( - Xim im, - char *str) -{ - char *server_name = im->core.im_name; - int len; - int str_len; - int category_len = strlen(XIM_SERVER_CATEGORY); - char *pp; - register char *p; - - if(server_name && *server_name) - len = strlen(server_name); - else - return True; - - if((int)strlen(str) < category_len) - return False; - - if(strncmp(str, XIM_SERVER_CATEGORY, category_len)) - return False; - - pp = &str[category_len]; - - for(;;) { - for(p = pp; (*p != ',') && (*p); p++); - str_len = (int)(p - pp); - - if((len == str_len) && (!strncmp(pp, server_name, len))) - break; - if(!(*p)) - return False; - pp = p + 1; - } - return True; -} - -Private char * -_XimCheckLocaleName( - Xim im, - char *address, - int address_len, - char *locale_name[], - int len) -{ - int category_len; - char *pp; - register char *p; - register int n; - Bool finish = False; - - category_len = strlen(XIM_LOCAL_CATEGORY); - if(address_len < category_len) - return (char*)NULL; - - if(strncmp(address, XIM_LOCAL_CATEGORY, category_len)) - return (char*)NULL; - - pp = &address[category_len]; - - for(;;) { - for( p = pp; *p && *p != ','; p++); - if (!*p) - finish = True; - address_len = (int)(p - pp); - *p = '\0'; - - for( n = 0; n < len; n++ ) - if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) ) - return locale_name[n]; - if (finish) - break; - pp = p + 1; - } - return (char *)NULL; -} - -Private Bool -_XimCheckTransport( - char *address, - int address_len, - const char *transport, - int len, - char **trans_addr) -{ - int category_len = strlen(XIM_TRANSPORT_CATEGORY); - char *pp; - register char *p; - - if(address_len < category_len) - return False; - - if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len)) - return False; - - pp = &address[category_len]; - - for(;;) { - *trans_addr = pp; - - for(p = pp; (*p != '/') && (*p != ',') && (*p); p++); - if(*p == ',') { - pp = p + 1; - continue; - } - if(!(*p)) - return False; - - address_len = (int)(p - pp); - - if((len == address_len) && (!strncmp(pp, transport, len))) - break; - pp = p + 1; - } - pp = p + 1; - for(p = pp; (*p != ',') && (*p); p++); - if (*p) - *p = '\0'; - return True; -} - -Private Bool -_CheckSNEvent( - Display *display, - XEvent *xevent, - XPointer arg) -{ - XSelectionEvent *event = (XSelectionEvent *)xevent; - Window window = *(Window*)arg; - - if((event->type == SelectionNotify) && (window == event->requestor)) - return True; - return False; -} - -Private Bool -_XimGetSelectionNotify( - Display *display, - Window window, - Atom target, - char **ret_address) -{ - XEvent event; - XSelectionEvent *ev = (XSelectionEvent *)&event; - Atom actual_type; - int actual_format; - unsigned long nitems, bytes_after; - - for(;;) { - XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window); - if((ev->type == SelectionNotify) && (window == ev->requestor)) - break; - } - - if(ev->property == (Atom)None) - return False; - if( XGetWindowProperty( display, window, target, 0L, 1000000L, - True, target, &actual_type, &actual_format, - &nitems, &bytes_after, - (unsigned char **)&*ret_address ) != Success ) - return False; - return True; -} - -Private Bool -_XimPreConnectionIM( - Xim im, - Atom selection) -{ - Display *display = im->core.display; - Atom locales, transport; - char *address; - XLCd lcd; - char *language; - char *territory; - char *codeset; - char *trans_addr; - char *locale_name[4], *locale; - int llen, tlen, clen; - register int i; - Window window; - char *str; - - if(!(lcd = im->core.lcd)) - return False; - - for( i = 0; i < 4; i++ ) - locale_name[i] = NULL; - /* requestor window */ - if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display), - 0, 0, 1, 1, 1, 0, 0))) - return False; - - /* server name check */ - if( !(str = XGetAtomName( display, selection )) ) - return False; - if(!_XimCheckServerName(im, str)) { - XFree( (XPointer)str ); - goto Error; - } - XFree( (XPointer)str ); - - /* locale name check */ - _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory, - XlcNCodeset, &codeset, NULL); - llen = strlen( language ); - tlen = territory ? strlen( territory ): 0; - clen = codeset ? strlen( codeset ): 0; - - if( tlen != 0 && clen != 0 ) { - if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL ) - sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset ); - } - if( clen != 0 ) { - if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL ) - sprintf( locale_name[1], "%s.%s", language, codeset ); - else - goto Error; - } - if( tlen != 0 ) { - if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL ) - sprintf( locale_name[2], "%s_%s", language, territory ); - else - goto Error; - } - if( (locale_name[3] = Xmalloc(llen+1)) != NULL ) - strcpy( locale_name[3], language ); - else - goto Error; - if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None) - goto Error; - - XConvertSelection(display, selection, locales, locales, window, - CurrentTime); - if(!(_XimGetSelectionNotify(display, window, locales, &address))) - goto Error; - - if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name, - 4)) == NULL) { - XFree((XPointer)address); - goto Error; - } - im->private.proto.locale_name = locale; - for( i = 0; i < 4; i++ ) { - if( locale_name[i] != NULL && locale_name[i] != locale ) { - XFree( locale_name[i] ); - locale_name[i] = NULL; - } - } - XFree((XPointer)address); - - /* transport check */ - if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None) - goto Error; - - XConvertSelection(display, selection, transport, transport, window, - CurrentTime); - if(!_XimGetSelectionNotify(display, window, transport, &address)) - goto Error; - - for(i = 0; _XimTransportRec[i].transportname ; i++) { - if( _XimCheckTransport(address, strlen(address), - _XimTransportRec[i].transportname, - strlen(_XimTransportRec[i].transportname), - &trans_addr)) { - if( _XimTransportRec[i].config(im, trans_addr) ) { - XFree((XPointer)address); - XDestroyWindow(display, window); - return True; - } - } - } - - XFree((XPointer)address); -Error: - for( i = 0; i < 4; i++ ) - if( locale_name[i] != NULL ) - XFree( locale_name[i] ); - XDestroyWindow(display, window); - return False; -} - -Private Bool -_XimPreConnect( - Xim im) -{ - Display *display = im->core.display; - Atom imserver; - Atom actual_type; - int actual_format; - unsigned long nitems; - unsigned long bytes_after; - unsigned char *prop_return; - Atom *atoms; - Window im_window = 0; - register int i; - - if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None) - return False; - - if(XGetWindowProperty(display, RootWindow(display, 0), - imserver, 0L, 1000000L, False, XA_ATOM, &actual_type, - &actual_format, &nitems, &bytes_after, - &prop_return) != Success) - return False; - - if( (actual_type != XA_ATOM) || (actual_format != 32) ) { - if( nitems ) - XFree((XPointer)prop_return); - return False; - } - - atoms = (Atom *)prop_return; - for(i = 0; i < nitems; i++) { - if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None) - continue; - - if(_XimPreConnectionIM(im, atoms[i])) - break; - } - - XFree((XPointer)prop_return); - if(i >= nitems) - return False; - - im->private.proto.im_window = im_window; - return True; -} - -Private Bool -_XimGetAuthProtocolNames( - Xim im, - CARD16 *buf, - CARD8 *num, - INT16 *len) -{ - if (!IS_USE_AUTHORIZATION_FUNC(im)) { - *num = 0; - *len = 0; - return True; - } - /* - * Not yet - */ - return True; -} - -Private Bool -_XimSetAuthReplyData( - Xim im, - XPointer buf, - INT16 *len) -{ - /* - * Not yet - */ - *len = 0; - return True; -} - -Private Bool -_XimSetAuthNextData( - Xim im, - XPointer buf, - INT16 *len) -{ - /* - * Not yet - */ - *len = 0; - return True; -} - -Private Bool -_XimSetAuthRequiredData( - Xim im, - XPointer buf, - INT16 *len) -{ - /* - * Not yet - */ - *len = 0; - return True; -} - -Private Bool -_XimCheckAuthSetupData( - Xim im, - XPointer buf) -{ - /* - * Not yet - */ - return True; -} - -Private Bool -_XimCheckAuthNextData( - Xim im, - XPointer buf) -{ - /* - * Not yet - */ - return True; -} - -#define NO_MORE_AUTH 2 -#define GOOD_AUTH 1 -#define BAD_AUTH 0 - -Private int -_XimClientAuthCheck( - Xim im, - XPointer buf) -{ - /* - * Not yet - */ - return NO_MORE_AUTH; -} - -Private void -_XimAuthNG( - Xim im) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - INT16 len = 0; - - _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len); - (void)_XimWrite(im, len, (XPointer)buf); - _XimFlush(im); - return; -} - -Private Bool -_XimAllRecv( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - return True; -} - -#define CLIENT_WAIT1 1 -#define CLIENT_WAIT2 2 - -Private Bool -_XimConnection( - Xim im) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; - CARD16 *buf_s = (CARD16 *)((XPointer)buf_b); - INT16 len; - CARD8 num; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - CARD8 major_opcode; - int wait_mode; - int ret; - - if(!(_XimConnect(im))) /* Transport Connect */ - return False; - - if(!_XimDispatchInit(im)) - return False; - - _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im); - - if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len)) - return False; - - im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION; - im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION; - - buf_b[0] = _XimGetMyEndian(); - buf_b[1] = 0; - buf_s[1] = PROTOCOLMAJORVERSION; - buf_s[2] = PROTOCOLMINORVERSION; - buf_s[3] = num; - len += sizeof(CARD8) - + sizeof(CARD8) - + sizeof(CARD16) - + sizeof(CARD16) - + sizeof(CARD16); - - major_opcode = XIM_CONNECT; - wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2; - - for(;;) { - _XimSetHeader((XPointer)buf, major_opcode, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else - return False; - - major_opcode = *((CARD8 *)preply); - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - - if (wait_mode == CLIENT_WAIT1) { - if (major_opcode == XIM_AUTH_REQUIRED) { - ret = _XimClientAuthCheck(im, (XPointer)buf_s); - if(reply != preply) - Xfree(preply); - if (ret == NO_MORE_AUTH) { - if (!(_XimSetAuthReplyData(im, - (XPointer)&buf[XIM_HEADER_SIZE], &len))) { - _XimAuthNG(im); - return False; - } - major_opcode = XIM_AUTH_REPLY; - wait_mode = CLIENT_WAIT2; - } else if (ret == GOOD_AUTH) { - if (!(_XimSetAuthNextData(im, - (XPointer)&buf[XIM_HEADER_SIZE], &len))) { - _XimAuthNG(im); - return False; - } - major_opcode = XIM_AUTH_NEXT; - } else { /* BAD_AUTH */ - _XimAuthNG(im); - return False; - } - } else { - if(reply != preply) - Xfree(preply); - _XimAuthNG(im); - return False; - } - } else { /* CLIENT_WAIT2 */ - if (major_opcode == XIM_CONNECT_REPLY) { - break; - } else if (major_opcode == XIM_AUTH_SETUP) { - if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) { - _XimAuthNG(im); - return False; - } - if(reply != preply) - Xfree(preply); - if (!(_XimSetAuthRequiredData(im, - (XPointer)&buf[XIM_HEADER_SIZE], &len))) { - _XimAuthNG(im); - return False; - } - major_opcode = XIM_AUTH_REQUIRED; - } else if (major_opcode == XIM_AUTH_NEXT) { - if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) { - _XimAuthNG(im); - return False; - } - if(reply != preply) - Xfree(preply); - if (!(_XimSetAuthRequiredData(im, - (XPointer)&buf[XIM_HEADER_SIZE], &len))) { - _XimAuthNG(im); - return False; - } - major_opcode = XIM_AUTH_REQUIRED; - } else if (major_opcode == XIM_AUTH_NG) { - if(reply != preply) - Xfree(preply); - return False; - } else { - _XimAuthNG(im); - if(reply != preply) - Xfree(preply); - return False; - } - } - } - - if (!( buf_s[0] == im->private.proto.protocol_major_version - && buf_s[1] == im->private.proto.protocol_minor_version)) { - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - MARK_SERVER_CONNECTED(im); - - _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0, - _XimRegisterTriggerKeysCallback, (XPointer)im); - return True; -} - -Private Bool -_XimDisconnectCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - - if ((major_opcode == XIM_DISCONNECT_REPLY) - && (minor_opcode == 0)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0)) - return True; - return False; -} - -Private Bool -_XimDisconnect( - Xim im) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - INT16 len = 0; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - - if (IS_SERVER_CONNECTED(im)) { - _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimDisconnectCheck, 0); - if(ret_code == XIM_OVERFLOW) { - if(len > 0) { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimDisconnectCheck, 0); - Xfree(preply); - if(ret_code != XIM_TRUE) - return False; - } - } else if(ret_code == XIM_FALSE) - return False; - - } - if (!(_XimShutdown(im))) /* Transport shutdown */ - return False; - return True; -} - -Private Bool -_XimOpenCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - - if ((major_opcode == XIM_OPEN_REPLY) - && (minor_opcode == 0)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0)) - return True; - return False; -} - -Private Bool -_XimOpen( - Xim im) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD8 *buf_b = &buf[XIM_HEADER_SIZE]; - CARD16 *buf_s; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - char *locale_name; - - locale_name = im->private.proto.locale_name; - len = strlen(locale_name); - buf_b[0] = (BYTE)len; /* length of locale name */ - (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */ - len += sizeof(BYTE); /* sizeof length */ - XIM_SET_PAD(buf_b, len); /* pad */ - - _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, reply, buf_size, - _XimOpenCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimOpenCheck, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else - return False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - - im->private.proto.imid = buf_s[0]; /* imid */ - - if (!(_XimGetAttributeID(im, &buf_s[1]))) { - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - - if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources), - &(im->private.proto.im_num_inner_resources)))) - return False; - - if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources), - &(im->private.proto.ic_num_inner_resources)))) - return False; - - _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); - _XimSetIMMode(im->private.proto.im_inner_resources, - im->private.proto.im_num_inner_resources); - - /* Transport Callbak */ - _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0, - _XimSetEventMaskCallback, (XPointer)im); - _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0, - _XimForwardEventCallback, (XPointer)im); - _XimRegProtoIntrCallback(im, XIM_COMMIT, 0, - _XimCommitCallback, (XPointer)im); - _XimRegProtoIntrCallback(im, XIM_SYNC, 0, - _XimSyncCallback, (XPointer)im); - - if(!_XimExtension(im)) - return False; - - /* register a hook for callback protocols */ - _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im); - - return True; -} - -Private Bool -_XimCloseCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - - if ((major_opcode == XIM_CLOSE_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid)) - return True; - return False; -} - -Private Bool -_XimClose( - Xim im) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - - if (!IS_SERVER_CONNECTED(im)) - return True; - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = 0; /* unused */ - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof unused */ - - _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimCloseCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else - return False; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - - if(reply != preply) - Xfree(preply); - return True; -} - -Public void -_XimProtoIMFree( - Xim im) -{ - /* XIMPrivateRec */ - if (im->private.proto.im_onkeylist) { - Xfree(im->private.proto.im_onkeylist); - im->private.proto.im_onkeylist = NULL; - } - if (im->private.proto.im_offkeylist) { - Xfree(im->private.proto.im_offkeylist); - im->private.proto.im_offkeylist = NULL; - } - if (im->private.proto.intrproto) { - _XimFreeProtoIntrCallback(im); - im->private.proto.intrproto = NULL; - } - if (im->private.proto.im_inner_resources) { - Xfree(im->private.proto.im_inner_resources); - im->private.proto.im_inner_resources = NULL; - } - if (im->private.proto.ic_inner_resources) { - Xfree(im->private.proto.ic_inner_resources); - im->private.proto.ic_inner_resources = NULL; - } - if (im->private.proto.hold_data) { - Xfree(im->private.proto.hold_data); - im->private.proto.hold_data = NULL; - } - if (im->private.proto.locale_name) { - Xfree(im->private.proto.locale_name); - im->private.proto.locale_name = NULL; - } - if (im->private.proto.ctom_conv) { - _XlcCloseConverter(im->private.proto.ctom_conv); - im->private.proto.ctom_conv = NULL; - } - if (im->private.proto.ctow_conv) { - _XlcCloseConverter(im->private.proto.ctow_conv); - im->private.proto.ctow_conv = NULL; - } - if (im->private.proto.ctoutf8_conv) { - _XlcCloseConverter(im->private.proto.ctoutf8_conv); - im->private.proto.ctoutf8_conv = NULL; - } - if (im->private.proto.cstomb_conv) { - _XlcCloseConverter(im->private.proto.cstomb_conv); - im->private.proto.cstomb_conv = NULL; - } - if (im->private.proto.cstowc_conv) { - _XlcCloseConverter(im->private.proto.cstowc_conv); - im->private.proto.cstowc_conv = NULL; - } - if (im->private.proto.cstoutf8_conv) { - _XlcCloseConverter(im->private.proto.cstoutf8_conv); - im->private.proto.cstoutf8_conv = NULL; - } - if (im->private.proto.ucstoc_conv) { - _XlcCloseConverter(im->private.proto.ucstoc_conv); - im->private.proto.ucstoc_conv = NULL; - } - if (im->private.proto.ucstoutf8_conv) { - _XlcCloseConverter(im->private.proto.ucstoutf8_conv); - im->private.proto.ucstoutf8_conv = NULL; - } - -#ifdef XIM_CONNECTABLE - if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { - return; - } -#endif /* XIM_CONNECTABLE */ - - if (im->private.proto.saved_imvalues) { - Xfree(im->private.proto.saved_imvalues); - im->private.proto.saved_imvalues = NULL; - } - if (im->private.proto.default_styles) { - Xfree(im->private.proto.default_styles); - im->private.proto.default_styles = NULL; - } - - /* core */ - if (im->core.res_name) { - Xfree(im->core.res_name); - im->core.res_name = NULL; - } - if (im->core.res_class) { - Xfree(im->core.res_class); - im->core.res_class = NULL; - } - if (im->core.im_values_list) { - Xfree(im->core.im_values_list); - im->core.im_values_list = NULL; - } - if (im->core.ic_values_list) { - Xfree(im->core.ic_values_list); - im->core.ic_values_list = NULL; - } - if (im->core.im_name) { - Xfree(im->core.im_name); - im->core.im_name = NULL; - } - if (im->core.styles) { - Xfree(im->core.styles); - im->core.styles = NULL; - } - if (im->core.im_resources) { - Xfree(im->core.im_resources); - im->core.im_resources = NULL; - } - if (im->core.ic_resources) { - Xfree(im->core.ic_resources); - im->core.ic_resources = NULL; - } - - return; -} - -Private Status -_XimProtoCloseIM( - XIM xim) -{ - Xim im = (Xim)xim; - XIC ic; - XIC next; - Status status; - - ic = im->core.ic_chain; - while (ic) { - (*ic->methods->destroy) (ic); - next = ic->core.next; -#ifdef XIM_CONNECTABLE - if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) { - Xfree ((char *) ic); - } -#else - Xfree ((char *) ic); -#endif /* XIM_CONNECTABLE */ - ic = next; - } -#ifdef XIM_CONNECTABLE - if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) - im->core.ic_chain = NULL; -#else - im->core.ic_chain = NULL; -#endif - - _XimUnregisterServerFilter(im); - _XimResetIMInstantiateCallback(im); - status = (Status)_XimClose(im); - status = (Status)_XimDisconnect(im) && status; - _XimProtoIMFree(im); -#ifdef XIM_CONNECTABLE - if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { - _XimReconnectModeSetAttr(im); - for (ic = im->core.ic_chain; ic; ic = ic->core.next) { - _XimReconnectModeCreateIC(ic); - } - return 0; - } -#endif /* XIM_CONNECTABLE */ - _XimDestroyIMStructureList(im); - return status; -} - -#ifdef XIM_CONNECTABLE -Private Bool -_XimCheckIMQuarkList( - XrmQuark *quark_list, - int num_quark, - XrmQuark quark) -{ - register int i; - - for (i = 0; i < num_quark; i++) { - if (quark_list[i] == quark) { - return True; - } - } - return False; -} - -Private Bool -_XimSaveIMValues( - Xim im, - XIMArg *arg) -{ - register XIMArg *p; - register int n; - XrmQuark *quark_list; - XrmQuark *tmp; - XrmQuark quark; - int num_quark; - - if (quark_list = im->private.proto.saved_imvalues) { - num_quark = im->private.proto.num_saved_imvalues; - for (p = arg; p && p->name; p++) { - quark = XrmStringToQuark(p->name); - if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) { - continue; - } - if (!(tmp = (XrmQuark *)Xrealloc(quark_list, - (sizeof(XrmQuark) * (num_quark + 1))))) { - im->private.proto.saved_imvalues = quark_list; - im->private.proto.num_saved_imvalues = num_quark; - return False; - } - num_quark++; - quark_list = tmp; - quark_list[num_quark] = quark; - } - im->private.proto.saved_imvalues = quark_list; - im->private.proto.num_saved_imvalues = num_quark; - return True; - } - - for (p = arg, n = 0; p && p->name; p++, n++); - - if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) { - return False; - } - - im->private.proto.saved_imvalues = quark_list; - im->private.proto.num_saved_imvalues = n; - for (p = arg; p && p->name; p++, quark_list++) { - *quark_list = XrmStringToQuark(p->name); - } - - return True; -} - -Private char * -_XimDelayModeSetIMValues( - Xim im, - XIMArg *arg) -{ - XimDefIMValues im_values; - char *name; - XIMArg *values; - - _XimGetCurrentIMValues(im, &im_values); - name = _XimSetIMValueData(im, (XPointer)&im_values, values, - im->core.im_resources, im->core.im_num_resources); - _XimSetCurrentIMValues(im, &im_values); - - return name; -} -#endif /* XIM_CONNECTABLE */ - -Private Bool -_XimSetIMValuesCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - - if ((major_opcode == XIM_SET_IM_VALUES_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid)) - return True; - return False; -} - -Private char * -_XimProtoSetIMValues( - XIM xim, - XIMArg *arg) -{ - Xim im = (Xim)xim; - XimDefIMValues im_values; - INT16 len; - CARD16 *buf_s; - char *tmp; - CARD32 tmp_buf32[BUFSIZE/4]; - char *tmp_buf = (char *)tmp_buf32; - char *buf; - int buf_size; - char *data; - int data_len; - int ret_len; - int total; - XIMArg *arg_ret; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int ret_code; - char *name; - -#ifndef XIM_CONNECTABLE - if (!IS_SERVER_CONNECTED(im)) - return arg->name; -#else - if (!_XimSaveIMValues(im, arg)) - return arg->name; - - if (!IS_SERVER_CONNECTED(im)) { - if (IS_CONNECTABLE(im)) { - if (!_XimConnectServer(im)) { - return _XimDelayModeSetIMValues(im, arg); - } - } else { - return arg->name; - } - } -#endif /* XIM_CONNECTABLE */ - - _XimGetCurrentIMValues(im, &im_values); - buf = tmp_buf; - buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); - data_len = BUFSIZE - buf_size; - total = 0; - arg_ret = arg; - for (;;) { - data = &buf[buf_size]; - if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources, - im->core.im_num_resources, arg, &arg_ret, data, data_len, - &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) { - if (buf != tmp_buf) - Xfree(buf); - break; - } - - total += ret_len; - if (!(arg = arg_ret)) { - break; - } - - buf_size += ret_len; - if (buf == tmp_buf) { - if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { - return arg->name; - } - memcpy(tmp, buf, buf_size); - buf = tmp; - } else { - if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { - Xfree(buf); - return arg->name; - } - buf = tmp; - } - } - _XimSetCurrentIMValues(im, &im_values); - - if (!total) - return (char *)NULL; - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - buf_s[0] = im->private.proto.imid; - buf_s[1] = (INT16)total; - - len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); - _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - if (buf != tmp_buf) - Xfree(buf); - return arg->name; - } - _XimFlush(im); - if (buf != tmp_buf) - Xfree(buf); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimSetIMValuesCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = (int)len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, reply, buf_size, - _XimSetIMValuesCheck, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return arg->name; - } - } - } else - return arg->name; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return arg->name; - } - if(reply != preply) - Xfree(preply); - - return name; -} - -#ifdef XIM_CONNECTABLE -Private char * -_XimDelayModeGetIMValues( - Xim im, - XIMArg *arg) -{ - XimDefIMValues im_values; - - _XimGetCurrentIMValues(im, &im_values); - return(_XimGetIMValueData(im, (XPointer)&im_values, arg, - im->core.im_resources, im->core.im_num_resources)); -} -#endif /* XIM_CONNECTABLE */ - -Private Bool -_XimGetIMValuesCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - - if ((major_opcode == XIM_GET_IM_VALUES_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid)) - return True; - return False; -} - -Private char * -_XimProtoGetIMValues( - XIM xim, - XIMArg *arg) -{ - Xim im = (Xim)xim; - register XIMArg *p; - register int n; - CARD8 *buf; - CARD16 *buf_s; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply = NULL; - int buf_size; - int ret_code; - char *makeid_name; - char *decode_name; - CARD16 *data = NULL; - INT16 data_len = 0; - -#ifndef XIM_CONNECTABLE - if (!IS_SERVER_CONNECTED(im)) - return arg->name; -#else - if (!IS_SERVER_CONNECTED(im)) { - if (IS_CONNECTABLE(im)) { - if (!_XimConnectServer(im)) { - return _XimDelayModeGetIMValues(im, arg); - } - } else { - return arg->name; - } - } -#endif /* XIM_CONNECTABLE */ - - for (n = 0, p = arg; p->name; p++) - n++; - - if (!n) - return (char *)NULL; - - buf_size = sizeof(CARD16) * n; - buf_size += XIM_HEADER_SIZE - + sizeof(CARD16) - + sizeof(INT16) - + XIM_PAD(buf_size); - - if (!(buf = (CARD8 *)Xmalloc(buf_size))) - return arg->name; - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - - makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources, - im->core.im_num_resources, arg, - &buf_s[2], &len, XIM_GETIMVALUES); - - if (len) { - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = len; /* length of im-attr-id */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += sizeof(CARD16) /* sizeof imid */ - + sizeof(INT16); /* sizeof length of attr */ - - _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - Xfree(buf); - return arg->name; - } - _XimFlush(im); - Xfree(buf); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimGetIMValuesCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimGetIMValuesCheck, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return arg->name; - } - } - } else - return arg->name; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return arg->name; - } - data = &buf_s[2]; - data_len = buf_s[1]; - } - decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources, - im->core.im_num_resources, data, data_len, - arg, XIM_GETIMVALUES); - if (reply != preply) - Xfree(preply); - - if (decode_name) - return decode_name; - else - return makeid_name; -} - -Private XIMMethodsRec im_methods = { - _XimProtoCloseIM, /* close */ - _XimProtoSetIMValues, /* set_values */ - _XimProtoGetIMValues, /* get_values */ - _XimProtoCreateIC, /* create_ic */ - _Ximctstombs, /* ctstombs */ - _Ximctstowcs, /* ctstowcs */ - _Ximctstoutf8 /* ctstoutf8 */ -}; - -Private Bool -_XimSetEncodingByName( - Xim im, - char **buf, - int *len) -{ - char *encoding = (char *)NULL; - int encoding_len; - int compound_len; - BYTE *ret; - - _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL); - if (!encoding) { - *buf = (char *)NULL; - *len = 0; - return True; - } - encoding_len = strlen(encoding); - compound_len = strlen("COMPOUND_TEXT"); - *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE); - if (!(ret = (BYTE *)Xmalloc(*len))) { - return False; - } - *buf = (char *)ret; - - ret[0] = (BYTE)encoding_len; - (void)strncpy((char *)&ret[1], encoding, encoding_len); - ret += (encoding_len + sizeof(BYTE)); - ret[0] = (BYTE)compound_len; - (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len); - return True; -} - -Private Bool -_XimSetEncodingByDetail( - Xim im, - char **buf, - int *len) -{ - *len = 0; - *buf = NULL; - return True; -} - -Private Bool -_XimGetEncoding( - Xim im, - CARD16 *buf, - char *name, - int name_len, - char *detail, - int detail_len) -{ - XLCd lcd = im->core.lcd; - CARD16 category = buf[0]; - CARD16 idx = buf[1]; - int len; - XlcConv ctom_conv = NULL; - XlcConv ctow_conv = NULL; - XlcConv ctoutf8_conv = NULL; - XlcConv conv; - XimProtoPrivateRec *private = &im->private.proto; - - if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */ - if (!(ctom_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNMultiByte))) - return False; - if (!(ctow_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNWideChar))) - return False; - if (!(ctoutf8_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNUtf8String))) - return False; - } - - if (category == XIM_Encoding_NameCategory) { - while (name_len > 0) { - len = (int)name[0]; - if (!strncmp(&name[1], "COMPOUND_TEXT", len)) { - if (!(ctom_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNMultiByte))) - return False; - if (!(ctow_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNWideChar))) - return False; - if (!(ctoutf8_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNUtf8String))) - return False; - break; - } else { - /* - * Not yet - */ - } - len += sizeof(BYTE); - name_len -= len; - name += len; - } - } else if (category == XIM_Encoding_DetailCategory) { - /* - * Not yet - */ - } else { - return False; - } - - private->ctom_conv = ctom_conv; - private->ctow_conv = ctow_conv; - private->ctoutf8_conv = ctoutf8_conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) - return False; - private->cstomb_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) - return False; - private->cstowc_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) - return False; - private->cstoutf8_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) - return False; - private->ucstoc_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) - return False; - private->ucstoutf8_conv = conv; - - return True; -} - -Private Bool -_XimEncodingNegoCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - - if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid)) - return True; - return False; -} - -Private Bool -_XimEncodingNegotiation( - Xim im) -{ - char *name_ptr = 0; - int name_len = 0; - char *detail_ptr = 0; - int detail_len = 0; - CARD8 *buf; - CARD16 *buf_s; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - - if (!(_XimSetEncodingByName(im, &name_ptr, &name_len))) - return False; - - if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) - goto free_name_ptr; - - len = sizeof(CARD16) - + sizeof(INT16) - + name_len - + XIM_PAD(name_len) - + sizeof(INT16) - + sizeof(CARD16) - + detail_len; - - if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) - goto free_detail_ptr; - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - - buf_s[0] = im->private.proto.imid; - buf_s[1] = (INT16)name_len; - if (name_ptr) - (void)memcpy((char *)&buf_s[2], name_ptr, name_len); - XIM_SET_PAD(&buf_s[2], name_len); - buf_s = (CARD16 *)((char *)&buf_s[2] + name_len); - buf_s[0] = detail_len; - buf_s[1] = 0; - if (detail_ptr) - (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len); - - _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - Xfree(buf); - goto free_detail_ptr; - } - _XimFlush(im); - Xfree(buf); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimEncodingNegoCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimEncodingNegoCheck, 0); - if(ret_code != XIM_TRUE) - goto free_preply; - } - } else - goto free_detail_ptr; - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - goto free_preply; - } - - if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len, - detail_ptr, detail_len))) - goto free_preply; - - if (name_ptr) - Xfree(name_ptr); - if (detail_ptr) - Xfree(detail_ptr); - - if(reply != preply) - Xfree(preply); - - return True; - -free_preply: - if (reply != preply) - Xfree(preply); - -free_detail_ptr: - Xfree(detail_ptr); - -free_name_ptr: - Xfree(name_ptr); - - return False; -} - -#ifdef XIM_CONNECTABLE -Private Bool -_XimSendSavedIMValues( - Xim im) -{ - XimDefIMValues im_values; - INT16 len; - CARD16 *buf_s; - char *tmp; - CARD32 tmp_buf32[BUFSIZE/4]; - char *tmp_buf = (char *)tmp_buf32; - char *buf; - int buf_size; - char *data; - int data_len; - int ret_len; - int total; - int idx; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int ret_code; - - _XimGetCurrentIMValues(im, &im_values); - buf = tmp_buf; - buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16); - data_len = BUFSIZE - buf_size; - total = 0; - idx = 0; - for (;;) { - data = &buf[buf_size]; - if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources, - im->core.im_num_resources, &idx, data, data_len, - &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) { - if (buf != tmp_buf) - Xfree(buf); - return False; - } - - total += ret_len; - if (idx == -1) { - break; - } - - buf_size += ret_len; - if (buf == tmp_buf) { - if (!(tmp = (char *)Xmalloc(buf_size + data_len))) { - return False; - } - memcpy(tmp, buf, buf_size); - buf = tmp; - } else { - if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) { - Xfree(buf); - return False; - } - buf = tmp; - } - } - - if (!total) - return True; - - buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - buf_s[0] = im->private.proto.imid; - buf_s[1] = (INT16)total; - - len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total); - _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) { - if (buf != tmp_buf) - Xfree(buf); - return False; - } - _XimFlush(im); - if (buf != tmp_buf) - Xfree(buf); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimSetIMValuesCheck, 0); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = (int)len; - preply = (XPointer)Xmalloc(buf_size); - ret_code = _XimRead(im, &len, reply, buf_size, - _XimSetIMValuesCheck, 0); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else - return False; - - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - - return True; -} - -Private void -_XimDelayModeIMFree( - Xim im) -{ - if (im->core.im_resources) { - Xfree(im->core.im_resources); - im->core.im_resources = NULL; - } - if (im->core.ic_resources) { - Xfree(im->core.ic_resources); - im->core.ic_resources = NULL; - } - if (im->core.im_values_list) { - Xfree(im->core.im_values_list); - im->core.im_values_list = NULL; - } - if (im->core.ic_values_list) { - Xfree(im->core.ic_values_list); - im->core.ic_values_list = NULL; - } - return; -} - -Public Bool -_XimConnectServer( - Xim im) -{ - Xim save_im; - - if (!(save_im = (Xim)Xmalloc(sizeof(XimRec)))) - return False; - memcpy((char *)save_im, (char *)im, sizeof(XimRec)); - - if (_XimPreConnect(im) && _XimConnection(im) - && _XimOpen(im) && _XimEncodingNegotiation(im)) { - if (_XimSendSavedIMValues(im)) { - _XimDelayModeIMFree(save_im); - _XimRegisterServerFilter(im); - Xfree(save_im); - return True; - } - } - memcpy((char *)im, (char *)save_im, sizeof(XimRec)); - Xfree(save_im); - return False; -} - -Public Bool -_XimDelayModeSetAttr( - Xim im) -{ - XimDefIMValues im_values; - - if(!_XimSetIMResourceList(&im->core.im_resources, - &im->core.im_num_resources)) { - return False; - } - if(!_XimSetICResourceList(&im->core.ic_resources, - &im->core.ic_num_resources)) { - return False; - } - - _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); - - _XimGetCurrentIMValues(im, &im_values); - if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values, - im->core.im_resources, im->core.im_num_resources)) { - return False; - } - _XimSetCurrentIMValues(im, &im_values); - if (im->private.proto.default_styles) { - if (im->core.styles) - Xfree(im->core.styles); - im->core.styles = im->private.proto.default_styles; - } - - return True; -} - -Private Bool -_XimReconnectModeSetAttr( - Xim im) -{ - XimDefIMValues im_values; - - if(!_XimSetIMResourceList(&im->core.im_resources, - &im->core.im_num_resources)) { - return False; - } - if(!_XimSetICResourceList(&im->core.ic_resources, - &im->core.ic_num_resources)) { - return False; - } - - _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); - - if (im->private.proto.default_styles) { - if (im->core.styles) - Xfree(im->core.styles); - im->core.styles = im->private.proto.default_styles; - } - - return True; -} -#endif /* XIM_CONNECTABLE */ - -Public Bool -_XimProtoOpenIM( - Xim im) -{ - _XimInitialResourceInfo(); - - im->methods = &im_methods; - -#ifdef XIM_CONNECTABLE - _XimSetProtoResource(im); -#endif /* XIM_CONNECTABLE */ - - if (_XimPreConnect(im)) { - if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) { - _XimRegisterServerFilter(im); - return True; - } - _XimShutdown(im); -#ifdef XIM_CONNECTABLE - } else if (IS_DELAYBINDABLE(im)) { - if (_XimDelayModeSetAttr(im)) - return True; -#endif /* XIM_CONNECTABLE */ - } - _XimProtoIMFree(im); - return False; -} +/*
+ * Copyright 1990, 1991, 1992 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+
+/******************************************************************
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+ Copyright 1993, 1994 by Sony Corporation
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Digital, FUJITSU
+LIMITED and Sony Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
+AND SONY CORPORATION 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.
+
+ Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
+ Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Makoto Wakamatsu Sony Corporation
+ makoto@sm.sony.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcPublic.h"
+#include "XlcPubI.h"
+#include "XimTrInt.h"
+#include "Ximint.h"
+
+
+Public int
+_XimCheckDataSize(
+ XPointer buf,
+ int len)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+
+ if(len < XIM_HEADER_SIZE)
+ return -1;
+ return buf_s[1];
+}
+
+Public void
+_XimSetHeader(
+ XPointer buf,
+ CARD8 major_opcode,
+ CARD8 minor_opcode,
+ INT16 *len
+)
+{
+ CARD8 *buf_b = (CARD8 *)buf;
+ CARD16 *buf_s = (CARD16 *)buf;
+
+ buf_b[0] = major_opcode;
+ buf_b[1] = minor_opcode;
+ buf_s[1] = ((*len) / 4);
+ *len += XIM_HEADER_SIZE;
+ return;
+}
+
+Public char
+_XimGetMyEndian(void)
+{
+ CARD16 test_card = 1;
+
+ if(*((char *)&test_card))
+ return LITTLEENDIAN;
+ else
+ return BIGENDIAN;
+}
+
+Private Bool
+_XimCheckServerName(
+ Xim im,
+ char *str)
+{
+ char *server_name = im->core.im_name;
+ int len;
+ int str_len;
+ int category_len = strlen(XIM_SERVER_CATEGORY);
+ char *pp;
+ register char *p;
+
+ if(server_name && *server_name)
+ len = strlen(server_name);
+ else
+ return True;
+
+ if((int)strlen(str) < category_len)
+ return False;
+
+ if(strncmp(str, XIM_SERVER_CATEGORY, category_len))
+ return False;
+
+ pp = &str[category_len];
+
+ for(;;) {
+ for(p = pp; (*p != ',') && (*p); p++);
+ str_len = (int)(p - pp);
+
+ if((len == str_len) && (!strncmp(pp, server_name, len)))
+ break;
+ if(!(*p))
+ return False;
+ pp = p + 1;
+ }
+ return True;
+}
+
+Private char *
+_XimCheckLocaleName(
+ Xim im,
+ char *address,
+ int address_len,
+ char *locale_name[],
+ int len)
+{
+ int category_len;
+ char *pp;
+ register char *p;
+ register int n;
+ Bool finish = False;
+
+ category_len = strlen(XIM_LOCAL_CATEGORY);
+ if(address_len < category_len)
+ return (char*)NULL;
+
+ if(strncmp(address, XIM_LOCAL_CATEGORY, category_len))
+ return (char*)NULL;
+
+ pp = &address[category_len];
+
+ for(;;) {
+ for( p = pp; *p && *p != ','; p++);
+ if (!*p)
+ finish = True;
+ address_len = (int)(p - pp);
+ *p = '\0';
+
+ for( n = 0; n < len; n++ )
+ if( locale_name[n] && !_XlcCompareISOLatin1( pp, locale_name[n] ) )
+ return locale_name[n];
+ if (finish)
+ break;
+ pp = p + 1;
+ }
+ return (char *)NULL;
+}
+
+Private Bool
+_XimCheckTransport(
+ char *address,
+ int address_len,
+ const char *transport,
+ int len,
+ char **trans_addr)
+{
+ int category_len = strlen(XIM_TRANSPORT_CATEGORY);
+ char *pp;
+ register char *p;
+
+ if(address_len < category_len)
+ return False;
+
+ if(strncmp(address, XIM_TRANSPORT_CATEGORY, category_len))
+ return False;
+
+ pp = &address[category_len];
+
+ for(;;) {
+ *trans_addr = pp;
+
+ for(p = pp; (*p != '/') && (*p != ',') && (*p); p++);
+ if(*p == ',') {
+ pp = p + 1;
+ continue;
+ }
+ if(!(*p))
+ return False;
+
+ address_len = (int)(p - pp);
+
+ if((len == address_len) && (!strncmp(pp, transport, len)))
+ break;
+ pp = p + 1;
+ }
+ pp = p + 1;
+ for(p = pp; (*p != ',') && (*p); p++);
+ if (*p)
+ *p = '\0';
+ return True;
+}
+
+Private Bool
+_CheckSNEvent(
+ Display *display,
+ XEvent *xevent,
+ XPointer arg)
+{
+ XSelectionEvent *event = (XSelectionEvent *)xevent;
+ Window window = *(Window*)arg;
+
+ if((event->type == SelectionNotify) && (window == event->requestor))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimGetSelectionNotify(
+ Display *display,
+ Window window,
+ Atom target,
+ char **ret_address)
+{
+ XEvent event;
+ XSelectionEvent *ev = (XSelectionEvent *)&event;
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+
+ for(;;) {
+ XIfEvent(display, &event, _CheckSNEvent, (XPointer)&window);
+ if((ev->type == SelectionNotify) && (window == ev->requestor))
+ break;
+ }
+
+ if(ev->property == (Atom)None)
+ return False;
+ if( XGetWindowProperty( display, window, target, 0L, 1000000L,
+ True, target, &actual_type, &actual_format,
+ &nitems, &bytes_after,
+ (unsigned char **)&*ret_address ) != Success )
+ return False;
+ return True;
+}
+
+Private Bool
+_XimPreConnectionIM(
+ Xim im,
+ Atom selection)
+{
+ Display *display = im->core.display;
+ Atom locales, transport;
+ char *address;
+ XLCd lcd;
+ char *language;
+ char *territory;
+ char *codeset;
+ char *trans_addr;
+ char *locale_name[4], *locale;
+ int llen, tlen, clen;
+ register int i;
+ Window window;
+ char *str;
+
+ if(!(lcd = im->core.lcd))
+ return False;
+
+ for( i = 0; i < 4; i++ )
+ locale_name[i] = NULL;
+ /* requestor window */
+ if(!(window = XCreateSimpleWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 1, 0, 0)))
+ return False;
+
+ /* server name check */
+ if( !(str = XGetAtomName( display, selection )) )
+ return False;
+ if(!_XimCheckServerName(im, str)) {
+ XFree( (XPointer)str );
+ goto Error;
+ }
+ XFree( (XPointer)str );
+
+ /* locale name check */
+ _XGetLCValues(lcd, XlcNLanguage, &language, XlcNTerritory, &territory,
+ XlcNCodeset, &codeset, NULL);
+ llen = strlen( language );
+ tlen = territory ? strlen( territory ): 0;
+ clen = codeset ? strlen( codeset ): 0;
+
+ if( tlen != 0 && clen != 0 ) {
+ if( (locale_name[0] = Xmalloc(llen+tlen+clen+3)) != NULL )
+ sprintf( locale_name[0], "%s_%s.%s", language, territory, codeset );
+ }
+ if( clen != 0 ) {
+ if( (locale_name[1] = Xmalloc(llen+clen+2)) != NULL )
+ sprintf( locale_name[1], "%s.%s", language, codeset );
+ else
+ goto Error;
+ }
+ if( tlen != 0 ) {
+ if( (locale_name[2] = Xmalloc(llen+tlen+2)) != NULL )
+ sprintf( locale_name[2], "%s_%s", language, territory );
+ else
+ goto Error;
+ }
+ if( (locale_name[3] = Xmalloc(llen+1)) != NULL )
+ strcpy( locale_name[3], language );
+ else
+ goto Error;
+ if((locales = XInternAtom(display, XIM_LOCALES, True)) == (Atom)None)
+ goto Error;
+
+ XConvertSelection(display, selection, locales, locales, window,
+ CurrentTime);
+ if(!(_XimGetSelectionNotify(display, window, locales, &address)))
+ goto Error;
+
+ if((locale = _XimCheckLocaleName(im, address, strlen(address), locale_name,
+ 4)) == NULL) {
+ XFree((XPointer)address);
+ goto Error;
+ }
+ im->private.proto.locale_name = locale;
+ for( i = 0; i < 4; i++ ) {
+ if( locale_name[i] != NULL && locale_name[i] != locale ) {
+ XFree( locale_name[i] );
+ locale_name[i] = NULL;
+ }
+ }
+ XFree((XPointer)address);
+
+ /* transport check */
+ if((transport = XInternAtom(display, XIM_TRANSPORT, True)) == (Atom)None)
+ goto Error;
+
+ XConvertSelection(display, selection, transport, transport, window,
+ CurrentTime);
+ if(!_XimGetSelectionNotify(display, window, transport, &address))
+ goto Error;
+
+ for(i = 0; _XimTransportRec[i].transportname ; i++) {
+ if( _XimCheckTransport(address, strlen(address),
+ _XimTransportRec[i].transportname,
+ strlen(_XimTransportRec[i].transportname),
+ &trans_addr)) {
+ if( _XimTransportRec[i].config(im, trans_addr) ) {
+ XFree((XPointer)address);
+ XDestroyWindow(display, window);
+ return True;
+ }
+ }
+ }
+
+ XFree((XPointer)address);
+Error:
+ for( i = 0; i < 4; i++ )
+ if( locale_name[i] != NULL )
+ XFree( locale_name[i] );
+ XDestroyWindow(display, window);
+ return False;
+}
+
+Private Bool
+_XimPreConnect(
+ Xim im)
+{
+ Display *display = im->core.display;
+ Atom imserver;
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char *prop_return;
+ Atom *atoms;
+ Window im_window = 0;
+ register int i;
+
+ if((imserver = XInternAtom(display, XIM_SERVERS, True)) == (Atom)None)
+ return False;
+
+ if(XGetWindowProperty(display, RootWindow(display, 0),
+ imserver, 0L, 1000000L, False, XA_ATOM, &actual_type,
+ &actual_format, &nitems, &bytes_after,
+ &prop_return) != Success)
+ return False;
+
+ if( (actual_type != XA_ATOM) || (actual_format != 32) ) {
+ if( nitems )
+ XFree((XPointer)prop_return);
+ return False;
+ }
+
+ atoms = (Atom *)prop_return;
+ for(i = 0; i < nitems; i++) {
+ if((im_window = XGetSelectionOwner(display, atoms[i])) == (Window)None)
+ continue;
+
+ if(_XimPreConnectionIM(im, atoms[i]))
+ break;
+ }
+
+ XFree((XPointer)prop_return);
+ if(i >= nitems)
+ return False;
+
+ im->private.proto.im_window = im_window;
+ return True;
+}
+
+Private Bool
+_XimGetAuthProtocolNames(
+ Xim im,
+ CARD16 *buf,
+ CARD8 *num,
+ INT16 *len)
+{
+ if (!IS_USE_AUTHORIZATION_FUNC(im)) {
+ *num = 0;
+ *len = 0;
+ return True;
+ }
+ /*
+ * Not yet
+ */
+ return True;
+}
+
+Private Bool
+_XimSetAuthReplyData(
+ Xim im,
+ XPointer buf,
+ INT16 *len)
+{
+ /*
+ * Not yet
+ */
+ *len = 0;
+ return True;
+}
+
+Private Bool
+_XimSetAuthNextData(
+ Xim im,
+ XPointer buf,
+ INT16 *len)
+{
+ /*
+ * Not yet
+ */
+ *len = 0;
+ return True;
+}
+
+Private Bool
+_XimSetAuthRequiredData(
+ Xim im,
+ XPointer buf,
+ INT16 *len)
+{
+ /*
+ * Not yet
+ */
+ *len = 0;
+ return True;
+}
+
+Private Bool
+_XimCheckAuthSetupData(
+ Xim im,
+ XPointer buf)
+{
+ /*
+ * Not yet
+ */
+ return True;
+}
+
+Private Bool
+_XimCheckAuthNextData(
+ Xim im,
+ XPointer buf)
+{
+ /*
+ * Not yet
+ */
+ return True;
+}
+
+#define NO_MORE_AUTH 2
+#define GOOD_AUTH 1
+#define BAD_AUTH 0
+
+Private int
+_XimClientAuthCheck(
+ Xim im,
+ XPointer buf)
+{
+ /*
+ * Not yet
+ */
+ return NO_MORE_AUTH;
+}
+
+Private void
+_XimAuthNG(
+ Xim im)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ INT16 len = 0;
+
+ _XimSetHeader((XPointer)buf, XIM_AUTH_NG, 0, &len);
+ (void)_XimWrite(im, len, (XPointer)buf);
+ _XimFlush(im);
+ return;
+}
+
+Private Bool
+_XimAllRecv(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ return True;
+}
+
+#define CLIENT_WAIT1 1
+#define CLIENT_WAIT2 2
+
+Private Bool
+_XimConnection(
+ Xim im)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
+ CARD16 *buf_s = (CARD16 *)((XPointer)buf_b);
+ INT16 len;
+ CARD8 num;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ CARD8 major_opcode;
+ int wait_mode;
+ int ret;
+
+ if(!(_XimConnect(im))) /* Transport Connect */
+ return False;
+
+ if(!_XimDispatchInit(im))
+ return False;
+
+ _XimRegProtoIntrCallback(im, XIM_ERROR, 0, _XimErrorCallback, (XPointer)im);
+
+ if(!_XimGetAuthProtocolNames(im, &buf_s[4], &num, &len))
+ return False;
+
+ im->private.proto.protocol_major_version = PROTOCOLMAJORVERSION;
+ im->private.proto.protocol_minor_version = PROTOCOLMINORVERSION;
+
+ buf_b[0] = _XimGetMyEndian();
+ buf_b[1] = 0;
+ buf_s[1] = PROTOCOLMAJORVERSION;
+ buf_s[2] = PROTOCOLMINORVERSION;
+ buf_s[3] = num;
+ len += sizeof(CARD8)
+ + sizeof(CARD8)
+ + sizeof(CARD16)
+ + sizeof(CARD16)
+ + sizeof(CARD16);
+
+ major_opcode = XIM_CONNECT;
+ wait_mode = (IS_USE_AUTHORIZATION_FUNC(im)) ? CLIENT_WAIT1 : CLIENT_WAIT2;
+
+ for(;;) {
+ _XimSetHeader((XPointer)buf, major_opcode, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, reply, buf_size, _XimAllRecv, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size, _XimAllRecv, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else
+ return False;
+
+ major_opcode = *((CARD8 *)preply);
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+
+ if (wait_mode == CLIENT_WAIT1) {
+ if (major_opcode == XIM_AUTH_REQUIRED) {
+ ret = _XimClientAuthCheck(im, (XPointer)buf_s);
+ if(reply != preply)
+ Xfree(preply);
+ if (ret == NO_MORE_AUTH) {
+ if (!(_XimSetAuthReplyData(im,
+ (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ major_opcode = XIM_AUTH_REPLY;
+ wait_mode = CLIENT_WAIT2;
+ } else if (ret == GOOD_AUTH) {
+ if (!(_XimSetAuthNextData(im,
+ (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ major_opcode = XIM_AUTH_NEXT;
+ } else { /* BAD_AUTH */
+ _XimAuthNG(im);
+ return False;
+ }
+ } else {
+ if(reply != preply)
+ Xfree(preply);
+ _XimAuthNG(im);
+ return False;
+ }
+ } else { /* CLIENT_WAIT2 */
+ if (major_opcode == XIM_CONNECT_REPLY) {
+ break;
+ } else if (major_opcode == XIM_AUTH_SETUP) {
+ if (!(_XimCheckAuthSetupData(im, (XPointer)buf_s))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ if (!(_XimSetAuthRequiredData(im,
+ (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ major_opcode = XIM_AUTH_REQUIRED;
+ } else if (major_opcode == XIM_AUTH_NEXT) {
+ if (!(_XimCheckAuthNextData(im, (XPointer)buf_s))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ if (!(_XimSetAuthRequiredData(im,
+ (XPointer)&buf[XIM_HEADER_SIZE], &len))) {
+ _XimAuthNG(im);
+ return False;
+ }
+ major_opcode = XIM_AUTH_REQUIRED;
+ } else if (major_opcode == XIM_AUTH_NG) {
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ } else {
+ _XimAuthNG(im);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ }
+ }
+
+ if (!( buf_s[0] == im->private.proto.protocol_major_version
+ && buf_s[1] == im->private.proto.protocol_minor_version)) {
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ MARK_SERVER_CONNECTED(im);
+
+ _XimRegProtoIntrCallback(im, XIM_REGISTER_TRIGGERKEYS, 0,
+ _XimRegisterTriggerKeysCallback, (XPointer)im);
+ return True;
+}
+
+Private Bool
+_XimDisconnectCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+
+ if ((major_opcode == XIM_DISCONNECT_REPLY)
+ && (minor_opcode == 0))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimDisconnect(
+ Xim im)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ INT16 len = 0;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+
+ if (IS_SERVER_CONNECTED(im)) {
+ _XimSetHeader((XPointer)buf, XIM_DISCONNECT, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimDisconnectCheck, 0);
+ if(ret_code == XIM_OVERFLOW) {
+ if(len > 0) {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimDisconnectCheck, 0);
+ Xfree(preply);
+ if(ret_code != XIM_TRUE)
+ return False;
+ }
+ } else if(ret_code == XIM_FALSE)
+ return False;
+
+ }
+ if (!(_XimShutdown(im))) /* Transport shutdown */
+ return False;
+ return True;
+}
+
+Private Bool
+_XimOpenCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+
+ if ((major_opcode == XIM_OPEN_REPLY)
+ && (minor_opcode == 0))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimOpen(
+ Xim im)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD8 *buf_b = &buf[XIM_HEADER_SIZE];
+ CARD16 *buf_s;
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ char *locale_name;
+
+ locale_name = im->private.proto.locale_name;
+ len = strlen(locale_name);
+ buf_b[0] = (BYTE)len; /* length of locale name */
+ (void)strcpy((char *)&buf_b[1], locale_name); /* locale name */
+ len += sizeof(BYTE); /* sizeof length */
+ XIM_SET_PAD(buf_b, len); /* pad */
+
+ _XimSetHeader((XPointer)buf, XIM_OPEN, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, reply, buf_size,
+ _XimOpenCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimOpenCheck, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else
+ return False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+
+ im->private.proto.imid = buf_s[0]; /* imid */
+
+ if (!(_XimGetAttributeID(im, &buf_s[1]))) {
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+
+ if (!(_XimSetInnerIMResourceList(&(im->private.proto.im_inner_resources),
+ &(im->private.proto.im_num_inner_resources))))
+ return False;
+
+ if (!(_XimSetInnerICResourceList(&(im->private.proto.ic_inner_resources),
+ &(im->private.proto.ic_num_inner_resources))))
+ return False;
+
+ _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
+ _XimSetIMMode(im->private.proto.im_inner_resources,
+ im->private.proto.im_num_inner_resources);
+
+ /* Transport Callbak */
+ _XimRegProtoIntrCallback(im, XIM_SET_EVENT_MASK, 0,
+ _XimSetEventMaskCallback, (XPointer)im);
+ _XimRegProtoIntrCallback(im, XIM_FORWARD_EVENT, 0,
+ _XimForwardEventCallback, (XPointer)im);
+ _XimRegProtoIntrCallback(im, XIM_COMMIT, 0,
+ _XimCommitCallback, (XPointer)im);
+ _XimRegProtoIntrCallback(im, XIM_SYNC, 0,
+ _XimSyncCallback, (XPointer)im);
+
+ if(!_XimExtension(im))
+ return False;
+
+ /* register a hook for callback protocols */
+ _XimRegisterDispatcher(im, _XimCbDispatch, (XPointer)im);
+
+ return True;
+}
+
+Private Bool
+_XimCloseCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+
+ if ((major_opcode == XIM_CLOSE_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimClose(
+ Xim im)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+
+ if (!IS_SERVER_CONNECTED(im))
+ return True;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = 0; /* unused */
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof unused */
+
+ _XimSetHeader((XPointer)buf, XIM_CLOSE, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimCloseCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size, _XimCloseCheck, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else
+ return False;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+
+ if(reply != preply)
+ Xfree(preply);
+ return True;
+}
+
+Public void
+_XimProtoIMFree(
+ Xim im)
+{
+ /* XIMPrivateRec */
+ if (im->private.proto.im_onkeylist) {
+ Xfree(im->private.proto.im_onkeylist);
+ im->private.proto.im_onkeylist = NULL;
+ }
+ if (im->private.proto.im_offkeylist) {
+ Xfree(im->private.proto.im_offkeylist);
+ im->private.proto.im_offkeylist = NULL;
+ }
+ if (im->private.proto.intrproto) {
+ _XimFreeProtoIntrCallback(im);
+ im->private.proto.intrproto = NULL;
+ }
+ if (im->private.proto.im_inner_resources) {
+ Xfree(im->private.proto.im_inner_resources);
+ im->private.proto.im_inner_resources = NULL;
+ }
+ if (im->private.proto.ic_inner_resources) {
+ Xfree(im->private.proto.ic_inner_resources);
+ im->private.proto.ic_inner_resources = NULL;
+ }
+ if (im->private.proto.hold_data) {
+ Xfree(im->private.proto.hold_data);
+ im->private.proto.hold_data = NULL;
+ }
+ if (im->private.proto.locale_name) {
+ Xfree(im->private.proto.locale_name);
+ im->private.proto.locale_name = NULL;
+ }
+ if (im->private.proto.ctom_conv) {
+ _XlcCloseConverter(im->private.proto.ctom_conv);
+ im->private.proto.ctom_conv = NULL;
+ }
+ if (im->private.proto.ctow_conv) {
+ _XlcCloseConverter(im->private.proto.ctow_conv);
+ im->private.proto.ctow_conv = NULL;
+ }
+ if (im->private.proto.ctoutf8_conv) {
+ _XlcCloseConverter(im->private.proto.ctoutf8_conv);
+ im->private.proto.ctoutf8_conv = NULL;
+ }
+ if (im->private.proto.cstomb_conv) {
+ _XlcCloseConverter(im->private.proto.cstomb_conv);
+ im->private.proto.cstomb_conv = NULL;
+ }
+ if (im->private.proto.cstowc_conv) {
+ _XlcCloseConverter(im->private.proto.cstowc_conv);
+ im->private.proto.cstowc_conv = NULL;
+ }
+ if (im->private.proto.cstoutf8_conv) {
+ _XlcCloseConverter(im->private.proto.cstoutf8_conv);
+ im->private.proto.cstoutf8_conv = NULL;
+ }
+ if (im->private.proto.ucstoc_conv) {
+ _XlcCloseConverter(im->private.proto.ucstoc_conv);
+ im->private.proto.ucstoc_conv = NULL;
+ }
+ if (im->private.proto.ucstoutf8_conv) {
+ _XlcCloseConverter(im->private.proto.ucstoutf8_conv);
+ im->private.proto.ucstoutf8_conv = NULL;
+ }
+
+#ifdef XIM_CONNECTABLE
+ if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
+ return;
+ }
+#endif /* XIM_CONNECTABLE */
+
+ if (im->private.proto.saved_imvalues) {
+ Xfree(im->private.proto.saved_imvalues);
+ im->private.proto.saved_imvalues = NULL;
+ }
+ if (im->private.proto.default_styles) {
+ Xfree(im->private.proto.default_styles);
+ im->private.proto.default_styles = NULL;
+ }
+
+ /* core */
+ if (im->core.res_name) {
+ Xfree(im->core.res_name);
+ im->core.res_name = NULL;
+ }
+ if (im->core.res_class) {
+ Xfree(im->core.res_class);
+ im->core.res_class = NULL;
+ }
+ if (im->core.im_values_list) {
+ Xfree(im->core.im_values_list);
+ im->core.im_values_list = NULL;
+ }
+ if (im->core.ic_values_list) {
+ Xfree(im->core.ic_values_list);
+ im->core.ic_values_list = NULL;
+ }
+ if (im->core.im_name) {
+ Xfree(im->core.im_name);
+ im->core.im_name = NULL;
+ }
+ if (im->core.styles) {
+ Xfree(im->core.styles);
+ im->core.styles = NULL;
+ }
+ if (im->core.im_resources) {
+ Xfree(im->core.im_resources);
+ im->core.im_resources = NULL;
+ }
+ if (im->core.ic_resources) {
+ Xfree(im->core.ic_resources);
+ im->core.ic_resources = NULL;
+ }
+
+ return;
+}
+
+Private Status
+_XimProtoCloseIM(
+ XIM xim)
+{
+ Xim im = (Xim)xim;
+ XIC ic;
+ XIC next;
+ Status status;
+
+ ic = im->core.ic_chain;
+ while (ic) {
+ (*ic->methods->destroy) (ic);
+ next = ic->core.next;
+#ifdef XIM_CONNECTABLE
+ if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im))) {
+ Xfree ((char *) ic);
+ }
+#else
+ Xfree ((char *) ic);
+#endif /* XIM_CONNECTABLE */
+ ic = next;
+ }
+#ifdef XIM_CONNECTABLE
+ if (!(!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)))
+ im->core.ic_chain = NULL;
+#else
+ im->core.ic_chain = NULL;
+#endif
+
+ _XimUnregisterServerFilter(im);
+ _XimResetIMInstantiateCallback(im);
+ status = (Status)_XimClose(im);
+ status = (Status)_XimDisconnect(im) && status;
+ _XimProtoIMFree(im);
+#ifdef XIM_CONNECTABLE
+ if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
+ _XimReconnectModeSetAttr(im);
+ for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
+ _XimReconnectModeCreateIC(ic);
+ }
+ return 0;
+ }
+#endif /* XIM_CONNECTABLE */
+ _XimDestroyIMStructureList(im);
+ return status;
+}
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimCheckIMQuarkList(
+ XrmQuark *quark_list,
+ int num_quark,
+ XrmQuark quark)
+{
+ register int i;
+
+ for (i = 0; i < num_quark; i++) {
+ if (quark_list[i] == quark) {
+ return True;
+ }
+ }
+ return False;
+}
+
+Private Bool
+_XimSaveIMValues(
+ Xim im,
+ XIMArg *arg)
+{
+ register XIMArg *p;
+ register int n;
+ XrmQuark *quark_list;
+ XrmQuark *tmp;
+ XrmQuark quark;
+ int num_quark;
+
+ if (quark_list = im->private.proto.saved_imvalues) {
+ num_quark = im->private.proto.num_saved_imvalues;
+ for (p = arg; p && p->name; p++) {
+ quark = XrmStringToQuark(p->name);
+ if (_XimCheckIMQuarkList(quark_list, num_quark, quark)) {
+ continue;
+ }
+ if (!(tmp = (XrmQuark *)Xrealloc(quark_list,
+ (sizeof(XrmQuark) * (num_quark + 1))))) {
+ im->private.proto.saved_imvalues = quark_list;
+ im->private.proto.num_saved_imvalues = num_quark;
+ return False;
+ }
+ num_quark++;
+ quark_list = tmp;
+ quark_list[num_quark] = quark;
+ }
+ im->private.proto.saved_imvalues = quark_list;
+ im->private.proto.num_saved_imvalues = num_quark;
+ return True;
+ }
+
+ for (p = arg, n = 0; p && p->name; p++, n++);
+
+ if (!(quark_list = (XrmQuark *)Xmalloc(sizeof(XrmQuark) * n))) {
+ return False;
+ }
+
+ im->private.proto.saved_imvalues = quark_list;
+ im->private.proto.num_saved_imvalues = n;
+ for (p = arg; p && p->name; p++, quark_list++) {
+ *quark_list = XrmStringToQuark(p->name);
+ }
+
+ return True;
+}
+
+Private char *
+_XimDelayModeSetIMValues(
+ Xim im,
+ XIMArg *arg)
+{
+ XimDefIMValues im_values;
+ char *name;
+ XIMArg *values;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ name = _XimSetIMValueData(im, (XPointer)&im_values, values,
+ im->core.im_resources, im->core.im_num_resources);
+ _XimSetCurrentIMValues(im, &im_values);
+
+ return name;
+}
+#endif /* XIM_CONNECTABLE */
+
+Private Bool
+_XimSetIMValuesCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+
+ if ((major_opcode == XIM_SET_IM_VALUES_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+Private char *
+_XimProtoSetIMValues(
+ XIM xim,
+ XIMArg *arg)
+{
+ Xim im = (Xim)xim;
+ XimDefIMValues im_values;
+ INT16 len;
+ CARD16 *buf_s;
+ char *tmp;
+ CARD32 tmp_buf32[BUFSIZE/4];
+ char *tmp_buf = (char *)tmp_buf32;
+ char *buf;
+ int buf_size;
+ char *data;
+ int data_len;
+ int ret_len;
+ int total;
+ XIMArg *arg_ret;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int ret_code;
+ char *name;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_SERVER_CONNECTED(im))
+ return arg->name;
+#else
+ if (!_XimSaveIMValues(im, arg))
+ return arg->name;
+
+ if (!IS_SERVER_CONNECTED(im)) {
+ if (IS_CONNECTABLE(im)) {
+ if (!_XimConnectServer(im)) {
+ return _XimDelayModeSetIMValues(im, arg);
+ }
+ } else {
+ return arg->name;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ _XimGetCurrentIMValues(im, &im_values);
+ buf = tmp_buf;
+ buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
+ data_len = BUFSIZE - buf_size;
+ total = 0;
+ arg_ret = arg;
+ for (;;) {
+ data = &buf[buf_size];
+ if ((name = _XimEncodeIMATTRIBUTE(im, im->core.im_resources,
+ im->core.im_num_resources, arg, &arg_ret, data, data_len,
+ &ret_len, (XPointer)&im_values, XIM_SETIMVALUES))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ break;
+ }
+
+ total += ret_len;
+ if (!(arg = arg_ret)) {
+ break;
+ }
+
+ buf_size += ret_len;
+ if (buf == tmp_buf) {
+ if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
+ return arg->name;
+ }
+ memcpy(tmp, buf, buf_size);
+ buf = tmp;
+ } else {
+ if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
+ Xfree(buf);
+ return arg->name;
+ }
+ buf = tmp;
+ }
+ }
+ _XimSetCurrentIMValues(im, &im_values);
+
+ if (!total)
+ return (char *)NULL;
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = (INT16)total;
+
+ len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
+ _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ return arg->name;
+ }
+ _XimFlush(im);
+ if (buf != tmp_buf)
+ Xfree(buf);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimSetIMValuesCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, reply, buf_size,
+ _XimSetIMValuesCheck, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return arg->name;
+ }
+ }
+ } else
+ return arg->name;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return arg->name;
+ }
+ if(reply != preply)
+ Xfree(preply);
+
+ return name;
+}
+
+#ifdef XIM_CONNECTABLE
+Private char *
+_XimDelayModeGetIMValues(
+ Xim im,
+ XIMArg *arg)
+{
+ XimDefIMValues im_values;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ return(_XimGetIMValueData(im, (XPointer)&im_values, arg,
+ im->core.im_resources, im->core.im_num_resources));
+}
+#endif /* XIM_CONNECTABLE */
+
+Private Bool
+_XimGetIMValuesCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+
+ if ((major_opcode == XIM_GET_IM_VALUES_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+Private char *
+_XimProtoGetIMValues(
+ XIM xim,
+ XIMArg *arg)
+{
+ Xim im = (Xim)xim;
+ register XIMArg *p;
+ register int n;
+ CARD8 *buf;
+ CARD16 *buf_s;
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply = NULL;
+ int buf_size;
+ int ret_code;
+ char *makeid_name;
+ char *decode_name;
+ CARD16 *data = NULL;
+ INT16 data_len = 0;
+
+#ifndef XIM_CONNECTABLE
+ if (!IS_SERVER_CONNECTED(im))
+ return arg->name;
+#else
+ if (!IS_SERVER_CONNECTED(im)) {
+ if (IS_CONNECTABLE(im)) {
+ if (!_XimConnectServer(im)) {
+ return _XimDelayModeGetIMValues(im, arg);
+ }
+ } else {
+ return arg->name;
+ }
+ }
+#endif /* XIM_CONNECTABLE */
+
+ for (n = 0, p = arg; p->name; p++)
+ n++;
+
+ if (!n)
+ return (char *)NULL;
+
+ buf_size = sizeof(CARD16) * n;
+ buf_size += XIM_HEADER_SIZE
+ + sizeof(CARD16)
+ + sizeof(INT16)
+ + XIM_PAD(buf_size);
+
+ if (!(buf = (CARD8 *)Xmalloc(buf_size)))
+ return arg->name;
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+
+ makeid_name = _XimMakeIMAttrIDList(im, im->core.im_resources,
+ im->core.im_num_resources, arg,
+ &buf_s[2], &len, XIM_GETIMVALUES);
+
+ if (len) {
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = len; /* length of im-attr-id */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += sizeof(CARD16) /* sizeof imid */
+ + sizeof(INT16); /* sizeof length of attr */
+
+ _XimSetHeader((XPointer)buf, XIM_GET_IM_VALUES, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ Xfree(buf);
+ return arg->name;
+ }
+ _XimFlush(im);
+ Xfree(buf);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimGetIMValuesCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimGetIMValuesCheck, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return arg->name;
+ }
+ }
+ } else
+ return arg->name;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return arg->name;
+ }
+ data = &buf_s[2];
+ data_len = buf_s[1];
+ }
+ decode_name = _XimDecodeIMATTRIBUTE(im, im->core.im_resources,
+ im->core.im_num_resources, data, data_len,
+ arg, XIM_GETIMVALUES);
+ if (reply != preply)
+ Xfree(preply);
+
+ if (decode_name)
+ return decode_name;
+ else
+ return makeid_name;
+}
+
+Private XIMMethodsRec im_methods = {
+ _XimProtoCloseIM, /* close */
+ _XimProtoSetIMValues, /* set_values */
+ _XimProtoGetIMValues, /* get_values */
+ _XimProtoCreateIC, /* create_ic */
+ _Ximctstombs, /* ctstombs */
+ _Ximctstowcs, /* ctstowcs */
+ _Ximctstoutf8 /* ctstoutf8 */
+};
+
+Private Bool
+_XimSetEncodingByName(
+ Xim im,
+ char **buf,
+ int *len)
+{
+ char *encoding = (char *)NULL;
+ int encoding_len;
+ int compound_len;
+ BYTE *ret;
+
+ _XGetLCValues(im->core.lcd, XlcNCodeset, &encoding, NULL);
+ if (!encoding) {
+ *buf = (char *)NULL;
+ *len = 0;
+ return True;
+ }
+ encoding_len = strlen(encoding);
+ compound_len = strlen("COMPOUND_TEXT");
+ *len = encoding_len + sizeof(BYTE) + compound_len + sizeof(BYTE);
+ if (!(ret = (BYTE *)Xmalloc(*len))) {
+ return False;
+ }
+ *buf = (char *)ret;
+
+ ret[0] = (BYTE)encoding_len;
+ (void)strncpy((char *)&ret[1], encoding, encoding_len);
+ ret += (encoding_len + sizeof(BYTE));
+ ret[0] = (BYTE)compound_len;
+ (void)strncpy((char *)&ret[1], "COMPOUND_TEXT", compound_len);
+ return True;
+}
+
+Private Bool
+_XimSetEncodingByDetail(
+ Xim im,
+ char **buf,
+ int *len)
+{
+ *len = 0;
+ *buf = NULL;
+ return True;
+}
+
+Private Bool
+_XimGetEncoding(
+ Xim im,
+ CARD16 *buf,
+ char *name,
+ int name_len,
+ char *detail,
+ int detail_len)
+{
+ XLCd lcd = im->core.lcd;
+ CARD16 category = buf[0];
+ CARD16 idx = buf[1];
+ int len;
+ XlcConv ctom_conv = NULL;
+ XlcConv ctow_conv = NULL;
+ XlcConv ctoutf8_conv = NULL;
+ XlcConv conv;
+ XimProtoPrivateRec *private = &im->private.proto;
+
+ if (idx == (CARD16)XIM_Default_Encoding_IDX) { /* XXX */
+ if (!(ctom_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNMultiByte)))
+ return False;
+ if (!(ctow_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNWideChar)))
+ return False;
+ if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNUtf8String)))
+ return False;
+ }
+
+ if (category == XIM_Encoding_NameCategory) {
+ while (name_len > 0) {
+ len = (int)name[0];
+ if (!strncmp(&name[1], "COMPOUND_TEXT", len)) {
+ if (!(ctom_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNMultiByte)))
+ return False;
+ if (!(ctow_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNWideChar)))
+ return False;
+ if (!(ctoutf8_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNUtf8String)))
+ return False;
+ break;
+ } else {
+ /*
+ * Not yet
+ */
+ }
+ len += sizeof(BYTE);
+ name_len -= len;
+ name += len;
+ }
+ } else if (category == XIM_Encoding_DetailCategory) {
+ /*
+ * Not yet
+ */
+ } else {
+ return False;
+ }
+
+ private->ctom_conv = ctom_conv;
+ private->ctow_conv = ctow_conv;
+ private->ctoutf8_conv = ctoutf8_conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
+ return False;
+ private->cstomb_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
+ return False;
+ private->cstowc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
+ return False;
+ private->cstoutf8_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
+ return False;
+ private->ucstoc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
+ return False;
+ private->ucstoutf8_conv = conv;
+
+ return True;
+}
+
+Private Bool
+_XimEncodingNegoCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+
+ if ((major_opcode == XIM_ENCODING_NEGOTIATION_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimEncodingNegotiation(
+ Xim im)
+{
+ char *name_ptr = 0;
+ int name_len = 0;
+ char *detail_ptr = 0;
+ int detail_len = 0;
+ CARD8 *buf;
+ CARD16 *buf_s;
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+
+ if (!(_XimSetEncodingByName(im, &name_ptr, &name_len)))
+ return False;
+
+ if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len)))
+ goto free_name_ptr;
+
+ len = sizeof(CARD16)
+ + sizeof(INT16)
+ + name_len
+ + XIM_PAD(name_len)
+ + sizeof(INT16)
+ + sizeof(CARD16)
+ + detail_len;
+
+ if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len)))
+ goto free_detail_ptr;
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = (INT16)name_len;
+ if (name_ptr)
+ (void)memcpy((char *)&buf_s[2], name_ptr, name_len);
+ XIM_SET_PAD(&buf_s[2], name_len);
+ buf_s = (CARD16 *)((char *)&buf_s[2] + name_len);
+ buf_s[0] = detail_len;
+ buf_s[1] = 0;
+ if (detail_ptr)
+ (void)memcpy((char *)&buf_s[2], detail_ptr, detail_len);
+
+ _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ Xfree(buf);
+ goto free_detail_ptr;
+ }
+ _XimFlush(im);
+ Xfree(buf);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimEncodingNegoCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimEncodingNegoCheck, 0);
+ if(ret_code != XIM_TRUE)
+ goto free_preply;
+ }
+ } else
+ goto free_detail_ptr;
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ goto free_preply;
+ }
+
+ if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len,
+ detail_ptr, detail_len)))
+ goto free_preply;
+
+ if (name_ptr)
+ Xfree(name_ptr);
+ if (detail_ptr)
+ Xfree(detail_ptr);
+
+ if(reply != preply)
+ Xfree(preply);
+
+ return True;
+
+free_preply:
+ if (reply != preply)
+ Xfree(preply);
+
+free_detail_ptr:
+ Xfree(detail_ptr);
+
+free_name_ptr:
+ Xfree(name_ptr);
+
+ return False;
+}
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimSendSavedIMValues(
+ Xim im)
+{
+ XimDefIMValues im_values;
+ INT16 len;
+ CARD16 *buf_s;
+ char *tmp;
+ CARD32 tmp_buf32[BUFSIZE/4];
+ char *tmp_buf = (char *)tmp_buf32;
+ char *buf;
+ int buf_size;
+ char *data;
+ int data_len;
+ int ret_len;
+ int total;
+ int idx;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int ret_code;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ buf = tmp_buf;
+ buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
+ data_len = BUFSIZE - buf_size;
+ total = 0;
+ idx = 0;
+ for (;;) {
+ data = &buf[buf_size];
+ if (!_XimEncodeSavedIMATTRIBUTE(im, im->core.im_resources,
+ im->core.im_num_resources, &idx, data, data_len,
+ &ret_len, (XPointer)&im_values, XIM_SETIMVALUES)) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ return False;
+ }
+
+ total += ret_len;
+ if (idx == -1) {
+ break;
+ }
+
+ buf_size += ret_len;
+ if (buf == tmp_buf) {
+ if (!(tmp = (char *)Xmalloc(buf_size + data_len))) {
+ return False;
+ }
+ memcpy(tmp, buf, buf_size);
+ buf = tmp;
+ } else {
+ if (!(tmp = (char *)Xrealloc(buf, (buf_size + data_len)))) {
+ Xfree(buf);
+ return False;
+ }
+ buf = tmp;
+ }
+ }
+
+ if (!total)
+ return True;
+
+ buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ buf_s[0] = im->private.proto.imid;
+ buf_s[1] = (INT16)total;
+
+ len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
+ _XimSetHeader((XPointer)buf, XIM_SET_IM_VALUES, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf))) {
+ if (buf != tmp_buf)
+ Xfree(buf);
+ return False;
+ }
+ _XimFlush(im);
+ if (buf != tmp_buf)
+ Xfree(buf);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimSetIMValuesCheck, 0);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = (int)len;
+ preply = (XPointer)Xmalloc(buf_size);
+ ret_code = _XimRead(im, &len, reply, buf_size,
+ _XimSetIMValuesCheck, 0);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else
+ return False;
+
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+
+ return True;
+}
+
+Private void
+_XimDelayModeIMFree(
+ Xim im)
+{
+ if (im->core.im_resources) {
+ Xfree(im->core.im_resources);
+ im->core.im_resources = NULL;
+ }
+ if (im->core.ic_resources) {
+ Xfree(im->core.ic_resources);
+ im->core.ic_resources = NULL;
+ }
+ if (im->core.im_values_list) {
+ Xfree(im->core.im_values_list);
+ im->core.im_values_list = NULL;
+ }
+ if (im->core.ic_values_list) {
+ Xfree(im->core.ic_values_list);
+ im->core.ic_values_list = NULL;
+ }
+ return;
+}
+
+Public Bool
+_XimConnectServer(
+ Xim im)
+{
+ Xim save_im;
+
+ if (!(save_im = (Xim)Xmalloc(sizeof(XimRec))))
+ return False;
+ memcpy((char *)save_im, (char *)im, sizeof(XimRec));
+
+ if (_XimPreConnect(im) && _XimConnection(im)
+ && _XimOpen(im) && _XimEncodingNegotiation(im)) {
+ if (_XimSendSavedIMValues(im)) {
+ _XimDelayModeIMFree(save_im);
+ _XimRegisterServerFilter(im);
+ Xfree(save_im);
+ return True;
+ }
+ }
+ memcpy((char *)im, (char *)save_im, sizeof(XimRec));
+ Xfree(save_im);
+ return False;
+}
+
+Public Bool
+_XimDelayModeSetAttr(
+ Xim im)
+{
+ XimDefIMValues im_values;
+
+ if(!_XimSetIMResourceList(&im->core.im_resources,
+ &im->core.im_num_resources)) {
+ return False;
+ }
+ if(!_XimSetICResourceList(&im->core.ic_resources,
+ &im->core.ic_num_resources)) {
+ return False;
+ }
+
+ _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
+
+ _XimGetCurrentIMValues(im, &im_values);
+ if(!_XimSetLocalIMDefaults(im, (XPointer)&im_values,
+ im->core.im_resources, im->core.im_num_resources)) {
+ return False;
+ }
+ _XimSetCurrentIMValues(im, &im_values);
+ if (im->private.proto.default_styles) {
+ if (im->core.styles)
+ Xfree(im->core.styles);
+ im->core.styles = im->private.proto.default_styles;
+ }
+
+ return True;
+}
+
+Private Bool
+_XimReconnectModeSetAttr(
+ Xim im)
+{
+ XimDefIMValues im_values;
+
+ if(!_XimSetIMResourceList(&im->core.im_resources,
+ &im->core.im_num_resources)) {
+ return False;
+ }
+ if(!_XimSetICResourceList(&im->core.ic_resources,
+ &im->core.ic_num_resources)) {
+ return False;
+ }
+
+ _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
+
+ if (im->private.proto.default_styles) {
+ if (im->core.styles)
+ Xfree(im->core.styles);
+ im->core.styles = im->private.proto.default_styles;
+ }
+
+ return True;
+}
+#endif /* XIM_CONNECTABLE */
+
+Public Bool
+_XimProtoOpenIM(
+ Xim im)
+{
+ _XimInitialResourceInfo();
+
+ im->methods = &im_methods;
+
+#ifdef XIM_CONNECTABLE
+ _XimSetProtoResource(im);
+#endif /* XIM_CONNECTABLE */
+
+ if (_XimPreConnect(im)) {
+ if (_XimConnection(im) && _XimOpen(im) && _XimEncodingNegotiation(im)) {
+ _XimRegisterServerFilter(im);
+ return True;
+ }
+ _XimShutdown(im);
+#ifdef XIM_CONNECTABLE
+ } else if (IS_DELAYBINDABLE(im)) {
+ if (_XimDelayModeSetAttr(im))
+ return True;
+#endif /* XIM_CONNECTABLE */
+ }
+ _XimProtoIMFree(im);
+ return False;
+}
diff --git a/libX11/modules/im/ximcp/imDefLkup.c b/libX11/modules/im/ximcp/imDefLkup.c index 996d36aef..e53845d4c 100644 --- a/libX11/modules/im/ximcp/imDefLkup.c +++ b/libX11/modules/im/ximcp/imDefLkup.c @@ -1,1170 +1,1170 @@ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" - -Public Xic -_XimICOfXICID( - Xim im, - XICID icid) -{ - Xic pic; - - for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) { - if (pic->private.proto.icid == icid) - return pic; - } - return (Xic)0; -} - -Private void -_XimProcIMSetEventMask( - Xim im, - XPointer buf) -{ - EVENTMASK *buf_l = (EVENTMASK *)buf; - - im->private.proto.forward_event_mask = buf_l[0]; - im->private.proto.synchronous_event_mask = buf_l[1]; - return; -} - -Private void -_XimProcICSetEventMask( - Xic ic, - XPointer buf) -{ - EVENTMASK *buf_l = (EVENTMASK *)buf; - - ic->private.proto.forward_event_mask = buf_l[0]; - ic->private.proto.synchronous_event_mask = buf_l[1]; - _XimReregisterFilter(ic); - return; -} - -Public Bool -_XimSetEventMaskCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - Xim im = (Xim)call_data; - Xic ic; - - if (imid == im->private.proto.imid) { - if (icid) { - ic = _XimICOfXICID(im, icid); - _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]); - } else { - _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]); - } - return True; - } - return False; -} - -Private Bool -_XimSyncCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - - if ((major_opcode == XIM_SYNC_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - return True; - return False; -} - -Public Bool -_XimSync( - Xim im, - Xic ic) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimSyncCheck, (XPointer)ic); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(len); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimSyncCheck, (XPointer)ic); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else { - return False; - } - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - return True; -} - -Public Bool -_XimProcSyncReply( - Xim im, - Xic ic) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len; - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16); /* sizeof icid */ - - _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - return True; -} - -Public Bool -_XimRespSyncReply( - Xic ic, - BITMASK16 mode) -{ - if (mode & XimSYNCHRONUS) /* SYNC Request */ { - if (IS_FOCUSED(ic)) - MARK_NEED_SYNC_REPLY(ic); - else - _XimProcSyncReply((Xim)ic->core.im, ic); - } - - return True; -} - -Public Bool -_XimSyncCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - Xim im = (Xim)call_data; - Xic ic; - - if ((imid == im->private.proto.imid) - && (ic = _XimICOfXICID(im, icid))) { - (void)_XimProcSyncReply(im, ic); - return True; - } - return False; -} - -Private INT16 -_XimSetEventToWire( - XEvent *ev, - xEvent *event) -{ - if (!(_XimProtoEventToWire(ev, event, False))) - return 0; - event->u.u.sequenceNumber = - ((XAnyEvent *)ev)->serial & (unsigned long)0xffff; - return sz_xEvent; -} - -Private Bool -_XimForwardEventCore( - Xic ic, - XEvent *ev, - Bool sync) -{ - Xim im = (Xim)ic->core.im; - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - INT16 len; - - if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4]))) - return False; /* X event */ - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */ - buf_s[3] = - (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16); - /* serial number */ - - len += sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16) /* sizeof icid */ - + sizeof(BITMASK16) /* sizeof flag */ - + sizeof(CARD16); /* sizeof serila number */ - - _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - - if (sync) { - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimSyncCheck, (XPointer)ic); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(len); - ret_code = _XimRead(im, &len, preply, buf_size, - _XimSyncCheck, (XPointer)ic); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else { - return False; - } - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - } - return True; -} - -Public Bool -_XimForwardEvent( - Xic ic, - XEvent *ev, - Bool sync) -{ -#ifdef EXT_FORWARD - if (((ev->type == KeyPress) || (ev->type == KeyRelease))) - if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync)) - return True; -#endif - return _XimForwardEventCore(ic, ev, sync); -} - -Private void -_XimProcEvent( - Display *d, - Xic ic, - XEvent *ev, - CARD16 *buf) -{ - INT16 serial = buf[0]; - xEvent *xev = (xEvent *)&buf[1]; - - _XimProtoWireToEvent(ev, xev, False); - ev->xany.serial |= serial << 16; - ev->xany.send_event = False; - ev->xany.display = d; - MARK_FABLICATED(ic); - return; -} - -Private Bool -_XimForwardEventRecv( - Xim im, - Xic ic, - XPointer buf) -{ - CARD16 *buf_s = (CARD16 *)buf; - Display *d = im->core.display; - XEvent ev; - - _XimProcEvent(d, ic, &ev, &buf_s[1]); - - (void)_XimRespSyncReply(ic, buf_s[0]); - - XPutBackEvent(d, &ev); - - return True; -} - -Public Bool -_XimForwardEventCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - Xim im = (Xim)call_data; - Xic ic; - - if ((imid == im->private.proto.imid) - && (ic = _XimICOfXICID(im, icid))) { - (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]); - return True; - } - return False; -} - -Private Bool -_XimRegisterTriggerkey( - Xim im, - XPointer buf) -{ - CARD32 *buf_l = (CARD32 *)buf; - CARD32 len; - CARD32 *key; - - if (IS_DYNAMIC_EVENT_FLOW(im)) /* already Dynamic event flow mode */ - return True; - - /* - * register onkeylist - */ - - len = buf_l[0]; /* length of on-keys */ - len += sizeof(INT32); /* sizeof length of on-keys */ - - if (!(key = (CARD32 *)Xmalloc(len))) { - _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); - return False; - } - memcpy((char *)key, (char *)buf_l, len); - im->private.proto.im_onkeylist = key; - - MARK_DYNAMIC_EVENT_FLOW(im); - - /* - * register offkeylist - */ - - buf_l = (CARD32 *)((char *)buf + len); - len = buf_l[0]; /* length of off-keys */ - len += sizeof(INT32); /* sizeof length of off-keys */ - - if (!(key = (CARD32 *)Xmalloc(len))) { - _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); - return False; - } - - memcpy((char *)key, (char *)buf_l, len); - im->private.proto.im_offkeylist = key; - - return True; -} - -Public Bool -_XimRegisterTriggerKeysCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - Xim im = (Xim)call_data; - - (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]); - return True; -} - -Public EVENTMASK -_XimGetWindowEventmask( - Xic ic) -{ - Xim im = (Xim )ic->core.im; - XWindowAttributes atr; - - if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr)) - return 0; - return (EVENTMASK)atr.your_event_mask; -} - - -Private Bool -_XimTriggerNotifyCheck( - Xim im, - INT16 len, - XPointer data, - XPointer arg) -{ - Xic ic = (Xic)arg; - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - CARD8 major_opcode = *((CARD8 *)data); - CARD8 minor_opcode = *((CARD8 *)data + 1); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - - if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY) - && (minor_opcode == 0) - && (imid == im->private.proto.imid) - && (icid == ic->private.proto.icid)) - return True; - if ((major_opcode == XIM_ERROR) - && (minor_opcode == 0) - && (buf_s[2] & XIM_IMID_VALID) - && (imid == im->private.proto.imid) - && (buf_s[2] & XIM_ICID_VALID) - && (icid == ic->private.proto.icid)) - return True; - return False; -} - -Public Bool -_XimTriggerNotify( - Xim im, - Xic ic, - int mode, - CARD32 idx) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE]; - CARD32 reply32[BUFSIZE/4]; - char *reply = (char *)reply32; - XPointer preply; - int buf_size; - int ret_code; - INT16 len; - EVENTMASK mask = _XimGetWindowEventmask(ic); - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[1] = ic->private.proto.icid; /* icid */ - buf_l[1] = mode; /* flag */ - buf_l[2] = idx; /* index of keys list */ - buf_l[3] = mask; /* select-event-mask */ - - len = sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16) /* sizeof icid */ - + sizeof(CARD32) /* sizeof flag */ - + sizeof(CARD32) /* sizeof index of key list */ - + sizeof(EVENTMASK); /* sizeof select-event-mask */ - - _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - buf_size = BUFSIZE; - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimTriggerNotifyCheck, (XPointer)ic); - if(ret_code == XIM_TRUE) { - preply = reply; - } else if(ret_code == XIM_OVERFLOW) { - if(len <= 0) { - preply = reply; - } else { - buf_size = len; - preply = (XPointer)Xmalloc(len); - ret_code = _XimRead(im, &len, (XPointer)reply, buf_size, - _XimTriggerNotifyCheck, (XPointer)ic); - if(ret_code != XIM_TRUE) { - Xfree(preply); - return False; - } - } - } else { - return False; - } - buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE); - if (*((CARD8 *)preply) == XIM_ERROR) { - _XimProcError(im, 0, (XPointer)&buf_s[3]); - if(reply != preply) - Xfree(preply); - return False; - } - if(reply != preply) - Xfree(preply); - return True; -} - -Private Bool -_XimRegCommitInfo( - Xic ic, - char *string, - int string_len, - KeySym *keysym, - int keysym_len) -{ - XimCommitInfo info; - - if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec)))) - return False; - info->string = string; - info->string_len = string_len; - info->keysym = keysym; - info->keysym_len = keysym_len; - info->next = ic->private.proto.commit_info; - ic->private.proto.commit_info = info; - return True; -} - -Private void -_XimUnregCommitInfo( - Xic ic) -{ - XimCommitInfo info; - - if (!(info = ic->private.proto.commit_info)) - return; - - if (info->string) - Xfree(info->string); - if (info->keysym) - Xfree(info->keysym); - ic->private.proto.commit_info = info->next; - Xfree(info); - return; -} - -Public void -_XimFreeCommitInfo( - Xic ic) -{ - while (ic->private.proto.commit_info) - _XimUnregCommitInfo(ic); - return; -} - -Private Bool -_XimProcKeySym( - Xic ic, - CARD32 sym, - KeySym **xim_keysym, - int *xim_keysym_len) -{ - Xim im = (Xim)ic->core.im; - - if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) { - _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); - return False; - } - - **xim_keysym = (KeySym)sym; - *xim_keysym_len = 1; - - return True; -} - -Private Bool -_XimProcCommit( - Xic ic, - BYTE *buf, - int len, - char **xim_string, - int *xim_string_len) -{ - Xim im = (Xim)ic->core.im; - char *string; - - if (!(string = (char *)Xmalloc(len + 1))) { - _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); - return False; - } - - (void)memcpy(string, (char *)buf, len); - string[len] = '\0'; - - *xim_string = string; - *xim_string_len = len; - return True; -} - -Private Bool -_XimCommitRecv( - Xim im, - Xic ic, - XPointer buf) -{ - CARD16 *buf_s = (CARD16 *)buf; - BITMASK16 flag = buf_s[0]; - XKeyEvent ev; - char *string = NULL; - int string_len = 0; - KeySym *keysym = NULL; - int keysym_len = 0; - - if ((flag & XimLookupBoth) == XimLookupChars) { - if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2], - (int)buf_s[1], &string, &string_len))) - return False; - - } else if ((flag & XimLookupBoth) == XimLookupKeySym) { - if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) - return False; - - } else if ((flag & XimLookupBoth) == XimLookupBoth) { - if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len))) - return False; - - if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5], - (int)buf_s[4], &string, &string_len))) { - Xfree(keysym); - return False; - } - } - - if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) { - if (string) - Xfree(string); - if (keysym) - Xfree(keysym); - _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL); - return False; - } - - (void)_XimRespSyncReply(ic, flag); - - MARK_FABLICATED(ic); - - ev.type = KeyPress; - ev.send_event = False; - ev.display = im->core.display; - ev.window = ic->core.focus_window; - ev.keycode = 0; - ev.state = 0; - - XPutBackEvent(im->core.display, (XEvent *)&ev); - - return True; -} - -Public Bool -_XimCommitCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - XIMID imid = buf_s[0]; - XICID icid = buf_s[1]; - Xim im = (Xim)call_data; - Xic ic; - - if ((imid == im->private.proto.imid) - && (ic = _XimICOfXICID(im, icid))) { - (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]); - return True; - } - return False; -} - -Public void -_XimProcError( - Xim im, - Xic ic, - XPointer data) -{ - return; -} - -Public Bool -_XimErrorCallback( - Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE); - BITMASK16 flag = buf_s[2]; - XIMID imid; - XICID icid; - Xim im = (Xim)call_data; - Xic ic = NULL; - - if (flag & XIM_IMID_VALID) { - imid = buf_s[0]; - if (imid != im->private.proto.imid) - return False; - } - if (flag & XIM_ICID_VALID) { - icid = buf_s[1]; - if (!(ic = _XimICOfXICID(im, icid))) - return False; - } - _XimProcError(im, ic, (XPointer)&buf_s[3]); - - return True; -} - -Public Bool -_XimError( - Xim im, - Xic ic, - CARD16 error_code, - INT16 detail_length, - CARD16 type, - char *detail) -{ - CARD32 buf32[BUFSIZE/4]; - CARD8 *buf = (CARD8 *)buf32; - CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE]; - INT16 len = 0; - - buf_s[0] = im->private.proto.imid; /* imid */ - buf_s[2] = XIM_IMID_VALID; /* flag */ - if (ic) { - buf_s[1] = ic->private.proto.icid; /* icid */ - buf_s[2] |= XIM_ICID_VALID; /* flag */ - } - buf_s[3] = error_code; /* Error Code */ - buf_s[4] = detail_length; /* length of error detail */ - buf_s[5] = type; /* type of error detail */ - - if (detail_length && detail) { - len = detail_length; - memcpy((char *)&buf_s[6], detail, len); - XIM_SET_PAD(&buf_s[6], len); - } - - len += sizeof(CARD16) /* sizeof imid */ - + sizeof(CARD16) /* sizeof icid */ - + sizeof(BITMASK16) /* sizeof flag */ - + sizeof(CARD16) /* sizeof error_code */ - + sizeof(INT16) /* sizeof length of detail */ - + sizeof(CARD16); /* sizeof type */ - - _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len); - if (!(_XimWrite(im, len, (XPointer)buf))) - return False; - _XimFlush(im); - return True; -} - -Private int -_Ximctsconvert( - XlcConv conv, - char *from, - int from_len, - char *to, - int to_len, - Status *state) -{ - int from_left; - int to_left; - int from_savelen; - int to_savelen; - int from_cnvlen; - int to_cnvlen; - char *from_buf; - char *to_buf; - char scratchbuf[BUFSIZ]; - Status tmp_state; - - if (!state) - state = &tmp_state; - - if (!conv || !from || !from_len) { - *state = XLookupNone; - return 0; - } - - /* Reset the converter. The CompoundText at 'from' starts in - initial state. */ - _XlcResetConverter(conv); - - from_left = from_len; - to_left = BUFSIZ; - from_cnvlen = 0; - to_cnvlen = 0; - for (;;) { - from_buf = &from[from_cnvlen]; - from_savelen = from_left; - to_buf = &scratchbuf[to_cnvlen]; - to_savelen = to_left; - if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, - (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { - *state = XLookupNone; - return 0; - } - from_cnvlen += (from_savelen - from_left); - to_cnvlen += (to_savelen - to_left); - if (from_left == 0) { - if (!to_cnvlen) { - *state = XLookupNone; - return 0; - } - break; - } - } - - if (!to || !to_len || (to_len < to_cnvlen)) { - *state = XBufferOverflow; - } else { - memcpy(to, scratchbuf, to_cnvlen); - *state = XLookupChars; - } - return to_cnvlen; -} - -Public int -_Ximctstombs(XIM xim, char *from, int from_len, - char *to, int to_len, Status *state) -{ - return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv, - from, from_len, to, to_len, state); -} - -Public int -_Ximctstowcs( - XIM xim, - char *from, - int from_len, - wchar_t *to, - int to_len, - Status *state) -{ - Xim im = (Xim)xim; - XlcConv conv = im->private.proto.ctow_conv; - int from_left; - int to_left; - int from_savelen; - int to_savelen; - int from_cnvlen; - int to_cnvlen; - char *from_buf; - wchar_t *to_buf; - wchar_t scratchbuf[BUFSIZ]; - Status tmp_state; - - if (!state) - state = &tmp_state; - - if (!conv || !from || !from_len) { - *state = XLookupNone; - return 0; - } - - /* Reset the converter. The CompoundText at 'from' starts in - initial state. */ - _XlcResetConverter(conv); - - from_left = from_len; - to_left = BUFSIZ; - from_cnvlen = 0; - to_cnvlen = 0; - for (;;) { - from_buf = &from[from_cnvlen]; - from_savelen = from_left; - to_buf = &scratchbuf[to_cnvlen]; - to_savelen = to_left; - if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, - (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { - *state = XLookupNone; - return 0; - } - from_cnvlen += (from_savelen - from_left); - to_cnvlen += (to_savelen - to_left); - if (from_left == 0) { - if (!to_cnvlen){ - *state = XLookupNone; - return 0; - } - break; - } - } - - if (!to || !to_len || (to_len < to_cnvlen)) { - *state = XBufferOverflow; - } else { - memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); - *state = XLookupChars; - } - return to_cnvlen; -} - -Public int -_Ximctstoutf8( - XIM xim, - char *from, - int from_len, - char *to, - int to_len, - Status *state) -{ - return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv, - from, from_len, to, to_len, state); -} - -Public int -_XimProtoMbLookupString( - XIC xic, - XKeyEvent *ev, - char *buffer, - int bytes, - KeySym *keysym, - Status *state) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - int ret; - Status tmp_state; - XimCommitInfo info; - - if (!IS_SERVER_CONNECTED(im)) - return 0; - - if (!state) - state = &tmp_state; - - if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */ - if (!(info = ic->private.proto.commit_info)) { - *state = XLookupNone; - return 0; - } - - ret = im->methods->ctstombs((XIM)im, info->string, - info->string_len, buffer, bytes, state); - if (*state == XBufferOverflow) - return ret; - if (keysym && (info->keysym && *(info->keysym))) { - *keysym = *(info->keysym); - if (*state == XLookupChars) - *state = XLookupBoth; - else - *state = XLookupKeySym; - } - _XimUnregCommitInfo(ic); - - } else if (ev->type == KeyPress) { - ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); - if (ret > 0) { - if (ret > bytes) - *state = XBufferOverflow; - else if (keysym && *keysym != NoSymbol) - *state = XLookupBoth; - else - *state = XLookupChars; - } else { - if (keysym && *keysym != NoSymbol) - *state = XLookupKeySym; - else - *state = XLookupNone; - } - } else { - *state = XLookupNone; - ret = 0; - } - - return ret; -} - -Public int -_XimProtoWcLookupString( - XIC xic, - XKeyEvent *ev, - wchar_t *buffer, - int bytes, - KeySym *keysym, - Status *state) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - int ret; - Status tmp_state; - XimCommitInfo info; - - if (!IS_SERVER_CONNECTED(im)) - return 0; - - if (!state) - state = &tmp_state; - - if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ - if (!(info = ic->private.proto.commit_info)) { - *state = XLookupNone; - return 0; - } - - ret = im->methods->ctstowcs((XIM)im, info->string, - info->string_len, buffer, bytes, state); - if (*state == XBufferOverflow) - return ret; - if (keysym && (info->keysym && *(info->keysym))) { - *keysym = *(info->keysym); - if (*state == XLookupChars) - *state = XLookupBoth; - else - *state = XLookupKeySym; - } - _XimUnregCommitInfo(ic); - - } else if (ev->type == KeyPress) { - ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL); - if (ret > 0) { - if (ret > bytes) - *state = XBufferOverflow; - else if (keysym && *keysym != NoSymbol) - *state = XLookupBoth; - else - *state = XLookupChars; - } else { - if (keysym && *keysym != NoSymbol) - *state = XLookupKeySym; - else - *state = XLookupNone; - } - } else { - *state = XLookupNone; - ret = 0; - } - - return ret; -} - -Public int -_XimProtoUtf8LookupString( - XIC xic, - XKeyEvent *ev, - char *buffer, - int bytes, - KeySym *keysym, - Status *state) -{ - Xic ic = (Xic)xic; - Xim im = (Xim)ic->core.im; - int ret; - Status tmp_state; - XimCommitInfo info; - - if (!IS_SERVER_CONNECTED(im)) - return 0; - - if (!state) - state = &tmp_state; - - if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */ - if (!(info = ic->private.proto.commit_info)) { - *state = XLookupNone; - return 0; - } - - ret = im->methods->ctstoutf8((XIM)im, info->string, - info->string_len, buffer, bytes, state); - if (*state == XBufferOverflow) - return ret; - if (keysym && (info->keysym && *(info->keysym))) { - *keysym = *(info->keysym); - if (*state == XLookupChars) - *state = XLookupBoth; - else - *state = XLookupKeySym; - } - _XimUnregCommitInfo(ic); - - } else if (ev->type == KeyPress) { - ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); - if (ret > 0) { - if (ret > bytes) - *state = XBufferOverflow; - else if (keysym && *keysym != NoSymbol) - *state = XLookupBoth; - else - *state = XLookupChars; - } else { - if (keysym && *keysym != NoSymbol) - *state = XLookupKeySym; - else - *state = XLookupNone; - } - } else { - *state = XLookupNone; - ret = 0; - } - - return ret; -} +/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Public Xic
+_XimICOfXICID(
+ Xim im,
+ XICID icid)
+{
+ Xic pic;
+
+ for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) {
+ if (pic->private.proto.icid == icid)
+ return pic;
+ }
+ return (Xic)0;
+}
+
+Private void
+_XimProcIMSetEventMask(
+ Xim im,
+ XPointer buf)
+{
+ EVENTMASK *buf_l = (EVENTMASK *)buf;
+
+ im->private.proto.forward_event_mask = buf_l[0];
+ im->private.proto.synchronous_event_mask = buf_l[1];
+ return;
+}
+
+Private void
+_XimProcICSetEventMask(
+ Xic ic,
+ XPointer buf)
+{
+ EVENTMASK *buf_l = (EVENTMASK *)buf;
+
+ ic->private.proto.forward_event_mask = buf_l[0];
+ ic->private.proto.synchronous_event_mask = buf_l[1];
+ _XimReregisterFilter(ic);
+ return;
+}
+
+Public Bool
+_XimSetEventMaskCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+ Xim im = (Xim)call_data;
+ Xic ic;
+
+ if (imid == im->private.proto.imid) {
+ if (icid) {
+ ic = _XimICOfXICID(im, icid);
+ _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]);
+ } else {
+ _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]);
+ }
+ return True;
+ }
+ return False;
+}
+
+Private Bool
+_XimSyncCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+
+ if ((major_opcode == XIM_SYNC_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ return True;
+ return False;
+}
+
+Public Bool
+_XimSync(
+ Xim im,
+ Xic ic)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimSyncCheck, (XPointer)ic);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(len);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimSyncCheck, (XPointer)ic);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else {
+ return False;
+ }
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ return True;
+}
+
+Public Bool
+_XimProcSyncReply(
+ Xim im,
+ Xic ic)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16); /* sizeof icid */
+
+ _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ return True;
+}
+
+Public Bool
+_XimRespSyncReply(
+ Xic ic,
+ BITMASK16 mode)
+{
+ if (mode & XimSYNCHRONUS) /* SYNC Request */ {
+ if (IS_FOCUSED(ic))
+ MARK_NEED_SYNC_REPLY(ic);
+ else
+ _XimProcSyncReply((Xim)ic->core.im, ic);
+ }
+
+ return True;
+}
+
+Public Bool
+_XimSyncCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+ Xim im = (Xim)call_data;
+ Xic ic;
+
+ if ((imid == im->private.proto.imid)
+ && (ic = _XimICOfXICID(im, icid))) {
+ (void)_XimProcSyncReply(im, ic);
+ return True;
+ }
+ return False;
+}
+
+Private INT16
+_XimSetEventToWire(
+ XEvent *ev,
+ xEvent *event)
+{
+ if (!(_XimProtoEventToWire(ev, event, False)))
+ return 0;
+ event->u.u.sequenceNumber =
+ ((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
+ return sz_xEvent;
+}
+
+Private Bool
+_XimForwardEventCore(
+ Xic ic,
+ XEvent *ev,
+ Bool sync)
+{
+ Xim im = (Xim)ic->core.im;
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ INT16 len;
+
+ if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
+ return False; /* X event */
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+ buf_s[2] = sync ? XimSYNCHRONUS : 0; /* flag */
+ buf_s[3] =
+ (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
+ /* serial number */
+
+ len += sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16) /* sizeof icid */
+ + sizeof(BITMASK16) /* sizeof flag */
+ + sizeof(CARD16); /* sizeof serila number */
+
+ _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+
+ if (sync) {
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimSyncCheck, (XPointer)ic);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(len);
+ ret_code = _XimRead(im, &len, preply, buf_size,
+ _XimSyncCheck, (XPointer)ic);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else {
+ return False;
+ }
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ }
+ return True;
+}
+
+Public Bool
+_XimForwardEvent(
+ Xic ic,
+ XEvent *ev,
+ Bool sync)
+{
+#ifdef EXT_FORWARD
+ if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
+ if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
+ return True;
+#endif
+ return _XimForwardEventCore(ic, ev, sync);
+}
+
+Private void
+_XimProcEvent(
+ Display *d,
+ Xic ic,
+ XEvent *ev,
+ CARD16 *buf)
+{
+ INT16 serial = buf[0];
+ xEvent *xev = (xEvent *)&buf[1];
+
+ _XimProtoWireToEvent(ev, xev, False);
+ ev->xany.serial |= serial << 16;
+ ev->xany.send_event = False;
+ ev->xany.display = d;
+ MARK_FABLICATED(ic);
+ return;
+}
+
+Private Bool
+_XimForwardEventRecv(
+ Xim im,
+ Xic ic,
+ XPointer buf)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+ Display *d = im->core.display;
+ XEvent ev;
+
+ _XimProcEvent(d, ic, &ev, &buf_s[1]);
+
+ (void)_XimRespSyncReply(ic, buf_s[0]);
+
+ XPutBackEvent(d, &ev);
+
+ return True;
+}
+
+Public Bool
+_XimForwardEventCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+ Xim im = (Xim)call_data;
+ Xic ic;
+
+ if ((imid == im->private.proto.imid)
+ && (ic = _XimICOfXICID(im, icid))) {
+ (void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
+ return True;
+ }
+ return False;
+}
+
+Private Bool
+_XimRegisterTriggerkey(
+ Xim im,
+ XPointer buf)
+{
+ CARD32 *buf_l = (CARD32 *)buf;
+ CARD32 len;
+ CARD32 *key;
+
+ if (IS_DYNAMIC_EVENT_FLOW(im)) /* already Dynamic event flow mode */
+ return True;
+
+ /*
+ * register onkeylist
+ */
+
+ len = buf_l[0]; /* length of on-keys */
+ len += sizeof(INT32); /* sizeof length of on-keys */
+
+ if (!(key = (CARD32 *)Xmalloc(len))) {
+ _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
+ return False;
+ }
+ memcpy((char *)key, (char *)buf_l, len);
+ im->private.proto.im_onkeylist = key;
+
+ MARK_DYNAMIC_EVENT_FLOW(im);
+
+ /*
+ * register offkeylist
+ */
+
+ buf_l = (CARD32 *)((char *)buf + len);
+ len = buf_l[0]; /* length of off-keys */
+ len += sizeof(INT32); /* sizeof length of off-keys */
+
+ if (!(key = (CARD32 *)Xmalloc(len))) {
+ _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
+ return False;
+ }
+
+ memcpy((char *)key, (char *)buf_l, len);
+ im->private.proto.im_offkeylist = key;
+
+ return True;
+}
+
+Public Bool
+_XimRegisterTriggerKeysCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ Xim im = (Xim)call_data;
+
+ (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
+ return True;
+}
+
+Public EVENTMASK
+_XimGetWindowEventmask(
+ Xic ic)
+{
+ Xim im = (Xim )ic->core.im;
+ XWindowAttributes atr;
+
+ if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
+ return 0;
+ return (EVENTMASK)atr.your_event_mask;
+}
+
+
+Private Bool
+_XimTriggerNotifyCheck(
+ Xim im,
+ INT16 len,
+ XPointer data,
+ XPointer arg)
+{
+ Xic ic = (Xic)arg;
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ CARD8 major_opcode = *((CARD8 *)data);
+ CARD8 minor_opcode = *((CARD8 *)data + 1);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+
+ if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
+ && (minor_opcode == 0)
+ && (imid == im->private.proto.imid)
+ && (icid == ic->private.proto.icid))
+ return True;
+ if ((major_opcode == XIM_ERROR)
+ && (minor_opcode == 0)
+ && (buf_s[2] & XIM_IMID_VALID)
+ && (imid == im->private.proto.imid)
+ && (buf_s[2] & XIM_ICID_VALID)
+ && (icid == ic->private.proto.icid))
+ return True;
+ return False;
+}
+
+Public Bool
+_XimTriggerNotify(
+ Xim im,
+ Xic ic,
+ int mode,
+ CARD32 idx)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ CARD32 *buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
+ CARD32 reply32[BUFSIZE/4];
+ char *reply = (char *)reply32;
+ XPointer preply;
+ int buf_size;
+ int ret_code;
+ INT16 len;
+ EVENTMASK mask = _XimGetWindowEventmask(ic);
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[1] = ic->private.proto.icid; /* icid */
+ buf_l[1] = mode; /* flag */
+ buf_l[2] = idx; /* index of keys list */
+ buf_l[3] = mask; /* select-event-mask */
+
+ len = sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16) /* sizeof icid */
+ + sizeof(CARD32) /* sizeof flag */
+ + sizeof(CARD32) /* sizeof index of key list */
+ + sizeof(EVENTMASK); /* sizeof select-event-mask */
+
+ _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ buf_size = BUFSIZE;
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimTriggerNotifyCheck, (XPointer)ic);
+ if(ret_code == XIM_TRUE) {
+ preply = reply;
+ } else if(ret_code == XIM_OVERFLOW) {
+ if(len <= 0) {
+ preply = reply;
+ } else {
+ buf_size = len;
+ preply = (XPointer)Xmalloc(len);
+ ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
+ _XimTriggerNotifyCheck, (XPointer)ic);
+ if(ret_code != XIM_TRUE) {
+ Xfree(preply);
+ return False;
+ }
+ }
+ } else {
+ return False;
+ }
+ buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
+ if (*((CARD8 *)preply) == XIM_ERROR) {
+ _XimProcError(im, 0, (XPointer)&buf_s[3]);
+ if(reply != preply)
+ Xfree(preply);
+ return False;
+ }
+ if(reply != preply)
+ Xfree(preply);
+ return True;
+}
+
+Private Bool
+_XimRegCommitInfo(
+ Xic ic,
+ char *string,
+ int string_len,
+ KeySym *keysym,
+ int keysym_len)
+{
+ XimCommitInfo info;
+
+ if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec))))
+ return False;
+ info->string = string;
+ info->string_len = string_len;
+ info->keysym = keysym;
+ info->keysym_len = keysym_len;
+ info->next = ic->private.proto.commit_info;
+ ic->private.proto.commit_info = info;
+ return True;
+}
+
+Private void
+_XimUnregCommitInfo(
+ Xic ic)
+{
+ XimCommitInfo info;
+
+ if (!(info = ic->private.proto.commit_info))
+ return;
+
+ if (info->string)
+ Xfree(info->string);
+ if (info->keysym)
+ Xfree(info->keysym);
+ ic->private.proto.commit_info = info->next;
+ Xfree(info);
+ return;
+}
+
+Public void
+_XimFreeCommitInfo(
+ Xic ic)
+{
+ while (ic->private.proto.commit_info)
+ _XimUnregCommitInfo(ic);
+ return;
+}
+
+Private Bool
+_XimProcKeySym(
+ Xic ic,
+ CARD32 sym,
+ KeySym **xim_keysym,
+ int *xim_keysym_len)
+{
+ Xim im = (Xim)ic->core.im;
+
+ if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) {
+ _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
+ return False;
+ }
+
+ **xim_keysym = (KeySym)sym;
+ *xim_keysym_len = 1;
+
+ return True;
+}
+
+Private Bool
+_XimProcCommit(
+ Xic ic,
+ BYTE *buf,
+ int len,
+ char **xim_string,
+ int *xim_string_len)
+{
+ Xim im = (Xim)ic->core.im;
+ char *string;
+
+ if (!(string = (char *)Xmalloc(len + 1))) {
+ _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
+ return False;
+ }
+
+ (void)memcpy(string, (char *)buf, len);
+ string[len] = '\0';
+
+ *xim_string = string;
+ *xim_string_len = len;
+ return True;
+}
+
+Private Bool
+_XimCommitRecv(
+ Xim im,
+ Xic ic,
+ XPointer buf)
+{
+ CARD16 *buf_s = (CARD16 *)buf;
+ BITMASK16 flag = buf_s[0];
+ XKeyEvent ev;
+ char *string = NULL;
+ int string_len = 0;
+ KeySym *keysym = NULL;
+ int keysym_len = 0;
+
+ if ((flag & XimLookupBoth) == XimLookupChars) {
+ if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
+ (int)buf_s[1], &string, &string_len)))
+ return False;
+
+ } else if ((flag & XimLookupBoth) == XimLookupKeySym) {
+ if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
+ return False;
+
+ } else if ((flag & XimLookupBoth) == XimLookupBoth) {
+ if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
+ return False;
+
+ if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
+ (int)buf_s[4], &string, &string_len))) {
+ Xfree(keysym);
+ return False;
+ }
+ }
+
+ if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
+ if (string)
+ Xfree(string);
+ if (keysym)
+ Xfree(keysym);
+ _XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
+ return False;
+ }
+
+ (void)_XimRespSyncReply(ic, flag);
+
+ MARK_FABLICATED(ic);
+
+ ev.type = KeyPress;
+ ev.send_event = False;
+ ev.display = im->core.display;
+ ev.window = ic->core.focus_window;
+ ev.keycode = 0;
+ ev.state = 0;
+
+ XPutBackEvent(im->core.display, (XEvent *)&ev);
+
+ return True;
+}
+
+Public Bool
+_XimCommitCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ XIMID imid = buf_s[0];
+ XICID icid = buf_s[1];
+ Xim im = (Xim)call_data;
+ Xic ic;
+
+ if ((imid == im->private.proto.imid)
+ && (ic = _XimICOfXICID(im, icid))) {
+ (void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
+ return True;
+ }
+ return False;
+}
+
+Public void
+_XimProcError(
+ Xim im,
+ Xic ic,
+ XPointer data)
+{
+ return;
+}
+
+Public Bool
+_XimErrorCallback(
+ Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ CARD16 *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
+ BITMASK16 flag = buf_s[2];
+ XIMID imid;
+ XICID icid;
+ Xim im = (Xim)call_data;
+ Xic ic = NULL;
+
+ if (flag & XIM_IMID_VALID) {
+ imid = buf_s[0];
+ if (imid != im->private.proto.imid)
+ return False;
+ }
+ if (flag & XIM_ICID_VALID) {
+ icid = buf_s[1];
+ if (!(ic = _XimICOfXICID(im, icid)))
+ return False;
+ }
+ _XimProcError(im, ic, (XPointer)&buf_s[3]);
+
+ return True;
+}
+
+Public Bool
+_XimError(
+ Xim im,
+ Xic ic,
+ CARD16 error_code,
+ INT16 detail_length,
+ CARD16 type,
+ char *detail)
+{
+ CARD32 buf32[BUFSIZE/4];
+ CARD8 *buf = (CARD8 *)buf32;
+ CARD16 *buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
+ INT16 len = 0;
+
+ buf_s[0] = im->private.proto.imid; /* imid */
+ buf_s[2] = XIM_IMID_VALID; /* flag */
+ if (ic) {
+ buf_s[1] = ic->private.proto.icid; /* icid */
+ buf_s[2] |= XIM_ICID_VALID; /* flag */
+ }
+ buf_s[3] = error_code; /* Error Code */
+ buf_s[4] = detail_length; /* length of error detail */
+ buf_s[5] = type; /* type of error detail */
+
+ if (detail_length && detail) {
+ len = detail_length;
+ memcpy((char *)&buf_s[6], detail, len);
+ XIM_SET_PAD(&buf_s[6], len);
+ }
+
+ len += sizeof(CARD16) /* sizeof imid */
+ + sizeof(CARD16) /* sizeof icid */
+ + sizeof(BITMASK16) /* sizeof flag */
+ + sizeof(CARD16) /* sizeof error_code */
+ + sizeof(INT16) /* sizeof length of detail */
+ + sizeof(CARD16); /* sizeof type */
+
+ _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
+ if (!(_XimWrite(im, len, (XPointer)buf)))
+ return False;
+ _XimFlush(im);
+ return True;
+}
+
+Private int
+_Ximctsconvert(
+ XlcConv conv,
+ char *from,
+ int from_len,
+ char *to,
+ int to_len,
+ Status *state)
+{
+ int from_left;
+ int to_left;
+ int from_savelen;
+ int to_savelen;
+ int from_cnvlen;
+ int to_cnvlen;
+ char *from_buf;
+ char *to_buf;
+ char scratchbuf[BUFSIZ];
+ Status tmp_state;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (!conv || !from || !from_len) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ /* Reset the converter. The CompoundText at 'from' starts in
+ initial state. */
+ _XlcResetConverter(conv);
+
+ from_left = from_len;
+ to_left = BUFSIZ;
+ from_cnvlen = 0;
+ to_cnvlen = 0;
+ for (;;) {
+ from_buf = &from[from_cnvlen];
+ from_savelen = from_left;
+ to_buf = &scratchbuf[to_cnvlen];
+ to_savelen = to_left;
+ if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
+ (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
+ *state = XLookupNone;
+ return 0;
+ }
+ from_cnvlen += (from_savelen - from_left);
+ to_cnvlen += (to_savelen - to_left);
+ if (from_left == 0) {
+ if (!to_cnvlen) {
+ *state = XLookupNone;
+ return 0;
+ }
+ break;
+ }
+ }
+
+ if (!to || !to_len || (to_len < to_cnvlen)) {
+ *state = XBufferOverflow;
+ } else {
+ memcpy(to, scratchbuf, to_cnvlen);
+ *state = XLookupChars;
+ }
+ return to_cnvlen;
+}
+
+Public int
+_Ximctstombs(XIM xim, char *from, int from_len,
+ char *to, int to_len, Status *state)
+{
+ return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
+ from, from_len, to, to_len, state);
+}
+
+Public int
+_Ximctstowcs(
+ XIM xim,
+ char *from,
+ int from_len,
+ wchar_t *to,
+ int to_len,
+ Status *state)
+{
+ Xim im = (Xim)xim;
+ XlcConv conv = im->private.proto.ctow_conv;
+ int from_left;
+ int to_left;
+ int from_savelen;
+ int to_savelen;
+ int from_cnvlen;
+ int to_cnvlen;
+ char *from_buf;
+ wchar_t *to_buf;
+ wchar_t scratchbuf[BUFSIZ];
+ Status tmp_state;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (!conv || !from || !from_len) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ /* Reset the converter. The CompoundText at 'from' starts in
+ initial state. */
+ _XlcResetConverter(conv);
+
+ from_left = from_len;
+ to_left = BUFSIZ;
+ from_cnvlen = 0;
+ to_cnvlen = 0;
+ for (;;) {
+ from_buf = &from[from_cnvlen];
+ from_savelen = from_left;
+ to_buf = &scratchbuf[to_cnvlen];
+ to_savelen = to_left;
+ if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
+ (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
+ *state = XLookupNone;
+ return 0;
+ }
+ from_cnvlen += (from_savelen - from_left);
+ to_cnvlen += (to_savelen - to_left);
+ if (from_left == 0) {
+ if (!to_cnvlen){
+ *state = XLookupNone;
+ return 0;
+ }
+ break;
+ }
+ }
+
+ if (!to || !to_len || (to_len < to_cnvlen)) {
+ *state = XBufferOverflow;
+ } else {
+ memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
+ *state = XLookupChars;
+ }
+ return to_cnvlen;
+}
+
+Public int
+_Ximctstoutf8(
+ XIM xim,
+ char *from,
+ int from_len,
+ char *to,
+ int to_len,
+ Status *state)
+{
+ return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
+ from, from_len, to, to_len, state);
+}
+
+Public int
+_XimProtoMbLookupString(
+ XIC xic,
+ XKeyEvent *ev,
+ char *buffer,
+ int bytes,
+ KeySym *keysym,
+ Status *state)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ int ret;
+ Status tmp_state;
+ XimCommitInfo info;
+
+ if (!IS_SERVER_CONNECTED(im))
+ return 0;
+
+ if (!state)
+ state = &tmp_state;
+
+ if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */
+ if (!(info = ic->private.proto.commit_info)) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ ret = im->methods->ctstombs((XIM)im, info->string,
+ info->string_len, buffer, bytes, state);
+ if (*state == XBufferOverflow)
+ return ret;
+ if (keysym && (info->keysym && *(info->keysym))) {
+ *keysym = *(info->keysym);
+ if (*state == XLookupChars)
+ *state = XLookupBoth;
+ else
+ *state = XLookupKeySym;
+ }
+ _XimUnregCommitInfo(ic);
+
+ } else if (ev->type == KeyPress) {
+ ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
+ if (ret > 0) {
+ if (ret > bytes)
+ *state = XBufferOverflow;
+ else if (keysym && *keysym != NoSymbol)
+ *state = XLookupBoth;
+ else
+ *state = XLookupChars;
+ } else {
+ if (keysym && *keysym != NoSymbol)
+ *state = XLookupKeySym;
+ else
+ *state = XLookupNone;
+ }
+ } else {
+ *state = XLookupNone;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+Public int
+_XimProtoWcLookupString(
+ XIC xic,
+ XKeyEvent *ev,
+ wchar_t *buffer,
+ int bytes,
+ KeySym *keysym,
+ Status *state)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ int ret;
+ Status tmp_state;
+ XimCommitInfo info;
+
+ if (!IS_SERVER_CONNECTED(im))
+ return 0;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
+ if (!(info = ic->private.proto.commit_info)) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ ret = im->methods->ctstowcs((XIM)im, info->string,
+ info->string_len, buffer, bytes, state);
+ if (*state == XBufferOverflow)
+ return ret;
+ if (keysym && (info->keysym && *(info->keysym))) {
+ *keysym = *(info->keysym);
+ if (*state == XLookupChars)
+ *state = XLookupBoth;
+ else
+ *state = XLookupKeySym;
+ }
+ _XimUnregCommitInfo(ic);
+
+ } else if (ev->type == KeyPress) {
+ ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
+ if (ret > 0) {
+ if (ret > bytes)
+ *state = XBufferOverflow;
+ else if (keysym && *keysym != NoSymbol)
+ *state = XLookupBoth;
+ else
+ *state = XLookupChars;
+ } else {
+ if (keysym && *keysym != NoSymbol)
+ *state = XLookupKeySym;
+ else
+ *state = XLookupNone;
+ }
+ } else {
+ *state = XLookupNone;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+Public int
+_XimProtoUtf8LookupString(
+ XIC xic,
+ XKeyEvent *ev,
+ char *buffer,
+ int bytes,
+ KeySym *keysym,
+ Status *state)
+{
+ Xic ic = (Xic)xic;
+ Xim im = (Xim)ic->core.im;
+ int ret;
+ Status tmp_state;
+ XimCommitInfo info;
+
+ if (!IS_SERVER_CONNECTED(im))
+ return 0;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
+ if (!(info = ic->private.proto.commit_info)) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ ret = im->methods->ctstoutf8((XIM)im, info->string,
+ info->string_len, buffer, bytes, state);
+ if (*state == XBufferOverflow)
+ return ret;
+ if (keysym && (info->keysym && *(info->keysym))) {
+ *keysym = *(info->keysym);
+ if (*state == XLookupChars)
+ *state = XLookupBoth;
+ else
+ *state = XLookupKeySym;
+ }
+ _XimUnregCommitInfo(ic);
+
+ } else if (ev->type == KeyPress) {
+ ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
+ if (ret > 0) {
+ if (ret > bytes)
+ *state = XBufferOverflow;
+ else if (keysym && *keysym != NoSymbol)
+ *state = XLookupBoth;
+ else
+ *state = XLookupChars;
+ } else {
+ if (keysym && *keysym != NoSymbol)
+ *state = XLookupKeySym;
+ else
+ *state = XLookupNone;
+ }
+ } else {
+ *state = XLookupNone;
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/libX11/modules/im/ximcp/imInt.c b/libX11/modules/im/ximcp/imInt.c index 26f4991a2..e9371827d 100644 --- a/libX11/modules/im/ximcp/imInt.c +++ b/libX11/modules/im/ximcp/imInt.c @@ -1,263 +1,264 @@ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <X11/Xmd.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" -#include "XimImSw.h" - -Private Xim *_XimCurrentIMlist = (Xim *)NULL; -Private int _XimCurrentIMcount = 0; - -Private Bool -_XimSetIMStructureList( - Xim im) -{ - register int i; - Xim *xim; - - if(!(_XimCurrentIMlist)) { - if(!(_XimCurrentIMlist = (Xim *)Xmalloc(sizeof(Xim)))) - return False; - _XimCurrentIMlist[0] = im; - _XimCurrentIMcount = 1; - } - else { - for(i = 0; i < _XimCurrentIMcount; i++) { - if(!( _XimCurrentIMlist[i])) { - _XimCurrentIMlist[i] = im; - break; - } - } - if(i >= _XimCurrentIMcount) { - if(!(xim = (Xim *)Xrealloc(_XimCurrentIMlist, - ((i + 1) * sizeof(Xim))))) - return False; - _XimCurrentIMlist = xim; - _XimCurrentIMlist[_XimCurrentIMcount] = im; - _XimCurrentIMcount++; - } - } - return True; -} - -Public void -_XimDestroyIMStructureList(Xim im) -{ - register int i; - - for(i = 0; i < _XimCurrentIMcount; i++) { - if(_XimCurrentIMlist[i] == im) { - _XimCurrentIMlist[i] = NULL; - break; - } - } - return; -} - -Public void -_XimServerDestroy(Xim im_2_destroy) -{ - register int i; - Xim im; - XIC ic; - - for(i = 0; i < _XimCurrentIMcount; i++) { - if(!(im = _XimCurrentIMlist[i])) - continue; - /* - * Only continue if this im is the one to be destroyed. - */ - if (im != im_2_destroy) - continue; - - if (im->core.destroy_callback.callback) - (*im->core.destroy_callback.callback)((XIM)im, - im->core.destroy_callback.client_data, NULL); - for (ic = im->core.ic_chain; ic; ic = ic->core.next) { - if (ic->core.destroy_callback.callback) { - (*ic->core.destroy_callback.callback)(ic, - ic->core.destroy_callback.client_data, NULL); - } - } - _XimResetIMInstantiateCallback( im ); - (void)im->methods->close((XIM)im); - Xfree(im); - _XimCurrentIMlist[i] = NULL; - return; - } -} - -#ifdef XIM_CONNECTABLE -Public void -_XimServerReconectableDestroy(void) -{ - register int i; - Xim im; - XIC ic; - - for(i = 0; i < _XimCurrentIMcount; i++) { - if(!(im = _XimCurrentIMlist[i])) - continue; - - if (im->core.destroy_callback.callback) - (*im->core.destroy_callback.callback)(im, - im->core.destroy_callback.client_data, NULL); - for (ic = im->core.ic_chain; ic; ic = ic->core.next) { - if (ic->core.destroy_callback.callback) { - (*ic->core.destroy_callback.callback)(ic, - ic->core.destroy_callback.client_data, NULL); - } - } - _XimResetIMInstantiateCallback( im ); - (void)im->methods->close((XIM)im); - } - return; -} -#endif /* XIM_CONNECTABLE */ - -Private const char * -_XimStrstr( - register const char *src, - register const char *dest) -{ - int len; - - len = strlen(dest); - while((src = strchr(src, *dest))) { - if(!strncmp(src, dest, len)) - return src; - src++; - } - return NULL; -} - -Private char * -_XimMakeImName( - XLCd lcd) -{ - const char* begin = NULL; - const char* end = NULL; - char* ret = NULL; - const char* ximmodifier = XIMMODIFIER; - - if(lcd->core->modifiers != NULL && *lcd->core->modifiers != '\0') { - begin = _XimStrstr(lcd->core->modifiers, ximmodifier); - if (begin != NULL) { - end = begin += strlen(ximmodifier); - while (*end && *end != '@') - end++; - } - } - ret = Xmalloc(end - begin + 1); - if (ret != NULL) { - if (begin != NULL && end != NULL) { - (void)strncpy(ret, begin, end - begin); - ret[end - begin] = '\0'; - } else { - ret[0] = '\0'; - } - } - - return ret; -} - -Public XIM -_XimOpenIM( - XLCd lcd, - Display *dpy, - XrmDatabase rdb, - char *res_name, - char *res_class) -{ - Xim im; - register int i; - - if (!(im = Xcalloc(1, sizeof(XimRec)))) - return (XIM)NULL; - - im->core.lcd = lcd; - im->core.ic_chain = (XIC)NULL; - im->core.display = dpy; - im->core.rdb = rdb; - im->core.res_name = NULL; - im->core.res_class = NULL; - if((res_name != NULL) && (*res_name != '\0')){ - if(!(im->core.res_name = strdup(res_name))) - goto Error1; - } - if((res_class != NULL) && (*res_class != '\0')){ - if(!(im->core.res_class = strdup(res_class))) - goto Error2; - } - if(!(im->core.im_name = _XimMakeImName(lcd))) - goto Error3; - - for(i= 0; ; i++) { - if(_XimImSportRec[i].checkprocessing(im)) { - if(!(_XimImSportRec[i].im_open(im))) - goto Error4; - if(!_XimSetIMStructureList(im)) - goto Error4; - return (XIM)im; - } - } - -Error4 : - _XimImSportRec[i].im_free(im); - Xfree(im); - return NULL; -Error3 : - if(im->core.im_name) - Xfree(im->core.im_name); -Error2: - if(im->core.res_class) - Xfree(im->core.res_class); -Error1: - if(im->core.res_name) - Xfree(im->core.res_name); - Xfree(im); - return NULL; -} - -Public Bool -_XInitIM(XLCd lcd) -{ - if(lcd == (XLCd)NULL) - return False; - lcd->methods->open_im = _XimOpenIM; - lcd->methods->register_callback = _XimRegisterIMInstantiateCallback; - lcd->methods->unregister_callback = _XimUnRegisterIMInstantiateCallback; - return True; -} +/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <unistd.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XimImSw.h"
+
+Private Xim *_XimCurrentIMlist = (Xim *)NULL;
+Private int _XimCurrentIMcount = 0;
+
+Private Bool
+_XimSetIMStructureList(
+ Xim im)
+{
+ register int i;
+ Xim *xim;
+
+ if(!(_XimCurrentIMlist)) {
+ if(!(_XimCurrentIMlist = (Xim *)Xmalloc(sizeof(Xim))))
+ return False;
+ _XimCurrentIMlist[0] = im;
+ _XimCurrentIMcount = 1;
+ }
+ else {
+ for(i = 0; i < _XimCurrentIMcount; i++) {
+ if(!( _XimCurrentIMlist[i])) {
+ _XimCurrentIMlist[i] = im;
+ break;
+ }
+ }
+ if(i >= _XimCurrentIMcount) {
+ if(!(xim = (Xim *)Xrealloc(_XimCurrentIMlist,
+ ((i + 1) * sizeof(Xim)))))
+ return False;
+ _XimCurrentIMlist = xim;
+ _XimCurrentIMlist[_XimCurrentIMcount] = im;
+ _XimCurrentIMcount++;
+ }
+ }
+ return True;
+}
+
+Public void
+_XimDestroyIMStructureList(Xim im)
+{
+ register int i;
+
+ for(i = 0; i < _XimCurrentIMcount; i++) {
+ if(_XimCurrentIMlist[i] == im) {
+ _XimCurrentIMlist[i] = NULL;
+ break;
+ }
+ }
+ return;
+}
+
+Public void
+_XimServerDestroy(Xim im_2_destroy)
+{
+ register int i;
+ Xim im;
+ XIC ic;
+
+ for(i = 0; i < _XimCurrentIMcount; i++) {
+ if(!(im = _XimCurrentIMlist[i]))
+ continue;
+ /*
+ * Only continue if this im is the one to be destroyed.
+ */
+ if (im != im_2_destroy)
+ continue;
+
+ if (im->core.destroy_callback.callback)
+ (*im->core.destroy_callback.callback)((XIM)im,
+ im->core.destroy_callback.client_data, NULL);
+ for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
+ if (ic->core.destroy_callback.callback) {
+ (*ic->core.destroy_callback.callback)(ic,
+ ic->core.destroy_callback.client_data, NULL);
+ }
+ }
+ _XimResetIMInstantiateCallback( im );
+ (void)im->methods->close((XIM)im);
+ Xfree(im);
+ _XimCurrentIMlist[i] = NULL;
+ return;
+ }
+}
+
+#ifdef XIM_CONNECTABLE
+Public void
+_XimServerReconectableDestroy(void)
+{
+ register int i;
+ Xim im;
+ XIC ic;
+
+ for(i = 0; i < _XimCurrentIMcount; i++) {
+ if(!(im = _XimCurrentIMlist[i]))
+ continue;
+
+ if (im->core.destroy_callback.callback)
+ (*im->core.destroy_callback.callback)(im,
+ im->core.destroy_callback.client_data, NULL);
+ for (ic = im->core.ic_chain; ic; ic = ic->core.next) {
+ if (ic->core.destroy_callback.callback) {
+ (*ic->core.destroy_callback.callback)(ic,
+ ic->core.destroy_callback.client_data, NULL);
+ }
+ }
+ _XimResetIMInstantiateCallback( im );
+ (void)im->methods->close((XIM)im);
+ }
+ return;
+}
+#endif /* XIM_CONNECTABLE */
+
+Private const char *
+_XimStrstr(
+ register const char *src,
+ register const char *dest)
+{
+ int len;
+
+ len = strlen(dest);
+ while((src = strchr(src, *dest))) {
+ if(!strncmp(src, dest, len))
+ return src;
+ src++;
+ }
+ return NULL;
+}
+
+Private char *
+_XimMakeImName(
+ XLCd lcd)
+{
+ const char* begin = NULL;
+ const char* end = NULL;
+ char* ret = NULL;
+ const char* ximmodifier = XIMMODIFIER;
+
+ if(lcd->core->modifiers != NULL && *lcd->core->modifiers != '\0') {
+ begin = _XimStrstr(lcd->core->modifiers, ximmodifier);
+ if (begin != NULL) {
+ end = begin += strlen(ximmodifier);
+ while (*end && *end != '@')
+ end++;
+ }
+ }
+ ret = Xmalloc(end - begin + 1);
+ if (ret != NULL) {
+ if (begin != NULL && end != NULL) {
+ (void)strncpy(ret, begin, end - begin);
+ ret[end - begin] = '\0';
+ } else {
+ ret[0] = '\0';
+ }
+ }
+
+ return ret;
+}
+
+Public XIM
+_XimOpenIM(
+ XLCd lcd,
+ Display *dpy,
+ XrmDatabase rdb,
+ char *res_name,
+ char *res_class)
+{
+ Xim im;
+ register int i;
+
+ if (!(im = Xcalloc(1, sizeof(XimRec))))
+ return (XIM)NULL;
+
+ im->core.lcd = lcd;
+ im->core.ic_chain = (XIC)NULL;
+ im->core.display = dpy;
+ im->core.rdb = rdb;
+ im->core.res_name = NULL;
+ im->core.res_class = NULL;
+ if((res_name != NULL) && (*res_name != '\0')){
+ if(!(im->core.res_name = strdup(res_name)))
+ goto Error1;
+ }
+ if((res_class != NULL) && (*res_class != '\0')){
+ if(!(im->core.res_class = strdup(res_class)))
+ goto Error2;
+ }
+ if(!(im->core.im_name = _XimMakeImName(lcd)))
+ goto Error3;
+
+ for(i= 0; ; i++) {
+ if(_XimImSportRec[i].checkprocessing(im)) {
+ if(!(_XimImSportRec[i].im_open(im)))
+ goto Error4;
+ if(!_XimSetIMStructureList(im))
+ goto Error4;
+ return (XIM)im;
+ }
+ }
+
+Error4 :
+ _XimImSportRec[i].im_free(im);
+ Xfree(im);
+ return NULL;
+Error3 :
+ if(im->core.im_name)
+ Xfree(im->core.im_name);
+Error2:
+ if(im->core.res_class)
+ Xfree(im->core.res_class);
+Error1:
+ if(im->core.res_name)
+ Xfree(im->core.res_name);
+ Xfree(im);
+ return NULL;
+}
+
+Public Bool
+_XInitIM(XLCd lcd)
+{
+ if(lcd == (XLCd)NULL)
+ return False;
+ lcd->methods->open_im = _XimOpenIM;
+ lcd->methods->register_callback = _XimRegisterIMInstantiateCallback;
+ lcd->methods->unregister_callback = _XimUnRegisterIMInstantiateCallback;
+ return True;
+}
diff --git a/libX11/modules/im/ximcp/imLcFlt.c b/libX11/modules/im/ximcp/imLcFlt.c index 06aa9980a..7ab56f8a1 100644 --- a/libX11/modules/im/ximcp/imLcFlt.c +++ b/libX11/modules/im/ximcp/imLcFlt.c @@ -1,125 +1,125 @@ -/****************************************************************** - - Copyright 1992 by Fuji Xerox Co., Ltd. - Copyright 1992, 1994 by FUJITSU LIMITED - -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 Fuji Xerox, -FUJITSU LIMITED not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. Fuji Xerox, FUJITSU LIMITED make no representations -about the suitability of this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX, -FUJITSU LIMITED 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. - - Author : Kazunori Nishihara Fuji Xerox - Modifier : Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include <X11/keysym.h> -#include "Xlcint.h" -#include "Ximint.h" - -Bool -_XimLocalFilter(Display *d, Window w, XEvent *ev, XPointer client_data) -{ - Xic ic = (Xic)client_data; - KeySym keysym; - static char buf[256]; - DefTree *b = ic->private.local.base.tree; - DTIndex t; - Bool braille = False; - - if(ev->xkey.keycode == 0) - return (False); - - XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL); - - if(IsModifierKey(keysym)) - return (False); - - if(keysym >= XK_braille_dot_1 && keysym <= XK_braille_dot_8) { - if(ev->type == KeyPress) { - ic->private.local.brl_pressed |= - 1<<(keysym-XK_braille_dot_1); - return(True); - } else { - if(!ic->private.local.brl_committing - || ev->xkey.time - ic->private.local.brl_release_start > 300) { - ic->private.local.brl_committing = ic->private.local.brl_pressed; - ic->private.local.brl_release_start = ev->xkey.time; - } - ic->private.local.brl_pressed &= ~(1<<(keysym-XK_braille_dot_1)); - if(!ic->private.local.brl_pressed && ic->private.local.brl_committing) { - /* Commited a braille pattern, let it go through compose tree */ - keysym = XK_braille_blank | ic->private.local.brl_committing; - ev->type = KeyPress; - braille = True; - } else { - return(True); - } - } - } - - if( (ev->type != KeyPress) - || (((Xim)ic->core.im)->private.local.top == 0 ) ) - goto emit_braille; - - for(t = ic->private.local.context; t; t = b[t].next) { - if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) && - (keysym == b[t].keysym)) - break; - } - - if(t) { /* Matched */ - if(b[t].succession) { /* Intermediate */ - ic->private.local.context = b[t].succession; - return(True); - } else { /* Terminate (reached to leaf) */ - ic->private.local.composed = t; - ic->private.local.brl_committed = 0; - /* return back to client KeyPressEvent keycode == 0 */ - ev->xkey.keycode = 0; - XPutBackEvent(d, ev); - /* initialize internal state for next key sequence */ - ic->private.local.context = ((Xim)ic->core.im)->private.local.top; - return(True); - } - } else { /* Unmatched */ - if(ic->private.local.context == ((Xim)ic->core.im)->private.local.top) { - goto emit_braille; - } - /* Error (Sequence Unmatch occured) */ - /* initialize internal state for next key sequence */ - ic->private.local.context = ((Xim)ic->core.im)->private.local.top; - return(True); - } - -emit_braille: - if(braille) { - /* Braille pattern is not in compose tree, emit alone */ - ic->private.local.brl_committed = ic->private.local.brl_committing; - ic->private.local.composed = 0; - ev->xkey.keycode = 0; - _XPutBackEvent(d, ev); - return(True); - } - return(False); -} +/******************************************************************
+
+ Copyright 1992 by Fuji Xerox Co., Ltd.
+ Copyright 1992, 1994 by FUJITSU LIMITED
+
+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 Fuji Xerox,
+FUJITSU LIMITED not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. Fuji Xerox, FUJITSU LIMITED make no representations
+about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
+FUJITSU LIMITED 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.
+
+ Author : Kazunori Nishihara Fuji Xerox
+ Modifier : Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <X11/keysym.h>
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Bool
+_XimLocalFilter(Display *d, Window w, XEvent *ev, XPointer client_data)
+{
+ Xic ic = (Xic)client_data;
+ KeySym keysym;
+ static char buf[256];
+ DefTree *b = ic->private.local.base.tree;
+ DTIndex t;
+ Bool braille = False;
+
+ if(ev->xkey.keycode == 0)
+ return (False);
+
+ XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL);
+
+ if(IsModifierKey(keysym))
+ return (False);
+
+ if(keysym >= XK_braille_dot_1 && keysym <= XK_braille_dot_8) {
+ if(ev->type == KeyPress) {
+ ic->private.local.brl_pressed |=
+ 1<<(keysym-XK_braille_dot_1);
+ return(True);
+ } else {
+ if(!ic->private.local.brl_committing
+ || ev->xkey.time - ic->private.local.brl_release_start > 300) {
+ ic->private.local.brl_committing = ic->private.local.brl_pressed;
+ ic->private.local.brl_release_start = ev->xkey.time;
+ }
+ ic->private.local.brl_pressed &= ~(1<<(keysym-XK_braille_dot_1));
+ if(!ic->private.local.brl_pressed && ic->private.local.brl_committing) {
+ /* Commited a braille pattern, let it go through compose tree */
+ keysym = XK_braille_blank | ic->private.local.brl_committing;
+ ev->type = KeyPress;
+ braille = True;
+ } else {
+ return(True);
+ }
+ }
+ }
+
+ if( (ev->type != KeyPress)
+ || (((Xim)ic->core.im)->private.local.top == 0 ) )
+ goto emit_braille;
+
+ for(t = ic->private.local.context; t; t = b[t].next) {
+ if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) &&
+ (keysym == b[t].keysym))
+ break;
+ }
+
+ if(t) { /* Matched */
+ if(b[t].succession) { /* Intermediate */
+ ic->private.local.context = b[t].succession;
+ return(True);
+ } else { /* Terminate (reached to leaf) */
+ ic->private.local.composed = t;
+ ic->private.local.brl_committed = 0;
+ /* return back to client KeyPressEvent keycode == 0 */
+ ev->xkey.keycode = 0;
+ XPutBackEvent(d, ev);
+ /* initialize internal state for next key sequence */
+ ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
+ return(True);
+ }
+ } else { /* Unmatched */
+ if(ic->private.local.context == ((Xim)ic->core.im)->private.local.top) {
+ goto emit_braille;
+ }
+ /* Error (Sequence Unmatch occured) */
+ /* initialize internal state for next key sequence */
+ ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
+ return(True);
+ }
+
+emit_braille:
+ if(braille) {
+ /* Braille pattern is not in compose tree, emit alone */
+ ic->private.local.brl_committed = ic->private.local.brl_committing;
+ ic->private.local.composed = 0;
+ ev->xkey.keycode = 0;
+ _XPutBackEvent(d, ev);
+ return(True);
+ }
+ return(False);
+}
diff --git a/libX11/modules/im/ximcp/imLcIc.c b/libX11/modules/im/ximcp/imLcIc.c index 49338853c..5cdd7d59d 100644 --- a/libX11/modules/im/ximcp/imLcIc.c +++ b/libX11/modules/im/ximcp/imLcIc.c @@ -1,199 +1,199 @@ -/****************************************************************** - - Copyright 1992,1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xlib.h> -#include <X11/Xmd.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" - -Private void -_XimLocalUnSetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL; - - if (ic->core.focus_window) - _XUnregisterFilter(ic->core.im->core.display, - ic->core.focus_window, _XimLocalFilter, (XPointer)ic); - return; -} - -Private void -_XimLocalDestroyIC( - XIC xic) -{ - Xic ic = (Xic)xic; - - if(((Xim)ic->core.im)->private.local.current_ic == (XIC)ic) { - ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL; - } - if (ic->core.focus_window) - _XUnregisterFilter(ic->core.im->core.display, - ic->core.focus_window, _XimLocalFilter, (XPointer)ic); - if(ic->private.local.ic_resources) { - Xfree(ic->private.local.ic_resources); - ic->private.local.ic_resources = NULL; - } - return; -} - -Private void -_XimLocalSetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - XIC current_ic = ((Xim)ic->core.im)->private.local.current_ic; - - if (current_ic == (XIC)ic) - return; - - if (current_ic != (XIC)NULL) { - _XimLocalUnSetFocus(current_ic); - } - ((Xim)ic->core.im)->private.local.current_ic = (XIC)ic; - - if (ic->core.focus_window) - _XRegisterFilterByType(ic->core.im->core.display, - ic->core.focus_window, KeyPress, KeyRelease, - _XimLocalFilter, (XPointer)ic); - return; -} - -Private void -_XimLocalReset( - XIC xic) -{ - Xic ic = (Xic)xic; - ic->private.local.composed = 0; - ic->private.local.context = ((Xim)ic->core.im)->private.local.top; - ic->private.local.brl_pressed = 0; - ic->private.local.brl_committing = 0; - ic->private.local.brl_committed = 0; -} - -Private char * -_XimLocalMbReset( - XIC xic) -{ - _XimLocalReset(xic); - return (char *)NULL; -} - -Private wchar_t * -_XimLocalWcReset( - XIC xic) -{ - _XimLocalReset(xic); - return (wchar_t *)NULL; -} - -Private XICMethodsRec Local_ic_methods = { - _XimLocalDestroyIC, /* destroy */ - _XimLocalSetFocus, /* set_focus */ - _XimLocalUnSetFocus, /* unset_focus */ - _XimLocalSetICValues, /* set_values */ - _XimLocalGetICValues, /* get_values */ - _XimLocalMbReset, /* mb_reset */ - _XimLocalWcReset, /* wc_reset */ - _XimLocalMbReset, /* utf8_reset */ - _XimLocalMbLookupString, /* mb_lookup_string */ - _XimLocalWcLookupString, /* wc_lookup_string */ - _XimLocalUtf8LookupString /* utf8_lookup_string */ -}; - -Public XIC -_XimLocalCreateIC( - XIM im, - XIMArg *values) -{ - Xic ic; - XimDefICValues ic_values; - XIMResourceList res; - unsigned int num; - int len; - - if((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) { - return ((XIC)NULL); - } - - ic->methods = &Local_ic_methods; - ic->core.im = im; - ic->private.local.base = ((Xim)im)->private.local.base; - ic->private.local.context = ((Xim)im)->private.local.top; - ic->private.local.composed = 0; - ic->private.local.brl_pressed = 0; - ic->private.local.brl_committing = 0; - ic->private.local.brl_committed = 0; - - num = im->core.ic_num_resources; - len = sizeof(XIMResource) * num; - if((res = (XIMResourceList)Xmalloc(len)) == (XIMResourceList)NULL) { - goto Set_Error; - } - (void)memcpy((char *)res, (char *)im->core.ic_resources, len); - ic->private.local.ic_resources = res; - ic->private.local.ic_num_resources = num; - - bzero((char *)&ic_values, sizeof(XimDefICValues)); - if(_XimCheckLocalInputStyle(ic, (XPointer)&ic_values, values, - im->core.styles, res, num) == False) { - goto Set_Error; - } - - _XimSetICMode(res, num, ic_values.input_style); - - if(_XimSetICValueData(ic, (XPointer)&ic_values, - ic->private.local.ic_resources, - ic->private.local.ic_num_resources, - values, XIM_CREATEIC, True)) { - goto Set_Error; - } - ic_values.filter_events = KeyPressMask | KeyReleaseMask; - _XimSetCurrentICValues(ic, &ic_values); - if(_XimSetICDefaults(ic, (XPointer)&ic_values, - XIM_SETICDEFAULTS, res, num) == False) { - goto Set_Error; - } - _XimSetCurrentICValues(ic, &ic_values); - - return((XIC)ic); - -Set_Error : - if (ic->private.local.ic_resources) { - Xfree(ic->private.local.ic_resources); - ic->private.local.ic_resources = NULL; - } - Xfree(ic); - return((XIC)NULL); -} +/******************************************************************
+
+ Copyright 1992,1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Private void
+_XimLocalUnSetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL;
+
+ if (ic->core.focus_window)
+ _XUnregisterFilter(ic->core.im->core.display,
+ ic->core.focus_window, _XimLocalFilter, (XPointer)ic);
+ return;
+}
+
+Private void
+_XimLocalDestroyIC(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+
+ if(((Xim)ic->core.im)->private.local.current_ic == (XIC)ic) {
+ ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL;
+ }
+ if (ic->core.focus_window)
+ _XUnregisterFilter(ic->core.im->core.display,
+ ic->core.focus_window, _XimLocalFilter, (XPointer)ic);
+ if(ic->private.local.ic_resources) {
+ Xfree(ic->private.local.ic_resources);
+ ic->private.local.ic_resources = NULL;
+ }
+ return;
+}
+
+Private void
+_XimLocalSetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ XIC current_ic = ((Xim)ic->core.im)->private.local.current_ic;
+
+ if (current_ic == (XIC)ic)
+ return;
+
+ if (current_ic != (XIC)NULL) {
+ _XimLocalUnSetFocus(current_ic);
+ }
+ ((Xim)ic->core.im)->private.local.current_ic = (XIC)ic;
+
+ if (ic->core.focus_window)
+ _XRegisterFilterByType(ic->core.im->core.display,
+ ic->core.focus_window, KeyPress, KeyRelease,
+ _XimLocalFilter, (XPointer)ic);
+ return;
+}
+
+Private void
+_XimLocalReset(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ ic->private.local.composed = 0;
+ ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
+ ic->private.local.brl_pressed = 0;
+ ic->private.local.brl_committing = 0;
+ ic->private.local.brl_committed = 0;
+}
+
+Private char *
+_XimLocalMbReset(
+ XIC xic)
+{
+ _XimLocalReset(xic);
+ return (char *)NULL;
+}
+
+Private wchar_t *
+_XimLocalWcReset(
+ XIC xic)
+{
+ _XimLocalReset(xic);
+ return (wchar_t *)NULL;
+}
+
+Private XICMethodsRec Local_ic_methods = {
+ _XimLocalDestroyIC, /* destroy */
+ _XimLocalSetFocus, /* set_focus */
+ _XimLocalUnSetFocus, /* unset_focus */
+ _XimLocalSetICValues, /* set_values */
+ _XimLocalGetICValues, /* get_values */
+ _XimLocalMbReset, /* mb_reset */
+ _XimLocalWcReset, /* wc_reset */
+ _XimLocalMbReset, /* utf8_reset */
+ _XimLocalMbLookupString, /* mb_lookup_string */
+ _XimLocalWcLookupString, /* wc_lookup_string */
+ _XimLocalUtf8LookupString /* utf8_lookup_string */
+};
+
+Public XIC
+_XimLocalCreateIC(
+ XIM im,
+ XIMArg *values)
+{
+ Xic ic;
+ XimDefICValues ic_values;
+ XIMResourceList res;
+ unsigned int num;
+ int len;
+
+ if((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) {
+ return ((XIC)NULL);
+ }
+
+ ic->methods = &Local_ic_methods;
+ ic->core.im = im;
+ ic->private.local.base = ((Xim)im)->private.local.base;
+ ic->private.local.context = ((Xim)im)->private.local.top;
+ ic->private.local.composed = 0;
+ ic->private.local.brl_pressed = 0;
+ ic->private.local.brl_committing = 0;
+ ic->private.local.brl_committed = 0;
+
+ num = im->core.ic_num_resources;
+ len = sizeof(XIMResource) * num;
+ if((res = (XIMResourceList)Xmalloc(len)) == (XIMResourceList)NULL) {
+ goto Set_Error;
+ }
+ (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
+ ic->private.local.ic_resources = res;
+ ic->private.local.ic_num_resources = num;
+
+ bzero((char *)&ic_values, sizeof(XimDefICValues));
+ if(_XimCheckLocalInputStyle(ic, (XPointer)&ic_values, values,
+ im->core.styles, res, num) == False) {
+ goto Set_Error;
+ }
+
+ _XimSetICMode(res, num, ic_values.input_style);
+
+ if(_XimSetICValueData(ic, (XPointer)&ic_values,
+ ic->private.local.ic_resources,
+ ic->private.local.ic_num_resources,
+ values, XIM_CREATEIC, True)) {
+ goto Set_Error;
+ }
+ ic_values.filter_events = KeyPressMask | KeyReleaseMask;
+ _XimSetCurrentICValues(ic, &ic_values);
+ if(_XimSetICDefaults(ic, (XPointer)&ic_values,
+ XIM_SETICDEFAULTS, res, num) == False) {
+ goto Set_Error;
+ }
+ _XimSetCurrentICValues(ic, &ic_values);
+
+ return((XIC)ic);
+
+Set_Error :
+ if (ic->private.local.ic_resources) {
+ Xfree(ic->private.local.ic_resources);
+ ic->private.local.ic_resources = NULL;
+ }
+ Xfree(ic);
+ return((XIC)NULL);
+}
diff --git a/libX11/modules/im/ximcp/imLcIm.c b/libX11/modules/im/ximcp/imLcIm.c index 904169830..44516e9ee 100644 --- a/libX11/modules/im/ximcp/imLcIm.c +++ b/libX11/modules/im/ximcp/imLcIm.c @@ -1,732 +1,732 @@ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - Copyright 1993 by Digital Equipment Corporation - -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 FUJITSU LIMITED and -Digital Equipment Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. FUJITSU LIMITED and Digital Equipment Corporation -makes no representations about the suitability of this software for -any purpose. It is provided "as is" without express or implied -warranty. - -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Modifier: Franky Ling Digital Equipment Corporation - frankyling@hgrd01.enet.dec.com - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> - -#include <X11/Xmd.h> -#include <X11/Xatom.h> -#include <X11/Xos.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "XlcPublic.h" -#include "XlcPubI.h" -#include "Ximint.h" -#include <ctype.h> -#include <assert.h> - -#ifdef COMPOSECACHE -# include <sys/types.h> -# include <sys/stat.h> -# include <sys/mman.h> -# include <langinfo.h> -#endif - - -#ifdef COMPOSECACHE - -/* include trailing '/' for cache directory, file prefix otherwise */ -#define XIM_GLOBAL_CACHE_DIR "/var/cache/libx11/compose/" -#define XIM_HOME_CACHE_DIR "/.compose-cache/" -#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24) -#define XIM_CACHE_VERSION 4 -#define XIM_CACHE_TREE_ALIGNMENT 4 - -#define XIM_HASH_PRIME_1 13 -#define XIM_HASH_PRIME_2 1234096939 - -typedef INT32 DTStructIndex; -struct _XimCacheStruct { - INT32 id; - INT32 version; - DTStructIndex tree; - DTStructIndex mb; - DTStructIndex wc; - DTStructIndex utf8; - DTStructIndex size; - DTIndex top; - DTIndex treeused; - DTCharIndex mbused; - DTCharIndex wcused; - DTCharIndex utf8used; - char fname[1]; - /* char encoding[1] */ -}; - -Private struct _XimCacheStruct* _XimCache_mmap = NULL; -Private DefTreeBase _XimCachedDefaultTreeBase; -Private int _XimCachedDefaultTreeRefcount = 0; - -#endif - - -Public Bool -_XimCheckIfLocalProcessing(Xim im) -{ - FILE *fp; - char *name; - - if(strcmp(im->core.im_name, "") == 0) { - name = _XlcFileName(im->core.lcd, COMPOSE_FILE); - if (name != (char *)NULL) { - fp = _XFopenFile (name, "r"); - Xfree(name); - if (fp != (FILE *)NULL) { - fclose(fp); - return(True); - } - } - return(False); - } else if(strcmp(im->core.im_name, "local") == 0 || - strcmp(im->core.im_name, "none" ) == 0 ) { - return(True); - } - return(False); -} - -Private void -XimFreeDefaultTree( - DefTreeBase *b) -{ - if (!b) return; - if (b->tree == NULL) return; -#ifdef COMPOSECACHE - if (b->tree == _XimCachedDefaultTreeBase.tree) { - _XimCachedDefaultTreeRefcount--; - /* No deleting, it's a cache after all. */ - return; - } -#endif - Xfree (b->tree); - if (b->mb) Xfree (b->mb); - if (b->wc) Xfree (b->wc); - if (b->utf8) Xfree (b->utf8); - b->tree = NULL; - b->mb = NULL; - b->wc = NULL; - b->utf8 = NULL; - b->treeused = b->treesize = 0; - b->mbused = b->mbsize = 0; - b->wcused = b->wcsize = 0; - b->utf8used = b->utf8size = 0; -} - -Public void -_XimLocalIMFree( - Xim im) -{ - XimFreeDefaultTree(&im->private.local.base); - im->private.local.top = 0; - - if(im->core.im_resources) { - Xfree(im->core.im_resources); - im->core.im_resources = NULL; - } - if(im->core.ic_resources) { - Xfree(im->core.ic_resources); - im->core.ic_resources = NULL; - } - if(im->core.im_values_list) { - Xfree(im->core.im_values_list); - im->core.im_values_list = NULL; - } - if(im->core.ic_values_list) { - Xfree(im->core.ic_values_list); - im->core.ic_values_list = NULL; - } - if(im->core.styles) { - Xfree(im->core.styles); - im->core.styles = NULL; - } - if(im->core.res_name) { - Xfree(im->core.res_name); - im->core.res_name = NULL; - } - if(im->core.res_class) { - Xfree(im->core.res_class); - im->core.res_class = NULL; - } - if(im->core.im_name) { - Xfree(im->core.im_name); - im->core.im_name = NULL; - } - if (im->private.local.ctom_conv) { - _XlcCloseConverter(im->private.local.ctom_conv); - im->private.local.ctom_conv = NULL; - } - if (im->private.local.ctow_conv) { - _XlcCloseConverter(im->private.local.ctow_conv); - im->private.local.ctow_conv = NULL; - } - if (im->private.local.ctoutf8_conv) { - _XlcCloseConverter(im->private.local.ctoutf8_conv); - im->private.local.ctoutf8_conv = NULL; - } - if (im->private.local.cstomb_conv) { - _XlcCloseConverter(im->private.local.cstomb_conv); - im->private.local.cstomb_conv = NULL; - } - if (im->private.local.cstowc_conv) { - _XlcCloseConverter(im->private.local.cstowc_conv); - im->private.local.cstowc_conv = NULL; - } - if (im->private.local.cstoutf8_conv) { - _XlcCloseConverter(im->private.local.cstoutf8_conv); - im->private.local.cstoutf8_conv = NULL; - } - if (im->private.local.ucstoc_conv) { - _XlcCloseConverter(im->private.local.ucstoc_conv); - im->private.local.ucstoc_conv = NULL; - } - if (im->private.local.ucstoutf8_conv) { - _XlcCloseConverter(im->private.local.ucstoutf8_conv); - im->private.local.ucstoutf8_conv = NULL; - } - return; -} - -Private Status -_XimLocalCloseIM( - XIM xim) -{ - Xim im = (Xim)xim; - XIC ic; - XIC next; - - ic = im->core.ic_chain; - im->core.ic_chain = NULL; - while (ic) { - (*ic->methods->destroy) (ic); - next = ic->core.next; - Xfree ((char *) ic); - ic = next; - } - _XimLocalIMFree(im); - _XimDestroyIMStructureList(im); - return(True); -} - -Public char * -_XimLocalGetIMValues( - XIM xim, - XIMArg *values) -{ - Xim im = (Xim)xim; - XimDefIMValues im_values; - - _XimGetCurrentIMValues(im, &im_values); - return(_XimGetIMValueData(im, (XPointer)&im_values, values, - im->core.im_resources, im->core.im_num_resources)); -} - -Public char * -_XimLocalSetIMValues( - XIM xim, - XIMArg *values) -{ - Xim im = (Xim)xim; - XimDefIMValues im_values; - char *name = (char *)NULL; - - _XimGetCurrentIMValues(im, &im_values); - name = _XimSetIMValueData(im, (XPointer)&im_values, values, - im->core.im_resources, im->core.im_num_resources); - _XimSetCurrentIMValues(im, &im_values); - return(name); -} - - -#ifdef COMPOSECACHE - -Private Bool -_XimReadCachedDefaultTree( - int fd_cache, - const char *name, - const char *encoding, - DTStructIndex size) -{ - struct _XimCacheStruct* m; - int namelen = strlen (name) + 1; - int encodinglen = strlen (encoding) + 1; - - m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0); - if (m == NULL || m == MAP_FAILED) - return False; - assert (m->id == XIM_CACHE_MAGIC); - assert (m->version == XIM_CACHE_VERSION); - if (size != m->size || - size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) { - fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding); - munmap (m, size); - return False; - } - if (strncmp (name, m->fname, namelen) != 0) { - /* m->fname may *not* be terminated - but who cares here */ - fprintf (stderr, "Filename hash clash - expected %s, got %s\n", - name, m->fname); - munmap (m, size); - return False; - } - if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) { - /* m->fname+namelen may *not* be terminated - but who cares here */ - fprintf (stderr, "Enoding hash clash - expected %s, got %s\n", - encoding, m->fname + namelen); - munmap (m, size); - return False; - } - _XimCache_mmap = m; - _XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree); - _XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb); - _XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc); - _XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8); - _XimCachedDefaultTreeBase.treeused = m->treeused; - _XimCachedDefaultTreeBase.mbused = m->mbused; - _XimCachedDefaultTreeBase.wcused = m->wcused; - _XimCachedDefaultTreeBase.utf8used = m->utf8used; - /* treesize etc. is ignored because only used during parsing */ - _XimCachedDefaultTreeRefcount = 0; -/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */ - return True; -} - -Private unsigned int strToHash ( - const char *name) -{ - unsigned int hash = 0; - while (*name) - hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++; - return hash % XIM_HASH_PRIME_2; -} - - -/* Returns read-only fd of cache file, -1 if none. - * Sets *res to cache filename if safe. Sets *size to file size of cache. */ -Private int _XimCachedFileName ( - const char *dir, const char *name, - const char *intname, const char *encoding, - uid_t uid, int isglobal, char **res, off_t *size) -{ - struct stat st_name, st; - int fd; - unsigned int len, hash, hash2; - struct _XimCacheStruct *m; - /* There are some races here with 'dir', but we are either in our own home - * or the global cache dir, and not inside some public writable dir */ -/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */ - if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode) - || stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid - || (st.st_mode & 0022) != 0000) { - *res = NULL; - return -1; - } - len = strlen (dir); - hash = strToHash (intname); - hash2 = strToHash (encoding); - *res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */ - - if (len == 0 || dir [len-1] != '/') - sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), - XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2); - else - sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(), - XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2); - -/* fprintf (stderr, "-> %s\n", *res); */ - if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1) - return -1; - - if (fstat (fd, &st) == -1) { - Xfree (*res); - *res = NULL; - close (fd); - return -1; - } - *size = st.st_size; - - if (! S_ISREG (st.st_mode) || st.st_uid != uid - || (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime - || (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) { - - close (fd); - if (unlink (*res) != 0) { - Xfree (*res); - *res = NULL; /* cache is not safe */ - } - return -1; - } - - m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE, - fd, 0); - if (m == NULL || m == MAP_FAILED) { - close (fd); - Xfree (*res); - *res = NULL; - return -1; - } - if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) { - munmap (m, sizeof (struct _XimCacheStruct)); - close (fd); - fprintf (stderr, "Ignoring broken XimCache %s\n", *res); - Xfree (*res); - *res = NULL; - return -1; - } - if (m->version != XIM_CACHE_VERSION) { - munmap (m, sizeof (struct _XimCacheStruct)); - close (fd); - if (unlink (*res) != 0) { - Xfree (*res); - *res = NULL; /* cache is not safe */ - } - return -1; - } - munmap (m, sizeof (struct _XimCacheStruct)); - - return fd; -} - - -Private Bool _XimLoadCache ( - int fd, - const char *name, - const char *encoding, - off_t size, - Xim im) -{ - if (_XimCache_mmap || - _XimReadCachedDefaultTree (fd, name, encoding, size)) { - _XimCachedDefaultTreeRefcount++; - memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase, - sizeof (_XimCachedDefaultTreeBase)); - im->private.local.top = _XimCache_mmap->top; - return True; - } - - return False; -} - - -Private void -_XimWriteCachedDefaultTree( - const char *name, - const char *encoding, - const char *cachename, - Xim im) -{ - int fd; - FILE *fp; - struct _XimCacheStruct *m; - int msize = (XOffsetOf(struct _XimCacheStruct, fname) - + strlen(name) + strlen(encoding) + 2 - + XIM_CACHE_TREE_ALIGNMENT-1) & -XIM_CACHE_TREE_ALIGNMENT; - DefTreeBase *b = &im->private.local.base; - - if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) ) - return; - if (! b->mb && ! (b->mb = Xmalloc (1)) ) - return; - if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) ) - return; - if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) ) - return; - - /* First entry is always unused */ - memset (b->tree, 0, sizeof(DefTree)); - b->mb[0] = 0; - b->wc[0] = 0; - b->utf8[0] = 0; - - m = Xmalloc (msize); - memset (m, 0, msize); - m->id = XIM_CACHE_MAGIC; - m->version = XIM_CACHE_VERSION; - m->top = im->private.local.top; - m->treeused = b->treeused; - m->mbused = b->mbused; - m->wcused = b->wcused; - m->utf8used = b->utf8used; - /* Tree first, then wide chars, then the rest due to alignment */ - m->tree = msize; - m->wc = msize + sizeof (DefTree) * m->treeused; - m->mb = m->wc + sizeof (wchar_t) * m->wcused; - m->utf8 = m->mb + m->mbused; - m->size = m->utf8 + m->utf8used; - strcpy (m->fname, name); - strcpy (m->fname+strlen(name)+1, encoding); - - /* This STILL might be racy on NFS */ - if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL, - 0600)) < 0) { - Xfree(m); - return; - } - if (! (fp = fdopen (fd, "wb")) ) { - close (fd); - Xfree(m); - return; - } - fwrite (m, msize, 1, fp); - fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp); - fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp); - fwrite (im->private.local.base.mb, 1, m->mbused, fp); - fwrite (im->private.local.base.utf8, 1, m->utf8used, fp); - if (fclose (fp) != 0) - unlink (cachename); - _XimCache_mmap = m; - memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base, - sizeof (_XimCachedDefaultTreeBase)); -/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */ -} - -#endif - - -Private void -_XimCreateDefaultTree( - Xim im) -{ - FILE *fp = NULL; - char *name, *tmpname = NULL, *intname; - char *cachename = NULL; - /* Should use getpwent() instead of $HOME (cross-platform?) */ - char *home = getenv("HOME"); - char *cachedir = NULL; - char *tmpcachedir = NULL; - int hl = home ? strlen (home) : 0; -#ifdef COMPOSECACHE - const char *encoding = nl_langinfo (CODESET); - uid_t euid = geteuid (); - gid_t egid = getegid (); - int cachefd = -1; - off_t size; -#endif - - name = getenv("XCOMPOSEFILE"); - if (name == (char *) NULL) { - if (home != (char *) NULL) { - tmpname = name = Xmalloc(hl + 10 + 1); - if (name != (char *) NULL) { - int fd; - strcpy(name, home); - strcpy(name + hl, "/.XCompose"); - if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) { - Xfree (name); - name = tmpname = NULL; - } else - close (fd); - } - } - } - - if (name == (char *) NULL) { - tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE); - } - intname = name; - -#ifdef COMPOSECACHE - if (getuid () == euid && getgid () == egid && euid != 0) { - char *c; - /* Usage: XCOMPOSECACHE=<cachedir>[=<filename>] - * cachedir: directory of cache files - * filename: internally used name for cache file */ - cachedir = getenv("XCOMPOSECACHE"); - if (cachedir && (c = strchr (cachedir, '='))) { - tmpcachedir = strdup (cachedir); - intname = tmpcachedir + (c-cachedir) + 1; - tmpcachedir[c-cachedir] = '\0'; - cachedir = tmpcachedir; - } - } - - if (! cachedir) { - cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname, - encoding, 0, 1, &cachename, &size); - if (cachefd != -1) { - if (_XimLoadCache (cachefd, intname, encoding, size, im)) { - if (tmpcachedir) - Xfree (tmpcachedir); - if (tmpname) - Xfree (tmpname); - if (cachename) - Xfree (cachename); - close (cachefd); - return; - } - close (cachefd); - } - if (cachename) - Xfree (cachename); - cachename = NULL; - } - - if (getuid () == euid && getgid () == egid && euid != 0 && home) { - - if (! cachedir) { - tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1); - strcpy (cachedir, home); - strcat (cachedir, XIM_HOME_CACHE_DIR); - } - cachefd = _XimCachedFileName (cachedir, name, intname, encoding, - euid, 0, &cachename, &size); - if (cachefd != -1) { - if (_XimLoadCache (cachefd, intname, encoding, size, im)) { - if (tmpcachedir) - Xfree (tmpcachedir); - if (tmpname) - Xfree (tmpname); - if (cachename) - Xfree (cachename); - close (cachefd); - return; - } - close (cachefd); - } - } -#endif - - if (! (fp = _XFopenFile (name, "r"))) { - if (tmpcachedir) - Xfree (tmpcachedir); - if (tmpname) - Xfree (tmpname); - if (cachename) - Xfree (cachename); - return; - } - _XimParseStringFile(fp, im); - fclose(fp); - -#ifdef COMPOSECACHE - if (cachename) { - assert (euid != 0); - _XimWriteCachedDefaultTree (intname, encoding, cachename, im); - } -#endif - - if (tmpcachedir) - Xfree (tmpcachedir); - if (tmpname) - Xfree (tmpname); - if (cachename) - Xfree (cachename); -} - -Private XIMMethodsRec Xim_im_local_methods = { - _XimLocalCloseIM, /* close */ - _XimLocalSetIMValues, /* set_values */ - _XimLocalGetIMValues, /* get_values */ - _XimLocalCreateIC, /* create_ic */ - _XimLcctstombs, /* ctstombs */ - _XimLcctstowcs, /* ctstowcs */ - _XimLcctstoutf8 /* ctstoutf8 */ -}; - -Public Bool -_XimLocalOpenIM( - Xim im) -{ - XLCd lcd = im->core.lcd; - XlcConv conv; - XimDefIMValues im_values; - XimLocalPrivateRec* private = &im->private.local; - - _XimInitialResourceInfo(); - if(_XimSetIMResourceList(&im->core.im_resources, - &im->core.im_num_resources) == False) { - goto Open_Error; - } - if(_XimSetICResourceList(&im->core.ic_resources, - &im->core.ic_num_resources) == False) { - goto Open_Error; - } - - _XimSetIMMode(im->core.im_resources, im->core.im_num_resources); - - _XimGetCurrentIMValues(im, &im_values); - if(_XimSetLocalIMDefaults(im, (XPointer)&im_values, - im->core.im_resources, im->core.im_num_resources) == False) { - goto Open_Error; - } - _XimSetCurrentIMValues(im, &im_values); - - if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte))) - goto Open_Error; - private->ctom_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar))) - goto Open_Error; - private->ctow_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String))) - goto Open_Error; - private->ctoutf8_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte))) - goto Open_Error; - private->cstomb_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar))) - goto Open_Error; - private->cstowc_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String))) - goto Open_Error; - private->cstoutf8_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar))) - goto Open_Error; - private->ucstoc_conv = conv; - - if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String))) - goto Open_Error; - private->ucstoutf8_conv = conv; - - private->base.treeused = 1; - private->base.mbused = 1; - private->base.wcused = 1; - private->base.utf8used = 1; - - _XimCreateDefaultTree(im); - - im->methods = &Xim_im_local_methods; - private->current_ic = (XIC)NULL; - - return(True); - -Open_Error : - _XimLocalIMFree(im); - return(False); -} +/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+ Copyright 1993 by Digital Equipment Corporation
+
+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 FUJITSU LIMITED and
+Digital Equipment Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission. FUJITSU LIMITED and Digital Equipment Corporation
+makes no representations about the suitability of this software for
+any purpose. It is provided "as is" without express or implied
+warranty.
+
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Modifier: Franky Ling Digital Equipment Corporation
+ frankyling@hgrd01.enet.dec.com
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+
+#include <X11/Xmd.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcPublic.h"
+#include "XlcPubI.h"
+#include "Ximint.h"
+#include <ctype.h>
+#include <assert.h>
+
+#ifdef COMPOSECACHE
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/mman.h>
+# include <langinfo.h>
+#endif
+
+
+#ifdef COMPOSECACHE
+
+/* include trailing '/' for cache directory, file prefix otherwise */
+#define XIM_GLOBAL_CACHE_DIR "/var/cache/libx11/compose/"
+#define XIM_HOME_CACHE_DIR "/.compose-cache/"
+#define XIM_CACHE_MAGIC ('X' | 'i'<<8 | 'm'<<16 | 'C'<<24)
+#define XIM_CACHE_VERSION 4
+#define XIM_CACHE_TREE_ALIGNMENT 4
+
+#define XIM_HASH_PRIME_1 13
+#define XIM_HASH_PRIME_2 1234096939
+
+typedef INT32 DTStructIndex;
+struct _XimCacheStruct {
+ INT32 id;
+ INT32 version;
+ DTStructIndex tree;
+ DTStructIndex mb;
+ DTStructIndex wc;
+ DTStructIndex utf8;
+ DTStructIndex size;
+ DTIndex top;
+ DTIndex treeused;
+ DTCharIndex mbused;
+ DTCharIndex wcused;
+ DTCharIndex utf8used;
+ char fname[1];
+ /* char encoding[1] */
+};
+
+Private struct _XimCacheStruct* _XimCache_mmap = NULL;
+Private DefTreeBase _XimCachedDefaultTreeBase;
+Private int _XimCachedDefaultTreeRefcount = 0;
+
+#endif
+
+
+Public Bool
+_XimCheckIfLocalProcessing(Xim im)
+{
+ FILE *fp;
+ char *name;
+
+ if(strcmp(im->core.im_name, "") == 0) {
+ name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
+ if (name != (char *)NULL) {
+ fp = _XFopenFile (name, "r");
+ Xfree(name);
+ if (fp != (FILE *)NULL) {
+ fclose(fp);
+ return(True);
+ }
+ }
+ return(False);
+ } else if(strcmp(im->core.im_name, "local") == 0 ||
+ strcmp(im->core.im_name, "none" ) == 0 ) {
+ return(True);
+ }
+ return(False);
+}
+
+Private void
+XimFreeDefaultTree(
+ DefTreeBase *b)
+{
+ if (!b) return;
+ if (b->tree == NULL) return;
+#ifdef COMPOSECACHE
+ if (b->tree == _XimCachedDefaultTreeBase.tree) {
+ _XimCachedDefaultTreeRefcount--;
+ /* No deleting, it's a cache after all. */
+ return;
+ }
+#endif
+ Xfree (b->tree);
+ if (b->mb) Xfree (b->mb);
+ if (b->wc) Xfree (b->wc);
+ if (b->utf8) Xfree (b->utf8);
+ b->tree = NULL;
+ b->mb = NULL;
+ b->wc = NULL;
+ b->utf8 = NULL;
+ b->treeused = b->treesize = 0;
+ b->mbused = b->mbsize = 0;
+ b->wcused = b->wcsize = 0;
+ b->utf8used = b->utf8size = 0;
+}
+
+Public void
+_XimLocalIMFree(
+ Xim im)
+{
+ XimFreeDefaultTree(&im->private.local.base);
+ im->private.local.top = 0;
+
+ if(im->core.im_resources) {
+ Xfree(im->core.im_resources);
+ im->core.im_resources = NULL;
+ }
+ if(im->core.ic_resources) {
+ Xfree(im->core.ic_resources);
+ im->core.ic_resources = NULL;
+ }
+ if(im->core.im_values_list) {
+ Xfree(im->core.im_values_list);
+ im->core.im_values_list = NULL;
+ }
+ if(im->core.ic_values_list) {
+ Xfree(im->core.ic_values_list);
+ im->core.ic_values_list = NULL;
+ }
+ if(im->core.styles) {
+ Xfree(im->core.styles);
+ im->core.styles = NULL;
+ }
+ if(im->core.res_name) {
+ Xfree(im->core.res_name);
+ im->core.res_name = NULL;
+ }
+ if(im->core.res_class) {
+ Xfree(im->core.res_class);
+ im->core.res_class = NULL;
+ }
+ if(im->core.im_name) {
+ Xfree(im->core.im_name);
+ im->core.im_name = NULL;
+ }
+ if (im->private.local.ctom_conv) {
+ _XlcCloseConverter(im->private.local.ctom_conv);
+ im->private.local.ctom_conv = NULL;
+ }
+ if (im->private.local.ctow_conv) {
+ _XlcCloseConverter(im->private.local.ctow_conv);
+ im->private.local.ctow_conv = NULL;
+ }
+ if (im->private.local.ctoutf8_conv) {
+ _XlcCloseConverter(im->private.local.ctoutf8_conv);
+ im->private.local.ctoutf8_conv = NULL;
+ }
+ if (im->private.local.cstomb_conv) {
+ _XlcCloseConverter(im->private.local.cstomb_conv);
+ im->private.local.cstomb_conv = NULL;
+ }
+ if (im->private.local.cstowc_conv) {
+ _XlcCloseConverter(im->private.local.cstowc_conv);
+ im->private.local.cstowc_conv = NULL;
+ }
+ if (im->private.local.cstoutf8_conv) {
+ _XlcCloseConverter(im->private.local.cstoutf8_conv);
+ im->private.local.cstoutf8_conv = NULL;
+ }
+ if (im->private.local.ucstoc_conv) {
+ _XlcCloseConverter(im->private.local.ucstoc_conv);
+ im->private.local.ucstoc_conv = NULL;
+ }
+ if (im->private.local.ucstoutf8_conv) {
+ _XlcCloseConverter(im->private.local.ucstoutf8_conv);
+ im->private.local.ucstoutf8_conv = NULL;
+ }
+ return;
+}
+
+Private Status
+_XimLocalCloseIM(
+ XIM xim)
+{
+ Xim im = (Xim)xim;
+ XIC ic;
+ XIC next;
+
+ ic = im->core.ic_chain;
+ im->core.ic_chain = NULL;
+ while (ic) {
+ (*ic->methods->destroy) (ic);
+ next = ic->core.next;
+ Xfree ((char *) ic);
+ ic = next;
+ }
+ _XimLocalIMFree(im);
+ _XimDestroyIMStructureList(im);
+ return(True);
+}
+
+Public char *
+_XimLocalGetIMValues(
+ XIM xim,
+ XIMArg *values)
+{
+ Xim im = (Xim)xim;
+ XimDefIMValues im_values;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ return(_XimGetIMValueData(im, (XPointer)&im_values, values,
+ im->core.im_resources, im->core.im_num_resources));
+}
+
+Public char *
+_XimLocalSetIMValues(
+ XIM xim,
+ XIMArg *values)
+{
+ Xim im = (Xim)xim;
+ XimDefIMValues im_values;
+ char *name = (char *)NULL;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ name = _XimSetIMValueData(im, (XPointer)&im_values, values,
+ im->core.im_resources, im->core.im_num_resources);
+ _XimSetCurrentIMValues(im, &im_values);
+ return(name);
+}
+
+
+#ifdef COMPOSECACHE
+
+Private Bool
+_XimReadCachedDefaultTree(
+ int fd_cache,
+ const char *name,
+ const char *encoding,
+ DTStructIndex size)
+{
+ struct _XimCacheStruct* m;
+ int namelen = strlen (name) + 1;
+ int encodinglen = strlen (encoding) + 1;
+
+ m = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd_cache, 0);
+ if (m == NULL || m == MAP_FAILED)
+ return False;
+ assert (m->id == XIM_CACHE_MAGIC);
+ assert (m->version == XIM_CACHE_VERSION);
+ if (size != m->size ||
+ size < XOffsetOf (struct _XimCacheStruct, fname) + namelen + encodinglen) {
+ fprintf (stderr, "Ignoring broken XimCache %s [%s]\n", name, encoding);
+ munmap (m, size);
+ return False;
+ }
+ if (strncmp (name, m->fname, namelen) != 0) {
+ /* m->fname may *not* be terminated - but who cares here */
+ fprintf (stderr, "Filename hash clash - expected %s, got %s\n",
+ name, m->fname);
+ munmap (m, size);
+ return False;
+ }
+ if (strncmp (encoding, m->fname + namelen, encodinglen) != 0) {
+ /* m->fname+namelen may *not* be terminated - but who cares here */
+ fprintf (stderr, "Enoding hash clash - expected %s, got %s\n",
+ encoding, m->fname + namelen);
+ munmap (m, size);
+ return False;
+ }
+ _XimCache_mmap = m;
+ _XimCachedDefaultTreeBase.tree = (DefTree *) (((char *) m) + m->tree);
+ _XimCachedDefaultTreeBase.mb = (((char *) m) + m->mb);
+ _XimCachedDefaultTreeBase.wc = (wchar_t *) (((char *) m) + m->wc);
+ _XimCachedDefaultTreeBase.utf8 = (((char *) m) + m->utf8);
+ _XimCachedDefaultTreeBase.treeused = m->treeused;
+ _XimCachedDefaultTreeBase.mbused = m->mbused;
+ _XimCachedDefaultTreeBase.wcused = m->wcused;
+ _XimCachedDefaultTreeBase.utf8used = m->utf8used;
+ /* treesize etc. is ignored because only used during parsing */
+ _XimCachedDefaultTreeRefcount = 0;
+/* fprintf (stderr, "read cached tree at %p: %s\n", (void *) m, name); */
+ return True;
+}
+
+Private unsigned int strToHash (
+ const char *name)
+{
+ unsigned int hash = 0;
+ while (*name)
+ hash = hash * XIM_HASH_PRIME_1 + *(unsigned const char *)name++;
+ return hash % XIM_HASH_PRIME_2;
+}
+
+
+/* Returns read-only fd of cache file, -1 if none.
+ * Sets *res to cache filename if safe. Sets *size to file size of cache. */
+Private int _XimCachedFileName (
+ const char *dir, const char *name,
+ const char *intname, const char *encoding,
+ uid_t uid, int isglobal, char **res, off_t *size)
+{
+ struct stat st_name, st;
+ int fd;
+ unsigned int len, hash, hash2;
+ struct _XimCacheStruct *m;
+ /* There are some races here with 'dir', but we are either in our own home
+ * or the global cache dir, and not inside some public writable dir */
+/* fprintf (stderr, "XimCachedFileName for dir %s name %s intname %s encoding %s uid %d\n", dir, name, intname, encoding, uid); */
+ if (stat (name, &st_name) == -1 || ! S_ISREG (st_name.st_mode)
+ || stat (dir, &st) == -1 || ! S_ISDIR (st.st_mode) || st.st_uid != uid
+ || (st.st_mode & 0022) != 0000) {
+ *res = NULL;
+ return -1;
+ }
+ len = strlen (dir);
+ hash = strToHash (intname);
+ hash2 = strToHash (encoding);
+ *res = Xmalloc (len + 1 + 27 + 1); /* Max VERSION 9999 */
+
+ if (len == 0 || dir [len-1] != '/')
+ sprintf (*res, "%s/%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
+ XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2);
+ else
+ sprintf (*res, "%s%c%d_%03x_%08x_%08x", dir, _XimGetMyEndian(),
+ XIM_CACHE_VERSION, (unsigned int)sizeof (DefTree), hash, hash2);
+
+/* fprintf (stderr, "-> %s\n", *res); */
+ if ( (fd = _XOpenFile (*res, O_RDONLY)) == -1)
+ return -1;
+
+ if (fstat (fd, &st) == -1) {
+ Xfree (*res);
+ *res = NULL;
+ close (fd);
+ return -1;
+ }
+ *size = st.st_size;
+
+ if (! S_ISREG (st.st_mode) || st.st_uid != uid
+ || (st.st_mode & 0022) != 0000 || st.st_mtime <= st_name.st_mtime
+ || (st.st_mtime < time (NULL) - 24*60*60 && ! isglobal)) {
+
+ close (fd);
+ if (unlink (*res) != 0) {
+ Xfree (*res);
+ *res = NULL; /* cache is not safe */
+ }
+ return -1;
+ }
+
+ m = mmap (NULL, sizeof (struct _XimCacheStruct), PROT_READ, MAP_PRIVATE,
+ fd, 0);
+ if (m == NULL || m == MAP_FAILED) {
+ close (fd);
+ Xfree (*res);
+ *res = NULL;
+ return -1;
+ }
+ if (*size < sizeof (struct _XimCacheStruct) || m->id != XIM_CACHE_MAGIC) {
+ munmap (m, sizeof (struct _XimCacheStruct));
+ close (fd);
+ fprintf (stderr, "Ignoring broken XimCache %s\n", *res);
+ Xfree (*res);
+ *res = NULL;
+ return -1;
+ }
+ if (m->version != XIM_CACHE_VERSION) {
+ munmap (m, sizeof (struct _XimCacheStruct));
+ close (fd);
+ if (unlink (*res) != 0) {
+ Xfree (*res);
+ *res = NULL; /* cache is not safe */
+ }
+ return -1;
+ }
+ munmap (m, sizeof (struct _XimCacheStruct));
+
+ return fd;
+}
+
+
+Private Bool _XimLoadCache (
+ int fd,
+ const char *name,
+ const char *encoding,
+ off_t size,
+ Xim im)
+{
+ if (_XimCache_mmap ||
+ _XimReadCachedDefaultTree (fd, name, encoding, size)) {
+ _XimCachedDefaultTreeRefcount++;
+ memcpy (&im->private.local.base, &_XimCachedDefaultTreeBase,
+ sizeof (_XimCachedDefaultTreeBase));
+ im->private.local.top = _XimCache_mmap->top;
+ return True;
+ }
+
+ return False;
+}
+
+
+Private void
+_XimWriteCachedDefaultTree(
+ const char *name,
+ const char *encoding,
+ const char *cachename,
+ Xim im)
+{
+ int fd;
+ FILE *fp;
+ struct _XimCacheStruct *m;
+ int msize = (XOffsetOf(struct _XimCacheStruct, fname)
+ + strlen(name) + strlen(encoding) + 2
+ + XIM_CACHE_TREE_ALIGNMENT-1) & -XIM_CACHE_TREE_ALIGNMENT;
+ DefTreeBase *b = &im->private.local.base;
+
+ if (! b->tree && ! (b->tree = Xmalloc (sizeof(DefTree))) )
+ return;
+ if (! b->mb && ! (b->mb = Xmalloc (1)) )
+ return;
+ if (! b->wc && ! (b->wc = Xmalloc (sizeof(wchar_t))) )
+ return;
+ if (! b->utf8 && ! (b->utf8 = Xmalloc (1)) )
+ return;
+
+ /* First entry is always unused */
+ memset (b->tree, 0, sizeof(DefTree));
+ b->mb[0] = 0;
+ b->wc[0] = 0;
+ b->utf8[0] = 0;
+
+ m = Xmalloc (msize);
+ memset (m, 0, msize);
+ m->id = XIM_CACHE_MAGIC;
+ m->version = XIM_CACHE_VERSION;
+ m->top = im->private.local.top;
+ m->treeused = b->treeused;
+ m->mbused = b->mbused;
+ m->wcused = b->wcused;
+ m->utf8used = b->utf8used;
+ /* Tree first, then wide chars, then the rest due to alignment */
+ m->tree = msize;
+ m->wc = msize + sizeof (DefTree) * m->treeused;
+ m->mb = m->wc + sizeof (wchar_t) * m->wcused;
+ m->utf8 = m->mb + m->mbused;
+ m->size = m->utf8 + m->utf8used;
+ strcpy (m->fname, name);
+ strcpy (m->fname+strlen(name)+1, encoding);
+
+ /* This STILL might be racy on NFS */
+ if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL,
+ 0600)) < 0) {
+ Xfree(m);
+ return;
+ }
+ if (! (fp = fdopen (fd, "wb")) ) {
+ close (fd);
+ Xfree(m);
+ return;
+ }
+ fwrite (m, msize, 1, fp);
+ fwrite (im->private.local.base.tree, sizeof(DefTree), m->treeused, fp);
+ fwrite (im->private.local.base.wc, sizeof(wchar_t), m->wcused, fp);
+ fwrite (im->private.local.base.mb, 1, m->mbused, fp);
+ fwrite (im->private.local.base.utf8, 1, m->utf8used, fp);
+ if (fclose (fp) != 0)
+ unlink (cachename);
+ _XimCache_mmap = m;
+ memcpy (&_XimCachedDefaultTreeBase, &im->private.local.base,
+ sizeof (_XimCachedDefaultTreeBase));
+/* fprintf (stderr, "wrote tree %s size %ld to %s\n", name, m->size, cachename); */
+}
+
+#endif
+
+
+Private void
+_XimCreateDefaultTree(
+ Xim im)
+{
+ FILE *fp = NULL;
+ char *name, *tmpname = NULL, *intname;
+ char *cachename = NULL;
+ /* Should use getpwent() instead of $HOME (cross-platform?) */
+ char *home = getenv("HOME");
+ char *cachedir = NULL;
+ char *tmpcachedir = NULL;
+ int hl = home ? strlen (home) : 0;
+#ifdef COMPOSECACHE
+ const char *encoding = nl_langinfo (CODESET);
+ uid_t euid = geteuid ();
+ gid_t egid = getegid ();
+ int cachefd = -1;
+ off_t size;
+#endif
+
+ name = getenv("XCOMPOSEFILE");
+ if (name == (char *) NULL) {
+ if (home != (char *) NULL) {
+ tmpname = name = Xmalloc(hl + 10 + 1);
+ if (name != (char *) NULL) {
+ int fd;
+ strcpy(name, home);
+ strcpy(name + hl, "/.XCompose");
+ if ( (fd = _XOpenFile (name, O_RDONLY)) < 0) {
+ Xfree (name);
+ name = tmpname = NULL;
+ } else
+ close (fd);
+ }
+ }
+ }
+
+ if (name == (char *) NULL) {
+ tmpname = name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
+ }
+ intname = name;
+
+#ifdef COMPOSECACHE
+ if (getuid () == euid && getgid () == egid && euid != 0) {
+ char *c;
+ /* Usage: XCOMPOSECACHE=<cachedir>[=<filename>]
+ * cachedir: directory of cache files
+ * filename: internally used name for cache file */
+ cachedir = getenv("XCOMPOSECACHE");
+ if (cachedir && (c = strchr (cachedir, '='))) {
+ tmpcachedir = strdup (cachedir);
+ intname = tmpcachedir + (c-cachedir) + 1;
+ tmpcachedir[c-cachedir] = '\0';
+ cachedir = tmpcachedir;
+ }
+ }
+
+ if (! cachedir) {
+ cachefd = _XimCachedFileName (XIM_GLOBAL_CACHE_DIR, name, intname,
+ encoding, 0, 1, &cachename, &size);
+ if (cachefd != -1) {
+ if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
+ if (tmpcachedir)
+ Xfree (tmpcachedir);
+ if (tmpname)
+ Xfree (tmpname);
+ if (cachename)
+ Xfree (cachename);
+ close (cachefd);
+ return;
+ }
+ close (cachefd);
+ }
+ if (cachename)
+ Xfree (cachename);
+ cachename = NULL;
+ }
+
+ if (getuid () == euid && getgid () == egid && euid != 0 && home) {
+
+ if (! cachedir) {
+ tmpcachedir = cachedir = Xmalloc (hl+strlen(XIM_HOME_CACHE_DIR)+1);
+ strcpy (cachedir, home);
+ strcat (cachedir, XIM_HOME_CACHE_DIR);
+ }
+ cachefd = _XimCachedFileName (cachedir, name, intname, encoding,
+ euid, 0, &cachename, &size);
+ if (cachefd != -1) {
+ if (_XimLoadCache (cachefd, intname, encoding, size, im)) {
+ if (tmpcachedir)
+ Xfree (tmpcachedir);
+ if (tmpname)
+ Xfree (tmpname);
+ if (cachename)
+ Xfree (cachename);
+ close (cachefd);
+ return;
+ }
+ close (cachefd);
+ }
+ }
+#endif
+
+ if (! (fp = _XFopenFile (name, "r"))) {
+ if (tmpcachedir)
+ Xfree (tmpcachedir);
+ if (tmpname)
+ Xfree (tmpname);
+ if (cachename)
+ Xfree (cachename);
+ return;
+ }
+ _XimParseStringFile(fp, im);
+ fclose(fp);
+
+#ifdef COMPOSECACHE
+ if (cachename) {
+ assert (euid != 0);
+ _XimWriteCachedDefaultTree (intname, encoding, cachename, im);
+ }
+#endif
+
+ if (tmpcachedir)
+ Xfree (tmpcachedir);
+ if (tmpname)
+ Xfree (tmpname);
+ if (cachename)
+ Xfree (cachename);
+}
+
+Private XIMMethodsRec Xim_im_local_methods = {
+ _XimLocalCloseIM, /* close */
+ _XimLocalSetIMValues, /* set_values */
+ _XimLocalGetIMValues, /* get_values */
+ _XimLocalCreateIC, /* create_ic */
+ _XimLcctstombs, /* ctstombs */
+ _XimLcctstowcs, /* ctstowcs */
+ _XimLcctstoutf8 /* ctstoutf8 */
+};
+
+Public Bool
+_XimLocalOpenIM(
+ Xim im)
+{
+ XLCd lcd = im->core.lcd;
+ XlcConv conv;
+ XimDefIMValues im_values;
+ XimLocalPrivateRec* private = &im->private.local;
+
+ _XimInitialResourceInfo();
+ if(_XimSetIMResourceList(&im->core.im_resources,
+ &im->core.im_num_resources) == False) {
+ goto Open_Error;
+ }
+ if(_XimSetICResourceList(&im->core.ic_resources,
+ &im->core.ic_num_resources) == False) {
+ goto Open_Error;
+ }
+
+ _XimSetIMMode(im->core.im_resources, im->core.im_num_resources);
+
+ _XimGetCurrentIMValues(im, &im_values);
+ if(_XimSetLocalIMDefaults(im, (XPointer)&im_values,
+ im->core.im_resources, im->core.im_num_resources) == False) {
+ goto Open_Error;
+ }
+ _XimSetCurrentIMValues(im, &im_values);
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte)))
+ goto Open_Error;
+ private->ctom_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar)))
+ goto Open_Error;
+ private->ctow_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCompoundText, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->ctoutf8_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte)))
+ goto Open_Error;
+ private->cstomb_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNWideChar)))
+ goto Open_Error;
+ private->cstowc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNCharSet, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->cstoutf8_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNChar)))
+ goto Open_Error;
+ private->ucstoc_conv = conv;
+
+ if (!(conv = _XlcOpenConverter(lcd, XlcNUcsChar, lcd, XlcNUtf8String)))
+ goto Open_Error;
+ private->ucstoutf8_conv = conv;
+
+ private->base.treeused = 1;
+ private->base.mbused = 1;
+ private->base.wcused = 1;
+ private->base.utf8used = 1;
+
+ _XimCreateDefaultTree(im);
+
+ im->methods = &Xim_im_local_methods;
+ private->current_ic = (XIC)NULL;
+
+ return(True);
+
+Open_Error :
+ _XimLocalIMFree(im);
+ return(False);
+}
diff --git a/libX11/modules/im/ximcp/imLcLkup.c b/libX11/modules/im/ximcp/imLcLkup.c index 8e4111a6a..c62a9106c 100644 --- a/libX11/modules/im/ximcp/imLcLkup.c +++ b/libX11/modules/im/ximcp/imLcLkup.c @@ -1,417 +1,417 @@ -/****************************************************************** - - Copyright 1992 by Fuji Xerox Co., Ltd. - Copyright 1992, 1994 by FUJITSU LIMITED - -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 Fuji Xerox, -FUJITSU LIMITED not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. Fuji Xerox, FUJITSU LIMITED make no representations -about the suitability of this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX, -FUJITSU LIMITED 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. - - Author: Kazunori Nishihara Fuji Xerox - Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xatom.h> -#include <X11/Xos.h> -#include <X11/Xlib.h> -#include <X11/keysym.h> -#include <X11/Xutil.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "XlcPubI.h" -#include "Ximint.h" - -Public int -_XimLocalMbLookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes, - KeySym *keysym, Status *status) -{ - Xic ic = (Xic)xic; - int ret; - DefTree *b = ic->private.local.base.tree; - char *mb = ic->private.local.base.mb; - - if(ev->type != KeyPress) { - if(status) *status = XLookupNone; - return(0); - } - if(ev->keycode == 0 && - ( (ic->private.local.composed != 0) - ||(ic->private.local.brl_committed != 0))) { - if (ic->private.local.brl_committed != 0) { /* Braille Event */ - unsigned char pattern = ic->private.local.brl_committed; - char mb[XLC_PUBLIC(ic->core.im->core.lcd, mb_cur_max)]; - ret = _Xlcwctomb(ic->core.im->core.lcd, mb, BRL_UC_ROW | pattern); - if(ret > bytes) { - if(status) *status = XBufferOverflow; - return(ret); - } - if(keysym) *keysym = XK_braille_blank | pattern; - if(ret > 0) { - if (keysym) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - memcpy(buffer, mb, ret); - } else { - if(keysym) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } else { /* Composed Event */ - ret = strlen(&mb[b[ic->private.local.composed].mb]); - if(ret > bytes) { - if(status) *status = XBufferOverflow; - return(ret); - } - memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret); - if(keysym) *keysym = b[ic->private.local.composed].ks; - if (ret > 0) { - if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); - } else { /* Throughed Event */ - ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL); - if(ret > 0) { - if (ret > bytes) { - if (status) *status = XBufferOverflow; - } else if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); -} - -Public int -_XimLocalWcLookupString(XIC xic, XKeyEvent *ev, wchar_t *buffer, int wlen, - KeySym *keysym, Status *status) -{ - Xic ic = (Xic)xic; - int ret; - DefTree *b = ic->private.local.base.tree; - wchar_t *wc = ic->private.local.base.wc; - - if(ev->type != KeyPress) { - if(status) *status = XLookupNone; - return(0); - } - if(ev->keycode == 0) { - if (ic->private.local.brl_committed != 0) { /* Braille Event */ - unsigned char pattern = ic->private.local.brl_committed; - ret = 1; - if (ret > wlen) { - if(status) *status = XBufferOverflow; - return (ret); - } - *buffer = BRL_UC_ROW | pattern; - if(keysym) { - *keysym = XK_braille_blank | pattern; - if(status) *status = XLookupBoth; - } else - if(status) *status = XLookupChars; - } else { /* Composed Event */ - ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]); - if(ret > wlen) { - if(status) *status = XBufferOverflow; - return (ret); - } - memcpy((char *)buffer, (char *)&wc[b[ic->private.local.composed].wc], - ret * sizeof(wchar_t)); - if(keysym) *keysym = b[ic->private.local.composed].ks; - if (ret > 0) { - if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); - } else { /* Throughed Event */ - ret = _XimLookupWCText(ic, ev, buffer, wlen, keysym, NULL); - if(ret > 0) { - if (ret > wlen) { - if (status) *status = XBufferOverflow; - } else if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); -} - -Public int -_XimLocalUtf8LookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes, - KeySym *keysym, Status *status) -{ - Xic ic = (Xic)xic; - int ret; - DefTree *b = ic->private.local.base.tree; - char *utf8 = ic->private.local.base.utf8; - - if(ev->type != KeyPress) { - if(status) *status = XLookupNone; - return(0); - } - if(ev->keycode == 0) { - if (ic->private.local.brl_committed != 0) { /* Braille Event */ - unsigned char pattern = ic->private.local.brl_committed; - ret = 3; - if (ret > bytes) { - if(status) *status = XBufferOverflow; - return (ret); - } - buffer[0] = 0xe0 | ((BRL_UC_ROW >> 12) & 0x0f); - buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6); - buffer[2] = 0x80 | (pattern & 0x3f); - if(keysym) { - *keysym = XK_braille_blank | pattern; - if(status) *status = XLookupBoth; - } else - if(status) *status = XLookupChars; - } else { /* Composed Event */ - ret = strlen(&utf8[b[ic->private.local.composed].utf8]); - if(ret > bytes) { - if(status) *status = XBufferOverflow; - return (ret); - } - memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret); - if(keysym) *keysym = b[ic->private.local.composed].ks; - if (ret > 0) { - if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); - } else { /* Throughed Event */ - ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL); - if(ret > 0) { - if (ret > bytes) { - if (status) *status = XBufferOverflow; - } else if (keysym && *keysym != NoSymbol) { - if(status) *status = XLookupBoth; - } else { - if(status) *status = XLookupChars; - } - } else { - if(keysym && *keysym != NoSymbol) { - if(status) *status = XLookupKeySym; - } else { - if(status) *status = XLookupNone; - } - } - } - return (ret); -} - -Private int -_XimLcctsconvert( - XlcConv conv, - char *from, - int from_len, - char *to, - int to_len, - Status *state) -{ - int from_left; - int to_left; - int from_savelen; - int to_savelen; - int from_cnvlen; - int to_cnvlen; - char *from_buf; - char *to_buf; - char scratchbuf[BUFSIZ]; - Status tmp_state; - - if (!state) - state = &tmp_state; - - if (!conv || !from || !from_len) { - *state = XLookupNone; - return 0; - } - - /* Reset the converter. The CompoundText at 'from' starts in - initial state. */ - _XlcResetConverter(conv); - - from_left = from_len; - to_left = BUFSIZ; - from_cnvlen = 0; - to_cnvlen = 0; - for (;;) { - from_buf = &from[from_cnvlen]; - from_savelen = from_left; - to_buf = &scratchbuf[to_cnvlen]; - to_savelen = to_left; - if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, - (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { - *state = XLookupNone; - return 0; - } - from_cnvlen += (from_savelen - from_left); - to_cnvlen += (to_savelen - to_left); - if (from_left == 0) { - if (!to_cnvlen) { - *state = XLookupNone; - return 0; - } - break; - } - } - - if (!to || !to_len || (to_len < to_cnvlen)) { - *state = XBufferOverflow; - } else { - memcpy(to, scratchbuf, to_cnvlen); - *state = XLookupChars; - } - return to_cnvlen; -} - -Public int -_XimLcctstombs(XIM xim, char *from, int from_len, - char *to, int to_len, Status *state) -{ - return _XimLcctsconvert(((Xim)xim)->private.local.ctom_conv, - from, from_len, to, to_len, state); -} - -Public int -_XimLcctstowcs(XIM xim, char *from, int from_len, - wchar_t *to, int to_len, Status *state) -{ - Xim im = (Xim)xim; - XlcConv conv = im->private.local.ctow_conv; - int from_left; - int to_left; - int from_savelen; - int to_savelen; - int from_cnvlen; - int to_cnvlen; - char *from_buf; - wchar_t *to_buf; - wchar_t scratchbuf[BUFSIZ]; - Status tmp_state; - - if (!state) - state = &tmp_state; - - if (!conv || !from || !from_len) { - *state = XLookupNone; - return 0; - } - - /* Reset the converter. The CompoundText at 'from' starts in - initial state. */ - _XlcResetConverter(conv); - - from_left = from_len; - to_left = BUFSIZ; - from_cnvlen = 0; - to_cnvlen = 0; - for (;;) { - from_buf = &from[from_cnvlen]; - from_savelen = from_left; - to_buf = &scratchbuf[to_cnvlen]; - to_savelen = to_left; - if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left, - (XPointer *)&to_buf, &to_left, NULL, 0) < 0) { - *state = XLookupNone; - return 0; - } - from_cnvlen += (from_savelen - from_left); - to_cnvlen += (to_savelen - to_left); - if (from_left == 0) { - if (!to_cnvlen){ - *state = XLookupNone; - return 0; - } - break; - } - } - - if (!to || !to_len || (to_len < to_cnvlen)) { - *state = XBufferOverflow; - } else { - memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t)); - *state = XLookupChars; - } - return to_cnvlen; -} - -Public int -_XimLcctstoutf8(XIM xim, char *from, int from_len, - char *to, int to_len, Status *state) -{ - return _XimLcctsconvert(((Xim)xim)->private.local.ctoutf8_conv, - from, from_len, to, to_len, state); -} +/******************************************************************
+
+ Copyright 1992 by Fuji Xerox Co., Ltd.
+ Copyright 1992, 1994 by FUJITSU LIMITED
+
+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 Fuji Xerox,
+FUJITSU LIMITED not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. Fuji Xerox, FUJITSU LIMITED make no representations
+about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
+FUJITSU LIMITED 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.
+
+ Author: Kazunori Nishihara Fuji Xerox
+ Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcPubI.h"
+#include "Ximint.h"
+
+Public int
+_XimLocalMbLookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes,
+ KeySym *keysym, Status *status)
+{
+ Xic ic = (Xic)xic;
+ int ret;
+ DefTree *b = ic->private.local.base.tree;
+ char *mb = ic->private.local.base.mb;
+
+ if(ev->type != KeyPress) {
+ if(status) *status = XLookupNone;
+ return(0);
+ }
+ if(ev->keycode == 0 &&
+ ( (ic->private.local.composed != 0)
+ ||(ic->private.local.brl_committed != 0))) {
+ if (ic->private.local.brl_committed != 0) { /* Braille Event */
+ unsigned char pattern = ic->private.local.brl_committed;
+ char *mb=alloca(XLC_PUBLIC(ic->core.im->core.lcd, mb_cur_max));
+ ret = _Xlcwctomb(ic->core.im->core.lcd, mb, BRL_UC_ROW | pattern);
+ if(ret > bytes) {
+ if(status) *status = XBufferOverflow;
+ return(ret);
+ }
+ if(keysym) *keysym = XK_braille_blank | pattern;
+ if(ret > 0) {
+ if (keysym) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ memcpy(buffer, mb, ret);
+ } else {
+ if(keysym) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ } else { /* Composed Event */
+ ret = strlen(&mb[b[ic->private.local.composed].mb]);
+ if(ret > bytes) {
+ if(status) *status = XBufferOverflow;
+ return(ret);
+ }
+ memcpy(buffer, &mb[b[ic->private.local.composed].mb], ret);
+ if(keysym) *keysym = b[ic->private.local.composed].ks;
+ if (ret > 0) {
+ if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+ } else { /* Throughed Event */
+ ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
+ if(ret > 0) {
+ if (ret > bytes) {
+ if (status) *status = XBufferOverflow;
+ } else if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+}
+
+Public int
+_XimLocalWcLookupString(XIC xic, XKeyEvent *ev, wchar_t *buffer, int wlen,
+ KeySym *keysym, Status *status)
+{
+ Xic ic = (Xic)xic;
+ int ret;
+ DefTree *b = ic->private.local.base.tree;
+ wchar_t *wc = ic->private.local.base.wc;
+
+ if(ev->type != KeyPress) {
+ if(status) *status = XLookupNone;
+ return(0);
+ }
+ if(ev->keycode == 0) {
+ if (ic->private.local.brl_committed != 0) { /* Braille Event */
+ unsigned char pattern = ic->private.local.brl_committed;
+ ret = 1;
+ if (ret > wlen) {
+ if(status) *status = XBufferOverflow;
+ return (ret);
+ }
+ *buffer = BRL_UC_ROW | pattern;
+ if(keysym) {
+ *keysym = XK_braille_blank | pattern;
+ if(status) *status = XLookupBoth;
+ } else
+ if(status) *status = XLookupChars;
+ } else { /* Composed Event */
+ ret = _Xwcslen(&wc[b[ic->private.local.composed].wc]);
+ if(ret > wlen) {
+ if(status) *status = XBufferOverflow;
+ return (ret);
+ }
+ memcpy((char *)buffer, (char *)&wc[b[ic->private.local.composed].wc],
+ ret * sizeof(wchar_t));
+ if(keysym) *keysym = b[ic->private.local.composed].ks;
+ if (ret > 0) {
+ if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+ } else { /* Throughed Event */
+ ret = _XimLookupWCText(ic, ev, buffer, wlen, keysym, NULL);
+ if(ret > 0) {
+ if (ret > wlen) {
+ if (status) *status = XBufferOverflow;
+ } else if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+}
+
+Public int
+_XimLocalUtf8LookupString(XIC xic, XKeyEvent *ev, char *buffer, int bytes,
+ KeySym *keysym, Status *status)
+{
+ Xic ic = (Xic)xic;
+ int ret;
+ DefTree *b = ic->private.local.base.tree;
+ char *utf8 = ic->private.local.base.utf8;
+
+ if(ev->type != KeyPress) {
+ if(status) *status = XLookupNone;
+ return(0);
+ }
+ if(ev->keycode == 0) {
+ if (ic->private.local.brl_committed != 0) { /* Braille Event */
+ unsigned char pattern = ic->private.local.brl_committed;
+ ret = 3;
+ if (ret > bytes) {
+ if(status) *status = XBufferOverflow;
+ return (ret);
+ }
+ buffer[0] = 0xe0 | ((BRL_UC_ROW >> 12) & 0x0f);
+ buffer[1] = 0x80 | ((BRL_UC_ROW >> 8) & 0x30) | (pattern >> 6);
+ buffer[2] = 0x80 | (pattern & 0x3f);
+ if(keysym) {
+ *keysym = XK_braille_blank | pattern;
+ if(status) *status = XLookupBoth;
+ } else
+ if(status) *status = XLookupChars;
+ } else { /* Composed Event */
+ ret = strlen(&utf8[b[ic->private.local.composed].utf8]);
+ if(ret > bytes) {
+ if(status) *status = XBufferOverflow;
+ return (ret);
+ }
+ memcpy(buffer, &utf8[b[ic->private.local.composed].utf8], ret);
+ if(keysym) *keysym = b[ic->private.local.composed].ks;
+ if (ret > 0) {
+ if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+ } else { /* Throughed Event */
+ ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
+ if(ret > 0) {
+ if (ret > bytes) {
+ if (status) *status = XBufferOverflow;
+ } else if (keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupBoth;
+ } else {
+ if(status) *status = XLookupChars;
+ }
+ } else {
+ if(keysym && *keysym != NoSymbol) {
+ if(status) *status = XLookupKeySym;
+ } else {
+ if(status) *status = XLookupNone;
+ }
+ }
+ }
+ return (ret);
+}
+
+Private int
+_XimLcctsconvert(
+ XlcConv conv,
+ char *from,
+ int from_len,
+ char *to,
+ int to_len,
+ Status *state)
+{
+ int from_left;
+ int to_left;
+ int from_savelen;
+ int to_savelen;
+ int from_cnvlen;
+ int to_cnvlen;
+ char *from_buf;
+ char *to_buf;
+ char scratchbuf[BUFSIZ];
+ Status tmp_state;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (!conv || !from || !from_len) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ /* Reset the converter. The CompoundText at 'from' starts in
+ initial state. */
+ _XlcResetConverter(conv);
+
+ from_left = from_len;
+ to_left = BUFSIZ;
+ from_cnvlen = 0;
+ to_cnvlen = 0;
+ for (;;) {
+ from_buf = &from[from_cnvlen];
+ from_savelen = from_left;
+ to_buf = &scratchbuf[to_cnvlen];
+ to_savelen = to_left;
+ if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
+ (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
+ *state = XLookupNone;
+ return 0;
+ }
+ from_cnvlen += (from_savelen - from_left);
+ to_cnvlen += (to_savelen - to_left);
+ if (from_left == 0) {
+ if (!to_cnvlen) {
+ *state = XLookupNone;
+ return 0;
+ }
+ break;
+ }
+ }
+
+ if (!to || !to_len || (to_len < to_cnvlen)) {
+ *state = XBufferOverflow;
+ } else {
+ memcpy(to, scratchbuf, to_cnvlen);
+ *state = XLookupChars;
+ }
+ return to_cnvlen;
+}
+
+Public int
+_XimLcctstombs(XIM xim, char *from, int from_len,
+ char *to, int to_len, Status *state)
+{
+ return _XimLcctsconvert(((Xim)xim)->private.local.ctom_conv,
+ from, from_len, to, to_len, state);
+}
+
+Public int
+_XimLcctstowcs(XIM xim, char *from, int from_len,
+ wchar_t *to, int to_len, Status *state)
+{
+ Xim im = (Xim)xim;
+ XlcConv conv = im->private.local.ctow_conv;
+ int from_left;
+ int to_left;
+ int from_savelen;
+ int to_savelen;
+ int from_cnvlen;
+ int to_cnvlen;
+ char *from_buf;
+ wchar_t *to_buf;
+ wchar_t scratchbuf[BUFSIZ];
+ Status tmp_state;
+
+ if (!state)
+ state = &tmp_state;
+
+ if (!conv || !from || !from_len) {
+ *state = XLookupNone;
+ return 0;
+ }
+
+ /* Reset the converter. The CompoundText at 'from' starts in
+ initial state. */
+ _XlcResetConverter(conv);
+
+ from_left = from_len;
+ to_left = BUFSIZ;
+ from_cnvlen = 0;
+ to_cnvlen = 0;
+ for (;;) {
+ from_buf = &from[from_cnvlen];
+ from_savelen = from_left;
+ to_buf = &scratchbuf[to_cnvlen];
+ to_savelen = to_left;
+ if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
+ (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
+ *state = XLookupNone;
+ return 0;
+ }
+ from_cnvlen += (from_savelen - from_left);
+ to_cnvlen += (to_savelen - to_left);
+ if (from_left == 0) {
+ if (!to_cnvlen){
+ *state = XLookupNone;
+ return 0;
+ }
+ break;
+ }
+ }
+
+ if (!to || !to_len || (to_len < to_cnvlen)) {
+ *state = XBufferOverflow;
+ } else {
+ memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
+ *state = XLookupChars;
+ }
+ return to_cnvlen;
+}
+
+Public int
+_XimLcctstoutf8(XIM xim, char *from, int from_len,
+ char *to, int to_len, Status *state)
+{
+ return _XimLcctsconvert(((Xim)xim)->private.local.ctoutf8_conv,
+ from, from_len, to, to_len, state);
+}
diff --git a/libX11/modules/im/ximcp/imRm.c b/libX11/modules/im/ximcp/imRm.c index da1207ca1..ae35272fa 100644 --- a/libX11/modules/im/ximcp/imRm.c +++ b/libX11/modules/im/ximcp/imRm.c @@ -1,3196 +1,3197 @@ -/****************************************************************** - - Copyright 1990, 1991, 1992,1993, 1994 by FUJITSU LIMITED - Copyright 1994 by Sony Corporation - -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 FUJITSU LIMITED -and Sony Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, -written prior permission. FUJITSU LIMITED and Sony Corporation make -no representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED AND SONY CORPORATION DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU LIMITED AND -SONY CORPORATION 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Modifier: Makoto Wakamatsu Sony Corporation - makoto@sm.sony.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xlib.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" -#include "Xresource.h" - -#define GET_NAME(x) name_table + x.name_offset - -typedef struct _XimValueOffsetInfo { - unsigned short name_offset; - XrmQuark quark; - unsigned int offset; - Bool (*defaults)( - struct _XimValueOffsetInfo *, XPointer, XPointer, unsigned long - ); - Bool (*encode)( - struct _XimValueOffsetInfo *, XPointer, XPointer - ); - Bool (*decode)( - struct _XimValueOffsetInfo *, XPointer, XPointer - ); -} XimValueOffsetInfoRec, *XimValueOffsetInfo; - -#ifdef XIM_CONNECTABLE -Private Bool -_XimCheckBool(str) - char *str; -{ - if(!strcmp(str, "True") || !strcmp(str, "true") || - !strcmp(str, "Yes") || !strcmp(str, "yes") || - !strcmp(str, "ON") || !strcmp(str, "on")) - return True; - return False; -} - -Public void -_XimSetProtoResource(im) - Xim im; -{ - char res_name_buf[256]; - char* res_name; - char res_class_buf[256]; - char* res_class; - char* str_type; - XrmValue value; - XIMStyle preedit_style = 0; - XIMStyle status_style = 0; - XIMStyles* imstyles; - char* dotximdot = ".xim."; - char* ximdot = "xim."; - char* dotXimdot = ".Xim."; - char* Ximdot = "Xim."; - - if (!im->core.rdb) - return; - - if (strlen (im->core.res_name) < 200) res_name = res_name_buf; - else res_name = Xmalloc (strlen (im->core.res_name) + 50); - if (strlen (im->core.res_class) < 200) res_class = res_class_buf; - else res_class = Xmalloc (strlen (im->core.res_class) + 50); - /* pretend malloc always works */ - - (void) sprintf (res_name, "%s%s%s", - im->core.res_name != NULL ? im->core.res_name : "*", - im->core.res_name != NULL ? dotximdot : ximdot, - "useAuth"); - (void) sprintf (res_class, "%s%s%s", - im->core.res_class != NULL ? im->core.res_class : "*", - im->core.res_class != NULL ? dotXimdot : Ximdot, - "UseAuth"); - bzero(&value, sizeof(XrmValue)); - if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) { - if(_XimCheckBool(value.addr)) { - MARK_USE_AUTHORIZATION_FUNC(im); - } - } - - (void) sprintf (res_name, "%s%s%s", - im->core.res_name != NULL ? im->core.res_name : "*", - im->core.res_name != NULL ? dotximdot : ximdot, - "delaybinding"); - (void) sprintf (res_class, "%s%s%s", - im->core.res_class != NULL ? im->core.res_class : "*", - im->core.res_class != NULL ? dotXimdot : Ximdot, - "Delaybinding"); - bzero(&value, sizeof(XrmValue)); - if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) { - if(_XimCheckBool(value.addr)) { - MARK_DELAYBINDABLE(im); - } - } - - (void) sprintf (res_name, "%s%s%s", - im->core.res_name != NULL ? im->core.res_name : "*", - im->core.res_name != NULL ? dotximdot : ximdot, - "reconnect"); - (void) sprintf (res_class, "%s%s%s", - im->core.res_class != NULL ? im->core.res_class : "*", - im->core.res_class != NULL ? dotXimdot : Ximdot, - "Reconnect"); - bzero(&value, sizeof(XrmValue)); - if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) { - if(_XimCheckBool(value.addr)) { - MARK_RECONNECTABLE(im); - } - } - - if(!IS_CONNECTABLE(im)) { - if (res_name != res_name_buf) Xfree (res_name); - if (res_class != res_class_buf) Xfree (res_class); - return; - } - - (void) sprintf (res_name, "%s%s%s", - im->core.res_name != NULL ? im->core.res_name : "*", - im->core.res_name != NULL ? dotximdot : ximdot, - "preeditDefaultStyle"); - (void) sprintf (res_class, "%s%s%s", - im->core.res_class != NULL ? im->core.res_class : "*", - im->core.res_class != NULL ? dotXimdot : Ximdot, - "PreeditDefaultStyle"); - if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) { - if(!strcmp(value.addr, "XIMPreeditArea")) - preedit_style = XIMPreeditArea; - else if(!strcmp(value.addr, "XIMPreeditCallbacks")) - preedit_style = XIMPreeditCallbacks; - else if(!strcmp(value.addr, "XIMPreeditPosition")) - preedit_style = XIMPreeditPosition; - else if(!strcmp(value.addr, "XIMPreeditNothing")) - preedit_style = XIMPreeditNothing; - else if(!strcmp(value.addr, "XIMPreeditNone")) - preedit_style = XIMPreeditNone; - } - if(!preedit_style) - preedit_style = XIMPreeditNothing; - - (void) sprintf (res_name, "%s%s%s", - im->core.res_name != NULL ? im->core.res_name : "*", - im->core.res_name != NULL ? dotximdot : ximdot, - "statusDefaultStyle"); - (void) sprintf (res_class, "%s%s%s", - im->core.res_class != NULL ? im->core.res_class : "*", - im->core.res_class != NULL ? dotXimdot : Ximdot, - "StatusDefaultStyle"); - if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) { - if(!strcmp(value.addr, "XIMStatusArea")) - status_style = XIMStatusArea; - else if(!strcmp(value.addr, "XIMStatusCallbacks")) - status_style = XIMStatusCallbacks; - else if(!strcmp(value.addr, "XIMStatusNothing")) - status_style = XIMStatusNothing; - else if(!strcmp(value.addr, "XIMStatusNone")) - status_style = XIMStatusNone; - } - if(!status_style) - status_style = XIMStatusNothing; - - if(!(imstyles = (XIMStyles *)Xmalloc(sizeof(XIMStyles) + sizeof(XIMStyle)))){ - if (res_name != res_name_buf) Xfree (res_name); - if (res_class != res_class_buf) Xfree (res_class); - return; - } - imstyles->count_styles = 1; - imstyles->supported_styles = - (XIMStyle *)((char *)imstyles + sizeof(XIMStyles)); - imstyles->supported_styles[0] = preedit_style | status_style; - im->private.proto.default_styles = imstyles; - if (res_name != res_name_buf) Xfree (res_name); - if (res_class != res_class_buf) Xfree (res_class); -} -#endif /* XIM_CONNECTABLE */ - -static const char name_table[] = - /* 0 */ XNQueryInputStyle"\0" - /* 16 */ XNClientWindow"\0" - /* 29 */ XNInputStyle"\0" - /* 40 */ XNFocusWindow"\0" - /* 52 */ XNResourceName"\0" - /* 65 */ XNResourceClass"\0" - /* 79 */ XNGeometryCallback"\0" - /* 96 */ XNDestroyCallback"\0" - /* 112 */ XNFilterEvents"\0" - /* 125 */ XNPreeditStartCallback"\0" - /* 146 */ XNPreeditDoneCallback"\0" - /* 166 */ XNPreeditDrawCallback"\0" - /* 186 */ XNPreeditCaretCallback"\0" - /* 207 */ XNPreeditStateNotifyCallback"\0" - /* 234 */ XNPreeditAttributes"\0" - /* 252 */ XNStatusStartCallback"\0" - /* 272 */ XNStatusDoneCallback"\0" - /* 291 */ XNStatusDrawCallback"\0" - /* 310 */ XNStatusAttributes"\0" - /* 327 */ XNArea"\0" - /* 332 */ XNAreaNeeded"\0" - /* 343 */ XNSpotLocation"\0" - /* 356 */ XNColormap"\0" - /* 365 */ XNStdColormap"\0" - /* 377 */ XNForeground"\0" - /* 388 */ XNBackground"\0" - /* 399 */ XNBackgroundPixmap"\0" - /* 416 */ XNFontSet"\0" - /* 424 */ XNLineSpace"\0" - /* 434 */ XNCursor"\0" - /* 441 */ XNQueryIMValuesList"\0" - /* 459 */ XNQueryICValuesList"\0" - /* 477 */ XNVisiblePosition"\0" - /* 493 */ XNStringConversionCallback"\0" - /* 518 */ XNStringConversion"\0" - /* 535 */ XNResetState"\0" - /* 546 */ XNHotKey"\0" - /* 553 */ XNHotKeyState"\0" - /* 565 */ XNPreeditState -; - -#define OFFSET_XNQUERYINPUTSTYLE 0 -#define OFFSET_XNCLIENTWINDOW 16 -#define OFFSET_XNINPUTSTYLE 29 -#define OFFSET_XNFOCUSWINDOW 40 -#define OFFSET_XNRESOURCENAME 52 -#define OFFSET_XNRESOURCECLASS 65 -#define OFFSET_XNGEOMETRYCALLBACK 79 -#define OFFSET_XNDESTROYCALLBACK 96 -#define OFFSET_XNFILTEREVENTS 112 -#define OFFSET_XNPREEDITSTARTCALLBACK 125 -#define OFFSET_XNPREEDITDONECALLBACK 146 -#define OFFSET_XNPREEDITDRAWCALLBACK 166 -#define OFFSET_XNPREEDITCARETCALLBACK 186 -#define OFFSET_XNPREEDITSTATENOTIFYCALLBACK 207 -#define OFFSET_XNPREEDITATTRIBUTES 234 -#define OFFSET_XNSTATUSSTARTCALLBACK 252 -#define OFFSET_XNSTATUSDONECALLBACK 272 -#define OFFSET_XNSTATUSDRAWCALLBACK 291 -#define OFFSET_XNSTATUSATTRIBUTES 310 -#define OFFSET_XNAREA 327 -#define OFFSET_XNAREANEEDED 332 -#define OFFSET_XNSPOTLOCATION 343 -#define OFFSET_XNCOLORMAP 356 -#define OFFSET_XNSTDCOLORMAP 365 -#define OFFSET_XNFOREGROUND 377 -#define OFFSET_XNBACKGROUND 388 -#define OFFSET_XNBACKGROUNDPIXMAP 399 -#define OFFSET_XNFONTSET 416 -#define OFFSET_XNLINESPACE 424 -#define OFFSET_XNCURSOR 434 -#define OFFSET_XNQUERYIMVALUESLIST 441 -#define OFFSET_XNQUERYICVALUESLIST 459 -#define OFFSET_XNVISIBLEPOSITION 477 -#define OFFSET_XNSTRINGCONVERSIONCALLBACK 493 -#define OFFSET_XNSTRINGCONVERSION 518 -#define OFFSET_XNRESETSTATE 535 -#define OFFSET_XNHOTKEY 546 -#define OFFSET_XNHOTKEYSTATE 553 -#define OFFSET_XNPREEDITSTATE 565 - -/* offsets into name_table */ -static const unsigned short supported_local_im_values_list[] = { - OFFSET_XNQUERYINPUTSTYLE, - OFFSET_XNRESOURCENAME, - OFFSET_XNRESOURCECLASS, - OFFSET_XNDESTROYCALLBACK, - OFFSET_XNQUERYIMVALUESLIST, - OFFSET_XNQUERYICVALUESLIST, - OFFSET_XNVISIBLEPOSITION -}; - -/* offsets into name_table */ -static const unsigned short supported_local_ic_values_list[] = { - OFFSET_XNINPUTSTYLE, - OFFSET_XNCLIENTWINDOW, - OFFSET_XNFOCUSWINDOW, - OFFSET_XNRESOURCENAME, - OFFSET_XNRESOURCECLASS, - OFFSET_XNGEOMETRYCALLBACK, - OFFSET_XNFILTEREVENTS, - OFFSET_XNDESTROYCALLBACK, - OFFSET_XNSTRINGCONVERSIONCALLBACK, - OFFSET_XNSTRINGCONVERSIONCALLBACK, - OFFSET_XNRESETSTATE, - OFFSET_XNHOTKEY, - OFFSET_XNHOTKEYSTATE, - OFFSET_XNPREEDITATTRIBUTES, - OFFSET_XNSTATUSATTRIBUTES, - OFFSET_XNAREA, - OFFSET_XNAREANEEDED, - OFFSET_XNSPOTLOCATION, - OFFSET_XNCOLORMAP, - OFFSET_XNSTDCOLORMAP, - OFFSET_XNFOREGROUND, - OFFSET_XNBACKGROUND, - OFFSET_XNBACKGROUNDPIXMAP, - OFFSET_XNFONTSET, - OFFSET_XNLINESPACE, - OFFSET_XNCURSOR, - OFFSET_XNPREEDITSTARTCALLBACK, - OFFSET_XNPREEDITDONECALLBACK, - OFFSET_XNPREEDITDRAWCALLBACK, - OFFSET_XNPREEDITCARETCALLBACK, - OFFSET_XNSTATUSSTARTCALLBACK, - OFFSET_XNSTATUSDONECALLBACK, - OFFSET_XNSTATUSDRAWCALLBACK, - OFFSET_XNPREEDITSTATE, - OFFSET_XNPREEDITSTATENOTIFYCALLBACK -}; - -static XIMStyle const supported_local_styles[] = { - XIMPreeditNone | XIMStatusNone, - XIMPreeditNothing | XIMStatusNothing, - 0 /* dummy */ -}; - -Private Bool -_XimDefaultStyles( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, /* unused */ - unsigned long mode) /* unused */ -{ - XIMStyles *styles; - XIMStyles **out; - register int i; - unsigned int n; - int len; - XPointer tmp; - - n = XIMNumber(supported_local_styles) - 1; - len = sizeof(XIMStyles) + sizeof(XIMStyle) * n; - if(!(tmp = Xcalloc(1, len))) { - return False; - } - - styles = (XIMStyles *)tmp; - if (n > 0) { - styles->count_styles = (unsigned short)n; - styles->supported_styles = - (XIMStyle *)((char *)tmp + sizeof(XIMStyles)); - for(i = 0; i < n; i++) { - styles->supported_styles[i] = supported_local_styles[i]; - } - } - - out = (XIMStyles **)((char *)top + info->offset); - *out = styles; - return True; -} - -Private Bool -_XimDefaultIMValues( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, /* unused */ - unsigned long mode) /* unused */ -{ - XIMValuesList *values_list; - XIMValuesList **out; - register int i; - unsigned int n; - int len; - XPointer tmp; - - n = XIMNumber(supported_local_im_values_list); - len = sizeof(XIMValuesList) + sizeof(char **) * n; - if(!(tmp = Xcalloc(1, len))) { - return False; - } - - values_list = (XIMValuesList *)tmp; - if (n > 0) { - values_list->count_values = (unsigned short)n; - values_list->supported_values - = (char **)((char *)tmp + sizeof(XIMValuesList)); - for(i = 0; i < n; i++) { - values_list->supported_values[i] = - (char *)name_table + supported_local_im_values_list[i]; - } - } - - out = (XIMValuesList **)((char *)top + info->offset); - *out = values_list; - return True; -} - -Private Bool -_XimDefaultICValues( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, /* unused */ - unsigned long mode) /* unused */ -{ - XIMValuesList *values_list; - XIMValuesList **out; - register int i; - unsigned int n; - int len; - XPointer tmp; - - n = XIMNumber(supported_local_ic_values_list); - len = sizeof(XIMValuesList) + sizeof(char **) * n; - if(!(tmp = Xcalloc(1, len))) { - return False; - } - - values_list = (XIMValuesList *)tmp; - if (n > 0) { - values_list->count_values = (unsigned short)n; - values_list->supported_values - = (char **)((char *)tmp + sizeof(XIMValuesList)); - for(i = 0; i < n; i++) { - values_list->supported_values[i] = - (char *)name_table + supported_local_ic_values_list[i]; - } - } - - out = (XIMValuesList **)((char *)top + info->offset); - *out = values_list; - return True; -} - -Private Bool -_XimDefaultVisiblePos( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, /* unused */ - unsigned long mode) /* unused */ -{ - Bool *out; - - out = (Bool *)((char *)top + info->offset); - *out = False; - return True; -} - -Private Bool -_XimDefaultFocusWindow( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Window *out; - - if(ic->core.client_window == (Window)NULL) { - return True; - } - - out = (Window *)((char *)top + info->offset); - *out = ic->core.client_window; - return True; -} - -Private Bool -_XimDefaultResName( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - char **out; - - if(im->core.res_name == (char *)NULL) { - return True; - } - - out = (char **)((char *)top + info->offset); - *out = im->core.res_name; - return True; -} - -Private Bool -_XimDefaultResClass( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - char **out; - - if(im->core.res_class == (char *)NULL) { - return True; - } - - out = (char **)((char *)top + info->offset); - *out = im->core.res_class; - return True; -} - -Private Bool -_XimDefaultDestroyCB( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - XIMCallback *out; - - out = (XIMCallback *)((char *)top + info->offset); - *out = im->core.destroy_callback; - return True; -} - -Private Bool -_XimDefaultResetState( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - XIMResetState *out; - - out = (XIMResetState *)((char *)top + info->offset); - *out = XIMInitialState; - return True; -} - -Private Bool -_XimDefaultHotKeyState( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - XIMHotKeyState *out; - - out = (XIMHotKeyState *)((char *)top + info->offset); - *out = XIMHotKeyStateOFF; - return True; -} - -Private Bool -_XimDefaultArea( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - Window root_return; - int x_return, y_return; - unsigned int width_return, height_return; - unsigned int border_width_return; - unsigned int depth_return; - XRectangle area; - XRectangle *out; - - if(ic->core.focus_window == (Window)NULL) { - return True; - } - if(XGetGeometry(im->core.display, (Drawable)ic->core.focus_window, - &root_return, &x_return, &y_return, &width_return, - &height_return, &border_width_return, &depth_return) - == (Status)Success) { - return True; - } - area.x = 0; - area.y = 0; - area.width = width_return; - area.height = height_return; - - out = (XRectangle *)((char *)top + info->offset); - *out = area; - return True; -} - -Private Bool -_XimDefaultColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - XWindowAttributes win_attr; - Colormap *out; - - if(ic->core.client_window == (Window)NULL) { - return True; - } - if(XGetWindowAttributes(im->core.display, ic->core.client_window, - &win_attr) == (Status)Success) { - return True; - } - - out = (Colormap *)((char *)top + info->offset); - *out = win_attr.colormap; - return True; -} - -Private Bool -_XimDefaultStdColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Atom *out; - - out = (Atom *)((char *)top + info->offset); - *out = (Atom)0; - return True; -} - -Private Bool -_XimDefaultFg( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - unsigned long fg; - unsigned long *out; - - fg = WhitePixel(im->core.display, DefaultScreen(im->core.display)); - out = (unsigned long *)((char *)top + info->offset); - *out = fg; - return True; -} - -Private Bool -_XimDefaultBg( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - Xim im = (Xim)ic->core.im; - unsigned long bg; - unsigned long *out; - - bg = BlackPixel(im->core.display, DefaultScreen(im->core.display)); - out = (unsigned long *)((char *)top + info->offset); - *out = bg; - return True; -} - -Private Bool -_XimDefaultBgPixmap( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Pixmap *out; - - out = (Pixmap *)((char *)top + info->offset); - *out = (Pixmap)0; - return True; -} - -Private Bool -_XimDefaultFontSet( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - XFontSet *out; - - out = (XFontSet *)((char *)top + info->offset); - *out = 0; - return True; -} - -Private Bool -_XimDefaultLineSpace( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Xic ic = (Xic)parm; - XFontSet fontset; - XFontSetExtents *fset_extents; - int line_space = 0; - int *out; - - if(mode & XIM_PREEDIT_ATTR) { - fontset = ic->core.preedit_attr.fontset; - } else if(mode & XIM_STATUS_ATTR) { - fontset = ic->core.status_attr.fontset; - } else { - return True; - } - if (fontset) { - fset_extents = XExtentsOfFontSet(fontset); - line_space = fset_extents->max_logical_extent.height; - } - out = (int *)((char *)top + info->offset); - *out = line_space; - return True; -} - -Private Bool -_XimDefaultCursor( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - Cursor *out; - - out = (Cursor *)((char *)top + info->offset); - *out = (Cursor)0; - return True; -} - -Private Bool -_XimDefaultPreeditState( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - XIMPreeditState *out; - - out = (XIMPreeditState *)((char *)top + info->offset); - *out = XIMPreeditDisable; - return True; -} - -Private Bool -_XimDefaultNest( - XimValueOffsetInfo info, - XPointer top, - XPointer parm, - unsigned long mode) -{ - return True; -} - -Private Bool -_XimEncodeCallback( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMCallback *out; - - out = (XIMCallback *)((char *)top + info->offset); - *out = *((XIMCallback *)val); - return True; -} - -Private Bool -_XimEncodeString( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - char *string; - char **out; - - if(val == (XPointer)NULL) { - return False; - } - if (!(string = strdup((char *)val))) { - return False; - } - - out = (char **)((char *)top + info->offset); - if(*out) { - Xfree(*out); - } - *out = string; - return True; -} - -Private Bool -_XimEncodeStyle( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMStyle *out; - - out = (XIMStyle *)((char *)top + info->offset); - *out = (XIMStyle)val; - return True; -} - -Private Bool -_XimEncodeWindow( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Window *out; - - out = (Window *)((char *)top + info->offset); - *out = (Window)val; - return True; -} - -Private Bool -_XimEncodeStringConv( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - /* - * Not yet - */ - return True; -} - -Private Bool -_XimEncodeResetState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMResetState *out; - - out = (XIMResetState *)((char *)top + info->offset); - *out = (XIMResetState)val; - return True; -} - -Private Bool -_XimEncodeHotKey( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMHotKeyTriggers *hotkey = (XIMHotKeyTriggers *)val; - XIMHotKeyTriggers **out; - XIMHotKeyTriggers *key_list; - XIMHotKeyTrigger *key; - XPointer tmp; - int num; - int len; - register int i; - - if(hotkey == (XIMHotKeyTriggers *)NULL) { - return True; - } - - if((num = hotkey->num_hot_key) == 0) { - return True; - } - - len = sizeof(XIMHotKeyTriggers) + sizeof(XIMHotKeyTrigger) * num; - if(!(tmp = (XPointer)Xmalloc(len))) { - return False; - } - - key_list = (XIMHotKeyTriggers *)tmp; - key = (XIMHotKeyTrigger *)((char *)tmp + sizeof(XIMHotKeyTriggers)); - - for(i = 0; i < num; i++) { - key[i] = hotkey->key[i]; - } - - key_list->num_hot_key = num; - key_list->key = key; - - out = (XIMHotKeyTriggers **)((char *)top + info->offset); - *out = key_list; - return True; -} - -Private Bool -_XimEncodeHotKetState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMHotKeyState *out; - - out = (XIMHotKeyState *)((char *)top + info->offset); - *out = (XIMHotKeyState)val; - return True; -} - -Private Bool -_XimEncodeRectangle( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XRectangle *out; - - out = (XRectangle *)((char *)top + info->offset); - *out = *((XRectangle *)val); - return True; -} - -Private Bool -_XimEncodeSpot( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XPoint *out; - - out = (XPoint *)((char *)top + info->offset); - *out = *((XPoint *)val); - return True; -} - -Private Bool -_XimEncodeColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Colormap *out; - - out = (Colormap *)((char *)top + info->offset); - *out = (Colormap)val; - return True; -} - -Private Bool -_XimEncodeStdColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Atom *out; - - out = (Atom *)((char *)top + info->offset); - *out = (Atom)val; - return True; -} - -Private Bool -_XimEncodeLong( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - unsigned long *out; - - out = (unsigned long *)((char *)top + info->offset); - *out = (unsigned long)val; - return True; -} - -Private Bool -_XimEncodeBgPixmap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Pixmap *out; - - out = (Pixmap *)((char *)top + info->offset); - *out = (Pixmap)val; - return True; -} - -Private Bool -_XimEncodeFontSet( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XFontSet *out; - - out = (XFontSet *)((char *)top + info->offset); - *out = (XFontSet)val; - return True; -} - -Private Bool -_XimEncodeLineSpace( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - int *out; - - out = (int *)((char *)top + info->offset); - *out = (long)val; - return True; -} - -Private Bool -_XimEncodeCursor( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Cursor *out; - - out = (Cursor *)((char *)top + info->offset); - *out = (Cursor)val; - return True; -} - -Private Bool -_XimEncodePreeditState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMPreeditState *out; - - out = (XIMPreeditState *)((char *)top + info->offset); - *out = (XIMPreeditState)val; - return True; -} - -Private Bool -_XimEncodeNest( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - return True; -} - -Private Bool -_XimDecodeStyles( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMStyles *styles; - XIMStyles *out; - register int i; - unsigned int num; - int len; - XPointer tmp; - - if(val == (XPointer)NULL) { - return False; - } - - styles = *((XIMStyles **)((char *)top + info->offset)); - num = styles->count_styles; - - len = sizeof(XIMStyles) + sizeof(XIMStyle) * num; - if(!(tmp = Xcalloc(1, len))) { - return False; - } - - out = (XIMStyles *)tmp; - if(num >0) { - out->count_styles = (unsigned short)num; - out->supported_styles = (XIMStyle *)((char *)tmp + sizeof(XIMStyles)); - - for(i = 0; i < num; i++) { - out->supported_styles[i] = styles->supported_styles[i]; - } - } - *((XIMStyles **)val) = out; - return True; -} - -Private Bool -_XimDecodeValues( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMValuesList *values_list; - XIMValuesList *out; - register int i; - unsigned int num; - int len; - XPointer tmp; - - if(val == (XPointer)NULL) { - return False; - } - - values_list = *((XIMValuesList **)((char *)top + info->offset)); - num = values_list->count_values; - - len = sizeof(XIMValuesList) + sizeof(char **) * num; - if(!(tmp = Xcalloc(1, len))) { - return False; - } - - out = (XIMValuesList *)tmp; - if(num) { - out->count_values = (unsigned short)num; - out->supported_values = (char **)((char *)tmp + sizeof(XIMValuesList)); - - for(i = 0; i < num; i++) { - out->supported_values[i] = values_list->supported_values[i]; - } - } - *((XIMValuesList **)val) = out; - return True; -} - -Private Bool -_XimDecodeCallback( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMCallback *in; - XIMCallback *callback; - - in = (XIMCallback *)((char *)top + info->offset); - if(!(callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback)))) { - return False; - } - callback->client_data = in->client_data; - callback->callback = in->callback; - - *((XIMCallback **)val) = callback; - return True; -} - -Private Bool -_XimDecodeString( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - char *in; - char *string; - - in = *((char **)((char *)top + info->offset)); - if (in != NULL) { - string = strdup(in); - } else { - string = Xcalloc(1, 1); /* strdup("") */ - } - if (string == NULL) { - return False; - } - *((char **)val) = string; - return True; -} - -Private Bool -_XimDecodeBool( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Bool *in; - - in = (Bool *)((char *)top + info->offset); - *((Bool *)val) = *in; - return True; -} - -Private Bool -_XimDecodeStyle( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMStyle *in; - - in = (XIMStyle *)((char *)top + info->offset); - *((XIMStyle *)val) = *in; - return True; -} - -Private Bool -_XimDecodeWindow( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Window *in; - - in = (Window *)((char *)top + info->offset); - *((Window *)val) = *in; - return True; -} - -Private Bool -_XimDecodeStringConv( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - /* - * Not yet - */ - return True; -} - -Private Bool -_XimDecodeResetState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMResetState *in; - - in = (XIMResetState *)((char *)top + info->offset); - *((XIMResetState *)val) = *in; - return True; -} - -Private Bool -_XimDecodeHotKey( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMHotKeyTriggers *in; - XIMHotKeyTriggers *hotkey; - XIMHotKeyTrigger *key; - XPointer tmp; - int num; - int len; - register int i; - - in = *((XIMHotKeyTriggers **)((char *)top + info->offset)); - num = in->num_hot_key; - len = sizeof(XIMHotKeyTriggers) + sizeof(XIMHotKeyTrigger) * num; - if(!(tmp = (XPointer)Xmalloc(len))) { - return False; - } - - hotkey = (XIMHotKeyTriggers *)tmp; - key = (XIMHotKeyTrigger *)((char *)tmp + sizeof(XIMHotKeyTriggers)); - - for(i = 0; i < num; i++) { - key[i] = in->key[i]; - } - hotkey->num_hot_key = num; - hotkey->key = key; - - *((XIMHotKeyTriggers **)val) = hotkey; - return True; -} - -Private Bool -_XimDecodeHotKetState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMHotKeyState *in; - - in = (XIMHotKeyState *)((char *)top + info->offset); - *((XIMHotKeyState *)val) = *in; - return True; -} - -Private Bool -_XimDecodeRectangle( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XRectangle *in; - XRectangle *rect; - - in = (XRectangle *)((char *)top + info->offset); - if(!(rect = (XRectangle *)Xmalloc(sizeof(XRectangle)))) { - return False; - } - *rect = *in; - *((XRectangle **)val) = rect; - return True; -} - -Private Bool -_XimDecodeSpot( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XPoint *in; - XPoint *spot; - - in = (XPoint *)((char *)top + info->offset); - if(!(spot = (XPoint *)Xmalloc(sizeof(XPoint)))) { - return False; - } - *spot = *in; - *((XPoint **)val) = spot; - return True; -} - -Private Bool -_XimDecodeColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Colormap *in; - - in = (Colormap *)((char *)top + info->offset); - *((Colormap *)val) = *in; - return True; -} - -Private Bool -_XimDecodeStdColormap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Atom *in; - - in = (Atom *)((char *)top + info->offset); - *((Atom *)val) = *in; - return True; -} - -Private Bool -_XimDecodeLong( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - unsigned long *in; - - in = (unsigned long *)((char *)top + info->offset); - *((unsigned long *)val) = *in; - return True; -} - -Private Bool -_XimDecodeBgPixmap( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Pixmap *in; - - in = (Pixmap *)((char *)top + info->offset); - *((Pixmap *)val) = *in; - return True; -} - -Private Bool -_XimDecodeFontSet( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XFontSet *in; - - in = (XFontSet *)((char *)top + info->offset); - *((XFontSet *)val) = *in; - return True; -} - -Private Bool -_XimDecodeLineSpace( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - int *in; - - in = (int *)((char *)top + info->offset); - *((int *)val) = *in; - return True; -} - -Private Bool -_XimDecodeCursor( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - Cursor *in; - - in = (Cursor *)((char *)top + info->offset); - *((Cursor *)val) = *in; - return True; -} - -Private Bool -_XimDecodePreeditState( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - XIMPreeditState *in; - - in = (XIMPreeditState *)((char *)top + info->offset); - *((XIMPreeditState *)val) = *in; - return True; -} - -Private Bool -_XimDecodeNest( - XimValueOffsetInfo info, - XPointer top, - XPointer val) -{ - return True; -} - -static XIMResource im_resources[] = { - {XNQueryInputStyle, 0, XimType_XIMStyles, 0, 0, 0}, - {XNDestroyCallback, 0, 0, 0, 0, 0}, - {XNResourceName, 0, XimType_STRING8, 0, 0, 0}, - {XNResourceClass, 0, XimType_STRING8, 0, 0, 0}, - {XNQueryIMValuesList, 0, 0, 0, 0, 0}, - {XNQueryICValuesList, 0, 0, 0, 0, 0}, - {XNVisiblePosition, 0, 0, 0, 0, 0} -}; - -static XIMResource im_inner_resources[] = { - {XNDestroyCallback, 0, 0, 0, 0, 0}, - {XNResourceName, 0, XimType_STRING8, 0, 0, 0}, - {XNResourceClass, 0, XimType_STRING8, 0, 0, 0}, - {XNQueryIMValuesList, 0, 0, 0, 0, 0}, - {XNQueryICValuesList, 0, 0, 0, 0, 0}, - {XNVisiblePosition, 0, 0, 0, 0, 0} -}; - -static XIMResource ic_resources[] = { - {XNInputStyle, 0, XimType_CARD32, 0, 0, 0}, - {XNClientWindow, 0, XimType_Window, 0, 0, 0}, - {XNFocusWindow, 0, XimType_Window, 0, 0, 0}, - {XNResourceName, 0, XimType_STRING8, 0, 0, 0}, - {XNResourceClass, 0, XimType_STRING8, 0, 0, 0}, - {XNGeometryCallback, 0, 0, 0, 0, 0}, - {XNFilterEvents, 0, XimType_CARD32, 0, 0, 0}, - {XNDestroyCallback, 0, 0, 0, 0, 0}, - {XNStringConversionCallback, 0, 0, 0, 0, 0}, - {XNStringConversion, 0, XimType_XIMStringConversion,0, 0, 0}, - {XNResetState, 0, 0, 0, 0, 0}, - {XNHotKey, 0, XimType_XIMHotKeyTriggers,0, 0, 0}, - {XNHotKeyState, 0, XimType_XIMHotKeyState, 0, 0, 0}, - {XNPreeditAttributes, 0, XimType_NEST, 0, 0, 0}, - {XNStatusAttributes, 0, XimType_NEST, 0, 0, 0}, - {XNArea, 0, XimType_XRectangle, 0, 0, 0}, - {XNAreaNeeded, 0, XimType_XRectangle, 0, 0, 0}, - {XNSpotLocation, 0, XimType_XPoint, 0, 0, 0}, - {XNColormap, 0, XimType_CARD32, 0, 0, 0}, - {XNStdColormap, 0, XimType_CARD32, 0, 0, 0}, - {XNForeground, 0, XimType_CARD32, 0, 0, 0}, - {XNBackground, 0, XimType_CARD32, 0, 0, 0}, - {XNBackgroundPixmap, 0, XimType_CARD32, 0, 0, 0}, - {XNFontSet, 0, XimType_XFontSet, 0, 0, 0}, - {XNLineSpace, 0, XimType_CARD32, 0, 0, 0}, - {XNCursor, 0, XimType_CARD32, 0, 0, 0}, - {XNPreeditStartCallback, 0, 0, 0, 0, 0}, - {XNPreeditDoneCallback, 0, 0, 0, 0, 0}, - {XNPreeditDrawCallback, 0, 0, 0, 0, 0}, - {XNPreeditCaretCallback, 0, 0, 0, 0, 0}, - {XNStatusStartCallback, 0, 0, 0, 0, 0}, - {XNStatusDoneCallback, 0, 0, 0, 0, 0}, - {XNStatusDrawCallback, 0, 0, 0, 0, 0}, - {XNPreeditState, 0, 0, 0, 0, 0}, - {XNPreeditStateNotifyCallback, 0, 0, 0, 0, 0}, -}; - -static XIMResource ic_inner_resources[] = { - {XNResourceName, 0, XimType_STRING8, 0, 0, 0}, - {XNResourceClass, 0, XimType_STRING8, 0, 0, 0}, - {XNGeometryCallback, 0, 0, 0, 0, 0}, - {XNDestroyCallback, 0, 0, 0, 0, 0}, - {XNStringConversionCallback, 0, 0, 0, 0, 0}, - {XNPreeditStartCallback, 0, 0, 0, 0, 0}, - {XNPreeditDoneCallback, 0, 0, 0, 0, 0}, - {XNPreeditDrawCallback, 0, 0, 0, 0, 0}, - {XNPreeditCaretCallback, 0, 0, 0, 0, 0}, - {XNStatusStartCallback, 0, 0, 0, 0, 0}, - {XNStatusDoneCallback, 0, 0, 0, 0, 0}, - {XNStatusDrawCallback, 0, 0, 0, 0, 0}, - {XNPreeditStateNotifyCallback, 0, 0, 0, 0, 0}, -}; - -static XimValueOffsetInfoRec im_attr_info[] = { - {OFFSET_XNQUERYINPUTSTYLE, 0, - XOffsetOf(XimDefIMValues, styles), - _XimDefaultStyles, NULL, _XimDecodeStyles}, - - {OFFSET_XNDESTROYCALLBACK, 0, - XOffsetOf(XimDefIMValues, destroy_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNRESOURCENAME, 0, - XOffsetOf(XimDefIMValues, res_name), - NULL, _XimEncodeString, _XimDecodeString}, - - {OFFSET_XNRESOURCECLASS, 0, - XOffsetOf(XimDefIMValues, res_class), - NULL, _XimEncodeString, _XimDecodeString}, - - {OFFSET_XNQUERYIMVALUESLIST, 0, - XOffsetOf(XimDefIMValues, im_values_list), - _XimDefaultIMValues, NULL, _XimDecodeValues}, - - {OFFSET_XNQUERYICVALUESLIST, 0, - XOffsetOf(XimDefIMValues, ic_values_list), - _XimDefaultICValues, NULL, _XimDecodeValues}, - - {OFFSET_XNVISIBLEPOSITION, 0, - XOffsetOf(XimDefIMValues, visible_position), - _XimDefaultVisiblePos, NULL, _XimDecodeBool} -}; - -static XimValueOffsetInfoRec ic_attr_info[] = { - {OFFSET_XNINPUTSTYLE, 0, - XOffsetOf(XimDefICValues, input_style), - NULL, _XimEncodeStyle, _XimDecodeStyle}, - - {OFFSET_XNCLIENTWINDOW, 0, - XOffsetOf(XimDefICValues, client_window), - NULL, _XimEncodeWindow, _XimDecodeWindow}, - - {OFFSET_XNFOCUSWINDOW, 0, - XOffsetOf(XimDefICValues, focus_window), - _XimDefaultFocusWindow, _XimEncodeWindow, _XimDecodeWindow}, - - {OFFSET_XNRESOURCENAME, 0, - XOffsetOf(XimDefICValues, res_name), - _XimDefaultResName, _XimEncodeString, _XimDecodeString}, - - {OFFSET_XNRESOURCECLASS, 0, - XOffsetOf(XimDefICValues, res_class), - _XimDefaultResClass, _XimEncodeString, _XimDecodeString}, - - {OFFSET_XNGEOMETRYCALLBACK, 0, - XOffsetOf(XimDefICValues, geometry_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNFILTEREVENTS, 0, - XOffsetOf(XimDefICValues, filter_events), - NULL, NULL, _XimDecodeLong}, - - {OFFSET_XNDESTROYCALLBACK, 0, - XOffsetOf(XimDefICValues, destroy_callback), - _XimDefaultDestroyCB, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNSTRINGCONVERSIONCALLBACK, 0, - XOffsetOf(XimDefICValues, string_conversion_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNSTRINGCONVERSION, 0, - XOffsetOf(XimDefICValues, string_conversion), - NULL, _XimEncodeStringConv, _XimDecodeStringConv}, - - {OFFSET_XNRESETSTATE, 0, - XOffsetOf(XimDefICValues, reset_state), - _XimDefaultResetState, _XimEncodeResetState, _XimDecodeResetState}, - - {OFFSET_XNHOTKEY, 0, - XOffsetOf(XimDefICValues, hotkey), - NULL, _XimEncodeHotKey, _XimDecodeHotKey}, - - {OFFSET_XNHOTKEYSTATE, 0, - XOffsetOf(XimDefICValues, hotkey_state), - _XimDefaultHotKeyState, _XimEncodeHotKetState, _XimDecodeHotKetState}, - - {OFFSET_XNPREEDITATTRIBUTES, 0, - XOffsetOf(XimDefICValues, preedit_attr), - _XimDefaultNest, _XimEncodeNest, _XimDecodeNest}, - - {OFFSET_XNSTATUSATTRIBUTES, 0, - XOffsetOf(XimDefICValues, status_attr), - _XimDefaultNest, _XimEncodeNest, _XimDecodeNest}, -}; - -static XimValueOffsetInfoRec ic_pre_attr_info[] = { - {OFFSET_XNAREA, 0, - XOffsetOf(ICPreeditAttributes, area), - _XimDefaultArea, _XimEncodeRectangle, _XimDecodeRectangle}, - - {OFFSET_XNAREANEEDED, 0, - XOffsetOf(ICPreeditAttributes, area_needed), - NULL, _XimEncodeRectangle, _XimDecodeRectangle}, - - {OFFSET_XNSPOTLOCATION, 0, - XOffsetOf(ICPreeditAttributes, spot_location), - NULL, _XimEncodeSpot, _XimDecodeSpot}, - - {OFFSET_XNCOLORMAP, 0, - XOffsetOf(ICPreeditAttributes, colormap), - _XimDefaultColormap, _XimEncodeColormap, _XimDecodeColormap}, - - {OFFSET_XNSTDCOLORMAP, 0, - XOffsetOf(ICPreeditAttributes, std_colormap), - _XimDefaultStdColormap, _XimEncodeStdColormap, _XimDecodeStdColormap}, - - {OFFSET_XNFOREGROUND, 0, - XOffsetOf(ICPreeditAttributes, foreground), - _XimDefaultFg, _XimEncodeLong, _XimDecodeLong}, - - {OFFSET_XNBACKGROUND, 0, - XOffsetOf(ICPreeditAttributes, background), - _XimDefaultBg, _XimEncodeLong, _XimDecodeLong}, - - {OFFSET_XNBACKGROUNDPIXMAP, 0, - XOffsetOf(ICPreeditAttributes, background_pixmap), - _XimDefaultBgPixmap, _XimEncodeBgPixmap, _XimDecodeBgPixmap}, - - {OFFSET_XNFONTSET, 0, - XOffsetOf(ICPreeditAttributes, fontset), - _XimDefaultFontSet, _XimEncodeFontSet, _XimDecodeFontSet}, - - {OFFSET_XNLINESPACE, 0, - XOffsetOf(ICPreeditAttributes, line_spacing), - _XimDefaultLineSpace, _XimEncodeLineSpace, _XimDecodeLineSpace}, - - {OFFSET_XNCURSOR, 0, - XOffsetOf(ICPreeditAttributes, cursor), - _XimDefaultCursor, _XimEncodeCursor, _XimDecodeCursor}, - - {OFFSET_XNPREEDITSTARTCALLBACK, 0, - XOffsetOf(ICPreeditAttributes, start_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNPREEDITDONECALLBACK, 0, - XOffsetOf(ICPreeditAttributes, done_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNPREEDITDRAWCALLBACK, 0, - XOffsetOf(ICPreeditAttributes, draw_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNPREEDITCARETCALLBACK, 0, - XOffsetOf(ICPreeditAttributes, caret_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNPREEDITSTATE, 0, - XOffsetOf(ICPreeditAttributes, preedit_state), - _XimDefaultPreeditState, _XimEncodePreeditState,_XimDecodePreeditState}, - - {OFFSET_XNPREEDITSTATENOTIFYCALLBACK, 0, - XOffsetOf(ICPreeditAttributes, state_notify_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, -}; - -static XimValueOffsetInfoRec ic_sts_attr_info[] = { - {OFFSET_XNAREA, 0, - XOffsetOf(ICStatusAttributes, area), - _XimDefaultArea, _XimEncodeRectangle, _XimDecodeRectangle}, - - {OFFSET_XNAREANEEDED, 0, - XOffsetOf(ICStatusAttributes, area_needed), - NULL, _XimEncodeRectangle, _XimDecodeRectangle}, - - {OFFSET_XNCOLORMAP, 0, - XOffsetOf(ICStatusAttributes, colormap), - _XimDefaultColormap, _XimEncodeColormap, _XimDecodeColormap}, - - {OFFSET_XNSTDCOLORMAP, 0, - XOffsetOf(ICStatusAttributes, std_colormap), - _XimDefaultStdColormap, _XimEncodeStdColormap, _XimDecodeStdColormap}, - - {OFFSET_XNFOREGROUND, 0, - XOffsetOf(ICStatusAttributes, foreground), - _XimDefaultFg, _XimEncodeLong, _XimDecodeLong}, - - {OFFSET_XNBACKGROUND, 0, - XOffsetOf(ICStatusAttributes, background), - _XimDefaultBg, _XimEncodeLong, _XimDecodeLong}, - - {OFFSET_XNBACKGROUNDPIXMAP, 0, - XOffsetOf(ICStatusAttributes, background_pixmap), - _XimDefaultBgPixmap, _XimEncodeBgPixmap, _XimDecodeBgPixmap}, - - {OFFSET_XNFONTSET, 0, - XOffsetOf(ICStatusAttributes, fontset), - _XimDefaultFontSet, _XimEncodeFontSet, _XimDecodeFontSet}, - - {OFFSET_XNLINESPACE, 0, - XOffsetOf(ICStatusAttributes, line_spacing), - _XimDefaultLineSpace, _XimEncodeLineSpace, _XimDecodeLineSpace}, - - {OFFSET_XNCURSOR, 0, - XOffsetOf(ICStatusAttributes, cursor), - _XimDefaultCursor, _XimEncodeCursor, _XimDecodeCursor}, - - {OFFSET_XNSTATUSSTARTCALLBACK, 0, - XOffsetOf(ICStatusAttributes, start_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNSTATUSDONECALLBACK, 0, - XOffsetOf(ICStatusAttributes, done_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback}, - - {OFFSET_XNSTATUSDRAWCALLBACK, 0, - XOffsetOf(ICStatusAttributes, draw_callback), - NULL, _XimEncodeCallback, _XimDecodeCallback} -}; - -typedef struct _XimIMMode { - unsigned short name_offset; - unsigned short mode; -} XimIMMode; - -static const XimIMMode im_mode[] = { - {OFFSET_XNQUERYINPUTSTYLE, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)}, - {OFFSET_XNDESTROYCALLBACK, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)}, - {OFFSET_XNRESOURCENAME, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)}, - {OFFSET_XNRESOURCECLASS, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)}, - {OFFSET_XNQUERYIMVALUESLIST, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)}, - {OFFSET_XNQUERYICVALUESLIST, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)}, - {OFFSET_XNVISIBLEPOSITION, - (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)} -}; - -typedef struct _XimICMode { - unsigned short name_offset; - unsigned short preedit_callback_mode; - unsigned short preedit_position_mode; - unsigned short preedit_area_mode; - unsigned short preedit_nothing_mode; - unsigned short preedit_none_mode; - unsigned short status_callback_mode; - unsigned short status_area_mode; - unsigned short status_nothing_mode; - unsigned short status_none_mode; -} XimICMode; - -static const XimICMode ic_mode[] = { - {OFFSET_XNINPUTSTYLE, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET), - (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET), - (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET), - (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET), - (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET)}, - {OFFSET_XNCLIENTWINDOW, - (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET), - 0, - (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET), - (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET), - (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNFOCUSWINDOW, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNRESOURCENAME, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNRESOURCECLASS, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNGEOMETRYCALLBACK, - 0, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0}, - {OFFSET_XNFILTEREVENTS, - XIM_MODE_PRE_GET, - XIM_MODE_PRE_GET, - XIM_MODE_PRE_GET, - XIM_MODE_PRE_GET, - 0, - XIM_MODE_STS_GET, - XIM_MODE_STS_GET, - XIM_MODE_STS_GET, - XIM_MODE_STS_GET}, - {OFFSET_XNDESTROYCALLBACK, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0}, - {OFFSET_XNSTRINGCONVERSIONCALLBACK, - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0}, - {OFFSET_XNSTRINGCONVERSION, - XIM_MODE_PRE_SET, - XIM_MODE_PRE_SET, - XIM_MODE_PRE_SET, - XIM_MODE_PRE_SET, - XIM_MODE_PRE_SET, - 0, - 0, - 0, - 0}, - {OFFSET_XNRESETSTATE, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNHOTKEY, - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNHOTKEYSTATE, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITATTRIBUTES, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNSTATUSATTRIBUTES, - 0, - 0, - 0, - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNAREA, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0}, - {OFFSET_XNAREANEEDED, - 0, - 0, - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - (XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0}, - {OFFSET_XNSPOTLOCATION, - 0, /*(XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),*/ - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0}, - {OFFSET_XNCOLORMAP, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNSTDCOLORMAP, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNFOREGROUND, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNBACKGROUND, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNBACKGROUNDPIXMAP, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNFONTSET, - 0, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNLINESPACE, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNCURSOR, - 0, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0}, - {OFFSET_XNPREEDITSTARTCALLBACK, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITDONECALLBACK, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITDRAWCALLBACK, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITCARETCALLBACK, - (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITSTATE, - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNPREEDITSTATENOTIFYCALLBACK, - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET), - 0, - 0, - 0, - 0, - 0}, - {OFFSET_XNSTATUSSTARTCALLBACK, - 0, - 0, - 0, - 0, - 0, - (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0, - 0}, - {OFFSET_XNSTATUSDONECALLBACK, - 0, - 0, - 0, - 0, - 0, - (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0, - 0}, - {OFFSET_XNSTATUSDRAWCALLBACK, - 0, - 0, - 0, - 0, - 0, - (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET), - 0, - 0, - 0} -}; - -/* the quarks are separated from im_mode/ic_mode so those arrays - * can be const. - */ -static XrmQuark im_mode_quark[sizeof(im_mode) / sizeof(im_mode[0])]; -static XrmQuark ic_mode_quark[sizeof(ic_mode) / sizeof(ic_mode[0])]; - -Private Bool -_XimSetResourceList( - XIMResourceList *res_list, - unsigned int *list_num, - XIMResourceList resource, - unsigned int num_resource, - unsigned short id) -{ - register int i; - int len; - XIMResourceList res; - - len = sizeof(XIMResource) * num_resource; - if(!(res = Xcalloc(1, len))) { - return False; - } - - for(i = 0; i < num_resource; i++, id++) { - res[i] = resource[i]; - res[i].id = id; - } - - _XIMCompileResourceList(res, num_resource); - *res_list = res; - *list_num = num_resource; - return True; -} - -Public Bool -_XimSetIMResourceList( - XIMResourceList *res_list, - unsigned int *list_num) -{ - return _XimSetResourceList(res_list, list_num, - im_resources, XIMNumber(im_resources), 100); -} - -Public Bool -_XimSetICResourceList( - XIMResourceList *res_list, - unsigned int *list_num) -{ - return _XimSetResourceList(res_list, list_num, - ic_resources, XIMNumber(ic_resources), 200); -} - -Public Bool -_XimSetInnerIMResourceList( - XIMResourceList *res_list, - unsigned int *list_num) -{ - return _XimSetResourceList(res_list, list_num, - im_inner_resources, XIMNumber(im_inner_resources), 100); -} - -Public Bool -_XimSetInnerICResourceList( - XIMResourceList *res_list, - unsigned int *list_num) -{ - return _XimSetResourceList(res_list, list_num, - ic_inner_resources, XIMNumber(ic_inner_resources), 200); -} - -Private XIMResourceList -_XimGetResourceListRecByMode( - XIMResourceList res_list, - unsigned int list_num, - unsigned short mode) -{ - register int i; - - for(i = 0; i < list_num; i++) { - if (res_list[i].mode & mode) { - return (XIMResourceList)&res_list[i]; - } - } - return (XIMResourceList)NULL; -} - -Public Bool -_XimCheckCreateICValues( - XIMResourceList res_list, - unsigned int list_num) -{ - if (!_XimGetResourceListRecByMode(res_list, list_num, XIM_MODE_IC_CREATE)) { - return True; - } - return False; -} - -Public XIMResourceList -_XimGetResourceListRecByQuark( - XIMResourceList res_list, - unsigned int list_num, - XrmQuark quark) -{ - register int i; - - for(i = 0; i < list_num; i++) { - if (res_list[i].xrm_name == quark) { - return (XIMResourceList)&res_list[i]; - } - } - return (XIMResourceList)NULL; -} - -Public XIMResourceList -_XimGetResourceListRec( - XIMResourceList res_list, - unsigned int list_num, - const char *name) -{ - XrmQuark quark = XrmStringToQuark(name); - - return _XimGetResourceListRecByQuark(res_list, list_num, quark); -} - -Public char * -_XimSetIMValueData( - Xim im, - XPointer top, - XIMArg *values, - XIMResourceList res_list, - unsigned int list_num) -{ - register XIMArg *p; - XIMResourceList res; - int check; - - for(p = values; p->name != NULL; p++) { - if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) { - return p->value; - } - check = _XimCheckIMMode(res, XIM_SETIMVALUES); - if(check == XIM_CHECK_INVALID) { - continue; - } else if (check == XIM_CHECK_ERROR) { - return p->value; - } - - if(!_XimEncodeLocalIMAttr(res, top, p->value)) { - return p->value; - } - } - return NULL; -} - -Public char * -_XimGetIMValueData( - Xim im, - XPointer top, - XIMArg *values, - XIMResourceList res_list, - unsigned int list_num) -{ - register XIMArg *p; - XIMResourceList res; - int check; - - for(p = values; p->name != NULL; p++) { - if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) { - return p->value; - } - check = _XimCheckIMMode(res, XIM_GETIMVALUES); - if(check == XIM_CHECK_INVALID) { - continue; - } else if (check == XIM_CHECK_ERROR) { - return p->value; - } - - if(!_XimDecodeLocalIMAttr(res, top, p->value)) { - return p->value; - } - } - return NULL; -} - -Public void -_XimSetIMMode( - XIMResourceList res_list, - unsigned int list_num) -{ - XIMResourceList res; - unsigned int n = XIMNumber(im_mode); - register int i; - - for(i = 0; i < n; i++) { - if(!(res = _XimGetResourceListRecByQuark(res_list, - list_num, im_mode_quark[i]))) { - continue; - } - res->mode = im_mode[i].mode; - } - return; -} - -Private int -_XimCheckSetIMDefaultsMode( - XIMResourceList res) -{ - if(res->mode & XIM_MODE_IM_DEFAULT) { - return XIM_CHECK_VALID; - } - return XIM_CHECK_INVALID; -} - -Private int -_XimCheckSetIMValuesMode( - XIMResourceList res) -{ - if(res->mode & XIM_MODE_IM_SET) { - return XIM_CHECK_VALID; - } - return XIM_CHECK_INVALID; -} - -Private int - _XimCheckGetIMValuesMode( - XIMResourceList res) -{ - if(res->mode & XIM_MODE_IM_GET) { - return XIM_CHECK_VALID; - } - return XIM_CHECK_INVALID; -} - -Public int - _XimCheckIMMode( - XIMResourceList res, - unsigned long mode) -{ - if(res->mode == 0) { - return XIM_CHECK_INVALID; - } - if(mode & XIM_SETIMDEFAULTS) { - return _XimCheckSetIMDefaultsMode(res); - } else if (mode & XIM_SETIMVALUES) { - return _XimCheckSetIMValuesMode(res); - } else if (mode & XIM_GETIMVALUES) { - return _XimCheckGetIMValuesMode(res); - } else { - return XIM_CHECK_ERROR; - } -} - -Public void -_XimSetICMode(XIMResourceList res_list, unsigned int list_num, XIMStyle style) -{ - XIMResourceList res; - unsigned int n = XIMNumber(ic_mode); - register int i; - unsigned int pre_offset; - unsigned int sts_offset; - - if(style & XIMPreeditArea) { - pre_offset = XOffsetOf(XimICMode, preedit_area_mode); - } else if(style & XIMPreeditCallbacks) { - pre_offset = XOffsetOf(XimICMode, preedit_callback_mode); - } else if(style & XIMPreeditPosition) { - pre_offset = XOffsetOf(XimICMode, preedit_position_mode); - } else if(style & XIMPreeditNothing) { - pre_offset = XOffsetOf(XimICMode, preedit_nothing_mode); - } else { - pre_offset = XOffsetOf(XimICMode, preedit_none_mode); - } - - if(style & XIMStatusArea) { - sts_offset = XOffsetOf(XimICMode, status_area_mode); - } else if(style & XIMStatusCallbacks) { - sts_offset = XOffsetOf(XimICMode, status_callback_mode); - } else if(style & XIMStatusNothing) { - sts_offset = XOffsetOf(XimICMode, status_nothing_mode); - } else { - sts_offset = XOffsetOf(XimICMode, status_none_mode); - } - - for(i = 0; i < n; i++) { - if(!(res = _XimGetResourceListRecByQuark(res_list, - list_num, ic_mode_quark[i]))) { - continue; - } - res->mode = ( (*(unsigned short *)((char *)&ic_mode[i] + pre_offset)) - | (*(unsigned short *)((char *)&ic_mode[i] + sts_offset))); - } - return; -} - -Private int -_XimCheckSetICDefaultsMode( - XIMResourceList res, - unsigned long mode) -{ - if(mode & XIM_PREEDIT_ATTR) { - if(!(res->mode & XIM_MODE_PRE_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_PRE_CREATE) { - return XIM_CHECK_ERROR; - } else if (!(res->mode & XIM_MODE_PRE_DEFAULT)) { - return XIM_CHECK_INVALID; - } - - } else if(mode & XIM_STATUS_ATTR) { - if(!(res->mode & XIM_MODE_STS_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_STS_CREATE) { - return XIM_CHECK_ERROR; - } - if(!(res->mode & XIM_MODE_STS_DEFAULT)) { - return XIM_CHECK_INVALID; - } - - } else { - if(!res->mode) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_IC_CREATE) { - return XIM_CHECK_ERROR; - } - if(!(res->mode & XIM_MODE_IC_DEFAULT)) { - return XIM_CHECK_INVALID; - } - } - return XIM_CHECK_VALID; -} - -Private int -_XimCheckCreateICMode( - XIMResourceList res, - unsigned long mode) -{ - if(mode & XIM_PREEDIT_ATTR) { - if(!(res->mode & XIM_MODE_PRE_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_PRE_CREATE) { - res->mode &= ~XIM_MODE_PRE_CREATE; - } else if(res->mode & XIM_MODE_PRE_ONCE) { - res->mode &= ~XIM_MODE_PRE_ONCE; - } else if(res->mode & XIM_MODE_PRE_DEFAULT) { - res->mode &= ~XIM_MODE_PRE_DEFAULT; - } else if (!(res->mode & XIM_MODE_PRE_SET)) { - return XIM_CHECK_ERROR; - } - - } else if(mode & XIM_STATUS_ATTR) { - if(!(res->mode & XIM_MODE_STS_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_STS_CREATE) { - res->mode &= ~XIM_MODE_STS_CREATE; - } else if(res->mode & XIM_MODE_STS_ONCE) { - res->mode &= ~XIM_MODE_STS_ONCE; - } else if(res->mode & XIM_MODE_STS_DEFAULT) { - res->mode &= ~XIM_MODE_STS_DEFAULT; - } else if (!(res->mode & XIM_MODE_STS_SET)) { - return XIM_CHECK_ERROR; - } - - } else { - if(!res->mode) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_IC_CREATE) { - res->mode &= ~XIM_MODE_IC_CREATE; - } else if(res->mode & XIM_MODE_IC_ONCE) { - res->mode &= ~XIM_MODE_IC_ONCE; - } else if(res->mode & XIM_MODE_IC_DEFAULT) { - res->mode &= ~XIM_MODE_IC_DEFAULT; - } else if (!(res->mode & XIM_MODE_IC_SET)) { - return XIM_CHECK_ERROR; - } - } - return XIM_CHECK_VALID; -} - -Private int -_XimCheckSetICValuesMode( - XIMResourceList res, - unsigned long mode) -{ - if(mode & XIM_PREEDIT_ATTR) { - if(!(res->mode & XIM_MODE_PRE_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_PRE_ONCE) { - res->mode &= ~XIM_MODE_PRE_ONCE; - } else if(!(res->mode & XIM_MODE_PRE_SET)) { - return XIM_CHECK_ERROR; - } - - } else if(mode & XIM_STATUS_ATTR) { - if(!(res->mode & XIM_MODE_STS_MASK)) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_STS_ONCE) { - res->mode &= ~XIM_MODE_STS_ONCE; - } else if(!(res->mode & XIM_MODE_STS_SET)) { - return XIM_CHECK_ERROR; - } - - } else { - if(!res->mode) { - return XIM_CHECK_INVALID; - } - - if(res->mode & XIM_MODE_IC_ONCE) { - res->mode &= ~XIM_MODE_IC_ONCE; - } else if(!(res->mode & XIM_MODE_IC_SET)) { - return XIM_CHECK_ERROR; - } - } - return XIM_CHECK_VALID; -} - -Private int -_XimCheckGetICValuesMode( - XIMResourceList res, - unsigned long mode) -{ - if(mode & XIM_PREEDIT_ATTR) { - if(!(res->mode & XIM_MODE_PRE_MASK)) { - return XIM_CHECK_INVALID; - } - - if(!(res->mode & XIM_MODE_PRE_GET)) { - return XIM_CHECK_ERROR; - } - - } else if(mode & XIM_STATUS_ATTR) { - if(!(res->mode & XIM_MODE_STS_MASK)) { - return XIM_CHECK_INVALID; - } - - if(!(res->mode & XIM_MODE_STS_GET)) { - return XIM_CHECK_ERROR; - } - - } else { - if(!res->mode) { - return XIM_CHECK_INVALID; - } - - if(!(res->mode & XIM_MODE_IC_GET)) { - return XIM_CHECK_ERROR; - } - } - return XIM_CHECK_VALID; -} - -Public int - _XimCheckICMode( - XIMResourceList res, - unsigned long mode) -{ - if(mode &XIM_SETICDEFAULTS) { - return _XimCheckSetICDefaultsMode(res, mode); - } else if (mode & XIM_CREATEIC) { - return _XimCheckCreateICMode(res, mode); - } else if (mode & XIM_SETICVALUES) { - return _XimCheckSetICValuesMode(res, mode); - } else if (mode & XIM_GETICVALUES) { - return _XimCheckGetICValuesMode(res, mode); - } else { - return XIM_CHECK_ERROR; - } -} - -Public Bool -_XimSetLocalIMDefaults( - Xim im, - XPointer top, - XIMResourceList res_list, - unsigned int list_num) -{ - XimValueOffsetInfo info; - unsigned int num; - register int i; - XIMResourceList res; - int check; - - info = im_attr_info; - num = XIMNumber(im_attr_info); - - for(i = 0; i < num; i++) { - if((res = _XimGetResourceListRecByQuark( res_list, list_num, - info[i].quark)) == (XIMResourceList)NULL) { - return False; - } - - check = _XimCheckIMMode(res, XIM_SETIMDEFAULTS); - if(check == XIM_CHECK_INVALID) { - continue; - } else if (check == XIM_CHECK_ERROR) { - return False; - } - - if(!info[i].defaults) { - continue; - } - if(!(info[i].defaults(&info[i], top, (XPointer)NULL, 0))) { - return False; - } - } - return True; -} - -Public Bool -_XimSetICDefaults( - Xic ic, - XPointer top, - unsigned long mode, - XIMResourceList res_list, - unsigned int list_num) -{ - unsigned int num; - XimValueOffsetInfo info; - register int i; - XIMResourceList res; - int check; - XrmQuark pre_quark; - XrmQuark sts_quark; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - if(mode & XIM_PREEDIT_ATTR) { - info = ic_pre_attr_info; - num = XIMNumber(ic_pre_attr_info); - } else if(mode & XIM_STATUS_ATTR) { - info = ic_sts_attr_info; - num = XIMNumber(ic_sts_attr_info); - } else { - info = ic_attr_info; - num = XIMNumber(ic_attr_info); - } - - for(i = 0; i < num; i++) { - if(info[i].quark == pre_quark) { - if(!_XimSetICDefaults(ic, (XPointer)((char *)top + info[i].offset), - (mode | XIM_PREEDIT_ATTR), res_list, list_num)) { - return False; - } - } else if (info[i].quark == sts_quark) { - if(!_XimSetICDefaults(ic, (XPointer)((char *)top + info[i].offset), - (mode | XIM_STATUS_ATTR), res_list, list_num)) { - return False; - } - } else { - if(!(res = _XimGetResourceListRecByQuark(res_list, list_num, - info[i].quark))) { - return False; - } - - check = _XimCheckICMode(res, mode); - if (check == XIM_CHECK_INVALID) { - continue; - } else if (check == XIM_CHECK_ERROR) { - return False; - } - - if (!info[i].defaults) { - continue; - } - if (!(info[i].defaults(&info[i], top, (XPointer)ic, mode))) { - return False; - } - } - } - return True; -} - -Private Bool -_XimEncodeAttr( - XimValueOffsetInfo info, - unsigned int num, - XIMResourceList res, - XPointer top, - XPointer val) -{ - register int i; - - for(i = 0; i < num; i++ ) { - if(info[i].quark == res->xrm_name) { - if(!info[i].encode) { - return False; - } - return (*info[i].encode)(&info[i], top, val); - } - } - return False; -} - -Public Bool -_XimEncodeLocalIMAttr( - XIMResourceList res, - XPointer top, - XPointer val) -{ - return _XimEncodeAttr(im_attr_info, XIMNumber(im_attr_info), - res, top, val); -} - -Public Bool -_XimEncodeLocalICAttr( - Xic ic, - XIMResourceList res, - XPointer top, - XIMArg *arg, - unsigned long mode) -{ - unsigned int num; - XimValueOffsetInfo info; - - if(mode & XIM_PREEDIT_ATTR) { - info = ic_pre_attr_info; - num = XIMNumber(ic_pre_attr_info); - } else if(mode & XIM_STATUS_ATTR) { - info = ic_sts_attr_info; - num = XIMNumber(ic_sts_attr_info); - } else { - info = ic_attr_info; - num = XIMNumber(ic_attr_info); - } - - return _XimEncodeAttr(info, num, res, top, arg->value); -} - -Private Bool -_XimEncodeLocalTopValue( - Xic ic, - XIMResourceList res, - XPointer val, - Bool flag) -{ - XIMArg *p = (XIMArg *)val; - - if (res->xrm_name == XrmStringToQuark(XNClientWindow)) { - ic->core.client_window = (Window)p->value; - if (ic->core.focus_window == (Window)0) - ic->core.focus_window = ic->core.client_window; - if (flag) { - _XRegisterFilterByType(ic->core.im->core.display, - ic->core.focus_window, - KeyPress, KeyRelease, _XimLocalFilter, (XPointer)ic); - } - } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) { - if (ic->core.client_window) { - if (flag) { - _XUnregisterFilter(ic->core.im->core.display, - ic->core.focus_window, _XimLocalFilter, (XPointer)ic); - } - ic->core.focus_window = (Window)p->value; - if (flag) { - _XRegisterFilterByType(ic->core.im->core.display, - ic->core.focus_window, KeyPress, KeyRelease, - _XimLocalFilter, (XPointer)ic); - } - } else - ic->core.focus_window = (Window)p->value; - } - return True; -} - -Private Bool -_XimEncodeLocalPreeditValue( - Xic ic, - XIMResourceList res, - XPointer val) -{ - XIMArg *p = (XIMArg *)val; - - if (res->xrm_name == XrmStringToQuark(XNStdColormap)) { - XStandardColormap *colormap_ret; - int count; - - if (!(XGetRGBColormaps(ic->core.im->core.display, - ic->core.focus_window, &colormap_ret, - &count, (Atom)p->value))) - return False; - - Xfree(colormap_ret); - } - return True; -} - -Private Bool -_XimEncodeLocalStatusValue( - Xic ic, - XIMResourceList res, - XPointer val) -{ - XIMArg *p = (XIMArg *)val; - - if (res->xrm_name == XrmStringToQuark(XNStdColormap)) { - XStandardColormap *colormap_ret; - int count; - - if (!(XGetRGBColormaps(ic->core.im->core.display, - ic->core.focus_window, &colormap_ret, - &count, (Atom)p->value))) - return False; - - Xfree(colormap_ret); - } - return True; -} - -Public char * -_XimSetICValueData( - Xic ic, - XPointer top, - XIMResourceList res_list, - unsigned int list_num, - XIMArg *values, - unsigned long mode, - Bool flag) -{ - register XIMArg *p; - XIMResourceList res; - char *name; - int check; - XrmQuark pre_quark; - XrmQuark sts_quark; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - for(p = values; p->name != NULL; p++) { - if((res = _XimGetResourceListRec(res_list, list_num, - p->name)) == (XIMResourceList)NULL) { - return p->name; - } - if(res->xrm_name == pre_quark) { - if(((name = _XimSetICValueData(ic, - (XPointer)(&((XimDefICValues *)top)->preedit_attr), - res_list, list_num, (XIMArg *)p->value, - (mode | XIM_PREEDIT_ATTR), flag)))) { - return name; - } - } else if(res->xrm_name == sts_quark) { - if(((name = _XimSetICValueData(ic, - (XPointer)(&((XimDefICValues *)top)->status_attr), - res_list, list_num, (XIMArg *)p->value, - (mode | XIM_STATUS_ATTR), flag)))) { - return name; - } - } else { - check = _XimCheckICMode(res, mode); - if(check == XIM_CHECK_INVALID) { - continue; - } else if(check == XIM_CHECK_ERROR) { - return p->name; - } - - if(mode & XIM_PREEDIT_ATTR) { - if (!_XimEncodeLocalPreeditValue(ic, res, (XPointer)p)) - return False; - } else if(mode & XIM_STATUS_ATTR) { - if (!_XimEncodeLocalStatusValue(ic, res, (XPointer)p)) - return False; - } else { - if (!_XimEncodeLocalTopValue(ic, res, (XPointer)p, flag)) - return False; - } - if(_XimEncodeLocalICAttr(ic, res, top, p, mode) == False) { - return p->name; - } - } - } - return NULL; -} - -Private Bool -_XimCheckInputStyle( - XIMStyles *styles, - XIMStyle style) -{ - int num = styles->count_styles; - register int i; - - for(i = 0; i < num; i++) { - if(styles->supported_styles[i] == style) { - return True; - } - } - return False; -} - -Public Bool -_XimCheckLocalInputStyle( - Xic ic, - XPointer top, - XIMArg *values, - XIMStyles *styles, - XIMResourceList res_list, - unsigned int list_num) -{ - XrmQuark quark = XrmStringToQuark(XNInputStyle); - register XIMArg *p; - XIMResourceList res; - - for(p = values; p && p->name != NULL; p++) { - if(quark == XrmStringToQuark(p->name)) { - if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) { - return False; - } - if(!_XimEncodeLocalICAttr(ic, res, top, p, 0)) { - return False; - } - if (_XimCheckInputStyle(styles, - ((XimDefICValues *)top)->input_style)) { - return True; - } - return False; - } - } - return False; -} - -Private Bool -_XimDecodeAttr( - XimValueOffsetInfo info, - unsigned int num, - XIMResourceList res, - XPointer top, - XPointer val) -{ - register int i; - - for(i = 0; i < num; i++ ) { - if(info[i].quark == res->xrm_name) { - if(!info[i].decode) { - return False; - } - return (*info[i].decode)(&info[i], top, val); - } - } - return False; -} - -Public Bool -_XimDecodeLocalIMAttr( - XIMResourceList res, - XPointer top, - XPointer val) -{ - return _XimDecodeAttr(im_attr_info, XIMNumber(im_attr_info), - res, top, val); -} - -Public Bool -_XimDecodeLocalICAttr( - XIMResourceList res, - XPointer top, - XPointer val, - unsigned long mode) -{ - unsigned int num; - XimValueOffsetInfo info; - - if(mode & XIM_PREEDIT_ATTR) { - info = ic_pre_attr_info; - num = XIMNumber(ic_pre_attr_info); - } else if(mode & XIM_STATUS_ATTR) { - info = ic_sts_attr_info; - num = XIMNumber(ic_sts_attr_info); - } else { - info = ic_attr_info; - num = XIMNumber(ic_attr_info); - } - - return _XimDecodeAttr(info, num, res, top, val); -} - -Public char * -_XimGetICValueData(Xic ic, XPointer top, XIMResourceList res_list, - unsigned int list_num, XIMArg *values, unsigned long mode) -{ - register XIMArg *p; - XIMResourceList res; - char *name; - int check; - XrmQuark pre_quark; - XrmQuark sts_quark; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - for(p = values; p->name != NULL; p++) { - if((res = _XimGetResourceListRec(res_list, list_num, - p->name)) == (XIMResourceList)NULL) { - return p->name; - } - if(res->xrm_name == pre_quark) { - if((name = _XimGetICValueData(ic, - (XPointer)(&((XimDefICValues *)top)->preedit_attr), - res_list, list_num, (XIMArg *)p->value, - (mode | XIM_PREEDIT_ATTR)))) { - return name; - } - } else if(res->xrm_name == sts_quark) { - if((name = _XimGetICValueData(ic, - (XPointer)(&((XimDefICValues *)top)->status_attr), - res_list, list_num, (XIMArg *)p->value, - (mode | XIM_STATUS_ATTR)))) { - return name; - } - } else { - check = _XimCheckICMode(res, mode); - if(check == XIM_CHECK_INVALID) { - continue; - } else if(check == XIM_CHECK_ERROR) { - return p->name; - } - - if(_XimDecodeLocalICAttr(res, top, p->value, mode) == False) { - return p->name; - } - } - } - return NULL; -} - -Public void -_XimGetCurrentIMValues(Xim im, XimDefIMValues *im_values) -{ - bzero((char *)im_values, sizeof(XimDefIMValues)); - - im_values->styles = im->core.styles; - im_values->im_values_list = im->core.im_values_list; - im_values->ic_values_list = im->core.ic_values_list; - im_values->destroy_callback = im->core.destroy_callback; - im_values->res_name = im->core.res_name; - im_values->res_class = im->core.res_class; - im_values->visible_position = im->core.visible_position; -} - -Public void -_XimSetCurrentIMValues(Xim im, XimDefIMValues *im_values) -{ - im->core.styles = im_values->styles; - im->core.im_values_list = im_values->im_values_list; - im->core.ic_values_list = im_values->ic_values_list; - im->core.destroy_callback = im_values->destroy_callback; - im->core.res_name = im_values->res_name; - im->core.res_class = im_values->res_class; - im->core.visible_position = im_values->visible_position; -} - -Public void -_XimGetCurrentICValues(Xic ic, XimDefICValues *ic_values) -{ - bzero((char *)ic_values, sizeof(XimDefICValues)); - - ic_values->input_style = ic->core.input_style; - ic_values->client_window = ic->core.client_window; - ic_values->focus_window = ic->core.focus_window; - ic_values->filter_events = ic->core.filter_events; - ic_values->geometry_callback = ic->core.geometry_callback; - ic_values->res_name = ic->core.res_name; - ic_values->res_class = ic->core.res_class; - ic_values->destroy_callback = ic->core.destroy_callback; - ic_values->string_conversion_callback - = ic->core.string_conversion_callback; - ic_values->string_conversion = ic->core.string_conversion; - ic_values->reset_state = ic->core.reset_state; - ic_values->hotkey = ic->core.hotkey; - ic_values->hotkey_state = ic->core.hotkey_state; - ic_values->preedit_attr = ic->core.preedit_attr; - ic_values->status_attr = ic->core.status_attr; -} - -Public void -_XimSetCurrentICValues( - Xic ic, - XimDefICValues *ic_values) -{ - ic->core.input_style = ic_values->input_style; - ic->core.client_window = ic_values->client_window; - if (ic_values->focus_window) - ic->core.focus_window = ic_values->focus_window; - ic->core.filter_events = ic_values->filter_events; - ic->core.geometry_callback = ic_values->geometry_callback; - ic->core.res_name = ic_values->res_name; - ic->core.res_class = ic_values->res_class; - ic->core.destroy_callback = ic_values->destroy_callback; - ic->core.string_conversion_callback - = ic_values->string_conversion_callback; - ic->core.string_conversion = ic_values->string_conversion; - ic->core.reset_state = ic_values->reset_state; - ic->core.hotkey = ic_values->hotkey; - ic->core.hotkey_state = ic_values->hotkey_state; - ic->core.preedit_attr = ic_values->preedit_attr; - ic->core.status_attr = ic_values->status_attr; -} - -Private void -_XimInitialIMOffsetInfo(void) -{ - unsigned int n = XIMNumber(im_attr_info); - register int i; - - for(i = 0; i < n; i++) { - im_attr_info[i].quark = XrmStringToQuark(GET_NAME(im_attr_info[i])); - } -} - -Private void -_XimInitialICOffsetInfo(void) -{ - unsigned int n; - register int i; - - n = XIMNumber(ic_attr_info); - for(i = 0; i < n; i++) { - ic_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_attr_info[i])); - } - - n = XIMNumber(ic_pre_attr_info); - for(i = 0; i < n; i++) { - ic_pre_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_pre_attr_info[i])); - } - - n = XIMNumber(ic_sts_attr_info); - for(i = 0; i < n; i++) { - ic_sts_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_sts_attr_info[i])); - } -} - -Private void -_XimInitialIMMode(void) -{ - unsigned int n = XIMNumber(im_mode); - register int i; - - for(i = 0; i < n; i++) { - im_mode_quark[i] = XrmStringToQuark(GET_NAME(im_mode[i])); - } -} - -Private void -_XimInitialICMode(void) -{ - unsigned int n = XIMNumber(ic_mode); - register int i; - - for(i = 0; i < n; i++) { - ic_mode_quark[i] = XrmStringToQuark(GET_NAME(ic_mode[i])); - } -} - -Public void -_XimInitialResourceInfo(void) -{ - static Bool init_flag = False; - - if(init_flag == True) { - return; - } - _XimInitialIMOffsetInfo(); - _XimInitialICOffsetInfo(); - _XimInitialIMMode(); - _XimInitialICMode(); - init_flag = True; -} +/******************************************************************
+
+ Copyright 1990, 1991, 1992,1993, 1994 by FUJITSU LIMITED
+ Copyright 1994 by Sony Corporation
+
+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 FUJITSU LIMITED
+and Sony Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission. FUJITSU LIMITED and Sony Corporation make
+no representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED AND SONY CORPORATION DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU LIMITED AND
+SONY CORPORATION 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Modifier: Makoto Wakamatsu Sony Corporation
+ makoto@sm.sony.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "Xresource.h"
+
+#define GET_NAME(x) name_table + x.name_offset
+
+typedef struct _XimValueOffsetInfo {
+ unsigned short name_offset;
+ XrmQuark quark;
+ unsigned int offset;
+ Bool (*defaults)(
+ struct _XimValueOffsetInfo *, XPointer, XPointer, unsigned long
+ );
+ Bool (*encode)(
+ struct _XimValueOffsetInfo *, XPointer, XPointer
+ );
+ Bool (*decode)(
+ struct _XimValueOffsetInfo *, XPointer, XPointer
+ );
+} XimValueOffsetInfoRec, *XimValueOffsetInfo;
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimCheckBool(str)
+ char *str;
+{
+ if(!strcmp(str, "True") || !strcmp(str, "true") ||
+ !strcmp(str, "Yes") || !strcmp(str, "yes") ||
+ !strcmp(str, "ON") || !strcmp(str, "on"))
+ return True;
+ return False;
+}
+
+Public void
+_XimSetProtoResource(im)
+ Xim im;
+{
+ char res_name_buf[256];
+ char* res_name;
+ char res_class_buf[256];
+ char* res_class;
+ char* str_type;
+ XrmValue value;
+ XIMStyle preedit_style = 0;
+ XIMStyle status_style = 0;
+ XIMStyles* imstyles;
+ char* dotximdot = ".xim.";
+ char* ximdot = "xim.";
+ char* dotXimdot = ".Xim.";
+ char* Ximdot = "Xim.";
+
+ if (!im->core.rdb)
+ return;
+
+ if (strlen (im->core.res_name) < 200) res_name = res_name_buf;
+ else res_name = Xmalloc (strlen (im->core.res_name) + 50);
+ if (strlen (im->core.res_class) < 200) res_class = res_class_buf;
+ else res_class = Xmalloc (strlen (im->core.res_class) + 50);
+ /* pretend malloc always works */
+
+ (void) sprintf (res_name, "%s%s%s",
+ im->core.res_name != NULL ? im->core.res_name : "*",
+ im->core.res_name != NULL ? dotximdot : ximdot,
+ "useAuth");
+ (void) sprintf (res_class, "%s%s%s",
+ im->core.res_class != NULL ? im->core.res_class : "*",
+ im->core.res_class != NULL ? dotXimdot : Ximdot,
+ "UseAuth");
+ bzero(&value, sizeof(XrmValue));
+ if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) {
+ if(_XimCheckBool(value.addr)) {
+ MARK_USE_AUTHORIZATION_FUNC(im);
+ }
+ }
+
+ (void) sprintf (res_name, "%s%s%s",
+ im->core.res_name != NULL ? im->core.res_name : "*",
+ im->core.res_name != NULL ? dotximdot : ximdot,
+ "delaybinding");
+ (void) sprintf (res_class, "%s%s%s",
+ im->core.res_class != NULL ? im->core.res_class : "*",
+ im->core.res_class != NULL ? dotXimdot : Ximdot,
+ "Delaybinding");
+ bzero(&value, sizeof(XrmValue));
+ if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) {
+ if(_XimCheckBool(value.addr)) {
+ MARK_DELAYBINDABLE(im);
+ }
+ }
+
+ (void) sprintf (res_name, "%s%s%s",
+ im->core.res_name != NULL ? im->core.res_name : "*",
+ im->core.res_name != NULL ? dotximdot : ximdot,
+ "reconnect");
+ (void) sprintf (res_class, "%s%s%s",
+ im->core.res_class != NULL ? im->core.res_class : "*",
+ im->core.res_class != NULL ? dotXimdot : Ximdot,
+ "Reconnect");
+ bzero(&value, sizeof(XrmValue));
+ if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) {
+ if(_XimCheckBool(value.addr)) {
+ MARK_RECONNECTABLE(im);
+ }
+ }
+
+ if(!IS_CONNECTABLE(im)) {
+ if (res_name != res_name_buf) Xfree (res_name);
+ if (res_class != res_class_buf) Xfree (res_class);
+ return;
+ }
+
+ (void) sprintf (res_name, "%s%s%s",
+ im->core.res_name != NULL ? im->core.res_name : "*",
+ im->core.res_name != NULL ? dotximdot : ximdot,
+ "preeditDefaultStyle");
+ (void) sprintf (res_class, "%s%s%s",
+ im->core.res_class != NULL ? im->core.res_class : "*",
+ im->core.res_class != NULL ? dotXimdot : Ximdot,
+ "PreeditDefaultStyle");
+ if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) {
+ if(!strcmp(value.addr, "XIMPreeditArea"))
+ preedit_style = XIMPreeditArea;
+ else if(!strcmp(value.addr, "XIMPreeditCallbacks"))
+ preedit_style = XIMPreeditCallbacks;
+ else if(!strcmp(value.addr, "XIMPreeditPosition"))
+ preedit_style = XIMPreeditPosition;
+ else if(!strcmp(value.addr, "XIMPreeditNothing"))
+ preedit_style = XIMPreeditNothing;
+ else if(!strcmp(value.addr, "XIMPreeditNone"))
+ preedit_style = XIMPreeditNone;
+ }
+ if(!preedit_style)
+ preedit_style = XIMPreeditNothing;
+
+ (void) sprintf (res_name, "%s%s%s",
+ im->core.res_name != NULL ? im->core.res_name : "*",
+ im->core.res_name != NULL ? dotximdot : ximdot,
+ "statusDefaultStyle");
+ (void) sprintf (res_class, "%s%s%s",
+ im->core.res_class != NULL ? im->core.res_class : "*",
+ im->core.res_class != NULL ? dotXimdot : Ximdot,
+ "StatusDefaultStyle");
+ if(XrmGetResource(im->core.rdb, res_name, res_class, &str_type, &value)) {
+ if(!strcmp(value.addr, "XIMStatusArea"))
+ status_style = XIMStatusArea;
+ else if(!strcmp(value.addr, "XIMStatusCallbacks"))
+ status_style = XIMStatusCallbacks;
+ else if(!strcmp(value.addr, "XIMStatusNothing"))
+ status_style = XIMStatusNothing;
+ else if(!strcmp(value.addr, "XIMStatusNone"))
+ status_style = XIMStatusNone;
+ }
+ if(!status_style)
+ status_style = XIMStatusNothing;
+
+ if(!(imstyles = (XIMStyles *)Xmalloc(sizeof(XIMStyles) + sizeof(XIMStyle)))){
+ if (res_name != res_name_buf) Xfree (res_name);
+ if (res_class != res_class_buf) Xfree (res_class);
+ return;
+ }
+ imstyles->count_styles = 1;
+ imstyles->supported_styles =
+ (XIMStyle *)((char *)imstyles + sizeof(XIMStyles));
+ imstyles->supported_styles[0] = preedit_style | status_style;
+ im->private.proto.default_styles = imstyles;
+ if (res_name != res_name_buf) Xfree (res_name);
+ if (res_class != res_class_buf) Xfree (res_class);
+}
+#endif /* XIM_CONNECTABLE */
+
+static const char name_table[] =
+ /* 0 */ XNQueryInputStyle"\0"
+ /* 16 */ XNClientWindow"\0"
+ /* 29 */ XNInputStyle"\0"
+ /* 40 */ XNFocusWindow"\0"
+ /* 52 */ XNResourceName"\0"
+ /* 65 */ XNResourceClass"\0"
+ /* 79 */ XNGeometryCallback"\0"
+ /* 96 */ XNDestroyCallback"\0"
+ /* 112 */ XNFilterEvents"\0"
+ /* 125 */ XNPreeditStartCallback"\0"
+ /* 146 */ XNPreeditDoneCallback"\0"
+ /* 166 */ XNPreeditDrawCallback"\0"
+ /* 186 */ XNPreeditCaretCallback"\0"
+ /* 207 */ XNPreeditStateNotifyCallback"\0"
+ /* 234 */ XNPreeditAttributes"\0"
+ /* 252 */ XNStatusStartCallback"\0"
+ /* 272 */ XNStatusDoneCallback"\0"
+ /* 291 */ XNStatusDrawCallback"\0"
+ /* 310 */ XNStatusAttributes"\0"
+ /* 327 */ XNArea"\0"
+ /* 332 */ XNAreaNeeded"\0"
+ /* 343 */ XNSpotLocation"\0"
+ /* 356 */ XNColormap"\0"
+ /* 365 */ XNStdColormap"\0"
+ /* 377 */ XNForeground"\0"
+ /* 388 */ XNBackground"\0"
+ /* 399 */ XNBackgroundPixmap"\0"
+ /* 416 */ XNFontSet"\0"
+ /* 424 */ XNLineSpace"\0"
+ /* 434 */ XNCursor"\0"
+ /* 441 */ XNQueryIMValuesList"\0"
+ /* 459 */ XNQueryICValuesList"\0"
+ /* 477 */ XNVisiblePosition"\0"
+ /* 493 */ XNStringConversionCallback"\0"
+ /* 518 */ XNStringConversion"\0"
+ /* 535 */ XNResetState"\0"
+ /* 546 */ XNHotKey"\0"
+ /* 553 */ XNHotKeyState"\0"
+ /* 565 */ XNPreeditState
+;
+
+#define OFFSET_XNQUERYINPUTSTYLE 0
+#define OFFSET_XNCLIENTWINDOW 16
+#define OFFSET_XNINPUTSTYLE 29
+#define OFFSET_XNFOCUSWINDOW 40
+#define OFFSET_XNRESOURCENAME 52
+#define OFFSET_XNRESOURCECLASS 65
+#define OFFSET_XNGEOMETRYCALLBACK 79
+#define OFFSET_XNDESTROYCALLBACK 96
+#define OFFSET_XNFILTEREVENTS 112
+#define OFFSET_XNPREEDITSTARTCALLBACK 125
+#define OFFSET_XNPREEDITDONECALLBACK 146
+#define OFFSET_XNPREEDITDRAWCALLBACK 166
+#define OFFSET_XNPREEDITCARETCALLBACK 186
+#define OFFSET_XNPREEDITSTATENOTIFYCALLBACK 207
+#define OFFSET_XNPREEDITATTRIBUTES 234
+#define OFFSET_XNSTATUSSTARTCALLBACK 252
+#define OFFSET_XNSTATUSDONECALLBACK 272
+#define OFFSET_XNSTATUSDRAWCALLBACK 291
+#define OFFSET_XNSTATUSATTRIBUTES 310
+#define OFFSET_XNAREA 327
+#define OFFSET_XNAREANEEDED 332
+#define OFFSET_XNSPOTLOCATION 343
+#define OFFSET_XNCOLORMAP 356
+#define OFFSET_XNSTDCOLORMAP 365
+#define OFFSET_XNFOREGROUND 377
+#define OFFSET_XNBACKGROUND 388
+#define OFFSET_XNBACKGROUNDPIXMAP 399
+#define OFFSET_XNFONTSET 416
+#define OFFSET_XNLINESPACE 424
+#define OFFSET_XNCURSOR 434
+#define OFFSET_XNQUERYIMVALUESLIST 441
+#define OFFSET_XNQUERYICVALUESLIST 459
+#define OFFSET_XNVISIBLEPOSITION 477
+#define OFFSET_XNSTRINGCONVERSIONCALLBACK 493
+#define OFFSET_XNSTRINGCONVERSION 518
+#define OFFSET_XNRESETSTATE 535
+#define OFFSET_XNHOTKEY 546
+#define OFFSET_XNHOTKEYSTATE 553
+#define OFFSET_XNPREEDITSTATE 565
+
+/* offsets into name_table */
+static const unsigned short supported_local_im_values_list[] = {
+ OFFSET_XNQUERYINPUTSTYLE,
+ OFFSET_XNRESOURCENAME,
+ OFFSET_XNRESOURCECLASS,
+ OFFSET_XNDESTROYCALLBACK,
+ OFFSET_XNQUERYIMVALUESLIST,
+ OFFSET_XNQUERYICVALUESLIST,
+ OFFSET_XNVISIBLEPOSITION
+};
+
+/* offsets into name_table */
+static const unsigned short supported_local_ic_values_list[] = {
+ OFFSET_XNINPUTSTYLE,
+ OFFSET_XNCLIENTWINDOW,
+ OFFSET_XNFOCUSWINDOW,
+ OFFSET_XNRESOURCENAME,
+ OFFSET_XNRESOURCECLASS,
+ OFFSET_XNGEOMETRYCALLBACK,
+ OFFSET_XNFILTEREVENTS,
+ OFFSET_XNDESTROYCALLBACK,
+ OFFSET_XNSTRINGCONVERSIONCALLBACK,
+ OFFSET_XNSTRINGCONVERSIONCALLBACK,
+ OFFSET_XNRESETSTATE,
+ OFFSET_XNHOTKEY,
+ OFFSET_XNHOTKEYSTATE,
+ OFFSET_XNPREEDITATTRIBUTES,
+ OFFSET_XNSTATUSATTRIBUTES,
+ OFFSET_XNAREA,
+ OFFSET_XNAREANEEDED,
+ OFFSET_XNSPOTLOCATION,
+ OFFSET_XNCOLORMAP,
+ OFFSET_XNSTDCOLORMAP,
+ OFFSET_XNFOREGROUND,
+ OFFSET_XNBACKGROUND,
+ OFFSET_XNBACKGROUNDPIXMAP,
+ OFFSET_XNFONTSET,
+ OFFSET_XNLINESPACE,
+ OFFSET_XNCURSOR,
+ OFFSET_XNPREEDITSTARTCALLBACK,
+ OFFSET_XNPREEDITDONECALLBACK,
+ OFFSET_XNPREEDITDRAWCALLBACK,
+ OFFSET_XNPREEDITCARETCALLBACK,
+ OFFSET_XNSTATUSSTARTCALLBACK,
+ OFFSET_XNSTATUSDONECALLBACK,
+ OFFSET_XNSTATUSDRAWCALLBACK,
+ OFFSET_XNPREEDITSTATE,
+ OFFSET_XNPREEDITSTATENOTIFYCALLBACK
+};
+
+static XIMStyle const supported_local_styles[] = {
+ XIMPreeditNone | XIMStatusNone,
+ XIMPreeditNothing | XIMStatusNothing,
+ 0 /* dummy */
+};
+
+Private Bool
+_XimDefaultStyles(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm, /* unused */
+ unsigned long mode) /* unused */
+{
+ XIMStyles *styles;
+ XIMStyles **out;
+ register int i;
+ unsigned int n;
+ int len;
+ XPointer tmp;
+
+ n = XIMNumber(supported_local_styles) - 1;
+ len = sizeof(XIMStyles) + sizeof(XIMStyle) * n;
+ if(!(tmp = Xcalloc(1, len))) {
+ return False;
+ }
+
+ styles = (XIMStyles *)tmp;
+ if (n > 0) {
+ styles->count_styles = (unsigned short)n;
+ styles->supported_styles =
+ (XIMStyle *)((char *)tmp + sizeof(XIMStyles));
+ for(i = 0; i < n; i++) {
+ styles->supported_styles[i] = supported_local_styles[i];
+ }
+ }
+
+ out = (XIMStyles **)((char *)top + info->offset);
+ *out = styles;
+ return True;
+}
+
+Private Bool
+_XimDefaultIMValues(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm, /* unused */
+ unsigned long mode) /* unused */
+{
+ XIMValuesList *values_list;
+ XIMValuesList **out;
+ register int i;
+ unsigned int n;
+ int len;
+ XPointer tmp;
+
+ n = XIMNumber(supported_local_im_values_list);
+ len = sizeof(XIMValuesList) + sizeof(char **) * n;
+ if(!(tmp = Xcalloc(1, len))) {
+ return False;
+ }
+
+ values_list = (XIMValuesList *)tmp;
+ if (n > 0) {
+ values_list->count_values = (unsigned short)n;
+ values_list->supported_values
+ = (char **)((char *)tmp + sizeof(XIMValuesList));
+ for(i = 0; i < n; i++) {
+ values_list->supported_values[i] =
+ (char *)name_table + supported_local_im_values_list[i];
+ }
+ }
+
+ out = (XIMValuesList **)((char *)top + info->offset);
+ *out = values_list;
+ return True;
+}
+
+Private Bool
+_XimDefaultICValues(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm, /* unused */
+ unsigned long mode) /* unused */
+{
+ XIMValuesList *values_list;
+ XIMValuesList **out;
+ register int i;
+ unsigned int n;
+ int len;
+ XPointer tmp;
+
+ n = XIMNumber(supported_local_ic_values_list);
+ len = sizeof(XIMValuesList) + sizeof(char **) * n;
+ if(!(tmp = Xcalloc(1, len))) {
+ return False;
+ }
+
+ values_list = (XIMValuesList *)tmp;
+ if (n > 0) {
+ values_list->count_values = (unsigned short)n;
+ values_list->supported_values
+ = (char **)((char *)tmp + sizeof(XIMValuesList));
+ for(i = 0; i < n; i++) {
+ values_list->supported_values[i] =
+ (char *)name_table + supported_local_ic_values_list[i];
+ }
+ }
+
+ out = (XIMValuesList **)((char *)top + info->offset);
+ *out = values_list;
+ return True;
+}
+
+Private Bool
+_XimDefaultVisiblePos(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm, /* unused */
+ unsigned long mode) /* unused */
+{
+ Bool *out;
+
+ out = (Bool *)((char *)top + info->offset);
+ *out = False;
+ return True;
+}
+
+Private Bool
+_XimDefaultFocusWindow(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Window *out;
+
+ if(ic->core.client_window == (Window)NULL) {
+ return True;
+ }
+
+ out = (Window *)((char *)top + info->offset);
+ *out = ic->core.client_window;
+ return True;
+}
+
+Private Bool
+_XimDefaultResName(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ char **out;
+
+ if(im->core.res_name == (char *)NULL) {
+ return True;
+ }
+
+ out = (char **)((char *)top + info->offset);
+ *out = im->core.res_name;
+ return True;
+}
+
+Private Bool
+_XimDefaultResClass(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ char **out;
+
+ if(im->core.res_class == (char *)NULL) {
+ return True;
+ }
+
+ out = (char **)((char *)top + info->offset);
+ *out = im->core.res_class;
+ return True;
+}
+
+Private Bool
+_XimDefaultDestroyCB(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ XIMCallback *out;
+
+ out = (XIMCallback *)((char *)top + info->offset);
+ *out = im->core.destroy_callback;
+ return True;
+}
+
+Private Bool
+_XimDefaultResetState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ XIMResetState *out;
+
+ out = (XIMResetState *)((char *)top + info->offset);
+ *out = XIMInitialState;
+ return True;
+}
+
+Private Bool
+_XimDefaultHotKeyState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ XIMHotKeyState *out;
+
+ out = (XIMHotKeyState *)((char *)top + info->offset);
+ *out = XIMHotKeyStateOFF;
+ return True;
+}
+
+Private Bool
+_XimDefaultArea(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ Window root_return;
+ int x_return, y_return;
+ unsigned int width_return, height_return;
+ unsigned int border_width_return;
+ unsigned int depth_return;
+ XRectangle area;
+ XRectangle *out;
+
+ if(ic->core.focus_window == (Window)NULL) {
+ return True;
+ }
+ if(XGetGeometry(im->core.display, (Drawable)ic->core.focus_window,
+ &root_return, &x_return, &y_return, &width_return,
+ &height_return, &border_width_return, &depth_return)
+ == (Status)Success) {
+ return True;
+ }
+ area.x = 0;
+ area.y = 0;
+ area.width = width_return;
+ area.height = height_return;
+
+ out = (XRectangle *)((char *)top + info->offset);
+ *out = area;
+ return True;
+}
+
+Private Bool
+_XimDefaultColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ XWindowAttributes win_attr;
+ Colormap *out;
+
+ if(ic->core.client_window == (Window)NULL) {
+ return True;
+ }
+ if(XGetWindowAttributes(im->core.display, ic->core.client_window,
+ &win_attr) == (Status)Success) {
+ return True;
+ }
+
+ out = (Colormap *)((char *)top + info->offset);
+ *out = win_attr.colormap;
+ return True;
+}
+
+Private Bool
+_XimDefaultStdColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Atom *out;
+
+ out = (Atom *)((char *)top + info->offset);
+ *out = (Atom)0;
+ return True;
+}
+
+Private Bool
+_XimDefaultFg(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ unsigned long fg;
+ unsigned long *out;
+
+ fg = WhitePixel(im->core.display, DefaultScreen(im->core.display));
+ out = (unsigned long *)((char *)top + info->offset);
+ *out = fg;
+ return True;
+}
+
+Private Bool
+_XimDefaultBg(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ Xim im = (Xim)ic->core.im;
+ unsigned long bg;
+ unsigned long *out;
+
+ bg = BlackPixel(im->core.display, DefaultScreen(im->core.display));
+ out = (unsigned long *)((char *)top + info->offset);
+ *out = bg;
+ return True;
+}
+
+Private Bool
+_XimDefaultBgPixmap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Pixmap *out;
+
+ out = (Pixmap *)((char *)top + info->offset);
+ *out = (Pixmap)0;
+ return True;
+}
+
+Private Bool
+_XimDefaultFontSet(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ XFontSet *out;
+
+ out = (XFontSet *)((char *)top + info->offset);
+ *out = 0;
+ return True;
+}
+
+Private Bool
+_XimDefaultLineSpace(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Xic ic = (Xic)parm;
+ XFontSet fontset;
+ XFontSetExtents *fset_extents;
+ int line_space = 0;
+ int *out;
+
+ if(mode & XIM_PREEDIT_ATTR) {
+ fontset = ic->core.preedit_attr.fontset;
+ } else if(mode & XIM_STATUS_ATTR) {
+ fontset = ic->core.status_attr.fontset;
+ } else {
+ return True;
+ }
+ if (fontset) {
+ fset_extents = XExtentsOfFontSet(fontset);
+ line_space = fset_extents->max_logical_extent.height;
+ }
+ out = (int *)((char *)top + info->offset);
+ *out = line_space;
+ return True;
+}
+
+Private Bool
+_XimDefaultCursor(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ Cursor *out;
+
+ out = (Cursor *)((char *)top + info->offset);
+ *out = (Cursor)0;
+ return True;
+}
+
+Private Bool
+_XimDefaultPreeditState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ XIMPreeditState *out;
+
+ out = (XIMPreeditState *)((char *)top + info->offset);
+ *out = XIMPreeditDisable;
+ return True;
+}
+
+Private Bool
+_XimDefaultNest(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer parm,
+ unsigned long mode)
+{
+ return True;
+}
+
+Private Bool
+_XimEncodeCallback(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMCallback *out;
+
+ out = (XIMCallback *)((char *)top + info->offset);
+ *out = *((XIMCallback *)val);
+ return True;
+}
+
+Private Bool
+_XimEncodeString(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ char *string;
+ char **out;
+
+ if(val == (XPointer)NULL) {
+ return False;
+ }
+ if (!(string = strdup((char *)val))) {
+ return False;
+ }
+
+ out = (char **)((char *)top + info->offset);
+ if(*out) {
+ Xfree(*out);
+ }
+ *out = string;
+ return True;
+}
+
+Private Bool
+_XimEncodeStyle(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMStyle *out;
+
+ out = (XIMStyle *)((char *)top + info->offset);
+ *out = (XIMStyle)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeWindow(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Window *out;
+
+ out = (Window *)((char *)top + info->offset);
+ *out = (Window)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeStringConv(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ /*
+ * Not yet
+ */
+ return True;
+}
+
+Private Bool
+_XimEncodeResetState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMResetState *out;
+
+ out = (XIMResetState *)((char *)top + info->offset);
+ *out = (XIMResetState)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeHotKey(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMHotKeyTriggers *hotkey = (XIMHotKeyTriggers *)val;
+ XIMHotKeyTriggers **out;
+ XIMHotKeyTriggers *key_list;
+ XIMHotKeyTrigger *key;
+ XPointer tmp;
+ int num;
+ int len;
+ register int i;
+
+ if(hotkey == (XIMHotKeyTriggers *)NULL) {
+ return True;
+ }
+
+ if((num = hotkey->num_hot_key) == 0) {
+ return True;
+ }
+
+ len = sizeof(XIMHotKeyTriggers) + sizeof(XIMHotKeyTrigger) * num;
+ if(!(tmp = (XPointer)Xmalloc(len))) {
+ return False;
+ }
+
+ key_list = (XIMHotKeyTriggers *)tmp;
+ key = (XIMHotKeyTrigger *)((char *)tmp + sizeof(XIMHotKeyTriggers));
+
+ for(i = 0; i < num; i++) {
+ key[i] = hotkey->key[i];
+ }
+
+ key_list->num_hot_key = num;
+ key_list->key = key;
+
+ out = (XIMHotKeyTriggers **)((char *)top + info->offset);
+ *out = key_list;
+ return True;
+}
+
+Private Bool
+_XimEncodeHotKetState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMHotKeyState *out;
+
+ out = (XIMHotKeyState *)((char *)top + info->offset);
+ *out = (XIMHotKeyState)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeRectangle(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XRectangle *out;
+
+ out = (XRectangle *)((char *)top + info->offset);
+ *out = *((XRectangle *)val);
+ return True;
+}
+
+Private Bool
+_XimEncodeSpot(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XPoint *out;
+
+ out = (XPoint *)((char *)top + info->offset);
+ *out = *((XPoint *)val);
+ return True;
+}
+
+Private Bool
+_XimEncodeColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Colormap *out;
+
+ out = (Colormap *)((char *)top + info->offset);
+ *out = (Colormap)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeStdColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Atom *out;
+
+ out = (Atom *)((char *)top + info->offset);
+ *out = (Atom)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeLong(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ unsigned long *out;
+
+ out = (unsigned long *)((char *)top + info->offset);
+ *out = (unsigned long)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeBgPixmap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Pixmap *out;
+
+ out = (Pixmap *)((char *)top + info->offset);
+ *out = (Pixmap)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeFontSet(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XFontSet *out;
+
+ out = (XFontSet *)((char *)top + info->offset);
+ *out = (XFontSet)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeLineSpace(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ int *out;
+
+ out = (int *)((char *)top + info->offset);
+ *out = (long)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeCursor(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Cursor *out;
+
+ out = (Cursor *)((char *)top + info->offset);
+ *out = (Cursor)val;
+ return True;
+}
+
+Private Bool
+_XimEncodePreeditState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMPreeditState *out;
+
+ out = (XIMPreeditState *)((char *)top + info->offset);
+ *out = (XIMPreeditState)val;
+ return True;
+}
+
+Private Bool
+_XimEncodeNest(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ return True;
+}
+
+Private Bool
+_XimDecodeStyles(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMStyles *styles;
+ XIMStyles *out;
+ register int i;
+ unsigned int num;
+ int len;
+ XPointer tmp;
+
+ if(val == (XPointer)NULL) {
+ return False;
+ }
+
+ styles = *((XIMStyles **)((char *)top + info->offset));
+ num = styles->count_styles;
+
+ len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
+ if(!(tmp = Xcalloc(1, len))) {
+ return False;
+ }
+
+ out = (XIMStyles *)tmp;
+ if(num >0) {
+ out->count_styles = (unsigned short)num;
+ out->supported_styles = (XIMStyle *)((char *)tmp + sizeof(XIMStyles));
+
+ for(i = 0; i < num; i++) {
+ out->supported_styles[i] = styles->supported_styles[i];
+ }
+ }
+ *((XIMStyles **)val) = out;
+ return True;
+}
+
+Private Bool
+_XimDecodeValues(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMValuesList *values_list;
+ XIMValuesList *out;
+ register int i;
+ unsigned int num;
+ int len;
+ XPointer tmp;
+
+ if(val == (XPointer)NULL) {
+ return False;
+ }
+
+ values_list = *((XIMValuesList **)((char *)top + info->offset));
+ num = values_list->count_values;
+
+ len = sizeof(XIMValuesList) + sizeof(char **) * num;
+ if(!(tmp = Xcalloc(1, len))) {
+ return False;
+ }
+
+ out = (XIMValuesList *)tmp;
+ if(num) {
+ out->count_values = (unsigned short)num;
+ out->supported_values = (char **)((char *)tmp + sizeof(XIMValuesList));
+
+ for(i = 0; i < num; i++) {
+ out->supported_values[i] = values_list->supported_values[i];
+ }
+ }
+ *((XIMValuesList **)val) = out;
+ return True;
+}
+
+Private Bool
+_XimDecodeCallback(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMCallback *in;
+ XIMCallback *callback;
+
+ in = (XIMCallback *)((char *)top + info->offset);
+ if(!(callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback)))) {
+ return False;
+ }
+ callback->client_data = in->client_data;
+ callback->callback = in->callback;
+
+ *((XIMCallback **)val) = callback;
+ return True;
+}
+
+Private Bool
+_XimDecodeString(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ char *in;
+ char *string;
+
+ in = *((char **)((char *)top + info->offset));
+ if (in != NULL) {
+ string = strdup(in);
+ } else {
+ string = Xcalloc(1, 1); /* strdup("") */
+ }
+ if (string == NULL) {
+ return False;
+ }
+ *((char **)val) = string;
+ return True;
+}
+
+Private Bool
+_XimDecodeBool(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Bool *in;
+
+ in = (Bool *)((char *)top + info->offset);
+ *((Bool *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeStyle(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMStyle *in;
+
+ in = (XIMStyle *)((char *)top + info->offset);
+ *((XIMStyle *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeWindow(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Window *in;
+
+ in = (Window *)((char *)top + info->offset);
+ *((Window *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeStringConv(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ /*
+ * Not yet
+ */
+ return True;
+}
+
+Private Bool
+_XimDecodeResetState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMResetState *in;
+
+ in = (XIMResetState *)((char *)top + info->offset);
+ *((XIMResetState *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeHotKey(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMHotKeyTriggers *in;
+ XIMHotKeyTriggers *hotkey;
+ XIMHotKeyTrigger *key;
+ XPointer tmp;
+ int num;
+ int len;
+ register int i;
+
+ in = *((XIMHotKeyTriggers **)((char *)top + info->offset));
+ num = in->num_hot_key;
+ len = sizeof(XIMHotKeyTriggers) + sizeof(XIMHotKeyTrigger) * num;
+ if(!(tmp = (XPointer)Xmalloc(len))) {
+ return False;
+ }
+
+ hotkey = (XIMHotKeyTriggers *)tmp;
+ key = (XIMHotKeyTrigger *)((char *)tmp + sizeof(XIMHotKeyTriggers));
+
+ for(i = 0; i < num; i++) {
+ key[i] = in->key[i];
+ }
+ hotkey->num_hot_key = num;
+ hotkey->key = key;
+
+ *((XIMHotKeyTriggers **)val) = hotkey;
+ return True;
+}
+
+Private Bool
+_XimDecodeHotKetState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMHotKeyState *in;
+
+ in = (XIMHotKeyState *)((char *)top + info->offset);
+ *((XIMHotKeyState *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeRectangle(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XRectangle *in;
+ XRectangle *rect;
+
+ in = (XRectangle *)((char *)top + info->offset);
+ if(!(rect = (XRectangle *)Xmalloc(sizeof(XRectangle)))) {
+ return False;
+ }
+ *rect = *in;
+ *((XRectangle **)val) = rect;
+ return True;
+}
+
+Private Bool
+_XimDecodeSpot(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XPoint *in;
+ XPoint *spot;
+
+ in = (XPoint *)((char *)top + info->offset);
+ if(!(spot = (XPoint *)Xmalloc(sizeof(XPoint)))) {
+ return False;
+ }
+ *spot = *in;
+ *((XPoint **)val) = spot;
+ return True;
+}
+
+Private Bool
+_XimDecodeColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Colormap *in;
+
+ in = (Colormap *)((char *)top + info->offset);
+ *((Colormap *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeStdColormap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Atom *in;
+
+ in = (Atom *)((char *)top + info->offset);
+ *((Atom *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeLong(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ unsigned long *in;
+
+ in = (unsigned long *)((char *)top + info->offset);
+ *((unsigned long *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeBgPixmap(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Pixmap *in;
+
+ in = (Pixmap *)((char *)top + info->offset);
+ *((Pixmap *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeFontSet(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XFontSet *in;
+
+ in = (XFontSet *)((char *)top + info->offset);
+ *((XFontSet *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeLineSpace(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ int *in;
+
+ in = (int *)((char *)top + info->offset);
+ *((int *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeCursor(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ Cursor *in;
+
+ in = (Cursor *)((char *)top + info->offset);
+ *((Cursor *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodePreeditState(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ XIMPreeditState *in;
+
+ in = (XIMPreeditState *)((char *)top + info->offset);
+ *((XIMPreeditState *)val) = *in;
+ return True;
+}
+
+Private Bool
+_XimDecodeNest(
+ XimValueOffsetInfo info,
+ XPointer top,
+ XPointer val)
+{
+ return True;
+}
+
+static XIMResource im_resources[] = {
+ {XNQueryInputStyle, 0, XimType_XIMStyles, 0, 0, 0},
+ {XNDestroyCallback, 0, 0, 0, 0, 0},
+ {XNResourceName, 0, XimType_STRING8, 0, 0, 0},
+ {XNResourceClass, 0, XimType_STRING8, 0, 0, 0},
+ {XNQueryIMValuesList, 0, 0, 0, 0, 0},
+ {XNQueryICValuesList, 0, 0, 0, 0, 0},
+ {XNVisiblePosition, 0, 0, 0, 0, 0}
+};
+
+static XIMResource im_inner_resources[] = {
+ {XNDestroyCallback, 0, 0, 0, 0, 0},
+ {XNResourceName, 0, XimType_STRING8, 0, 0, 0},
+ {XNResourceClass, 0, XimType_STRING8, 0, 0, 0},
+ {XNQueryIMValuesList, 0, 0, 0, 0, 0},
+ {XNQueryICValuesList, 0, 0, 0, 0, 0},
+ {XNVisiblePosition, 0, 0, 0, 0, 0}
+};
+
+static XIMResource ic_resources[] = {
+ {XNInputStyle, 0, XimType_CARD32, 0, 0, 0},
+ {XNClientWindow, 0, XimType_Window, 0, 0, 0},
+ {XNFocusWindow, 0, XimType_Window, 0, 0, 0},
+ {XNResourceName, 0, XimType_STRING8, 0, 0, 0},
+ {XNResourceClass, 0, XimType_STRING8, 0, 0, 0},
+ {XNGeometryCallback, 0, 0, 0, 0, 0},
+ {XNFilterEvents, 0, XimType_CARD32, 0, 0, 0},
+ {XNDestroyCallback, 0, 0, 0, 0, 0},
+ {XNStringConversionCallback, 0, 0, 0, 0, 0},
+ {XNStringConversion, 0, XimType_XIMStringConversion,0, 0, 0},
+ {XNResetState, 0, 0, 0, 0, 0},
+ {XNHotKey, 0, XimType_XIMHotKeyTriggers,0, 0, 0},
+ {XNHotKeyState, 0, XimType_XIMHotKeyState, 0, 0, 0},
+ {XNPreeditAttributes, 0, XimType_NEST, 0, 0, 0},
+ {XNStatusAttributes, 0, XimType_NEST, 0, 0, 0},
+ {XNArea, 0, XimType_XRectangle, 0, 0, 0},
+ {XNAreaNeeded, 0, XimType_XRectangle, 0, 0, 0},
+ {XNSpotLocation, 0, XimType_XPoint, 0, 0, 0},
+ {XNColormap, 0, XimType_CARD32, 0, 0, 0},
+ {XNStdColormap, 0, XimType_CARD32, 0, 0, 0},
+ {XNForeground, 0, XimType_CARD32, 0, 0, 0},
+ {XNBackground, 0, XimType_CARD32, 0, 0, 0},
+ {XNBackgroundPixmap, 0, XimType_CARD32, 0, 0, 0},
+ {XNFontSet, 0, XimType_XFontSet, 0, 0, 0},
+ {XNLineSpace, 0, XimType_CARD32, 0, 0, 0},
+ {XNCursor, 0, XimType_CARD32, 0, 0, 0},
+ {XNPreeditStartCallback, 0, 0, 0, 0, 0},
+ {XNPreeditDoneCallback, 0, 0, 0, 0, 0},
+ {XNPreeditDrawCallback, 0, 0, 0, 0, 0},
+ {XNPreeditCaretCallback, 0, 0, 0, 0, 0},
+ {XNStatusStartCallback, 0, 0, 0, 0, 0},
+ {XNStatusDoneCallback, 0, 0, 0, 0, 0},
+ {XNStatusDrawCallback, 0, 0, 0, 0, 0},
+ {XNPreeditState, 0, 0, 0, 0, 0},
+ {XNPreeditStateNotifyCallback, 0, 0, 0, 0, 0},
+};
+
+static XIMResource ic_inner_resources[] = {
+ {XNResourceName, 0, XimType_STRING8, 0, 0, 0},
+ {XNResourceClass, 0, XimType_STRING8, 0, 0, 0},
+ {XNGeometryCallback, 0, 0, 0, 0, 0},
+ {XNDestroyCallback, 0, 0, 0, 0, 0},
+ {XNStringConversionCallback, 0, 0, 0, 0, 0},
+ {XNPreeditStartCallback, 0, 0, 0, 0, 0},
+ {XNPreeditDoneCallback, 0, 0, 0, 0, 0},
+ {XNPreeditDrawCallback, 0, 0, 0, 0, 0},
+ {XNPreeditCaretCallback, 0, 0, 0, 0, 0},
+ {XNStatusStartCallback, 0, 0, 0, 0, 0},
+ {XNStatusDoneCallback, 0, 0, 0, 0, 0},
+ {XNStatusDrawCallback, 0, 0, 0, 0, 0},
+ {XNPreeditStateNotifyCallback, 0, 0, 0, 0, 0},
+};
+
+static XimValueOffsetInfoRec im_attr_info[] = {
+ {OFFSET_XNQUERYINPUTSTYLE, 0,
+ XOffsetOf(XimDefIMValues, styles),
+ _XimDefaultStyles, NULL, _XimDecodeStyles},
+
+ {OFFSET_XNDESTROYCALLBACK, 0,
+ XOffsetOf(XimDefIMValues, destroy_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNRESOURCENAME, 0,
+ XOffsetOf(XimDefIMValues, res_name),
+ NULL, _XimEncodeString, _XimDecodeString},
+
+ {OFFSET_XNRESOURCECLASS, 0,
+ XOffsetOf(XimDefIMValues, res_class),
+ NULL, _XimEncodeString, _XimDecodeString},
+
+ {OFFSET_XNQUERYIMVALUESLIST, 0,
+ XOffsetOf(XimDefIMValues, im_values_list),
+ _XimDefaultIMValues, NULL, _XimDecodeValues},
+
+ {OFFSET_XNQUERYICVALUESLIST, 0,
+ XOffsetOf(XimDefIMValues, ic_values_list),
+ _XimDefaultICValues, NULL, _XimDecodeValues},
+
+ {OFFSET_XNVISIBLEPOSITION, 0,
+ XOffsetOf(XimDefIMValues, visible_position),
+ _XimDefaultVisiblePos, NULL, _XimDecodeBool}
+};
+
+static XimValueOffsetInfoRec ic_attr_info[] = {
+ {OFFSET_XNINPUTSTYLE, 0,
+ XOffsetOf(XimDefICValues, input_style),
+ NULL, _XimEncodeStyle, _XimDecodeStyle},
+
+ {OFFSET_XNCLIENTWINDOW, 0,
+ XOffsetOf(XimDefICValues, client_window),
+ NULL, _XimEncodeWindow, _XimDecodeWindow},
+
+ {OFFSET_XNFOCUSWINDOW, 0,
+ XOffsetOf(XimDefICValues, focus_window),
+ _XimDefaultFocusWindow, _XimEncodeWindow, _XimDecodeWindow},
+
+ {OFFSET_XNRESOURCENAME, 0,
+ XOffsetOf(XimDefICValues, res_name),
+ _XimDefaultResName, _XimEncodeString, _XimDecodeString},
+
+ {OFFSET_XNRESOURCECLASS, 0,
+ XOffsetOf(XimDefICValues, res_class),
+ _XimDefaultResClass, _XimEncodeString, _XimDecodeString},
+
+ {OFFSET_XNGEOMETRYCALLBACK, 0,
+ XOffsetOf(XimDefICValues, geometry_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNFILTEREVENTS, 0,
+ XOffsetOf(XimDefICValues, filter_events),
+ NULL, NULL, _XimDecodeLong},
+
+ {OFFSET_XNDESTROYCALLBACK, 0,
+ XOffsetOf(XimDefICValues, destroy_callback),
+ _XimDefaultDestroyCB, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNSTRINGCONVERSIONCALLBACK, 0,
+ XOffsetOf(XimDefICValues, string_conversion_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNSTRINGCONVERSION, 0,
+ XOffsetOf(XimDefICValues, string_conversion),
+ NULL, _XimEncodeStringConv, _XimDecodeStringConv},
+
+ {OFFSET_XNRESETSTATE, 0,
+ XOffsetOf(XimDefICValues, reset_state),
+ _XimDefaultResetState, _XimEncodeResetState, _XimDecodeResetState},
+
+ {OFFSET_XNHOTKEY, 0,
+ XOffsetOf(XimDefICValues, hotkey),
+ NULL, _XimEncodeHotKey, _XimDecodeHotKey},
+
+ {OFFSET_XNHOTKEYSTATE, 0,
+ XOffsetOf(XimDefICValues, hotkey_state),
+ _XimDefaultHotKeyState, _XimEncodeHotKetState, _XimDecodeHotKetState},
+
+ {OFFSET_XNPREEDITATTRIBUTES, 0,
+ XOffsetOf(XimDefICValues, preedit_attr),
+ _XimDefaultNest, _XimEncodeNest, _XimDecodeNest},
+
+ {OFFSET_XNSTATUSATTRIBUTES, 0,
+ XOffsetOf(XimDefICValues, status_attr),
+ _XimDefaultNest, _XimEncodeNest, _XimDecodeNest},
+};
+
+static XimValueOffsetInfoRec ic_pre_attr_info[] = {
+ {OFFSET_XNAREA, 0,
+ XOffsetOf(ICPreeditAttributes, area),
+ _XimDefaultArea, _XimEncodeRectangle, _XimDecodeRectangle},
+
+ {OFFSET_XNAREANEEDED, 0,
+ XOffsetOf(ICPreeditAttributes, area_needed),
+ NULL, _XimEncodeRectangle, _XimDecodeRectangle},
+
+ {OFFSET_XNSPOTLOCATION, 0,
+ XOffsetOf(ICPreeditAttributes, spot_location),
+ NULL, _XimEncodeSpot, _XimDecodeSpot},
+
+ {OFFSET_XNCOLORMAP, 0,
+ XOffsetOf(ICPreeditAttributes, colormap),
+ _XimDefaultColormap, _XimEncodeColormap, _XimDecodeColormap},
+
+ {OFFSET_XNSTDCOLORMAP, 0,
+ XOffsetOf(ICPreeditAttributes, std_colormap),
+ _XimDefaultStdColormap, _XimEncodeStdColormap, _XimDecodeStdColormap},
+
+ {OFFSET_XNFOREGROUND, 0,
+ XOffsetOf(ICPreeditAttributes, foreground),
+ _XimDefaultFg, _XimEncodeLong, _XimDecodeLong},
+
+ {OFFSET_XNBACKGROUND, 0,
+ XOffsetOf(ICPreeditAttributes, background),
+ _XimDefaultBg, _XimEncodeLong, _XimDecodeLong},
+
+ {OFFSET_XNBACKGROUNDPIXMAP, 0,
+ XOffsetOf(ICPreeditAttributes, background_pixmap),
+ _XimDefaultBgPixmap, _XimEncodeBgPixmap, _XimDecodeBgPixmap},
+
+ {OFFSET_XNFONTSET, 0,
+ XOffsetOf(ICPreeditAttributes, fontset),
+ _XimDefaultFontSet, _XimEncodeFontSet, _XimDecodeFontSet},
+
+ {OFFSET_XNLINESPACE, 0,
+ XOffsetOf(ICPreeditAttributes, line_spacing),
+ _XimDefaultLineSpace, _XimEncodeLineSpace, _XimDecodeLineSpace},
+
+ {OFFSET_XNCURSOR, 0,
+ XOffsetOf(ICPreeditAttributes, cursor),
+ _XimDefaultCursor, _XimEncodeCursor, _XimDecodeCursor},
+
+ {OFFSET_XNPREEDITSTARTCALLBACK, 0,
+ XOffsetOf(ICPreeditAttributes, start_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNPREEDITDONECALLBACK, 0,
+ XOffsetOf(ICPreeditAttributes, done_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNPREEDITDRAWCALLBACK, 0,
+ XOffsetOf(ICPreeditAttributes, draw_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNPREEDITCARETCALLBACK, 0,
+ XOffsetOf(ICPreeditAttributes, caret_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNPREEDITSTATE, 0,
+ XOffsetOf(ICPreeditAttributes, preedit_state),
+ _XimDefaultPreeditState, _XimEncodePreeditState,_XimDecodePreeditState},
+
+ {OFFSET_XNPREEDITSTATENOTIFYCALLBACK, 0,
+ XOffsetOf(ICPreeditAttributes, state_notify_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+};
+
+static XimValueOffsetInfoRec ic_sts_attr_info[] = {
+ {OFFSET_XNAREA, 0,
+ XOffsetOf(ICStatusAttributes, area),
+ _XimDefaultArea, _XimEncodeRectangle, _XimDecodeRectangle},
+
+ {OFFSET_XNAREANEEDED, 0,
+ XOffsetOf(ICStatusAttributes, area_needed),
+ NULL, _XimEncodeRectangle, _XimDecodeRectangle},
+
+ {OFFSET_XNCOLORMAP, 0,
+ XOffsetOf(ICStatusAttributes, colormap),
+ _XimDefaultColormap, _XimEncodeColormap, _XimDecodeColormap},
+
+ {OFFSET_XNSTDCOLORMAP, 0,
+ XOffsetOf(ICStatusAttributes, std_colormap),
+ _XimDefaultStdColormap, _XimEncodeStdColormap, _XimDecodeStdColormap},
+
+ {OFFSET_XNFOREGROUND, 0,
+ XOffsetOf(ICStatusAttributes, foreground),
+ _XimDefaultFg, _XimEncodeLong, _XimDecodeLong},
+
+ {OFFSET_XNBACKGROUND, 0,
+ XOffsetOf(ICStatusAttributes, background),
+ _XimDefaultBg, _XimEncodeLong, _XimDecodeLong},
+
+ {OFFSET_XNBACKGROUNDPIXMAP, 0,
+ XOffsetOf(ICStatusAttributes, background_pixmap),
+ _XimDefaultBgPixmap, _XimEncodeBgPixmap, _XimDecodeBgPixmap},
+
+ {OFFSET_XNFONTSET, 0,
+ XOffsetOf(ICStatusAttributes, fontset),
+ _XimDefaultFontSet, _XimEncodeFontSet, _XimDecodeFontSet},
+
+ {OFFSET_XNLINESPACE, 0,
+ XOffsetOf(ICStatusAttributes, line_spacing),
+ _XimDefaultLineSpace, _XimEncodeLineSpace, _XimDecodeLineSpace},
+
+ {OFFSET_XNCURSOR, 0,
+ XOffsetOf(ICStatusAttributes, cursor),
+ _XimDefaultCursor, _XimEncodeCursor, _XimDecodeCursor},
+
+ {OFFSET_XNSTATUSSTARTCALLBACK, 0,
+ XOffsetOf(ICStatusAttributes, start_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNSTATUSDONECALLBACK, 0,
+ XOffsetOf(ICStatusAttributes, done_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback},
+
+ {OFFSET_XNSTATUSDRAWCALLBACK, 0,
+ XOffsetOf(ICStatusAttributes, draw_callback),
+ NULL, _XimEncodeCallback, _XimDecodeCallback}
+};
+
+typedef struct _XimIMMode {
+ unsigned short name_offset;
+ unsigned short mode;
+} XimIMMode;
+
+static const XimIMMode im_mode[] = {
+ {OFFSET_XNQUERYINPUTSTYLE,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)},
+ {OFFSET_XNDESTROYCALLBACK,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)},
+ {OFFSET_XNRESOURCENAME,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)},
+ {OFFSET_XNRESOURCECLASS,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_SET | XIM_MODE_IM_GET)},
+ {OFFSET_XNQUERYIMVALUESLIST,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)},
+ {OFFSET_XNQUERYICVALUESLIST,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)},
+ {OFFSET_XNVISIBLEPOSITION,
+ (XIM_MODE_IM_DEFAULT | XIM_MODE_IM_GET)}
+};
+
+typedef struct _XimICMode {
+ unsigned short name_offset;
+ unsigned short preedit_callback_mode;
+ unsigned short preedit_position_mode;
+ unsigned short preedit_area_mode;
+ unsigned short preedit_nothing_mode;
+ unsigned short preedit_none_mode;
+ unsigned short status_callback_mode;
+ unsigned short status_area_mode;
+ unsigned short status_nothing_mode;
+ unsigned short status_none_mode;
+} XimICMode;
+
+static const XimICMode ic_mode[] = {
+ {OFFSET_XNINPUTSTYLE,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_GET),
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_GET)},
+ {OFFSET_XNCLIENTWINDOW,
+ (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_ONCE | XIM_MODE_PRE_GET),
+ 0,
+ (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_ONCE | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNFOCUSWINDOW,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNRESOURCENAME,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNRESOURCECLASS,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNGEOMETRYCALLBACK,
+ 0,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0},
+ {OFFSET_XNFILTEREVENTS,
+ XIM_MODE_PRE_GET,
+ XIM_MODE_PRE_GET,
+ XIM_MODE_PRE_GET,
+ XIM_MODE_PRE_GET,
+ 0,
+ XIM_MODE_STS_GET,
+ XIM_MODE_STS_GET,
+ XIM_MODE_STS_GET,
+ XIM_MODE_STS_GET},
+ {OFFSET_XNDESTROYCALLBACK,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTRINGCONVERSIONCALLBACK,
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTRINGCONVERSION,
+ XIM_MODE_PRE_SET,
+ XIM_MODE_PRE_SET,
+ XIM_MODE_PRE_SET,
+ XIM_MODE_PRE_SET,
+ XIM_MODE_PRE_SET,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNRESETSTATE,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNHOTKEY,
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNHOTKEYSTATE,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITATTRIBUTES,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTATUSATTRIBUTES,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNAREA,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0},
+ {OFFSET_XNAREANEEDED,
+ 0,
+ 0,
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0},
+ {OFFSET_XNSPOTLOCATION,
+ 0, /*(XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),*/
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNCOLORMAP,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNSTDCOLORMAP,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNFOREGROUND,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNBACKGROUND,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNBACKGROUNDPIXMAP,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNFONTSET,
+ 0,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNLINESPACE,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNCURSOR,
+ 0,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ (XIM_MODE_STS_DEFAULT | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0},
+ {OFFSET_XNPREEDITSTARTCALLBACK,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITDONECALLBACK,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITDRAWCALLBACK,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITCARETCALLBACK,
+ (XIM_MODE_PRE_CREATE | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITSTATE,
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_DEFAULT | XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNPREEDITSTATENOTIFYCALLBACK,
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ (XIM_MODE_PRE_SET | XIM_MODE_PRE_GET),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTATUSSTARTCALLBACK,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTATUSDONECALLBACK,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0,
+ 0},
+ {OFFSET_XNSTATUSDRAWCALLBACK,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ (XIM_MODE_STS_CREATE | XIM_MODE_STS_SET | XIM_MODE_STS_GET),
+ 0,
+ 0,
+ 0}
+};
+
+/* the quarks are separated from im_mode/ic_mode so those arrays
+ * can be const.
+ */
+static XrmQuark im_mode_quark[sizeof(im_mode) / sizeof(im_mode[0])];
+static XrmQuark ic_mode_quark[sizeof(ic_mode) / sizeof(ic_mode[0])];
+
+Private Bool
+_XimSetResourceList(
+ XIMResourceList *res_list,
+ unsigned int *list_num,
+ XIMResourceList resource,
+ unsigned int num_resource,
+ unsigned short id)
+{
+ register int i;
+ int len;
+ XIMResourceList res;
+
+ len = sizeof(XIMResource) * num_resource;
+ if(!(res = Xcalloc(1, len))) {
+ return False;
+ }
+
+ for(i = 0; i < num_resource; i++, id++) {
+ res[i] = resource[i];
+ res[i].id = id;
+ }
+
+ _XIMCompileResourceList(res, num_resource);
+ *res_list = res;
+ *list_num = num_resource;
+ return True;
+}
+
+Public Bool
+_XimSetIMResourceList(
+ XIMResourceList *res_list,
+ unsigned int *list_num)
+{
+ return _XimSetResourceList(res_list, list_num,
+ im_resources, XIMNumber(im_resources), 100);
+}
+
+Public Bool
+_XimSetICResourceList(
+ XIMResourceList *res_list,
+ unsigned int *list_num)
+{
+ return _XimSetResourceList(res_list, list_num,
+ ic_resources, XIMNumber(ic_resources), 200);
+}
+
+Public Bool
+_XimSetInnerIMResourceList(
+ XIMResourceList *res_list,
+ unsigned int *list_num)
+{
+ return _XimSetResourceList(res_list, list_num,
+ im_inner_resources, XIMNumber(im_inner_resources), 100);
+}
+
+Public Bool
+_XimSetInnerICResourceList(
+ XIMResourceList *res_list,
+ unsigned int *list_num)
+{
+ return _XimSetResourceList(res_list, list_num,
+ ic_inner_resources, XIMNumber(ic_inner_resources), 200);
+}
+
+Private XIMResourceList
+_XimGetResourceListRecByMode(
+ XIMResourceList res_list,
+ unsigned int list_num,
+ unsigned short mode)
+{
+ register int i;
+
+ for(i = 0; i < list_num; i++) {
+ if (res_list[i].mode & mode) {
+ return (XIMResourceList)&res_list[i];
+ }
+ }
+ return (XIMResourceList)NULL;
+}
+
+Public Bool
+_XimCheckCreateICValues(
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ if (!_XimGetResourceListRecByMode(res_list, list_num, XIM_MODE_IC_CREATE)) {
+ return True;
+ }
+ return False;
+}
+
+Public XIMResourceList
+_XimGetResourceListRecByQuark(
+ XIMResourceList res_list,
+ unsigned int list_num,
+ XrmQuark quark)
+{
+ register int i;
+
+ for(i = 0; i < list_num; i++) {
+ if (res_list[i].xrm_name == quark) {
+ return (XIMResourceList)&res_list[i];
+ }
+ }
+ return (XIMResourceList)NULL;
+}
+
+Public XIMResourceList
+_XimGetResourceListRec(
+ XIMResourceList res_list,
+ unsigned int list_num,
+ const char *name)
+{
+ XrmQuark quark = XrmStringToQuark(name);
+
+ return _XimGetResourceListRecByQuark(res_list, list_num, quark);
+}
+
+Public char *
+_XimSetIMValueData(
+ Xim im,
+ XPointer top,
+ XIMArg *values,
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+
+ for(p = values; p->name != NULL; p++) {
+ if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) {
+ return p->value;
+ }
+ check = _XimCheckIMMode(res, XIM_SETIMVALUES);
+ if(check == XIM_CHECK_INVALID) {
+ continue;
+ } else if (check == XIM_CHECK_ERROR) {
+ return p->value;
+ }
+
+ if(!_XimEncodeLocalIMAttr(res, top, p->value)) {
+ return p->value;
+ }
+ }
+ return NULL;
+}
+
+Public char *
+_XimGetIMValueData(
+ Xim im,
+ XPointer top,
+ XIMArg *values,
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+
+ for(p = values; p->name != NULL; p++) {
+ if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) {
+ return p->value;
+ }
+ check = _XimCheckIMMode(res, XIM_GETIMVALUES);
+ if(check == XIM_CHECK_INVALID) {
+ continue;
+ } else if (check == XIM_CHECK_ERROR) {
+ return p->value;
+ }
+
+ if(!_XimDecodeLocalIMAttr(res, top, p->value)) {
+ return p->value;
+ }
+ }
+ return NULL;
+}
+
+Public void
+_XimSetIMMode(
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ XIMResourceList res;
+ unsigned int n = XIMNumber(im_mode);
+ register int i;
+
+ for(i = 0; i < n; i++) {
+ if(!(res = _XimGetResourceListRecByQuark(res_list,
+ list_num, im_mode_quark[i]))) {
+ continue;
+ }
+ res->mode = im_mode[i].mode;
+ }
+ return;
+}
+
+Private int
+_XimCheckSetIMDefaultsMode(
+ XIMResourceList res)
+{
+ if(res->mode & XIM_MODE_IM_DEFAULT) {
+ return XIM_CHECK_VALID;
+ }
+ return XIM_CHECK_INVALID;
+}
+
+Private int
+_XimCheckSetIMValuesMode(
+ XIMResourceList res)
+{
+ if(res->mode & XIM_MODE_IM_SET) {
+ return XIM_CHECK_VALID;
+ }
+ return XIM_CHECK_INVALID;
+}
+
+Private int
+ _XimCheckGetIMValuesMode(
+ XIMResourceList res)
+{
+ if(res->mode & XIM_MODE_IM_GET) {
+ return XIM_CHECK_VALID;
+ }
+ return XIM_CHECK_INVALID;
+}
+
+Public int
+ _XimCheckIMMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(res->mode == 0) {
+ return XIM_CHECK_INVALID;
+ }
+ if(mode & XIM_SETIMDEFAULTS) {
+ return _XimCheckSetIMDefaultsMode(res);
+ } else if (mode & XIM_SETIMVALUES) {
+ return _XimCheckSetIMValuesMode(res);
+ } else if (mode & XIM_GETIMVALUES) {
+ return _XimCheckGetIMValuesMode(res);
+ } else {
+ return XIM_CHECK_ERROR;
+ }
+}
+
+Public void
+_XimSetICMode(XIMResourceList res_list, unsigned int list_num, XIMStyle style)
+{
+ XIMResourceList res;
+ unsigned int n = XIMNumber(ic_mode);
+ register int i;
+ unsigned int pre_offset;
+ unsigned int sts_offset;
+
+ if(style & XIMPreeditArea) {
+ pre_offset = XOffsetOf(XimICMode, preedit_area_mode);
+ } else if(style & XIMPreeditCallbacks) {
+ pre_offset = XOffsetOf(XimICMode, preedit_callback_mode);
+ } else if(style & XIMPreeditPosition) {
+ pre_offset = XOffsetOf(XimICMode, preedit_position_mode);
+ } else if(style & XIMPreeditNothing) {
+ pre_offset = XOffsetOf(XimICMode, preedit_nothing_mode);
+ } else {
+ pre_offset = XOffsetOf(XimICMode, preedit_none_mode);
+ }
+
+ if(style & XIMStatusArea) {
+ sts_offset = XOffsetOf(XimICMode, status_area_mode);
+ } else if(style & XIMStatusCallbacks) {
+ sts_offset = XOffsetOf(XimICMode, status_callback_mode);
+ } else if(style & XIMStatusNothing) {
+ sts_offset = XOffsetOf(XimICMode, status_nothing_mode);
+ } else {
+ sts_offset = XOffsetOf(XimICMode, status_none_mode);
+ }
+
+ for(i = 0; i < n; i++) {
+ if(!(res = _XimGetResourceListRecByQuark(res_list,
+ list_num, ic_mode_quark[i]))) {
+ continue;
+ }
+ res->mode = ( (*(unsigned short *)((char *)&ic_mode[i] + pre_offset))
+ | (*(unsigned short *)((char *)&ic_mode[i] + sts_offset)));
+ }
+ return;
+}
+
+Private int
+_XimCheckSetICDefaultsMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(mode & XIM_PREEDIT_ATTR) {
+ if(!(res->mode & XIM_MODE_PRE_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_PRE_CREATE) {
+ return XIM_CHECK_ERROR;
+ } else if (!(res->mode & XIM_MODE_PRE_DEFAULT)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ } else if(mode & XIM_STATUS_ATTR) {
+ if(!(res->mode & XIM_MODE_STS_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_STS_CREATE) {
+ return XIM_CHECK_ERROR;
+ }
+ if(!(res->mode & XIM_MODE_STS_DEFAULT)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ } else {
+ if(!res->mode) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_IC_CREATE) {
+ return XIM_CHECK_ERROR;
+ }
+ if(!(res->mode & XIM_MODE_IC_DEFAULT)) {
+ return XIM_CHECK_INVALID;
+ }
+ }
+ return XIM_CHECK_VALID;
+}
+
+Private int
+_XimCheckCreateICMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(mode & XIM_PREEDIT_ATTR) {
+ if(!(res->mode & XIM_MODE_PRE_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_PRE_CREATE) {
+ res->mode &= ~XIM_MODE_PRE_CREATE;
+ } else if(res->mode & XIM_MODE_PRE_ONCE) {
+ res->mode &= ~XIM_MODE_PRE_ONCE;
+ } else if(res->mode & XIM_MODE_PRE_DEFAULT) {
+ res->mode &= ~XIM_MODE_PRE_DEFAULT;
+ } else if (!(res->mode & XIM_MODE_PRE_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else if(mode & XIM_STATUS_ATTR) {
+ if(!(res->mode & XIM_MODE_STS_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_STS_CREATE) {
+ res->mode &= ~XIM_MODE_STS_CREATE;
+ } else if(res->mode & XIM_MODE_STS_ONCE) {
+ res->mode &= ~XIM_MODE_STS_ONCE;
+ } else if(res->mode & XIM_MODE_STS_DEFAULT) {
+ res->mode &= ~XIM_MODE_STS_DEFAULT;
+ } else if (!(res->mode & XIM_MODE_STS_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else {
+ if(!res->mode) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_IC_CREATE) {
+ res->mode &= ~XIM_MODE_IC_CREATE;
+ } else if(res->mode & XIM_MODE_IC_ONCE) {
+ res->mode &= ~XIM_MODE_IC_ONCE;
+ } else if(res->mode & XIM_MODE_IC_DEFAULT) {
+ res->mode &= ~XIM_MODE_IC_DEFAULT;
+ } else if (!(res->mode & XIM_MODE_IC_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+ }
+ return XIM_CHECK_VALID;
+}
+
+Private int
+_XimCheckSetICValuesMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(mode & XIM_PREEDIT_ATTR) {
+ if(!(res->mode & XIM_MODE_PRE_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_PRE_ONCE) {
+ res->mode &= ~XIM_MODE_PRE_ONCE;
+ } else if(!(res->mode & XIM_MODE_PRE_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else if(mode & XIM_STATUS_ATTR) {
+ if(!(res->mode & XIM_MODE_STS_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_STS_ONCE) {
+ res->mode &= ~XIM_MODE_STS_ONCE;
+ } else if(!(res->mode & XIM_MODE_STS_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else {
+ if(!res->mode) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(res->mode & XIM_MODE_IC_ONCE) {
+ res->mode &= ~XIM_MODE_IC_ONCE;
+ } else if(!(res->mode & XIM_MODE_IC_SET)) {
+ return XIM_CHECK_ERROR;
+ }
+ }
+ return XIM_CHECK_VALID;
+}
+
+Private int
+_XimCheckGetICValuesMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(mode & XIM_PREEDIT_ATTR) {
+ if(!(res->mode & XIM_MODE_PRE_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(!(res->mode & XIM_MODE_PRE_GET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else if(mode & XIM_STATUS_ATTR) {
+ if(!(res->mode & XIM_MODE_STS_MASK)) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(!(res->mode & XIM_MODE_STS_GET)) {
+ return XIM_CHECK_ERROR;
+ }
+
+ } else {
+ if(!res->mode) {
+ return XIM_CHECK_INVALID;
+ }
+
+ if(!(res->mode & XIM_MODE_IC_GET)) {
+ return XIM_CHECK_ERROR;
+ }
+ }
+ return XIM_CHECK_VALID;
+}
+
+Public int
+ _XimCheckICMode(
+ XIMResourceList res,
+ unsigned long mode)
+{
+ if(mode &XIM_SETICDEFAULTS) {
+ return _XimCheckSetICDefaultsMode(res, mode);
+ } else if (mode & XIM_CREATEIC) {
+ return _XimCheckCreateICMode(res, mode);
+ } else if (mode & XIM_SETICVALUES) {
+ return _XimCheckSetICValuesMode(res, mode);
+ } else if (mode & XIM_GETICVALUES) {
+ return _XimCheckGetICValuesMode(res, mode);
+ } else {
+ return XIM_CHECK_ERROR;
+ }
+}
+
+Public Bool
+_XimSetLocalIMDefaults(
+ Xim im,
+ XPointer top,
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ XimValueOffsetInfo info;
+ unsigned int num;
+ register int i;
+ XIMResourceList res;
+ int check;
+
+ info = im_attr_info;
+ num = XIMNumber(im_attr_info);
+
+ for(i = 0; i < num; i++) {
+ if((res = _XimGetResourceListRecByQuark( res_list, list_num,
+ info[i].quark)) == (XIMResourceList)NULL) {
+ return False;
+ }
+
+ check = _XimCheckIMMode(res, XIM_SETIMDEFAULTS);
+ if(check == XIM_CHECK_INVALID) {
+ continue;
+ } else if (check == XIM_CHECK_ERROR) {
+ return False;
+ }
+
+ if(!info[i].defaults) {
+ continue;
+ }
+ if(!(info[i].defaults(&info[i], top, (XPointer)NULL, 0))) {
+ return False;
+ }
+ }
+ return True;
+}
+
+Public Bool
+_XimSetICDefaults(
+ Xic ic,
+ XPointer top,
+ unsigned long mode,
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ unsigned int num;
+ XimValueOffsetInfo info;
+ register int i;
+ XIMResourceList res;
+ int check;
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ if(mode & XIM_PREEDIT_ATTR) {
+ info = ic_pre_attr_info;
+ num = XIMNumber(ic_pre_attr_info);
+ } else if(mode & XIM_STATUS_ATTR) {
+ info = ic_sts_attr_info;
+ num = XIMNumber(ic_sts_attr_info);
+ } else {
+ info = ic_attr_info;
+ num = XIMNumber(ic_attr_info);
+ }
+
+ for(i = 0; i < num; i++) {
+ if(info[i].quark == pre_quark) {
+ if(!_XimSetICDefaults(ic, (XPointer)((char *)top + info[i].offset),
+ (mode | XIM_PREEDIT_ATTR), res_list, list_num)) {
+ return False;
+ }
+ } else if (info[i].quark == sts_quark) {
+ if(!_XimSetICDefaults(ic, (XPointer)((char *)top + info[i].offset),
+ (mode | XIM_STATUS_ATTR), res_list, list_num)) {
+ return False;
+ }
+ } else {
+ if(!(res = _XimGetResourceListRecByQuark(res_list, list_num,
+ info[i].quark))) {
+ return False;
+ }
+
+ check = _XimCheckICMode(res, mode);
+ if (check == XIM_CHECK_INVALID) {
+ continue;
+ } else if (check == XIM_CHECK_ERROR) {
+ return False;
+ }
+
+ if (!info[i].defaults) {
+ continue;
+ }
+ if (!(info[i].defaults(&info[i], top, (XPointer)ic, mode))) {
+ return False;
+ }
+ }
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodeAttr(
+ XimValueOffsetInfo info,
+ unsigned int num,
+ XIMResourceList res,
+ XPointer top,
+ XPointer val)
+{
+ register int i;
+
+ for(i = 0; i < num; i++ ) {
+ if(info[i].quark == res->xrm_name) {
+ if(!info[i].encode) {
+ return False;
+ }
+ return (*info[i].encode)(&info[i], top, val);
+ }
+ }
+ return False;
+}
+
+Public Bool
+_XimEncodeLocalIMAttr(
+ XIMResourceList res,
+ XPointer top,
+ XPointer val)
+{
+ return _XimEncodeAttr(im_attr_info, XIMNumber(im_attr_info),
+ res, top, val);
+}
+
+Public Bool
+_XimEncodeLocalICAttr(
+ Xic ic,
+ XIMResourceList res,
+ XPointer top,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ unsigned int num;
+ XimValueOffsetInfo info;
+
+ if(mode & XIM_PREEDIT_ATTR) {
+ info = ic_pre_attr_info;
+ num = XIMNumber(ic_pre_attr_info);
+ } else if(mode & XIM_STATUS_ATTR) {
+ info = ic_sts_attr_info;
+ num = XIMNumber(ic_sts_attr_info);
+ } else {
+ info = ic_attr_info;
+ num = XIMNumber(ic_attr_info);
+ }
+
+ return _XimEncodeAttr(info, num, res, top, arg->value);
+}
+
+Private Bool
+_XimEncodeLocalTopValue(
+ Xic ic,
+ XIMResourceList res,
+ XPointer val,
+ Bool flag)
+{
+ XIMArg *p = (XIMArg *)val;
+
+ if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
+ ic->core.client_window = (Window)p->value;
+ if (ic->core.focus_window == (Window)0)
+ ic->core.focus_window = ic->core.client_window;
+ if (flag) {
+ _XRegisterFilterByType(ic->core.im->core.display,
+ ic->core.focus_window,
+ KeyPress, KeyRelease, _XimLocalFilter, (XPointer)ic);
+ }
+ } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
+ if (ic->core.client_window) {
+ if (flag) {
+ _XUnregisterFilter(ic->core.im->core.display,
+ ic->core.focus_window, _XimLocalFilter, (XPointer)ic);
+ }
+ ic->core.focus_window = (Window)p->value;
+ if (flag) {
+ _XRegisterFilterByType(ic->core.im->core.display,
+ ic->core.focus_window, KeyPress, KeyRelease,
+ _XimLocalFilter, (XPointer)ic);
+ }
+ } else
+ ic->core.focus_window = (Window)p->value;
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodeLocalPreeditValue(
+ Xic ic,
+ XIMResourceList res,
+ XPointer val)
+{
+ XIMArg *p = (XIMArg *)val;
+
+ if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
+ XStandardColormap *colormap_ret;
+ int count;
+
+ if (!(XGetRGBColormaps(ic->core.im->core.display,
+ ic->core.focus_window, &colormap_ret,
+ &count, (Atom)p->value)))
+ return False;
+
+ Xfree(colormap_ret);
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodeLocalStatusValue(
+ Xic ic,
+ XIMResourceList res,
+ XPointer val)
+{
+ XIMArg *p = (XIMArg *)val;
+
+ if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
+ XStandardColormap *colormap_ret;
+ int count;
+
+ if (!(XGetRGBColormaps(ic->core.im->core.display,
+ ic->core.focus_window, &colormap_ret,
+ &count, (Atom)p->value)))
+ return False;
+
+ Xfree(colormap_ret);
+ }
+ return True;
+}
+
+Public char *
+_XimSetICValueData(
+ Xic ic,
+ XPointer top,
+ XIMResourceList res_list,
+ unsigned int list_num,
+ XIMArg *values,
+ unsigned long mode,
+ Bool flag)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ char *name;
+ int check;
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ for(p = values; p->name != NULL; p++) {
+ if((res = _XimGetResourceListRec(res_list, list_num,
+ p->name)) == (XIMResourceList)NULL) {
+ return p->name;
+ }
+ if(res->xrm_name == pre_quark) {
+ if(((name = _XimSetICValueData(ic,
+ (XPointer)(&((XimDefICValues *)top)->preedit_attr),
+ res_list, list_num, (XIMArg *)p->value,
+ (mode | XIM_PREEDIT_ATTR), flag)))) {
+ return name;
+ }
+ } else if(res->xrm_name == sts_quark) {
+ if(((name = _XimSetICValueData(ic,
+ (XPointer)(&((XimDefICValues *)top)->status_attr),
+ res_list, list_num, (XIMArg *)p->value,
+ (mode | XIM_STATUS_ATTR), flag)))) {
+ return name;
+ }
+ } else {
+ check = _XimCheckICMode(res, mode);
+ if(check == XIM_CHECK_INVALID) {
+ continue;
+ } else if(check == XIM_CHECK_ERROR) {
+ return p->name;
+ }
+
+ if(mode & XIM_PREEDIT_ATTR) {
+ if (!_XimEncodeLocalPreeditValue(ic, res, (XPointer)p))
+ return False;
+ } else if(mode & XIM_STATUS_ATTR) {
+ if (!_XimEncodeLocalStatusValue(ic, res, (XPointer)p))
+ return False;
+ } else {
+ if (!_XimEncodeLocalTopValue(ic, res, (XPointer)p, flag))
+ return False;
+ }
+ if(_XimEncodeLocalICAttr(ic, res, top, p, mode) == False) {
+ return p->name;
+ }
+ }
+ }
+ return NULL;
+}
+
+Private Bool
+_XimCheckInputStyle(
+ XIMStyles *styles,
+ XIMStyle style)
+{
+ int num = styles->count_styles;
+ register int i;
+
+ for(i = 0; i < num; i++) {
+ if(styles->supported_styles[i] == style) {
+ return True;
+ }
+ }
+ return False;
+}
+
+Public Bool
+_XimCheckLocalInputStyle(
+ Xic ic,
+ XPointer top,
+ XIMArg *values,
+ XIMStyles *styles,
+ XIMResourceList res_list,
+ unsigned int list_num)
+{
+ XrmQuark quark = XrmStringToQuark(XNInputStyle);
+ register XIMArg *p;
+ XIMResourceList res;
+
+ for(p = values; p && p->name != NULL; p++) {
+ if(quark == XrmStringToQuark(p->name)) {
+ if(!(res = _XimGetResourceListRec(res_list, list_num, p->name))) {
+ return False;
+ }
+ if(!_XimEncodeLocalICAttr(ic, res, top, p, 0)) {
+ return False;
+ }
+ if (_XimCheckInputStyle(styles,
+ ((XimDefICValues *)top)->input_style)) {
+ return True;
+ }
+ return False;
+ }
+ }
+ return False;
+}
+
+Private Bool
+_XimDecodeAttr(
+ XimValueOffsetInfo info,
+ unsigned int num,
+ XIMResourceList res,
+ XPointer top,
+ XPointer val)
+{
+ register int i;
+
+ for(i = 0; i < num; i++ ) {
+ if(info[i].quark == res->xrm_name) {
+ if(!info[i].decode) {
+ return False;
+ }
+ return (*info[i].decode)(&info[i], top, val);
+ }
+ }
+ return False;
+}
+
+Public Bool
+_XimDecodeLocalIMAttr(
+ XIMResourceList res,
+ XPointer top,
+ XPointer val)
+{
+ return _XimDecodeAttr(im_attr_info, XIMNumber(im_attr_info),
+ res, top, val);
+}
+
+Public Bool
+_XimDecodeLocalICAttr(
+ XIMResourceList res,
+ XPointer top,
+ XPointer val,
+ unsigned long mode)
+{
+ unsigned int num;
+ XimValueOffsetInfo info;
+
+ if(mode & XIM_PREEDIT_ATTR) {
+ info = ic_pre_attr_info;
+ num = XIMNumber(ic_pre_attr_info);
+ } else if(mode & XIM_STATUS_ATTR) {
+ info = ic_sts_attr_info;
+ num = XIMNumber(ic_sts_attr_info);
+ } else {
+ info = ic_attr_info;
+ num = XIMNumber(ic_attr_info);
+ }
+
+ return _XimDecodeAttr(info, num, res, top, val);
+}
+
+Public char *
+_XimGetICValueData(Xic ic, XPointer top, XIMResourceList res_list,
+ unsigned int list_num, XIMArg *values, unsigned long mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ char *name;
+ int check;
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ for(p = values; p->name != NULL; p++) {
+ if((res = _XimGetResourceListRec(res_list, list_num,
+ p->name)) == (XIMResourceList)NULL) {
+ return p->name;
+ }
+ if(res->xrm_name == pre_quark) {
+ if((name = _XimGetICValueData(ic,
+ (XPointer)(&((XimDefICValues *)top)->preedit_attr),
+ res_list, list_num, (XIMArg *)p->value,
+ (mode | XIM_PREEDIT_ATTR)))) {
+ return name;
+ }
+ } else if(res->xrm_name == sts_quark) {
+ if((name = _XimGetICValueData(ic,
+ (XPointer)(&((XimDefICValues *)top)->status_attr),
+ res_list, list_num, (XIMArg *)p->value,
+ (mode | XIM_STATUS_ATTR)))) {
+ return name;
+ }
+ } else {
+ check = _XimCheckICMode(res, mode);
+ if(check == XIM_CHECK_INVALID) {
+ continue;
+ } else if(check == XIM_CHECK_ERROR) {
+ return p->name;
+ }
+
+ if(_XimDecodeLocalICAttr(res, top, p->value, mode) == False) {
+ return p->name;
+ }
+ }
+ }
+ return NULL;
+}
+
+Public void
+_XimGetCurrentIMValues(Xim im, XimDefIMValues *im_values)
+{
+ bzero((char *)im_values, sizeof(XimDefIMValues));
+
+ im_values->styles = im->core.styles;
+ im_values->im_values_list = im->core.im_values_list;
+ im_values->ic_values_list = im->core.ic_values_list;
+ im_values->destroy_callback = im->core.destroy_callback;
+ im_values->res_name = im->core.res_name;
+ im_values->res_class = im->core.res_class;
+ im_values->visible_position = im->core.visible_position;
+}
+
+Public void
+_XimSetCurrentIMValues(Xim im, XimDefIMValues *im_values)
+{
+ im->core.styles = im_values->styles;
+ im->core.im_values_list = im_values->im_values_list;
+ im->core.ic_values_list = im_values->ic_values_list;
+ im->core.destroy_callback = im_values->destroy_callback;
+ im->core.res_name = im_values->res_name;
+ im->core.res_class = im_values->res_class;
+ im->core.visible_position = im_values->visible_position;
+}
+
+Public void
+_XimGetCurrentICValues(Xic ic, XimDefICValues *ic_values)
+{
+ bzero((char *)ic_values, sizeof(XimDefICValues));
+
+ ic_values->input_style = ic->core.input_style;
+ ic_values->client_window = ic->core.client_window;
+ ic_values->focus_window = ic->core.focus_window;
+ ic_values->filter_events = ic->core.filter_events;
+ ic_values->geometry_callback = ic->core.geometry_callback;
+ ic_values->res_name = ic->core.res_name;
+ ic_values->res_class = ic->core.res_class;
+ ic_values->destroy_callback = ic->core.destroy_callback;
+ ic_values->string_conversion_callback
+ = ic->core.string_conversion_callback;
+ ic_values->string_conversion = ic->core.string_conversion;
+ ic_values->reset_state = ic->core.reset_state;
+ ic_values->hotkey = ic->core.hotkey;
+ ic_values->hotkey_state = ic->core.hotkey_state;
+ ic_values->preedit_attr = ic->core.preedit_attr;
+ ic_values->status_attr = ic->core.status_attr;
+}
+
+Public void
+_XimSetCurrentICValues(
+ Xic ic,
+ XimDefICValues *ic_values)
+{
+ ic->core.input_style = ic_values->input_style;
+ ic->core.client_window = ic_values->client_window;
+ if (ic_values->focus_window)
+ ic->core.focus_window = ic_values->focus_window;
+ ic->core.filter_events = ic_values->filter_events;
+ ic->core.geometry_callback = ic_values->geometry_callback;
+ ic->core.res_name = ic_values->res_name;
+ ic->core.res_class = ic_values->res_class;
+ ic->core.destroy_callback = ic_values->destroy_callback;
+ ic->core.string_conversion_callback
+ = ic_values->string_conversion_callback;
+ ic->core.string_conversion = ic_values->string_conversion;
+ ic->core.reset_state = ic_values->reset_state;
+ ic->core.hotkey = ic_values->hotkey;
+ ic->core.hotkey_state = ic_values->hotkey_state;
+ ic->core.preedit_attr = ic_values->preedit_attr;
+ ic->core.status_attr = ic_values->status_attr;
+}
+
+Private void
+_XimInitialIMOffsetInfo(void)
+{
+ unsigned int n = XIMNumber(im_attr_info);
+ register int i;
+
+ for(i = 0; i < n; i++) {
+ im_attr_info[i].quark = XrmStringToQuark(GET_NAME(im_attr_info[i]));
+ }
+}
+
+Private void
+_XimInitialICOffsetInfo(void)
+{
+ unsigned int n;
+ register int i;
+
+ n = XIMNumber(ic_attr_info);
+ for(i = 0; i < n; i++) {
+ ic_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_attr_info[i]));
+ }
+
+ n = XIMNumber(ic_pre_attr_info);
+ for(i = 0; i < n; i++) {
+ ic_pre_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_pre_attr_info[i]));
+ }
+
+ n = XIMNumber(ic_sts_attr_info);
+ for(i = 0; i < n; i++) {
+ ic_sts_attr_info[i].quark = XrmStringToQuark(GET_NAME(ic_sts_attr_info[i]));
+ }
+}
+
+Private void
+_XimInitialIMMode(void)
+{
+ unsigned int n = XIMNumber(im_mode);
+ register int i;
+
+ for(i = 0; i < n; i++) {
+ im_mode_quark[i] = XrmStringToQuark(GET_NAME(im_mode[i]));
+ }
+}
+
+Private void
+_XimInitialICMode(void)
+{
+ unsigned int n = XIMNumber(ic_mode);
+ register int i;
+
+ for(i = 0; i < n; i++) {
+ ic_mode_quark[i] = XrmStringToQuark(GET_NAME(ic_mode[i]));
+ }
+}
+
+Public void
+_XimInitialResourceInfo(void)
+{
+ static Bool init_flag = False;
+
+ if(init_flag == True) {
+ return;
+ }
+ _XimInitialIMOffsetInfo();
+ _XimInitialICOffsetInfo();
+ _XimInitialIMMode();
+ _XimInitialICMode();
+ init_flag = True;
+}
diff --git a/libX11/modules/im/ximcp/imRmAttr.c b/libX11/modules/im/ximcp/imRmAttr.c index 2e732658a..ac47f3bbe 100644 --- a/libX11/modules/im/ximcp/imRmAttr.c +++ b/libX11/modules/im/ximcp/imRmAttr.c @@ -1,1515 +1,1515 @@ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" - - -Private XIMResourceList -_XimGetNestedListSeparator( - XIMResourceList res_list, /* LISTofIMATTR or IMATTR */ - unsigned int res_num) -{ - return _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList); -} - -Private Bool -_XimCheckInnerIMAttributes( - Xim im, - XIMArg *arg, - unsigned long mode) -{ - XIMResourceList res; - int check; - - if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources, - im->private.proto.im_num_inner_resources, arg->name))) - return False; - - check = _XimCheckIMMode(res, mode); - if(check == XIM_CHECK_INVALID) - return True; - else if(check == XIM_CHECK_ERROR) - return False; - - return True; -} - -Public char * -_XimMakeIMAttrIDList( - Xim im, - XIMResourceList res_list, - unsigned int res_num, - XIMArg *arg, - CARD16 *buf, - INT16 *len, - unsigned long mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - - *len = 0; - if (!arg) - return (char *)NULL; - - for (p = arg; p->name; p++) { - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimCheckInnerIMAttributes(im, p, mode)) - continue; - return p->name; - } - - check = _XimCheckIMMode(res, mode); - if (check == XIM_CHECK_INVALID) - continue; - else if (check == XIM_CHECK_ERROR) - return p->name; - - *buf = res->id; - *len += sizeof(CARD16); - buf++; - } - return (char *)NULL; -} - -Private Bool -_XimCheckInnerICAttributes( - Xic ic, - XIMArg *arg, - unsigned long mode) -{ - XIMResourceList res; - int check; - - if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources, - ic->private.proto.ic_num_inner_resources, arg->name))) - return False; - - check = _XimCheckICMode(res, mode); - if(check == XIM_CHECK_INVALID) - return True; - else if(check == XIM_CHECK_ERROR) - return False; - - return True; -} - -Public char * -_XimMakeICAttrIDList( - Xic ic, - XIMResourceList res_list, - unsigned int res_num, - XIMArg *arg, - CARD16 *buf, - INT16 *len, - unsigned long mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - XrmQuark pre_quark; - XrmQuark sts_quark; - char *name; - INT16 new_len; - - *len = 0; - if (!arg) - return (char *)NULL; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - for (p = arg; p && p->name; p++) { - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimCheckInnerICAttributes(ic, p, mode)) - continue; - *len = -1; - return p->name; - } - - check = _XimCheckICMode(res, mode); - if(check == XIM_CHECK_INVALID) - continue; - else if(check == XIM_CHECK_ERROR) { - *len = -1; - return p->name; - } - - *buf = res->id; - *len += sizeof(CARD16); - buf++; - if (res->resource_size == XimType_NEST) { - if (res->xrm_name == pre_quark) { - if ((name = _XimMakeICAttrIDList(ic, res_list, res_num, - (XIMArg *)p->value, buf, &new_len, - (mode | XIM_PREEDIT_ATTR)))) { - if (new_len < 0) *len = -1; - else *len += new_len; - return name; - } - } else if (res->xrm_name == sts_quark) { - if ((name = _XimMakeICAttrIDList(ic, res_list, res_num, - (XIMArg *)p->value, buf, &new_len, - (mode | XIM_STATUS_ATTR)))) { - if (new_len < 0) *len = -1; - else *len += new_len; - return name; - } - } - *len += new_len; - buf = (CARD16 *)((char *)buf + new_len); - if (!(res = _XimGetNestedListSeparator(res_list, res_num))) { - p++; - if (p) { - *len = -1; - return p->name; - } - else { - return (char *)NULL; - } - } - *buf = res->id; - *len += sizeof(CARD16); - buf++; - } - } - return (char *)NULL; -} - -Private Bool -_XimAttributeToValue( - Xic ic, - XIMResourceList res, - CARD16 *data, - INT16 data_len, - XPointer value, - BITMASK32 mode) -{ - switch (res->resource_size) { - case XimType_SeparatorOfNestedList: - case XimType_NEST: - break; - - case XimType_CARD8: - case XimType_CARD16: - case XimType_CARD32: - case XimType_Window: - case XimType_XIMHotKeyState: - _XCopyToArg((XPointer)data, (XPointer *)&value, data_len); - break; - - case XimType_STRING8: - { - char *str; - - if (!(value)) - return False; - - if (!(str = (char *)Xmalloc(data_len + 1))) - return False; - - (void)memcpy(str, (char *)data, data_len); - str[data_len] = '\0'; - - *((char **)value) = str; - break; - } - - case XimType_XIMStyles: - { - INT16 num = data[0]; - register CARD32 *style_list = (CARD32 *)&data[2]; - XIMStyle *style; - XIMStyles *rep; - register int i; - char *p; - int alloc_len; - - if (!(value)) - return False; - - alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num; - if (!(p = (char *)Xmalloc(alloc_len))) - return False; - - rep = (XIMStyles *)p; - style = (XIMStyle *)(p + sizeof(XIMStyles)); - - for (i = 0; i < num; i++) - style[i] = (XIMStyle)style_list[i]; - - rep->count_styles = (unsigned short)num; - rep->supported_styles = style; - *((XIMStyles **)value) = rep; - break; - } - - case XimType_XRectangle: - { - XRectangle *rep; - - if (!(value)) - return False; - - if (!(rep = (XRectangle *)Xmalloc(sizeof(XRectangle)))) - return False; - - rep->x = data[0]; - rep->y = data[1]; - rep->width = data[2]; - rep->height = data[3]; - *((XRectangle **)value) = rep; - break; - } - - case XimType_XPoint: - { - XPoint *rep; - - if (!(value)) - return False; - - if (!(rep = (XPoint *)Xmalloc(sizeof(XPoint)))) - return False; - - rep->x = data[0]; - rep->y = data[1]; - *((XPoint **)value) = rep; - break; - } - - case XimType_XFontSet: - { - INT16 len = data[0]; - char *base_name; - XFontSet rep = (XFontSet)NULL; - char **missing_list = NULL; - int missing_count; - char *def_string; - - if (!(value)) - return False; - if (!ic) - return False; - - if (!(base_name = (char *)Xmalloc(len + 1))) - return False; - - (void)strncpy(base_name, (char *)&data[1], (int)len); - base_name[len] = '\0'; - - if (mode & XIM_PREEDIT_ATTR) { - if (!strcmp(base_name, ic->private.proto.preedit_font)) { - rep = ic->core.preedit_attr.fontset; - } else if (!ic->private.proto.preedit_font_length) { - rep = XCreateFontSet(ic->core.im->core.display, - base_name, &missing_list, - &missing_count, &def_string); - } - } else if (mode & XIM_STATUS_ATTR) { - if (!strcmp(base_name, ic->private.proto.status_font)) { - rep = ic->core.status_attr.fontset; - } else if (!ic->private.proto.status_font_length) { - rep = XCreateFontSet(ic->core.im->core.display, - base_name, &missing_list, - &missing_count, &def_string); - } - } - - Xfree(base_name); - Xfree(missing_list); - *((XFontSet *)value) = rep; - break; - } - - case XimType_XIMHotKeyTriggers: - { - INT32 num = *((CARD32 *)data); - register CARD32 *key_list = (CARD32 *)&data[2]; - XIMHotKeyTrigger *key; - XIMHotKeyTriggers *rep; - register int i; - char *p; - int alloc_len; - - if (!(value)) - return False; - - alloc_len = sizeof(XIMHotKeyTriggers) - + sizeof(XIMHotKeyTrigger) * num; - if (!(p = (char *)Xmalloc(alloc_len))) - return False; - - rep = (XIMHotKeyTriggers *)p; - key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers)); - - for (i = 0; i < num; i++, key_list += 3) { - key[i].keysym = (KeySym)key_list[0]; /* keysym */ - key[i].modifier = (int)key_list[1]; /* modifier */ - key[i].modifier_mask = (int)key_list[2]; /* modifier_mask */ - } - - rep->num_hot_key = (int)num; - rep->key = key; - *((XIMHotKeyTriggers **)value) = rep; - break; - } - - case XimType_XIMStringConversion: - { - break; - } - - default: - return False; - } - return True; -} - -Private Bool -_XimDecodeInnerIMATTRIBUTE( - Xim im, - XIMArg *arg) -{ - XIMResourceList res; - XimDefIMValues im_values; - - if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources, - im->private.proto.im_num_inner_resources, arg->name))) - return False; - - _XimGetCurrentIMValues(im, &im_values); - return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value); -} - -Public char * -_XimDecodeIMATTRIBUTE( - Xim im, - XIMResourceList res_list, - unsigned int res_num, - CARD16 *data, - INT16 data_len, - XIMArg *arg, - BITMASK32 mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - INT16 len; - CARD16 *buf; - INT16 total; - INT16 min_len = sizeof(CARD16) /* sizeof attributeID */ - + sizeof(INT16); /* sizeof length */ - - for (p = arg; p->name; p++) { - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimDecodeInnerIMATTRIBUTE(im, p)) - continue; - return p->name; - } - - check = _XimCheckIMMode(res, mode); - if(check == XIM_CHECK_INVALID) - continue; - else if(check == XIM_CHECK_ERROR) - return p->name; - - total = data_len; - buf = data; - while (total >= min_len) { - if (res->id == buf[0]) - break; - - len = buf[1]; - len += XIM_PAD(len) + min_len; - buf = (CARD16 *)((char *)buf + len); - total -= len; - } - if (total < min_len) - return p->name; - - if (!(_XimAttributeToValue((Xic) im->private.local.current_ic, - res, &buf[2], buf[1], p->value, mode))) - return p->name; - } - return (char *)NULL; -} - -Private Bool -_XimDecodeInnerICATTRIBUTE( - Xic ic, - XIMArg *arg, - unsigned long mode) -{ - XIMResourceList res; - XimDefICValues ic_values; - - if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources, - ic->private.proto.ic_num_inner_resources, arg->name))) - return False; - - _XimGetCurrentICValues(ic, &ic_values); - if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode)) - return False; - _XimSetCurrentICValues(ic, &ic_values); - return True; -} - -Public char * -_XimDecodeICATTRIBUTE( - Xic ic, - XIMResourceList res_list, - unsigned int res_num, - CARD16 *data, - INT16 data_len, - XIMArg *arg, - BITMASK32 mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - INT16 len; - CARD16 *buf; - INT16 total; - char *name; - INT16 min_len = sizeof(CARD16) /* sizeof attributeID */ - + sizeof(INT16); /* sizeof length */ - XrmQuark pre_quark; - XrmQuark sts_quark; - - if (!arg) - return (char *)NULL; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - for (p = arg; p->name; p++) { - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimDecodeInnerICATTRIBUTE(ic, p, mode)) - continue; - return p->name; - } - - check = _XimCheckICMode(res, mode); - if (check == XIM_CHECK_INVALID) - continue; - else if (check == XIM_CHECK_ERROR) - return p->name; - - total = data_len; - buf = data; - while (total >= min_len) { - if (res->id == buf[0]) - break; - - len = buf[1]; - len += XIM_PAD(len) + min_len; - buf = (CARD16 *)((char *)buf + len); - total -= len; - } - if (total < min_len) - return p->name; - - if (res->resource_size == XimType_NEST) { - if (res->xrm_name == pre_quark) { - if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num, - &buf[2], buf[1], (XIMArg *)p->value, - (mode | XIM_PREEDIT_ATTR)))) - return name; - } else if (res->xrm_name == sts_quark) { - if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num, - &buf[2], buf[1], (XIMArg *)p->value, - (mode | XIM_STATUS_ATTR)))) - return name; - } - } else { - if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1], - p->value, mode))) - return p->name; - } - } - return (char *)NULL; -} - -Private Bool -_XimValueToAttribute( - XIMResourceList res, - XPointer buf, - int buf_size, - XPointer value, - int *len, - unsigned long mode, - XPointer param) -{ - int ret_len; - - switch (res->resource_size) { - case XimType_SeparatorOfNestedList: - case XimType_NEST: - *len = 0; - break; - - case XimType_CARD8: - ret_len = sizeof(CARD8); - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - *((CARD8 *)buf) = (CARD8)(long)value; - *len = ret_len; - break; - - case XimType_CARD16: - ret_len = sizeof(CARD16); - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - *((CARD16 *)buf) = (CARD16)(long)value; - *len = ret_len; - break; - - case XimType_CARD32: - case XimType_Window: - case XimType_XIMHotKeyState: - ret_len = sizeof(CARD32); - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - *((CARD32 *)buf) = (CARD32)(long)value; - *len = ret_len; - break; - - case XimType_STRING8: - if (!value) { - *len = 0; - return False; - } - - ret_len = strlen((char *)value); - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - (void)memcpy((char *)buf, (char *)value, ret_len); - *len = ret_len; - break; - - case XimType_XRectangle: - { - XRectangle *rect = (XRectangle *)value; - CARD16 *buf_s = (CARD16 *)buf; - - if (!rect) { - *len = 0; - return False; - } - - ret_len = sizeof(INT16) /* sizeof X */ - + sizeof(INT16) /* sizeof Y */ - + sizeof(CARD16) /* sizeof width */ - + sizeof(CARD16); /* sizeof height */ - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - buf_s[0] = (CARD16)rect->x; /* X */ - buf_s[1] = (CARD16)rect->y; /* Y */ - buf_s[2] = (CARD16)rect->width; /* width */ - buf_s[3] = (CARD16)rect->height; /* heght */ - *len = ret_len; - break; - } - - case XimType_XPoint: - { - XPoint *point = (XPoint *)value; - CARD16 *buf_s = (CARD16 *)buf; - - if (!point) { - *len = 0; - return False; - } - - ret_len = sizeof(INT16) /* sizeof X */ - + sizeof(INT16); /* sizeof Y */ - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - buf_s[0] = (CARD16)point->x; /* X */ - buf_s[1] = (CARD16)point->y; /* Y */ - *len = ret_len; - break; - } - - case XimType_XFontSet: - { - XFontSet font = (XFontSet)value; - Xic ic = (Xic)param; - char *base_name = NULL; - int length = 0; - CARD16 *buf_s = (CARD16 *)buf; - - if (!font) { - *len = 0; - return False; - } - - if (mode & XIM_PREEDIT_ATTR) { - base_name = ic->private.proto.preedit_font; - length = ic->private.proto.preedit_font_length; - } else if (mode & XIM_STATUS_ATTR) { - base_name = ic->private.proto.status_font; - length = ic->private.proto.status_font_length; - } - - if (!base_name) { - *len = 0; - return False; - } - - ret_len = sizeof(CARD16) /* sizeof length of Base name */ - + length; /* sizeof Base font name list */ - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - buf_s[0] = (INT16)length; /* length of Base font name */ - (void)memcpy((char *)&buf_s[1], base_name, length); - /* Base font name list */ - *len = ret_len; - break; - } - - case XimType_XIMHotKeyTriggers: - { - XIMHotKeyTriggers *hotkey = (XIMHotKeyTriggers *)value; - INT32 num; - CARD32 *buf_l = (CARD32 *)buf; - register CARD32 *key = (CARD32 *)&buf_l[1]; - register int i; - - if (!hotkey) { - *len = 0; - return False; - } - num = (INT32)hotkey->num_hot_key; - - ret_len = sizeof(INT32) /* sizeof number of key list */ - + (sizeof(CARD32) /* sizeof keysyn */ - + sizeof(CARD32) /* sizeof modifier */ - + sizeof(CARD32)) /* sizeof modifier_mask */ - * num; /* number of key list */ - if (buf_size < ret_len + XIM_PAD(ret_len)) { - *len = -1; - return False; - } - - buf_l[0] = num; /* number of key list */ - for (i = 0; i < num; i++, key += 3) { - key[0] = (CARD32)(hotkey->key[i].keysym); - /* keysym */ - key[1] = (CARD32)(hotkey->key[i].modifier); - /* modifier */ - key[2] = (CARD32)(hotkey->key[i].modifier_mask); - /* modifier_mask */ - } - *len = ret_len; - break; - } - - case XimType_XIMStringConversion: - { - *len = 0; - break; - } - - default: - return False; - } - return True; -} - -Private Bool -_XimSetInnerIMAttributes( - Xim im, - XPointer top, - XIMArg *arg, - unsigned long mode) -{ - XIMResourceList res; - int check; - - if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources, - im->private.proto.im_num_inner_resources, arg->name))) - return False; - - check = _XimCheckIMMode(res, mode); - if(check == XIM_CHECK_INVALID) - return True; - else if(check == XIM_CHECK_ERROR) - return False; - - return _XimEncodeLocalIMAttr(res, top, arg->value); -} - -Public char * -_XimEncodeIMATTRIBUTE( - Xim im, - XIMResourceList res_list, - unsigned int res_num, - XIMArg *arg, - XIMArg **arg_ret, - char *buf, - int size, - int *ret_len, - XPointer top, - unsigned long mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - CARD16 *buf_s; - int len; - int min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(INT16); /* sizeof value length */ - - *ret_len = 0; - for (p = arg; p->name; p++) { - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimSetInnerIMAttributes(im, top, p, mode)) - continue; - return p->name; - } - - check = _XimCheckIMMode(res, mode); - if (check == XIM_CHECK_INVALID) - continue; - else if (check == XIM_CHECK_ERROR) - return p->name; - - if (!(_XimEncodeLocalIMAttr(res, top, p->value))) - return p->name; - - buf_s = (CARD16 *)buf; - if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len), - p->value, &len, mode, (XPointer)NULL))) - return p->name; - - if (len == 0) { - continue; - } else if (len < 0) { - *arg_ret = p; - return (char *)NULL; - } - - buf_s[0] = res->id; /* attribute ID */ - buf_s[1] = len; /* value length */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += min_len; - - buf += len; - *ret_len += len; - size -= len; - } - *arg_ret = (XIMArg *)NULL; - return (char *)NULL; -} - -#ifdef XIM_CONNECTABLE -Public Bool -_XimEncodeSavedIMATTRIBUTE( - Xim im, - XIMResourceList res_list, - unsigned int res_num, - int *idx, - char *buf, - int size, - int *ret_len, - XPointer top, - unsigned long mode) -{ - register int i; - int num = im->private.proto.num_saved_imvalues; - XrmQuark *quark_list = im->private.proto.saved_imvalues; - XIMResourceList res; - XPointer value; - CARD16 *buf_s; - int len; - int min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(INT16); /* sizeof value length */ - - if (!im->private.proto.saved_imvalues) { - *idx = -1; - *ret_len = 0; - return True; - } - - *ret_len = 0; - for (i = *idx; i < num; i++) { - if (!(res = _XimGetResourceListRecByQuark(res_list, - res_num, quark_list[i]))) - continue; - - if (!_XimDecodeLocalIMAttr(res, top, value)) - return False; - - buf_s = (CARD16 *)buf; - if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], - (size - min_len), value, &len, mode, (XPointer)NULL))) - return False; - - if (len == 0) { - continue; - } else if (len < 0) { - *idx = i; - return True; - } - - buf_s[0] = res->id; /* attribute ID */ - buf_s[1] = len; /* value length */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += min_len; - - buf += len; - *ret_len += len; - size -= len; - } - *idx = -1; - return True; -} -#endif /* XIM_CONNECTABLE */ - -Private Bool -_XimEncodeTopValue( - Xic ic, - XIMResourceList res, - XIMArg *p) -{ - if (res->xrm_name == XrmStringToQuark(XNClientWindow)) { - ic->core.client_window = (Window)p->value; - if (ic->core.focus_window == (Window)0) - ic->core.focus_window = ic->core.client_window; - _XimRegisterFilter(ic); - - } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) { - if (ic->core.client_window) { - _XimUnregisterFilter(ic); - ic->core.focus_window = (Window)p->value; - _XimRegisterFilter(ic); - } else /* client_window not yet */ - ic->core.focus_window = (Window)p->value; - } - return True; -} - -Private Bool -_XimEncodePreeditValue( - Xic ic, - XIMResourceList res, - XIMArg *p) -{ - if (res->xrm_name == XrmStringToQuark(XNStdColormap)) { - XStandardColormap *colormap_ret; - int count; - - if (!(XGetRGBColormaps(ic->core.im->core.display, - ic->core.focus_window, &colormap_ret, - &count, (Atom)p->value))) - return False; - - XFree(colormap_ret); - } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) { - int list_ret; - XFontStruct **struct_list; - char **name_list; - char *tmp; - int len; - register int i; - - if (!p->value) - return False; - - if (ic->private.proto.preedit_font) - Xfree(ic->private.proto.preedit_font); - - list_ret = XFontsOfFontSet((XFontSet)p->value, - &struct_list, &name_list); - for (i = 0, len = 0; i < list_ret; i++) { - len += (strlen(name_list[i]) + sizeof(char)); - } - if (!(tmp = Xmalloc(len + 1))) { - ic->private.proto.preedit_font = NULL; - return False; - } - - tmp[0] = '\0'; - for (i = 0; i < list_ret; i++) { - strcat(tmp, name_list[i]); - strcat(tmp, ","); - } - tmp[len - 1] = 0; - ic->private.proto.preedit_font = tmp; - ic->private.proto.preedit_font_length = len - 1; - } - return True; -} - -Private Bool -_XimEncodeStatusValue( - Xic ic, - XIMResourceList res, - XIMArg *p) -{ - if (res->xrm_name == XrmStringToQuark(XNStdColormap)) { - XStandardColormap *colormap_ret = NULL; - int count; - - if (!(XGetRGBColormaps(ic->core.im->core.display, - ic->core.focus_window, &colormap_ret, - &count, (Atom)p->value))) - return False; - - XFree(colormap_ret); - } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) { - int list_ret; - XFontStruct **struct_list; - char **name_list; - char *tmp; - int len; - register int i; - - if (!p->value) - return False; - - if (ic->private.proto.status_font) - Xfree(ic->private.proto.status_font); - - list_ret = XFontsOfFontSet((XFontSet)p->value, - &struct_list, &name_list); - for (i = 0, len = 0; i < list_ret; i++) { - len += (strlen(name_list[i]) + sizeof(char)); - } - if (!(tmp = Xmalloc(len+1))) { - ic->private.proto.status_font = NULL; - return False; - } - - tmp[0] = '\0'; - for(i = 0; i < list_ret; i++) { - strcat(tmp, name_list[i]); - strcat(tmp, ","); - } - tmp[len - 1] = 0; - ic->private.proto.status_font = tmp; - ic->private.proto.status_font_length = len - 1; - } - return True; -} - -Private Bool -_XimSetInnerICAttributes( - Xic ic, - XPointer top, - XIMArg *arg, - unsigned long mode) -{ - XIMResourceList res; - int check; - - if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources, - ic->private.proto.ic_num_inner_resources, arg->name))) - return False; - - check = _XimCheckICMode(res, mode); - if(check == XIM_CHECK_INVALID) - return True; - else if(check == XIM_CHECK_ERROR) - return False; - - return _XimEncodeLocalICAttr(ic, res, top, arg, mode); -} - -Public char * -_XimEncodeICATTRIBUTE( - Xic ic, - XIMResourceList res_list, - unsigned int res_num, - XIMArg *arg, - XIMArg **arg_ret, - char *buf, - int size, - int *ret_len, - XPointer top, - BITMASK32 *flag, - unsigned long mode) -{ - register XIMArg *p; - XIMResourceList res; - int check; - CARD16 *buf_s; - int len; - int min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(INT16); /* sizeof value length */ - XrmQuark pre_quark; - XrmQuark sts_quark; - char *name; - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - - *ret_len = 0; - for (p = arg; p && p->name; p++) { - buf_s = (CARD16 *)buf; - if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) { - if (_XimSetInnerICAttributes(ic, top, p, mode)) - continue; - return p->name; - } - - check = _XimCheckICMode(res, mode); - if (check == XIM_CHECK_INVALID) - continue; - else if (check == XIM_CHECK_ERROR) - return p->name; - - if (mode & XIM_PREEDIT_ATTR) { - if (!(_XimEncodePreeditValue(ic, res, p))) - return p->name; - } else if (mode & XIM_STATUS_ATTR) { - if (!(_XimEncodeStatusValue(ic, res, p))) - return p->name; - } else { - if (!(_XimEncodeTopValue(ic, res, p))) - return p->name; - } - - if (res->resource_size == XimType_NEST) { - XimDefICValues *ic_attr = (XimDefICValues *)top; - - if (res->xrm_name == pre_quark) { - XIMArg *arg_rt; - if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num, - (XIMArg *)p->value, &arg_rt, - (char *)&buf_s[2], (size - min_len), - &len, (XPointer)&ic_attr->preedit_attr, flag, - (mode | XIM_PREEDIT_ATTR)))) { - return name; - } - - } else if (res->xrm_name == sts_quark) { - XIMArg *arg_rt; - if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num, - (XIMArg *)p->value, &arg_rt, - (char *)&buf_s[2], (size - min_len), - &len, (XPointer)&ic_attr->status_attr, flag, - (mode | XIM_STATUS_ATTR)))) { - return name; - } - } - } else { -#ifdef EXT_MOVE - if (flag) - *flag |= _XimExtenArgCheck(p); -#endif - if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode))) - return p->name; - - if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], - (size - min_len), p->value, - &len, mode, (XPointer)ic))) - return p->name; - } - - if (len == 0) { - continue; - } else if (len < 0) { - *arg_ret = p; - return (char *)NULL; - } - - buf_s[0] = res->id; /* attribute ID */ - buf_s[1] = len; /* value length */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += min_len; - - buf += len; - *ret_len += len; - size -= len; - } - *arg_ret = (XIMArg *)NULL; - return (char *)NULL; -} - -#ifdef XIM_CONNECTABLE -Private Bool -_XimEncodeSavedPreeditValue( - Xic ic, - XIMResourceList res, - XPointer value) -{ - int list_ret; - XFontStruct **struct_list; - char **name_list; - char *tmp; - int len; - register int i; - - if (res->xrm_name == XrmStringToQuark(XNFontSet)) { - if (!value) - return False; - - if (ic->private.proto.preedit_font) - Xfree(ic->private.proto.preedit_font); - - list_ret = XFontsOfFontSet((XFontSet)value, - &struct_list, &name_list); - for(i = 0, len = 0; i < list_ret; i++) { - len += (strlen(name_list[i]) + sizeof(char)); - } - if(!(tmp = Xmalloc(len + 1))) { - ic->private.proto.preedit_font = NULL; - return False; - } - - tmp[0] = '\0'; - for(i = 0; i < list_ret; i++) { - strcat(tmp, name_list[i]); - strcat(tmp, ","); - } - tmp[len - 1] = 0; - ic->private.proto.preedit_font = tmp; - ic->private.proto.preedit_font_length = len - 1; - } - return True; -} - -Private Bool -_XimEncodeSavedStatusValue( - Xic ic, - XIMResourceList res, - XPointer value) -{ - int list_ret; - XFontStruct **struct_list; - char **name_list; - char *tmp; - int len; - register int i; - - if (res->xrm_name == XrmStringToQuark(XNFontSet)) { - if (!value) - return False; - - if (ic->private.proto.status_font) - Xfree(ic->private.proto.status_font); - - list_ret = XFontsOfFontSet((XFontSet)value, - &struct_list, &name_list); - for(i = 0, len = 0; i < list_ret; i++) { - len += (strlen(name_list[i]) + sizeof(char)); - } - if(!(tmp = Xmalloc(len + 1))) { - ic->private.proto.status_font = NULL; - return False; - } - - tmp[0] = '\0'; - for(i = 0; i < list_ret; i++) { - strcat(tmp, name_list[i]); - strcat(tmp, ","); - } - tmp[len - 1] = 0; - ic->private.proto.status_font = tmp; - ic->private.proto.status_font_length = len - 1; - } - return True; -} - -Public Bool -_XimEncodeSavedICATTRIBUTE( - Xic ic, - XIMResourceList res_list, - unsigned int res_num, - int *idx, - char *buf, - int size, - int *ret_len, - XPointer top, - unsigned long mode) -{ - int i; - int num = ic->private.proto.num_saved_icvalues; - XrmQuark *quark_list = ic->private.proto.saved_icvalues; - XIMResourceList res; - XPointer value; - CARD16 *buf_s; - int len; - int min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(INT16); /* sizeof value length */ - XrmQuark pre_quark; - XrmQuark sts_quark; - XrmQuark separator; - - if (!ic->private.proto.saved_icvalues) { - *idx = -1; - *ret_len = 0; - return True; - } - - pre_quark = XrmStringToQuark(XNPreeditAttributes); - sts_quark = XrmStringToQuark(XNStatusAttributes); - separator = XrmStringToQuark(XNSeparatorofNestedList); - - *ret_len = 0; - for (i = *idx; i < num; i++) { - if (quark_list[i] == separator) { - *idx = i; - return True; - } - - if (!(res = _XimGetResourceListRecByQuark(res_list, - res_num, quark_list[i]))) - continue; - - if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode)) - return False; - - if (mode & XIM_PREEDIT_ATTR) { - if (!(_XimEncodeSavedPreeditValue(ic, res, value))) { - return False; - } - } else if (mode & XIM_STATUS_ATTR) { - if (!(_XimEncodeSavedStatusValue(ic, res, value))) { - return False; - } - } - - buf_s = (CARD16 *)buf; - if (res->resource_size == XimType_NEST) { - XimDefICValues *ic_attr = (XimDefICValues *)top; - - i++; - if (res->xrm_name == pre_quark) { - if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num, - &i, (char *)&buf_s[2], (size - min_len), - &len, (XPointer)&ic_attr->preedit_attr, - (mode | XIM_PREEDIT_ATTR))) { - return False; - } - - } else if (res->xrm_name == sts_quark) { - if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num, - &i, (char *)&buf_s[2], (size - min_len), - &len, (XPointer)&ic_attr->status_attr, - (mode | XIM_STATUS_ATTR))) { - return False; - } - } - } else { - if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], - (size - min_len), value, - &len, mode, (XPointer)ic))) { - return False; - } - } - - if (len == 0) { - continue; - } else if (len < 0) { - if (quark_list[i] == separator) - i++; - *idx = i; - return True; - } - - buf_s[0] = res->id; /* attribute ID */ - buf_s[1] = len; /* value length */ - XIM_SET_PAD(&buf_s[2], len); /* pad */ - len += min_len; - - buf += len; - *ret_len += len; - size -= len; - } - *idx = -1; - return True; -} -#endif /* XIM_CONNECTABLE */ - -Private unsigned int -_XimCountNumberOfAttr( - INT16 total, - CARD16 *attr, - int *names_len) -{ - unsigned int n; - INT16 len; - INT16 min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(CARD16) /* sizeof type of value */ - + sizeof(INT16); /* sizeof length of attribute */ - - n = 0; - *names_len = 0; - while (total > min_len) { - len = attr[2]; - *names_len += (len + 1); - len += (min_len + XIM_PAD(len + 2)); - total -= len; - attr = (CARD16 *)((char *)attr + len); - n++; - } - return n; -} - -Public Bool -_XimGetAttributeID( - Xim im, - CARD16 *buf) -{ - unsigned int n; - XIMResourceList res; - char *names; - int names_len; - XPointer tmp; - XIMValuesList *values_list; - char **values; - int values_len; - register int i; - INT16 len; - INT16 min_len = sizeof(CARD16) /* sizeof attribute ID */ - + sizeof(CARD16) /* sizeof type of value */ - + sizeof(INT16); /* sizeof length of attr */ - /* - * IM attribute ID - */ - - if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len))) - return False; - - if (!(res = Xcalloc(n, sizeof(XIMResource)))) - return False; - - values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; - if (!(tmp = Xcalloc(1, values_len))) { - Xfree(res); - return False; - } - - values_list = (XIMValuesList *)tmp; - values = (char **)((char *)tmp + sizeof(XIMValuesList)); - names = (char *)((char *)values + (sizeof(char **) * n)); - - values_list->count_values = n; - values_list->supported_values = values; - - buf++; - for (i = 0; i < n; i++) { - len = buf[2]; - (void)memcpy(names, (char *)&buf[3], len); - values[i] = names; - names[len] = '\0'; - res[i].resource_name = names; - res[i].resource_size = buf[1]; - res[i].id = buf[0]; - names += (len + 1); - len += (min_len + XIM_PAD(len + 2)); - buf = (CARD16 *)((char *)buf + len); - } - _XIMCompileResourceList(res, n); - - if (im->core.im_resources) - Xfree(im->core.im_resources); - if (im->core.im_values_list) - Xfree(im->core.im_values_list); - im->core.im_resources = res; - im->core.im_num_resources = n; - im->core.im_values_list = values_list; - - /* - * IC attribute ID - */ - - if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len))) - return False; - - if (!(res = Xcalloc(n, sizeof(XIMResource)))) - return False; - - values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len; - if (!(tmp = Xcalloc(1, values_len))) { - Xfree(res); - return False; - } - - values_list = (XIMValuesList *)tmp; - values = (char **)((char *)tmp + sizeof(XIMValuesList)); - names = (char *)((char *)values + (sizeof(char **) * n)); - - values_list->count_values = n; - values_list->supported_values = values; - - buf += 2; - for (i = 0; i < n; i++) { - len = buf[2]; - (void)memcpy(names, (char *)&buf[3], len); - values[i] = names; - names[len] = '\0'; - res[i].resource_name = names; - res[i].resource_size = buf[1]; - res[i].id = buf[0]; - names += (len + 1); - len += (min_len + XIM_PAD(len + 2)); - buf = (CARD16 *)((char *)buf + len); - } - _XIMCompileResourceList(res, n); - - if (im->core.ic_resources) - Xfree(im->core.ic_resources); - if (im->core.ic_values_list) - Xfree(im->core.ic_values_list); - im->core.ic_resources = res; - im->core.ic_num_resources = n; - im->core.ic_values_list = values_list; - - return True; -} +/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+
+Private XIMResourceList
+_XimGetNestedListSeparator(
+ XIMResourceList res_list, /* LISTofIMATTR or IMATTR */
+ unsigned int res_num)
+{
+ return _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList);
+}
+
+Private Bool
+_XimCheckInnerIMAttributes(
+ Xim im,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ XIMResourceList res;
+ int check;
+
+ if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
+ im->private.proto.im_num_inner_resources, arg->name)))
+ return False;
+
+ check = _XimCheckIMMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ return True;
+ else if(check == XIM_CHECK_ERROR)
+ return False;
+
+ return True;
+}
+
+Public char *
+_XimMakeIMAttrIDList(
+ Xim im,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ XIMArg *arg,
+ CARD16 *buf,
+ INT16 *len,
+ unsigned long mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+
+ *len = 0;
+ if (!arg)
+ return (char *)NULL;
+
+ for (p = arg; p->name; p++) {
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimCheckInnerIMAttributes(im, p, mode))
+ continue;
+ return p->name;
+ }
+
+ check = _XimCheckIMMode(res, mode);
+ if (check == XIM_CHECK_INVALID)
+ continue;
+ else if (check == XIM_CHECK_ERROR)
+ return p->name;
+
+ *buf = res->id;
+ *len += sizeof(CARD16);
+ buf++;
+ }
+ return (char *)NULL;
+}
+
+Private Bool
+_XimCheckInnerICAttributes(
+ Xic ic,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ XIMResourceList res;
+ int check;
+
+ if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
+ ic->private.proto.ic_num_inner_resources, arg->name)))
+ return False;
+
+ check = _XimCheckICMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ return True;
+ else if(check == XIM_CHECK_ERROR)
+ return False;
+
+ return True;
+}
+
+Public char *
+_XimMakeICAttrIDList(
+ Xic ic,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ XIMArg *arg,
+ CARD16 *buf,
+ INT16 *len,
+ unsigned long mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+ char *name;
+ INT16 new_len;
+
+ *len = 0;
+ if (!arg)
+ return (char *)NULL;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ for (p = arg; p && p->name; p++) {
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimCheckInnerICAttributes(ic, p, mode))
+ continue;
+ *len = -1;
+ return p->name;
+ }
+
+ check = _XimCheckICMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ continue;
+ else if(check == XIM_CHECK_ERROR) {
+ *len = -1;
+ return p->name;
+ }
+
+ *buf = res->id;
+ *len += sizeof(CARD16);
+ buf++;
+ if (res->resource_size == XimType_NEST) {
+ if (res->xrm_name == pre_quark) {
+ if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
+ (XIMArg *)p->value, buf, &new_len,
+ (mode | XIM_PREEDIT_ATTR)))) {
+ if (new_len < 0) *len = -1;
+ else *len += new_len;
+ return name;
+ }
+ } else if (res->xrm_name == sts_quark) {
+ if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
+ (XIMArg *)p->value, buf, &new_len,
+ (mode | XIM_STATUS_ATTR)))) {
+ if (new_len < 0) *len = -1;
+ else *len += new_len;
+ return name;
+ }
+ }
+ *len += new_len;
+ buf = (CARD16 *)((char *)buf + new_len);
+ if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
+ p++;
+ if (p) {
+ *len = -1;
+ return p->name;
+ }
+ else {
+ return (char *)NULL;
+ }
+ }
+ *buf = res->id;
+ *len += sizeof(CARD16);
+ buf++;
+ }
+ }
+ return (char *)NULL;
+}
+
+Private Bool
+_XimAttributeToValue(
+ Xic ic,
+ XIMResourceList res,
+ CARD16 *data,
+ INT16 data_len,
+ XPointer value,
+ BITMASK32 mode)
+{
+ switch (res->resource_size) {
+ case XimType_SeparatorOfNestedList:
+ case XimType_NEST:
+ break;
+
+ case XimType_CARD8:
+ case XimType_CARD16:
+ case XimType_CARD32:
+ case XimType_Window:
+ case XimType_XIMHotKeyState:
+ _XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
+ break;
+
+ case XimType_STRING8:
+ {
+ char *str;
+
+ if (!(value))
+ return False;
+
+ if (!(str = (char *)Xmalloc(data_len + 1)))
+ return False;
+
+ (void)memcpy(str, (char *)data, data_len);
+ str[data_len] = '\0';
+
+ *((char **)value) = str;
+ break;
+ }
+
+ case XimType_XIMStyles:
+ {
+ INT16 num = data[0];
+ register CARD32 *style_list = (CARD32 *)&data[2];
+ XIMStyle *style;
+ XIMStyles *rep;
+ register int i;
+ char *p;
+ int alloc_len;
+
+ if (!(value))
+ return False;
+
+ alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
+ if (!(p = (char *)Xmalloc(alloc_len)))
+ return False;
+
+ rep = (XIMStyles *)p;
+ style = (XIMStyle *)(p + sizeof(XIMStyles));
+
+ for (i = 0; i < num; i++)
+ style[i] = (XIMStyle)style_list[i];
+
+ rep->count_styles = (unsigned short)num;
+ rep->supported_styles = style;
+ *((XIMStyles **)value) = rep;
+ break;
+ }
+
+ case XimType_XRectangle:
+ {
+ XRectangle *rep;
+
+ if (!(value))
+ return False;
+
+ if (!(rep = (XRectangle *)Xmalloc(sizeof(XRectangle))))
+ return False;
+
+ rep->x = data[0];
+ rep->y = data[1];
+ rep->width = data[2];
+ rep->height = data[3];
+ *((XRectangle **)value) = rep;
+ break;
+ }
+
+ case XimType_XPoint:
+ {
+ XPoint *rep;
+
+ if (!(value))
+ return False;
+
+ if (!(rep = (XPoint *)Xmalloc(sizeof(XPoint))))
+ return False;
+
+ rep->x = data[0];
+ rep->y = data[1];
+ *((XPoint **)value) = rep;
+ break;
+ }
+
+ case XimType_XFontSet:
+ {
+ INT16 len = data[0];
+ char *base_name;
+ XFontSet rep = (XFontSet)NULL;
+ char **missing_list = NULL;
+ int missing_count;
+ char *def_string;
+
+ if (!(value))
+ return False;
+ if (!ic)
+ return False;
+
+ if (!(base_name = (char *)Xmalloc(len + 1)))
+ return False;
+
+ (void)strncpy(base_name, (char *)&data[1], (int)len);
+ base_name[len] = '\0';
+
+ if (mode & XIM_PREEDIT_ATTR) {
+ if (!strcmp(base_name, ic->private.proto.preedit_font)) {
+ rep = ic->core.preedit_attr.fontset;
+ } else if (!ic->private.proto.preedit_font_length) {
+ rep = XCreateFontSet(ic->core.im->core.display,
+ base_name, &missing_list,
+ &missing_count, &def_string);
+ }
+ } else if (mode & XIM_STATUS_ATTR) {
+ if (!strcmp(base_name, ic->private.proto.status_font)) {
+ rep = ic->core.status_attr.fontset;
+ } else if (!ic->private.proto.status_font_length) {
+ rep = XCreateFontSet(ic->core.im->core.display,
+ base_name, &missing_list,
+ &missing_count, &def_string);
+ }
+ }
+
+ Xfree(base_name);
+ Xfree(missing_list);
+ *((XFontSet *)value) = rep;
+ break;
+ }
+
+ case XimType_XIMHotKeyTriggers:
+ {
+ INT32 num = *((CARD32 *)data);
+ register CARD32 *key_list = (CARD32 *)&data[2];
+ XIMHotKeyTrigger *key;
+ XIMHotKeyTriggers *rep;
+ register int i;
+ char *p;
+ int alloc_len;
+
+ if (!(value))
+ return False;
+
+ alloc_len = sizeof(XIMHotKeyTriggers)
+ + sizeof(XIMHotKeyTrigger) * num;
+ if (!(p = (char *)Xmalloc(alloc_len)))
+ return False;
+
+ rep = (XIMHotKeyTriggers *)p;
+ key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
+
+ for (i = 0; i < num; i++, key_list += 3) {
+ key[i].keysym = (KeySym)key_list[0]; /* keysym */
+ key[i].modifier = (int)key_list[1]; /* modifier */
+ key[i].modifier_mask = (int)key_list[2]; /* modifier_mask */
+ }
+
+ rep->num_hot_key = (int)num;
+ rep->key = key;
+ *((XIMHotKeyTriggers **)value) = rep;
+ break;
+ }
+
+ case XimType_XIMStringConversion:
+ {
+ break;
+ }
+
+ default:
+ return False;
+ }
+ return True;
+}
+
+Private Bool
+_XimDecodeInnerIMATTRIBUTE(
+ Xim im,
+ XIMArg *arg)
+{
+ XIMResourceList res;
+ XimDefIMValues im_values;
+
+ if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
+ im->private.proto.im_num_inner_resources, arg->name)))
+ return False;
+
+ _XimGetCurrentIMValues(im, &im_values);
+ return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
+}
+
+Public char *
+_XimDecodeIMATTRIBUTE(
+ Xim im,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ CARD16 *data,
+ INT16 data_len,
+ XIMArg *arg,
+ BITMASK32 mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+ INT16 len;
+ CARD16 *buf;
+ INT16 total;
+ INT16 min_len = sizeof(CARD16) /* sizeof attributeID */
+ + sizeof(INT16); /* sizeof length */
+
+ for (p = arg; p->name; p++) {
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimDecodeInnerIMATTRIBUTE(im, p))
+ continue;
+ return p->name;
+ }
+
+ check = _XimCheckIMMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ continue;
+ else if(check == XIM_CHECK_ERROR)
+ return p->name;
+
+ total = data_len;
+ buf = data;
+ while (total >= min_len) {
+ if (res->id == buf[0])
+ break;
+
+ len = buf[1];
+ len += XIM_PAD(len) + min_len;
+ buf = (CARD16 *)((char *)buf + len);
+ total -= len;
+ }
+ if (total < min_len)
+ return p->name;
+
+ if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
+ res, &buf[2], buf[1], p->value, mode)))
+ return p->name;
+ }
+ return (char *)NULL;
+}
+
+Private Bool
+_XimDecodeInnerICATTRIBUTE(
+ Xic ic,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ XIMResourceList res;
+ XimDefICValues ic_values;
+
+ if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
+ ic->private.proto.ic_num_inner_resources, arg->name)))
+ return False;
+
+ _XimGetCurrentICValues(ic, &ic_values);
+ if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
+ return False;
+ _XimSetCurrentICValues(ic, &ic_values);
+ return True;
+}
+
+Public char *
+_XimDecodeICATTRIBUTE(
+ Xic ic,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ CARD16 *data,
+ INT16 data_len,
+ XIMArg *arg,
+ BITMASK32 mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+ INT16 len;
+ CARD16 *buf;
+ INT16 total;
+ char *name;
+ INT16 min_len = sizeof(CARD16) /* sizeof attributeID */
+ + sizeof(INT16); /* sizeof length */
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+
+ if (!arg)
+ return (char *)NULL;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ for (p = arg; p->name; p++) {
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
+ continue;
+ return p->name;
+ }
+
+ check = _XimCheckICMode(res, mode);
+ if (check == XIM_CHECK_INVALID)
+ continue;
+ else if (check == XIM_CHECK_ERROR)
+ return p->name;
+
+ total = data_len;
+ buf = data;
+ while (total >= min_len) {
+ if (res->id == buf[0])
+ break;
+
+ len = buf[1];
+ len += XIM_PAD(len) + min_len;
+ buf = (CARD16 *)((char *)buf + len);
+ total -= len;
+ }
+ if (total < min_len)
+ return p->name;
+
+ if (res->resource_size == XimType_NEST) {
+ if (res->xrm_name == pre_quark) {
+ if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
+ &buf[2], buf[1], (XIMArg *)p->value,
+ (mode | XIM_PREEDIT_ATTR))))
+ return name;
+ } else if (res->xrm_name == sts_quark) {
+ if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
+ &buf[2], buf[1], (XIMArg *)p->value,
+ (mode | XIM_STATUS_ATTR))))
+ return name;
+ }
+ } else {
+ if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
+ p->value, mode)))
+ return p->name;
+ }
+ }
+ return (char *)NULL;
+}
+
+Private Bool
+_XimValueToAttribute(
+ XIMResourceList res,
+ XPointer buf,
+ int buf_size,
+ XPointer value,
+ int *len,
+ unsigned long mode,
+ XPointer param)
+{
+ int ret_len;
+
+ switch (res->resource_size) {
+ case XimType_SeparatorOfNestedList:
+ case XimType_NEST:
+ *len = 0;
+ break;
+
+ case XimType_CARD8:
+ ret_len = sizeof(CARD8);
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ *((CARD8 *)buf) = (CARD8)(long)value;
+ *len = ret_len;
+ break;
+
+ case XimType_CARD16:
+ ret_len = sizeof(CARD16);
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ *((CARD16 *)buf) = (CARD16)(long)value;
+ *len = ret_len;
+ break;
+
+ case XimType_CARD32:
+ case XimType_Window:
+ case XimType_XIMHotKeyState:
+ ret_len = sizeof(CARD32);
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ *((CARD32 *)buf) = (CARD32)(long)value;
+ *len = ret_len;
+ break;
+
+ case XimType_STRING8:
+ if (!value) {
+ *len = 0;
+ return False;
+ }
+
+ ret_len = strlen((char *)value);
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ (void)memcpy((char *)buf, (char *)value, ret_len);
+ *len = ret_len;
+ break;
+
+ case XimType_XRectangle:
+ {
+ XRectangle *rect = (XRectangle *)value;
+ CARD16 *buf_s = (CARD16 *)buf;
+
+ if (!rect) {
+ *len = 0;
+ return False;
+ }
+
+ ret_len = sizeof(INT16) /* sizeof X */
+ + sizeof(INT16) /* sizeof Y */
+ + sizeof(CARD16) /* sizeof width */
+ + sizeof(CARD16); /* sizeof height */
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ buf_s[0] = (CARD16)rect->x; /* X */
+ buf_s[1] = (CARD16)rect->y; /* Y */
+ buf_s[2] = (CARD16)rect->width; /* width */
+ buf_s[3] = (CARD16)rect->height; /* heght */
+ *len = ret_len;
+ break;
+ }
+
+ case XimType_XPoint:
+ {
+ XPoint *point = (XPoint *)value;
+ CARD16 *buf_s = (CARD16 *)buf;
+
+ if (!point) {
+ *len = 0;
+ return False;
+ }
+
+ ret_len = sizeof(INT16) /* sizeof X */
+ + sizeof(INT16); /* sizeof Y */
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ buf_s[0] = (CARD16)point->x; /* X */
+ buf_s[1] = (CARD16)point->y; /* Y */
+ *len = ret_len;
+ break;
+ }
+
+ case XimType_XFontSet:
+ {
+ XFontSet font = (XFontSet)value;
+ Xic ic = (Xic)param;
+ char *base_name = NULL;
+ int length = 0;
+ CARD16 *buf_s = (CARD16 *)buf;
+
+ if (!font) {
+ *len = 0;
+ return False;
+ }
+
+ if (mode & XIM_PREEDIT_ATTR) {
+ base_name = ic->private.proto.preedit_font;
+ length = ic->private.proto.preedit_font_length;
+ } else if (mode & XIM_STATUS_ATTR) {
+ base_name = ic->private.proto.status_font;
+ length = ic->private.proto.status_font_length;
+ }
+
+ if (!base_name) {
+ *len = 0;
+ return False;
+ }
+
+ ret_len = sizeof(CARD16) /* sizeof length of Base name */
+ + length; /* sizeof Base font name list */
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ buf_s[0] = (INT16)length; /* length of Base font name */
+ (void)memcpy((char *)&buf_s[1], base_name, length);
+ /* Base font name list */
+ *len = ret_len;
+ break;
+ }
+
+ case XimType_XIMHotKeyTriggers:
+ {
+ XIMHotKeyTriggers *hotkey = (XIMHotKeyTriggers *)value;
+ INT32 num;
+ CARD32 *buf_l = (CARD32 *)buf;
+ register CARD32 *key = (CARD32 *)&buf_l[1];
+ register int i;
+
+ if (!hotkey) {
+ *len = 0;
+ return False;
+ }
+ num = (INT32)hotkey->num_hot_key;
+
+ ret_len = sizeof(INT32) /* sizeof number of key list */
+ + (sizeof(CARD32) /* sizeof keysyn */
+ + sizeof(CARD32) /* sizeof modifier */
+ + sizeof(CARD32)) /* sizeof modifier_mask */
+ * num; /* number of key list */
+ if (buf_size < ret_len + XIM_PAD(ret_len)) {
+ *len = -1;
+ return False;
+ }
+
+ buf_l[0] = num; /* number of key list */
+ for (i = 0; i < num; i++, key += 3) {
+ key[0] = (CARD32)(hotkey->key[i].keysym);
+ /* keysym */
+ key[1] = (CARD32)(hotkey->key[i].modifier);
+ /* modifier */
+ key[2] = (CARD32)(hotkey->key[i].modifier_mask);
+ /* modifier_mask */
+ }
+ *len = ret_len;
+ break;
+ }
+
+ case XimType_XIMStringConversion:
+ {
+ *len = 0;
+ break;
+ }
+
+ default:
+ return False;
+ }
+ return True;
+}
+
+Private Bool
+_XimSetInnerIMAttributes(
+ Xim im,
+ XPointer top,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ XIMResourceList res;
+ int check;
+
+ if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
+ im->private.proto.im_num_inner_resources, arg->name)))
+ return False;
+
+ check = _XimCheckIMMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ return True;
+ else if(check == XIM_CHECK_ERROR)
+ return False;
+
+ return _XimEncodeLocalIMAttr(res, top, arg->value);
+}
+
+Public char *
+_XimEncodeIMATTRIBUTE(
+ Xim im,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ XIMArg *arg,
+ XIMArg **arg_ret,
+ char *buf,
+ int size,
+ int *ret_len,
+ XPointer top,
+ unsigned long mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+ CARD16 *buf_s;
+ int len;
+ int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(INT16); /* sizeof value length */
+
+ *ret_len = 0;
+ for (p = arg; p->name; p++) {
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimSetInnerIMAttributes(im, top, p, mode))
+ continue;
+ return p->name;
+ }
+
+ check = _XimCheckIMMode(res, mode);
+ if (check == XIM_CHECK_INVALID)
+ continue;
+ else if (check == XIM_CHECK_ERROR)
+ return p->name;
+
+ if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
+ return p->name;
+
+ buf_s = (CARD16 *)buf;
+ if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
+ p->value, &len, mode, (XPointer)NULL)))
+ return p->name;
+
+ if (len == 0) {
+ continue;
+ } else if (len < 0) {
+ *arg_ret = p;
+ return (char *)NULL;
+ }
+
+ buf_s[0] = res->id; /* attribute ID */
+ buf_s[1] = len; /* value length */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += min_len;
+
+ buf += len;
+ *ret_len += len;
+ size -= len;
+ }
+ *arg_ret = (XIMArg *)NULL;
+ return (char *)NULL;
+}
+
+#ifdef XIM_CONNECTABLE
+Public Bool
+_XimEncodeSavedIMATTRIBUTE(
+ Xim im,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ int *idx,
+ char *buf,
+ int size,
+ int *ret_len,
+ XPointer top,
+ unsigned long mode)
+{
+ register int i;
+ int num = im->private.proto.num_saved_imvalues;
+ XrmQuark *quark_list = im->private.proto.saved_imvalues;
+ XIMResourceList res;
+ XPointer value;
+ CARD16 *buf_s;
+ int len;
+ int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(INT16); /* sizeof value length */
+
+ if (!im->private.proto.saved_imvalues) {
+ *idx = -1;
+ *ret_len = 0;
+ return True;
+ }
+
+ *ret_len = 0;
+ for (i = *idx; i < num; i++) {
+ if (!(res = _XimGetResourceListRecByQuark(res_list,
+ res_num, quark_list[i])))
+ continue;
+
+ if (!_XimDecodeLocalIMAttr(res, top, value))
+ return False;
+
+ buf_s = (CARD16 *)buf;
+ if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
+ (size - min_len), value, &len, mode, (XPointer)NULL)))
+ return False;
+
+ if (len == 0) {
+ continue;
+ } else if (len < 0) {
+ *idx = i;
+ return True;
+ }
+
+ buf_s[0] = res->id; /* attribute ID */
+ buf_s[1] = len; /* value length */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += min_len;
+
+ buf += len;
+ *ret_len += len;
+ size -= len;
+ }
+ *idx = -1;
+ return True;
+}
+#endif /* XIM_CONNECTABLE */
+
+Private Bool
+_XimEncodeTopValue(
+ Xic ic,
+ XIMResourceList res,
+ XIMArg *p)
+{
+ if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
+ ic->core.client_window = (Window)p->value;
+ if (ic->core.focus_window == (Window)0)
+ ic->core.focus_window = ic->core.client_window;
+ _XimRegisterFilter(ic);
+
+ } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
+ if (ic->core.client_window) {
+ _XimUnregisterFilter(ic);
+ ic->core.focus_window = (Window)p->value;
+ _XimRegisterFilter(ic);
+ } else /* client_window not yet */
+ ic->core.focus_window = (Window)p->value;
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodePreeditValue(
+ Xic ic,
+ XIMResourceList res,
+ XIMArg *p)
+{
+ if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
+ XStandardColormap *colormap_ret;
+ int count;
+
+ if (!(XGetRGBColormaps(ic->core.im->core.display,
+ ic->core.focus_window, &colormap_ret,
+ &count, (Atom)p->value)))
+ return False;
+
+ XFree(colormap_ret);
+ } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
+ int list_ret;
+ XFontStruct **struct_list;
+ char **name_list;
+ char *tmp;
+ int len;
+ register int i;
+
+ if (!p->value)
+ return False;
+
+ if (ic->private.proto.preedit_font)
+ Xfree(ic->private.proto.preedit_font);
+
+ list_ret = XFontsOfFontSet((XFontSet)p->value,
+ &struct_list, &name_list);
+ for (i = 0, len = 0; i < list_ret; i++) {
+ len += (strlen(name_list[i]) + sizeof(char));
+ }
+ if (!(tmp = Xmalloc(len + 1))) {
+ ic->private.proto.preedit_font = NULL;
+ return False;
+ }
+
+ tmp[0] = '\0';
+ for (i = 0; i < list_ret; i++) {
+ strcat(tmp, name_list[i]);
+ strcat(tmp, ",");
+ }
+ tmp[len - 1] = 0;
+ ic->private.proto.preedit_font = tmp;
+ ic->private.proto.preedit_font_length = len - 1;
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodeStatusValue(
+ Xic ic,
+ XIMResourceList res,
+ XIMArg *p)
+{
+ if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
+ XStandardColormap *colormap_ret = NULL;
+ int count;
+
+ if (!(XGetRGBColormaps(ic->core.im->core.display,
+ ic->core.focus_window, &colormap_ret,
+ &count, (Atom)p->value)))
+ return False;
+
+ XFree(colormap_ret);
+ } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
+ int list_ret;
+ XFontStruct **struct_list;
+ char **name_list;
+ char *tmp;
+ int len;
+ register int i;
+
+ if (!p->value)
+ return False;
+
+ if (ic->private.proto.status_font)
+ Xfree(ic->private.proto.status_font);
+
+ list_ret = XFontsOfFontSet((XFontSet)p->value,
+ &struct_list, &name_list);
+ for (i = 0, len = 0; i < list_ret; i++) {
+ len += (strlen(name_list[i]) + sizeof(char));
+ }
+ if (!(tmp = Xmalloc(len+1))) {
+ ic->private.proto.status_font = NULL;
+ return False;
+ }
+
+ tmp[0] = '\0';
+ for(i = 0; i < list_ret; i++) {
+ strcat(tmp, name_list[i]);
+ strcat(tmp, ",");
+ }
+ tmp[len - 1] = 0;
+ ic->private.proto.status_font = tmp;
+ ic->private.proto.status_font_length = len - 1;
+ }
+ return True;
+}
+
+Private Bool
+_XimSetInnerICAttributes(
+ Xic ic,
+ XPointer top,
+ XIMArg *arg,
+ unsigned long mode)
+{
+ XIMResourceList res;
+ int check;
+
+ if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
+ ic->private.proto.ic_num_inner_resources, arg->name)))
+ return False;
+
+ check = _XimCheckICMode(res, mode);
+ if(check == XIM_CHECK_INVALID)
+ return True;
+ else if(check == XIM_CHECK_ERROR)
+ return False;
+
+ return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
+}
+
+Public char *
+_XimEncodeICATTRIBUTE(
+ Xic ic,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ XIMArg *arg,
+ XIMArg **arg_ret,
+ char *buf,
+ int size,
+ int *ret_len,
+ XPointer top,
+ BITMASK32 *flag,
+ unsigned long mode)
+{
+ register XIMArg *p;
+ XIMResourceList res;
+ int check;
+ CARD16 *buf_s;
+ int len;
+ int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(INT16); /* sizeof value length */
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+ char *name;
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+
+ *ret_len = 0;
+ for (p = arg; p && p->name; p++) {
+ buf_s = (CARD16 *)buf;
+ if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
+ if (_XimSetInnerICAttributes(ic, top, p, mode))
+ continue;
+ return p->name;
+ }
+
+ check = _XimCheckICMode(res, mode);
+ if (check == XIM_CHECK_INVALID)
+ continue;
+ else if (check == XIM_CHECK_ERROR)
+ return p->name;
+
+ if (mode & XIM_PREEDIT_ATTR) {
+ if (!(_XimEncodePreeditValue(ic, res, p)))
+ return p->name;
+ } else if (mode & XIM_STATUS_ATTR) {
+ if (!(_XimEncodeStatusValue(ic, res, p)))
+ return p->name;
+ } else {
+ if (!(_XimEncodeTopValue(ic, res, p)))
+ return p->name;
+ }
+
+ if (res->resource_size == XimType_NEST) {
+ XimDefICValues *ic_attr = (XimDefICValues *)top;
+
+ if (res->xrm_name == pre_quark) {
+ XIMArg *arg_rt;
+ if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
+ (XIMArg *)p->value, &arg_rt,
+ (char *)&buf_s[2], (size - min_len),
+ &len, (XPointer)&ic_attr->preedit_attr, flag,
+ (mode | XIM_PREEDIT_ATTR)))) {
+ return name;
+ }
+
+ } else if (res->xrm_name == sts_quark) {
+ XIMArg *arg_rt;
+ if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
+ (XIMArg *)p->value, &arg_rt,
+ (char *)&buf_s[2], (size - min_len),
+ &len, (XPointer)&ic_attr->status_attr, flag,
+ (mode | XIM_STATUS_ATTR)))) {
+ return name;
+ }
+ }
+ } else {
+#ifdef EXT_MOVE
+ if (flag)
+ *flag |= _XimExtenArgCheck(p);
+#endif
+ if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
+ return p->name;
+
+ if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
+ (size - min_len), p->value,
+ &len, mode, (XPointer)ic)))
+ return p->name;
+ }
+
+ if (len == 0) {
+ continue;
+ } else if (len < 0) {
+ *arg_ret = p;
+ return (char *)NULL;
+ }
+
+ buf_s[0] = res->id; /* attribute ID */
+ buf_s[1] = len; /* value length */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += min_len;
+
+ buf += len;
+ *ret_len += len;
+ size -= len;
+ }
+ *arg_ret = (XIMArg *)NULL;
+ return (char *)NULL;
+}
+
+#ifdef XIM_CONNECTABLE
+Private Bool
+_XimEncodeSavedPreeditValue(
+ Xic ic,
+ XIMResourceList res,
+ XPointer value)
+{
+ int list_ret;
+ XFontStruct **struct_list;
+ char **name_list;
+ char *tmp;
+ int len;
+ register int i;
+
+ if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
+ if (!value)
+ return False;
+
+ if (ic->private.proto.preedit_font)
+ Xfree(ic->private.proto.preedit_font);
+
+ list_ret = XFontsOfFontSet((XFontSet)value,
+ &struct_list, &name_list);
+ for(i = 0, len = 0; i < list_ret; i++) {
+ len += (strlen(name_list[i]) + sizeof(char));
+ }
+ if(!(tmp = Xmalloc(len + 1))) {
+ ic->private.proto.preedit_font = NULL;
+ return False;
+ }
+
+ tmp[0] = '\0';
+ for(i = 0; i < list_ret; i++) {
+ strcat(tmp, name_list[i]);
+ strcat(tmp, ",");
+ }
+ tmp[len - 1] = 0;
+ ic->private.proto.preedit_font = tmp;
+ ic->private.proto.preedit_font_length = len - 1;
+ }
+ return True;
+}
+
+Private Bool
+_XimEncodeSavedStatusValue(
+ Xic ic,
+ XIMResourceList res,
+ XPointer value)
+{
+ int list_ret;
+ XFontStruct **struct_list;
+ char **name_list;
+ char *tmp;
+ int len;
+ register int i;
+
+ if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
+ if (!value)
+ return False;
+
+ if (ic->private.proto.status_font)
+ Xfree(ic->private.proto.status_font);
+
+ list_ret = XFontsOfFontSet((XFontSet)value,
+ &struct_list, &name_list);
+ for(i = 0, len = 0; i < list_ret; i++) {
+ len += (strlen(name_list[i]) + sizeof(char));
+ }
+ if(!(tmp = Xmalloc(len + 1))) {
+ ic->private.proto.status_font = NULL;
+ return False;
+ }
+
+ tmp[0] = '\0';
+ for(i = 0; i < list_ret; i++) {
+ strcat(tmp, name_list[i]);
+ strcat(tmp, ",");
+ }
+ tmp[len - 1] = 0;
+ ic->private.proto.status_font = tmp;
+ ic->private.proto.status_font_length = len - 1;
+ }
+ return True;
+}
+
+Public Bool
+_XimEncodeSavedICATTRIBUTE(
+ Xic ic,
+ XIMResourceList res_list,
+ unsigned int res_num,
+ int *idx,
+ char *buf,
+ int size,
+ int *ret_len,
+ XPointer top,
+ unsigned long mode)
+{
+ int i;
+ int num = ic->private.proto.num_saved_icvalues;
+ XrmQuark *quark_list = ic->private.proto.saved_icvalues;
+ XIMResourceList res;
+ XPointer value;
+ CARD16 *buf_s;
+ int len;
+ int min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(INT16); /* sizeof value length */
+ XrmQuark pre_quark;
+ XrmQuark sts_quark;
+ XrmQuark separator;
+
+ if (!ic->private.proto.saved_icvalues) {
+ *idx = -1;
+ *ret_len = 0;
+ return True;
+ }
+
+ pre_quark = XrmStringToQuark(XNPreeditAttributes);
+ sts_quark = XrmStringToQuark(XNStatusAttributes);
+ separator = XrmStringToQuark(XNSeparatorofNestedList);
+
+ *ret_len = 0;
+ for (i = *idx; i < num; i++) {
+ if (quark_list[i] == separator) {
+ *idx = i;
+ return True;
+ }
+
+ if (!(res = _XimGetResourceListRecByQuark(res_list,
+ res_num, quark_list[i])))
+ continue;
+
+ if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
+ return False;
+
+ if (mode & XIM_PREEDIT_ATTR) {
+ if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
+ return False;
+ }
+ } else if (mode & XIM_STATUS_ATTR) {
+ if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
+ return False;
+ }
+ }
+
+ buf_s = (CARD16 *)buf;
+ if (res->resource_size == XimType_NEST) {
+ XimDefICValues *ic_attr = (XimDefICValues *)top;
+
+ i++;
+ if (res->xrm_name == pre_quark) {
+ if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
+ &i, (char *)&buf_s[2], (size - min_len),
+ &len, (XPointer)&ic_attr->preedit_attr,
+ (mode | XIM_PREEDIT_ATTR))) {
+ return False;
+ }
+
+ } else if (res->xrm_name == sts_quark) {
+ if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
+ &i, (char *)&buf_s[2], (size - min_len),
+ &len, (XPointer)&ic_attr->status_attr,
+ (mode | XIM_STATUS_ATTR))) {
+ return False;
+ }
+ }
+ } else {
+ if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
+ (size - min_len), value,
+ &len, mode, (XPointer)ic))) {
+ return False;
+ }
+ }
+
+ if (len == 0) {
+ continue;
+ } else if (len < 0) {
+ if (quark_list[i] == separator)
+ i++;
+ *idx = i;
+ return True;
+ }
+
+ buf_s[0] = res->id; /* attribute ID */
+ buf_s[1] = len; /* value length */
+ XIM_SET_PAD(&buf_s[2], len); /* pad */
+ len += min_len;
+
+ buf += len;
+ *ret_len += len;
+ size -= len;
+ }
+ *idx = -1;
+ return True;
+}
+#endif /* XIM_CONNECTABLE */
+
+Private unsigned int
+_XimCountNumberOfAttr(
+ INT16 total,
+ CARD16 *attr,
+ int *names_len)
+{
+ unsigned int n;
+ INT16 len;
+ INT16 min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(CARD16) /* sizeof type of value */
+ + sizeof(INT16); /* sizeof length of attribute */
+
+ n = 0;
+ *names_len = 0;
+ while (total > min_len) {
+ len = attr[2];
+ *names_len += (len + 1);
+ len += (min_len + XIM_PAD(len + 2));
+ total -= len;
+ attr = (CARD16 *)((char *)attr + len);
+ n++;
+ }
+ return n;
+}
+
+Public Bool
+_XimGetAttributeID(
+ Xim im,
+ CARD16 *buf)
+{
+ unsigned int n;
+ XIMResourceList res;
+ char *names;
+ int names_len;
+ XPointer tmp;
+ XIMValuesList *values_list;
+ char **values;
+ int values_len;
+ register int i;
+ INT16 len;
+ INT16 min_len = sizeof(CARD16) /* sizeof attribute ID */
+ + sizeof(CARD16) /* sizeof type of value */
+ + sizeof(INT16); /* sizeof length of attr */
+ /*
+ * IM attribute ID
+ */
+
+ if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
+ return False;
+
+ if (!(res = Xcalloc(n, sizeof(XIMResource))))
+ return False;
+
+ values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
+ if (!(tmp = Xcalloc(1, values_len))) {
+ Xfree(res);
+ return False;
+ }
+
+ values_list = (XIMValuesList *)tmp;
+ values = (char **)((char *)tmp + sizeof(XIMValuesList));
+ names = (char *)((char *)values + (sizeof(char **) * n));
+
+ values_list->count_values = n;
+ values_list->supported_values = values;
+
+ buf++;
+ for (i = 0; i < n; i++) {
+ len = buf[2];
+ (void)memcpy(names, (char *)&buf[3], len);
+ values[i] = names;
+ names[len] = '\0';
+ res[i].resource_name = names;
+ res[i].resource_size = buf[1];
+ res[i].id = buf[0];
+ names += (len + 1);
+ len += (min_len + XIM_PAD(len + 2));
+ buf = (CARD16 *)((char *)buf + len);
+ }
+ _XIMCompileResourceList(res, n);
+
+ if (im->core.im_resources)
+ Xfree(im->core.im_resources);
+ if (im->core.im_values_list)
+ Xfree(im->core.im_values_list);
+ im->core.im_resources = res;
+ im->core.im_num_resources = n;
+ im->core.im_values_list = values_list;
+
+ /*
+ * IC attribute ID
+ */
+
+ if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
+ return False;
+
+ if (!(res = Xcalloc(n, sizeof(XIMResource))))
+ return False;
+
+ values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
+ if (!(tmp = Xcalloc(1, values_len))) {
+ Xfree(res);
+ return False;
+ }
+
+ values_list = (XIMValuesList *)tmp;
+ values = (char **)((char *)tmp + sizeof(XIMValuesList));
+ names = (char *)((char *)values + (sizeof(char **) * n));
+
+ values_list->count_values = n;
+ values_list->supported_values = values;
+
+ buf += 2;
+ for (i = 0; i < n; i++) {
+ len = buf[2];
+ (void)memcpy(names, (char *)&buf[3], len);
+ values[i] = names;
+ names[len] = '\0';
+ res[i].resource_name = names;
+ res[i].resource_size = buf[1];
+ res[i].id = buf[0];
+ names += (len + 1);
+ len += (min_len + XIM_PAD(len + 2));
+ buf = (CARD16 *)((char *)buf + len);
+ }
+ _XIMCompileResourceList(res, n);
+
+ if (im->core.ic_resources)
+ Xfree(im->core.ic_resources);
+ if (im->core.ic_values_list)
+ Xfree(im->core.ic_values_list);
+ im->core.ic_resources = res;
+ im->core.ic_num_resources = n;
+ im->core.ic_values_list = values_list;
+
+ return True;
+}
diff --git a/libX11/modules/im/ximcp/imThaiIc.c b/libX11/modules/im/ximcp/imThaiIc.c index 95433f3d7..6b8784387 100644 --- a/libX11/modules/im/ximcp/imThaiIc.c +++ b/libX11/modules/im/ximcp/imThaiIc.c @@ -1,227 +1,227 @@ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - Copyright 1993 by Digital Equipment Corporation - -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 FUJITSU LIMITED and -Digital Equipment Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. FUJITSU LIMITED and Digital Equipment Corporation -makes no representations about the suitability of this software for -any purpose. It is provided "as is" without express or implied -warranty. - -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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. - - Author: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Modifier: Franky Ling Digital Equipment Corporation - frankyling@hgrd01.enet.dec.com - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xlib.h> -#include <X11/Xmd.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" - -Private void -_XimThaiUnSetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL; - - if (ic->core.focus_window) - _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window, - _XimThaiFilter, (XPointer)ic); - return; -} - -Private void -_XimThaiDestroyIC( - XIC xic) -{ - Xic ic = (Xic)xic; - DefTreeBase *b = &ic->private.local.base; - - if(((Xim)ic->core.im)->private.local.current_ic == (XIC)ic) { - _XimThaiUnSetFocus(xic); - } - if(ic->private.local.ic_resources) { - Xfree(ic->private.local.ic_resources); - ic->private.local.ic_resources = NULL; - } - - if (b->tree) Xfree (b->tree); - if (b->mb) Xfree (b->mb); - if (b->wc) Xfree (b->wc); - if (b->utf8) Xfree (b->utf8); - b->tree = NULL; - b->mb = NULL; - b->wc = NULL; - b->utf8 = NULL; - return; -} - -Private void -_XimThaiSetFocus( - XIC xic) -{ - Xic ic = (Xic)xic; - XIC current_ic = ((Xim)ic->core.im)->private.local.current_ic; - - if (current_ic == (XIC)ic) - return; - - if (current_ic != (XIC)NULL) { - _XimThaiUnSetFocus(current_ic); - } - ((Xim)ic->core.im)->private.local.current_ic = (XIC)ic; - - if (ic->core.focus_window) - _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window, - KeyPress, KeyPress, _XimThaiFilter, (XPointer)ic); - return; -} - -Private void -_XimThaiReset( - XIC xic) -{ - Xic ic = (Xic)xic; - DefTreeBase *b = &ic->private.local.base; - ic->private.local.thai.comp_state = 0; - ic->private.local.thai.keysym = 0; - b->mb[b->tree[ic->private.local.composed].mb] = '\0'; - b->wc[b->tree[ic->private.local.composed].wc] = '\0'; - b->utf8[b->tree[ic->private.local.composed].utf8] = '\0'; -} - -Private char * -_XimThaiMbReset( - XIC xic) -{ - _XimThaiReset(xic); - return (char *)NULL; -} - -Private wchar_t * -_XimThaiWcReset( - XIC xic) -{ - _XimThaiReset(xic); - return (wchar_t *)NULL; -} - -Private XICMethodsRec Thai_ic_methods = { - _XimThaiDestroyIC, /* destroy */ - _XimThaiSetFocus, /* set_focus */ - _XimThaiUnSetFocus, /* unset_focus */ - _XimLocalSetICValues, /* set_values */ - _XimLocalGetICValues, /* get_values */ - _XimThaiMbReset, /* mb_reset */ - _XimThaiWcReset, /* wc_reset */ - _XimThaiMbReset, /* utf8_reset */ - _XimLocalMbLookupString, /* mb_lookup_string */ - _XimLocalWcLookupString, /* wc_lookup_string */ - _XimLocalUtf8LookupString /* utf8_lookup_string */ -}; - -XIC -_XimThaiCreateIC( - XIM im, - XIMArg *values) -{ - Xic ic; - XimDefICValues ic_values; - XIMResourceList res; - unsigned int num; - int len; - DefTree *tree; - - if((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) { - return ((XIC)NULL); - } - - ic->methods = &Thai_ic_methods; - ic->core.im = im; - ic->core.filter_events = KeyPressMask; - - if (! (ic->private.local.base.tree = tree = (DefTree *)Xmalloc(sizeof(DefTree)*3)) ) - goto Set_Error; - if (! (ic->private.local.base.mb = (char *)Xmalloc(21)) ) - goto Set_Error; - if (! (ic->private.local.base.wc = (wchar_t*)Xmalloc(sizeof(wchar_t)*21)) ) - goto Set_Error; - if (! (ic->private.local.base.utf8 = (char *)Xmalloc(21)) ) - goto Set_Error; - ic->private.local.context = 1; - tree[1].mb = 1; - tree[1].wc = 1; - tree[1].utf8 = 1; - ic->private.local.composed = 2; - tree[2].mb = 11; - tree[2].wc = 11; - tree[2].utf8 = 11; - - ic->private.local.thai.comp_state = 0; - ic->private.local.thai.keysym = 0; - ic->private.local.thai.input_mode = 0; - - num = im->core.ic_num_resources; - len = sizeof(XIMResource) * num; - if((res = (XIMResourceList)Xmalloc(len)) == (XIMResourceList)NULL) { - goto Set_Error; - } - (void)memcpy((char *)res, (char *)im->core.ic_resources, len); - ic->private.local.ic_resources = res; - ic->private.local.ic_num_resources = num; - - bzero((char *)&ic_values, sizeof(XimDefICValues)); - if(_XimCheckLocalInputStyle(ic, (XPointer)&ic_values, values, - im->core.styles, res, num) == False) { - goto Set_Error; - } - - _XimSetICMode(res, num, ic_values.input_style); - - if(_XimSetICValueData(ic, (XPointer)&ic_values, - ic->private.local.ic_resources, - ic->private.local.ic_num_resources, - values, XIM_CREATEIC, True)) { - goto Set_Error; - } - if(_XimSetICDefaults(ic, (XPointer)&ic_values, - XIM_SETICDEFAULTS, res, num) == False) { - goto Set_Error; - } - ic_values.filter_events = KeyPressMask; - _XimSetCurrentICValues(ic, &ic_values); - - return ((XIC)ic); - -Set_Error : - if (ic->private.local.ic_resources) { - Xfree(ic->private.local.ic_resources); - } - Xfree(ic); - return((XIC)NULL); -} +/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+ Copyright 1993 by Digital Equipment Corporation
+
+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 FUJITSU LIMITED and
+Digital Equipment Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission. FUJITSU LIMITED and Digital Equipment Corporation
+makes no representations about the suitability of this software for
+any purpose. It is provided "as is" without express or implied
+warranty.
+
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION 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.
+
+ Author: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Modifier: Franky Ling Digital Equipment Corporation
+ frankyling@hgrd01.enet.dec.com
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+
+Private void
+_XimThaiUnSetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ ((Xim)ic->core.im)->private.local.current_ic = (XIC)NULL;
+
+ if (ic->core.focus_window)
+ _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
+ _XimThaiFilter, (XPointer)ic);
+ return;
+}
+
+Private void
+_XimThaiDestroyIC(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ DefTreeBase *b = &ic->private.local.base;
+
+ if(((Xim)ic->core.im)->private.local.current_ic == (XIC)ic) {
+ _XimThaiUnSetFocus(xic);
+ }
+ if(ic->private.local.ic_resources) {
+ Xfree(ic->private.local.ic_resources);
+ ic->private.local.ic_resources = NULL;
+ }
+
+ if (b->tree) Xfree (b->tree);
+ if (b->mb) Xfree (b->mb);
+ if (b->wc) Xfree (b->wc);
+ if (b->utf8) Xfree (b->utf8);
+ b->tree = NULL;
+ b->mb = NULL;
+ b->wc = NULL;
+ b->utf8 = NULL;
+ return;
+}
+
+Private void
+_XimThaiSetFocus(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ XIC current_ic = ((Xim)ic->core.im)->private.local.current_ic;
+
+ if (current_ic == (XIC)ic)
+ return;
+
+ if (current_ic != (XIC)NULL) {
+ _XimThaiUnSetFocus(current_ic);
+ }
+ ((Xim)ic->core.im)->private.local.current_ic = (XIC)ic;
+
+ if (ic->core.focus_window)
+ _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
+ KeyPress, KeyPress, _XimThaiFilter, (XPointer)ic);
+ return;
+}
+
+Private void
+_XimThaiReset(
+ XIC xic)
+{
+ Xic ic = (Xic)xic;
+ DefTreeBase *b = &ic->private.local.base;
+ ic->private.local.thai.comp_state = 0;
+ ic->private.local.thai.keysym = 0;
+ b->mb[b->tree[ic->private.local.composed].mb] = '\0';
+ b->wc[b->tree[ic->private.local.composed].wc] = '\0';
+ b->utf8[b->tree[ic->private.local.composed].utf8] = '\0';
+}
+
+Private char *
+_XimThaiMbReset(
+ XIC xic)
+{
+ _XimThaiReset(xic);
+ return (char *)NULL;
+}
+
+Private wchar_t *
+_XimThaiWcReset(
+ XIC xic)
+{
+ _XimThaiReset(xic);
+ return (wchar_t *)NULL;
+}
+
+Private XICMethodsRec Thai_ic_methods = {
+ _XimThaiDestroyIC, /* destroy */
+ _XimThaiSetFocus, /* set_focus */
+ _XimThaiUnSetFocus, /* unset_focus */
+ _XimLocalSetICValues, /* set_values */
+ _XimLocalGetICValues, /* get_values */
+ _XimThaiMbReset, /* mb_reset */
+ _XimThaiWcReset, /* wc_reset */
+ _XimThaiMbReset, /* utf8_reset */
+ _XimLocalMbLookupString, /* mb_lookup_string */
+ _XimLocalWcLookupString, /* wc_lookup_string */
+ _XimLocalUtf8LookupString /* utf8_lookup_string */
+};
+
+XIC
+_XimThaiCreateIC(
+ XIM im,
+ XIMArg *values)
+{
+ Xic ic;
+ XimDefICValues ic_values;
+ XIMResourceList res;
+ unsigned int num;
+ int len;
+ DefTree *tree;
+
+ if((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL) {
+ return ((XIC)NULL);
+ }
+
+ ic->methods = &Thai_ic_methods;
+ ic->core.im = im;
+ ic->core.filter_events = KeyPressMask;
+
+ if (! (ic->private.local.base.tree = tree = (DefTree *)Xmalloc(sizeof(DefTree)*3)) )
+ goto Set_Error;
+ if (! (ic->private.local.base.mb = (char *)Xmalloc(21)) )
+ goto Set_Error;
+ if (! (ic->private.local.base.wc = (wchar_t*)Xmalloc(sizeof(wchar_t)*21)) )
+ goto Set_Error;
+ if (! (ic->private.local.base.utf8 = (char *)Xmalloc(21)) )
+ goto Set_Error;
+ ic->private.local.context = 1;
+ tree[1].mb = 1;
+ tree[1].wc = 1;
+ tree[1].utf8 = 1;
+ ic->private.local.composed = 2;
+ tree[2].mb = 11;
+ tree[2].wc = 11;
+ tree[2].utf8 = 11;
+
+ ic->private.local.thai.comp_state = 0;
+ ic->private.local.thai.keysym = 0;
+ ic->private.local.thai.input_mode = 0;
+
+ num = im->core.ic_num_resources;
+ len = sizeof(XIMResource) * num;
+ if((res = (XIMResourceList)Xmalloc(len)) == (XIMResourceList)NULL) {
+ goto Set_Error;
+ }
+ (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
+ ic->private.local.ic_resources = res;
+ ic->private.local.ic_num_resources = num;
+
+ bzero((char *)&ic_values, sizeof(XimDefICValues));
+ if(_XimCheckLocalInputStyle(ic, (XPointer)&ic_values, values,
+ im->core.styles, res, num) == False) {
+ goto Set_Error;
+ }
+
+ _XimSetICMode(res, num, ic_values.input_style);
+
+ if(_XimSetICValueData(ic, (XPointer)&ic_values,
+ ic->private.local.ic_resources,
+ ic->private.local.ic_num_resources,
+ values, XIM_CREATEIC, True)) {
+ goto Set_Error;
+ }
+ if(_XimSetICDefaults(ic, (XPointer)&ic_values,
+ XIM_SETICDEFAULTS, res, num) == False) {
+ goto Set_Error;
+ }
+ ic_values.filter_events = KeyPressMask;
+ _XimSetCurrentICValues(ic, &ic_values);
+
+ return ((XIC)ic);
+
+Set_Error :
+ if (ic->private.local.ic_resources) {
+ Xfree(ic->private.local.ic_resources);
+ }
+ Xfree(ic);
+ return((XIC)NULL);
+}
diff --git a/libX11/modules/im/ximcp/imTrX.c b/libX11/modules/im/ximcp/imTrX.c index d85d1d114..27ef03e21 100644 --- a/libX11/modules/im/ximcp/imTrX.c +++ b/libX11/modules/im/ximcp/imTrX.c @@ -1,518 +1,518 @@ -/* - * Copyright 1992 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. - Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" -#include "XimTrInt.h" -#include "XimTrX.h" - -Private Bool -_XimXRegisterDispatcher( - Xim im, - Bool (*callback)( - Xim, INT16, XPointer, XPointer - ), - XPointer call_data) -{ - XIntrCallbackPtr rec; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - - if (!(rec = (XIntrCallbackPtr)Xmalloc(sizeof(XIntrCallbackRec)))) - return False; - - rec->func = callback; - rec->call_data = call_data; - rec->next = spec->intr_cb; - spec->intr_cb = rec; - return True; -} - -Private void -_XimXFreeIntrCallback( - Xim im) -{ - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - register XIntrCallbackPtr rec, next; - - for (rec = spec->intr_cb; rec;) { - next = rec->next; - Xfree(rec); - rec = next; - } - return; -} - -Private Bool -_XimXCallDispatcher(Xim im, INT16 len, XPointer data) -{ - register XIntrCallbackRec *rec; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - - for (rec = spec->intr_cb; rec; rec = rec->next) { - if ((*rec->func)(im, len, data, rec->call_data)) - return True; - } - return False; -} - -Private Bool -_XimXFilterWaitEvent( - Display *d, - Window w, - XEvent *ev, - XPointer arg) -{ - Xim im = (Xim)arg; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - Bool ret; - - spec->ev = (XPointer)ev; - ret = _XimFilterWaitEvent(im); - - /* - * If ev is a pointer to a stack variable, there could be - * a coredump later on if the pointer is dereferenced. - * Therefore, reset to NULL to force reinitialization in - * _XimXRead(). - * - * Keep in mind _XimXRead may be called again when the stack - * is very different. - */ - spec->ev = (XPointer)NULL; - - return ret; -} - -Private Bool -_CheckConnect( - Display *display, - XEvent *event, - XPointer xim) -{ - Xim im = (Xim)xim; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - - if ((event->type == ClientMessage) - && (event->xclient.message_type == spec->imconnectid)) { - return True; - } - return False; -} - -Private Bool -_XimXConnect(Xim im) -{ - XEvent event; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - CARD32 major_code; - CARD32 minor_code; - - if (!(spec->lib_connect_wid = XCreateSimpleWindow(im->core.display, - DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) { - return False; - } - - event.xclient.type = ClientMessage; - event.xclient.display = im->core.display; - event.xclient.window = im->private.proto.im_window; - event.xclient.message_type = spec->imconnectid; - event.xclient.format = 32; - event.xclient.data.l[0] = (CARD32)spec->lib_connect_wid; - event.xclient.data.l[1] = spec->major_code; - event.xclient.data.l[2] = spec->minor_code; - event.xclient.data.l[3] = 0; - event.xclient.data.l[4] = 0; - - if(event.xclient.data.l[1] == 1 || event.xclient.data.l[1] == 2) { - XWindowAttributes atr; - long event_mask; - - XGetWindowAttributes(im->core.display, spec->lib_connect_wid, &atr); - event_mask = atr.your_event_mask | PropertyChangeMask; - XSelectInput(im->core.display, spec->lib_connect_wid, event_mask); - _XRegisterFilterByType(im->core.display, spec->lib_connect_wid, - PropertyNotify, PropertyNotify, - _XimXFilterWaitEvent, (XPointer)im); - } - - XSendEvent(im->core.display, im->private.proto.im_window, - False, NoEventMask, &event); - XFlush(im->core.display); - - for (;;) { - XIfEvent(im->core.display, &event, _CheckConnect, (XPointer)im); - if (event.xclient.type != ClientMessage) { - return False; - } - if (event.xclient.message_type == spec->imconnectid) - break; - } - - spec->ims_connect_wid = (Window)event.xclient.data.l[0]; - major_code = (CARD32)event.xclient.data.l[1]; - minor_code = (CARD32)event.xclient.data.l[2]; - - if (((major_code == 0) && (minor_code <= 2)) || - ((major_code == 1) && (minor_code == 0)) || - ((major_code == 2) && (minor_code <= 1))) { - spec->major_code = major_code; - spec->minor_code = minor_code; - } - if (((major_code == 0) && (minor_code == 2)) || - ((major_code == 2) && (minor_code == 1))) { - spec->BoundarySize = (CARD32)event.xclient.data.l[3]; - } - - /* ClientMessage Event Filter */ - _XRegisterFilterByType(im->core.display, spec->lib_connect_wid, - ClientMessage, ClientMessage, - _XimXFilterWaitEvent, (XPointer)im); - return True; -} - -Private Bool -_XimXShutdown(Xim im) -{ - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - - if (!spec) - return True; - - /* ClientMessage Event Filter */ - _XUnregisterFilter(im->core.display, - ((XSpecRec *)im->private.proto.spec)->lib_connect_wid, - _XimXFilterWaitEvent, (XPointer)im); - XDestroyWindow(im->core.display, - ((XSpecRec *)im->private.proto.spec)->lib_connect_wid); - _XimXFreeIntrCallback(im); - Xfree(spec); - im->private.proto.spec = 0; - return True; -} - -Private char * -_NewAtom( - char *atomName) -{ - static int sequence = 0; - - (void)sprintf(atomName, "_client%d", sequence); - sequence = ((sequence < 20) ? sequence + 1 : 0); - return atomName; -} - -Private Bool -_XimXWrite(Xim im, INT16 len, XPointer data) -{ - Atom atom; - char atomName[16]; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - XEvent event; - CARD8 *p; - CARD32 major_code = spec->major_code; - CARD32 minor_code = spec->minor_code; - int BoundSize; - - bzero(&event,sizeof(XEvent)); - event.xclient.type = ClientMessage; - event.xclient.display = im->core.display; - event.xclient.window = spec->ims_connect_wid; - if(major_code == 1 && minor_code == 0) { - BoundSize = 0; - } else if((major_code == 0 && minor_code == 2) || - (major_code == 2 && minor_code == 1)) { - BoundSize = spec->BoundarySize; - } else if(major_code == 0 && minor_code == 1) { - BoundSize = len; - } else { - BoundSize = XIM_CM_DATA_SIZE; - } - if (len > BoundSize) { - event.xclient.message_type = spec->improtocolid; - atom = XInternAtom(im->core.display, _NewAtom(atomName), False); - XChangeProperty(im->core.display, spec->ims_connect_wid, - atom, XA_STRING, 8, PropModeAppend, - (unsigned char *)data, len); - if(major_code == 0) { - event.xclient.format = 32; - event.xclient.data.l[0] = (long)len; - event.xclient.data.l[1] = (long)atom; - XSendEvent(im->core.display, spec->ims_connect_wid, - False, NoEventMask, &event); - } - } else { - int length; - - event.xclient.format = 8; - for(length = 0 ; length < len ; length += XIM_CM_DATA_SIZE) { - p = (CARD8 *)&event.xclient.data.b[0]; - if((length + XIM_CM_DATA_SIZE) >= len) { - event.xclient.message_type = spec->improtocolid; - bzero(p, XIM_CM_DATA_SIZE); - memcpy((char *)p, (data + length), (len - length)); - } else { - event.xclient.message_type = spec->immoredataid; - memcpy((char *)p, (data + length), XIM_CM_DATA_SIZE); - } - XSendEvent(im->core.display, spec->ims_connect_wid, - False, NoEventMask, &event); - } - } - - return True; -} - -Private Bool -_XimXGetReadData( - Xim im, - char *buf, - int buf_len, - int *ret_len, - XEvent *event) -{ - char *data; - int len; - - char tmp_buf[XIM_CM_DATA_SIZE]; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - unsigned long length; - Atom prop; - int return_code; - Atom type_ret; - int format_ret; - unsigned long nitems; - unsigned long bytes_after_ret; - unsigned char *prop_ret; - - if ((event->type == ClientMessage) && - !((event->xclient.message_type == spec->improtocolid) || - (event->xclient.message_type == spec->immoredataid))) { - /* This event has nothing to do with us, - * FIXME should not have gotten here then... - */ - return False; - } else if ((event->type == ClientMessage) && (event->xclient.format == 8)) { - data = event->xclient.data.b; - if (buf_len >= XIM_CM_DATA_SIZE) { - (void)memcpy(buf, data, XIM_CM_DATA_SIZE); - *ret_len = XIM_CM_DATA_SIZE; - } else { - (void)memcpy(buf, data, buf_len); - len = XIM_CM_DATA_SIZE - buf_len; - (void)memcpy(tmp_buf, &data[buf_len], len); - bzero(data, XIM_CM_DATA_SIZE); - (void)memcpy(data, tmp_buf, len); - XPutBackEvent(im->core.display, event); - *ret_len = buf_len; - } - } else if ((event->type == ClientMessage) - && (event->xclient.format == 32)) { - length = (unsigned long)event->xclient.data.l[0]; - prop = (Atom)event->xclient.data.l[1]; - return_code = XGetWindowProperty(im->core.display, - spec->lib_connect_wid, prop, 0L, - (long)((length + 3)/ 4), True, AnyPropertyType, - &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); - if (return_code != Success || format_ret == 0 || nitems == 0) { - if (return_code == Success) - XFree(prop_ret); - return False; - } - if (buf_len >= length) { - (void)memcpy(buf, prop_ret, (int)nitems); - *ret_len = (int)nitems; - if (bytes_after_ret > 0) { - XFree(prop_ret); - if (XGetWindowProperty(im->core.display, - spec->lib_connect_wid, prop, 0L, - ((length + bytes_after_ret + 3)/ 4), - True, AnyPropertyType, - &type_ret, &format_ret, &nitems, - &bytes_after_ret, - &prop_ret) == Success) { - XChangeProperty(im->core.display, spec->lib_connect_wid, prop, - XA_STRING, 8, PropModePrepend, &prop_ret[length], - (nitems - length)); - } else { - return False; - } - } - } else { - (void)memcpy(buf, prop_ret, buf_len); - *ret_len = buf_len; - len = nitems - buf_len; - - if (bytes_after_ret > 0) { - XFree(prop_ret); - if (XGetWindowProperty(im->core.display, - spec->lib_connect_wid, prop, 0L, - ((length + bytes_after_ret + 3)/ 4), - True, AnyPropertyType, - &type_ret, &format_ret, &nitems, - &bytes_after_ret, &prop_ret) != Success) { - return False; - } - } - XChangeProperty(im->core.display, spec->lib_connect_wid, prop, - XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len); - event->xclient.data.l[0] = (long)len; - event->xclient.data.l[1] = (long)prop; - XPutBackEvent(im->core.display, event); - } - XFree(prop_ret); - } else if (event->type == PropertyNotify) { - prop = event->xproperty.atom; - return_code = XGetWindowProperty(im->core.display, - spec->lib_connect_wid, prop, 0L, - 1000000L, True, AnyPropertyType, - &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); - if (return_code != Success || format_ret == 0 || nitems == 0) { - if (return_code == Success) - XFree(prop_ret); - return False; - } - if (buf_len >= nitems) { - (void)memcpy(buf, prop_ret, (int)nitems); - *ret_len = (int)nitems; - } else { - (void)memcpy(buf, prop_ret, buf_len); - *ret_len = buf_len; - len = nitems - buf_len; - XChangeProperty(im->core.display, spec->lib_connect_wid, prop, - XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len); - } - XFree(prop_ret); - } - return True; -} - -Private Bool -_CheckCMEvent( - Display *display, - XEvent *event, - XPointer xim) -{ - Xim im = (Xim)xim; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - CARD32 major_code = spec->major_code; - - if ((event->type == ClientMessage) - &&((event->xclient.message_type == spec->improtocolid) || - (event->xclient.message_type == spec->immoredataid))) - return True; - if((major_code == 1 || major_code == 2) && - (event->type == PropertyNotify) && - (event->xproperty.state == PropertyNewValue)) - return True; - return False; -} - -Private Bool -_XimXRead(Xim im, XPointer recv_buf, int buf_len, int *ret_len) -{ - XEvent *ev; - XEvent event; - int len = 0; - XSpecRec *spec = (XSpecRec *)im->private.proto.spec; - XPointer arg = spec->ev; - - if (!arg) { - bzero(&event, sizeof(XEvent)); - ev = &event; - XIfEvent(im->core.display, ev, _CheckCMEvent, (XPointer)im); - } else { - ev = (XEvent *)arg; - spec->ev = (XPointer)NULL; - } - if (!(_XimXGetReadData(im, recv_buf, buf_len, &len, ev))) - return False; - *ret_len = len; - return True; -} - -Private void -_XimXFlush(Xim im) -{ - XFlush(im->core.display); - return; -} - -Public Bool -_XimXConf(Xim im, char *address) -{ - XSpecRec *spec; - - if (!(spec = Xcalloc(1, sizeof(XSpecRec)))) - return False; - - spec->improtocolid = XInternAtom(im->core.display, _XIM_PROTOCOL, False); - spec->imconnectid = XInternAtom(im->core.display, _XIM_XCONNECT, False); - spec->immoredataid = XInternAtom(im->core.display, _XIM_MOREDATA, False); - spec->major_code = MAJOR_TRANSPORT_VERSION; - spec->minor_code = MINOR_TRANSPORT_VERSION; - - im->private.proto.spec = (XPointer)spec; - im->private.proto.connect = _XimXConnect; - im->private.proto.shutdown = _XimXShutdown; - im->private.proto.write = _XimXWrite; - im->private.proto.read = _XimXRead; - im->private.proto.flush = _XimXFlush; - im->private.proto.register_dispatcher = _XimXRegisterDispatcher; - im->private.proto.call_dispatcher = _XimXCallDispatcher; - - return True; -} +/*
+ * Copyright 1992 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
+ Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XimTrInt.h"
+#include "XimTrX.h"
+
+Private Bool
+_XimXRegisterDispatcher(
+ Xim im,
+ Bool (*callback)(
+ Xim, INT16, XPointer, XPointer
+ ),
+ XPointer call_data)
+{
+ XIntrCallbackPtr rec;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+
+ if (!(rec = (XIntrCallbackPtr)Xmalloc(sizeof(XIntrCallbackRec))))
+ return False;
+
+ rec->func = callback;
+ rec->call_data = call_data;
+ rec->next = spec->intr_cb;
+ spec->intr_cb = rec;
+ return True;
+}
+
+Private void
+_XimXFreeIntrCallback(
+ Xim im)
+{
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ register XIntrCallbackPtr rec, next;
+
+ for (rec = spec->intr_cb; rec;) {
+ next = rec->next;
+ Xfree(rec);
+ rec = next;
+ }
+ return;
+}
+
+Private Bool
+_XimXCallDispatcher(Xim im, INT16 len, XPointer data)
+{
+ register XIntrCallbackRec *rec;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+
+ for (rec = spec->intr_cb; rec; rec = rec->next) {
+ if ((*rec->func)(im, len, data, rec->call_data))
+ return True;
+ }
+ return False;
+}
+
+Private Bool
+_XimXFilterWaitEvent(
+ Display *d,
+ Window w,
+ XEvent *ev,
+ XPointer arg)
+{
+ Xim im = (Xim)arg;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ Bool ret;
+
+ spec->ev = (XPointer)ev;
+ ret = _XimFilterWaitEvent(im);
+
+ /*
+ * If ev is a pointer to a stack variable, there could be
+ * a coredump later on if the pointer is dereferenced.
+ * Therefore, reset to NULL to force reinitialization in
+ * _XimXRead().
+ *
+ * Keep in mind _XimXRead may be called again when the stack
+ * is very different.
+ */
+ spec->ev = (XPointer)NULL;
+
+ return ret;
+}
+
+Private Bool
+_CheckConnect(
+ Display *display,
+ XEvent *event,
+ XPointer xim)
+{
+ Xim im = (Xim)xim;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+
+ if ((event->type == ClientMessage)
+ && (event->xclient.message_type == spec->imconnectid)) {
+ return True;
+ }
+ return False;
+}
+
+Private Bool
+_XimXConnect(Xim im)
+{
+ XEvent event;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ CARD32 major_code;
+ CARD32 minor_code;
+
+ if (!(spec->lib_connect_wid = XCreateSimpleWindow(im->core.display,
+ DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) {
+ return False;
+ }
+
+ event.xclient.type = ClientMessage;
+ event.xclient.display = im->core.display;
+ event.xclient.window = im->private.proto.im_window;
+ event.xclient.message_type = spec->imconnectid;
+ event.xclient.format = 32;
+ event.xclient.data.l[0] = (CARD32)spec->lib_connect_wid;
+ event.xclient.data.l[1] = spec->major_code;
+ event.xclient.data.l[2] = spec->minor_code;
+ event.xclient.data.l[3] = 0;
+ event.xclient.data.l[4] = 0;
+
+ if(event.xclient.data.l[1] == 1 || event.xclient.data.l[1] == 2) {
+ XWindowAttributes atr;
+ long event_mask;
+
+ XGetWindowAttributes(im->core.display, spec->lib_connect_wid, &atr);
+ event_mask = atr.your_event_mask | PropertyChangeMask;
+ XSelectInput(im->core.display, spec->lib_connect_wid, event_mask);
+ _XRegisterFilterByType(im->core.display, spec->lib_connect_wid,
+ PropertyNotify, PropertyNotify,
+ _XimXFilterWaitEvent, (XPointer)im);
+ }
+
+ XSendEvent(im->core.display, im->private.proto.im_window,
+ False, NoEventMask, &event);
+ XFlush(im->core.display);
+
+ for (;;) {
+ XIfEvent(im->core.display, &event, _CheckConnect, (XPointer)im);
+ if (event.xclient.type != ClientMessage) {
+ return False;
+ }
+ if (event.xclient.message_type == spec->imconnectid)
+ break;
+ }
+
+ spec->ims_connect_wid = (Window)event.xclient.data.l[0];
+ major_code = (CARD32)event.xclient.data.l[1];
+ minor_code = (CARD32)event.xclient.data.l[2];
+
+ if (((major_code == 0) && (minor_code <= 2)) ||
+ ((major_code == 1) && (minor_code == 0)) ||
+ ((major_code == 2) && (minor_code <= 1))) {
+ spec->major_code = major_code;
+ spec->minor_code = minor_code;
+ }
+ if (((major_code == 0) && (minor_code == 2)) ||
+ ((major_code == 2) && (minor_code == 1))) {
+ spec->BoundarySize = (CARD32)event.xclient.data.l[3];
+ }
+
+ /* ClientMessage Event Filter */
+ _XRegisterFilterByType(im->core.display, spec->lib_connect_wid,
+ ClientMessage, ClientMessage,
+ _XimXFilterWaitEvent, (XPointer)im);
+ return True;
+}
+
+Private Bool
+_XimXShutdown(Xim im)
+{
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+
+ if (!spec)
+ return True;
+
+ /* ClientMessage Event Filter */
+ _XUnregisterFilter(im->core.display,
+ ((XSpecRec *)im->private.proto.spec)->lib_connect_wid,
+ _XimXFilterWaitEvent, (XPointer)im);
+ XDestroyWindow(im->core.display,
+ ((XSpecRec *)im->private.proto.spec)->lib_connect_wid);
+ _XimXFreeIntrCallback(im);
+ Xfree(spec);
+ im->private.proto.spec = 0;
+ return True;
+}
+
+Private char *
+_NewAtom(
+ char *atomName)
+{
+ static int sequence = 0;
+
+ (void)sprintf(atomName, "_client%d", sequence);
+ sequence = ((sequence < 20) ? sequence + 1 : 0);
+ return atomName;
+}
+
+Private Bool
+_XimXWrite(Xim im, INT16 len, XPointer data)
+{
+ Atom atom;
+ char atomName[16];
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ XEvent event;
+ CARD8 *p;
+ CARD32 major_code = spec->major_code;
+ CARD32 minor_code = spec->minor_code;
+ int BoundSize;
+
+ bzero(&event,sizeof(XEvent));
+ event.xclient.type = ClientMessage;
+ event.xclient.display = im->core.display;
+ event.xclient.window = spec->ims_connect_wid;
+ if(major_code == 1 && minor_code == 0) {
+ BoundSize = 0;
+ } else if((major_code == 0 && minor_code == 2) ||
+ (major_code == 2 && minor_code == 1)) {
+ BoundSize = spec->BoundarySize;
+ } else if(major_code == 0 && minor_code == 1) {
+ BoundSize = len;
+ } else {
+ BoundSize = XIM_CM_DATA_SIZE;
+ }
+ if (len > BoundSize) {
+ event.xclient.message_type = spec->improtocolid;
+ atom = XInternAtom(im->core.display, _NewAtom(atomName), False);
+ XChangeProperty(im->core.display, spec->ims_connect_wid,
+ atom, XA_STRING, 8, PropModeAppend,
+ (unsigned char *)data, len);
+ if(major_code == 0) {
+ event.xclient.format = 32;
+ event.xclient.data.l[0] = (long)len;
+ event.xclient.data.l[1] = (long)atom;
+ XSendEvent(im->core.display, spec->ims_connect_wid,
+ False, NoEventMask, &event);
+ }
+ } else {
+ int length;
+
+ event.xclient.format = 8;
+ for(length = 0 ; length < len ; length += XIM_CM_DATA_SIZE) {
+ p = (CARD8 *)&event.xclient.data.b[0];
+ if((length + XIM_CM_DATA_SIZE) >= len) {
+ event.xclient.message_type = spec->improtocolid;
+ bzero(p, XIM_CM_DATA_SIZE);
+ memcpy((char *)p, (data + length), (len - length));
+ } else {
+ event.xclient.message_type = spec->immoredataid;
+ memcpy((char *)p, (data + length), XIM_CM_DATA_SIZE);
+ }
+ XSendEvent(im->core.display, spec->ims_connect_wid,
+ False, NoEventMask, &event);
+ }
+ }
+
+ return True;
+}
+
+Private Bool
+_XimXGetReadData(
+ Xim im,
+ char *buf,
+ int buf_len,
+ int *ret_len,
+ XEvent *event)
+{
+ char *data;
+ int len;
+
+ char tmp_buf[XIM_CM_DATA_SIZE];
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ unsigned long length;
+ Atom prop;
+ int return_code;
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems;
+ unsigned long bytes_after_ret;
+ unsigned char *prop_ret;
+
+ if ((event->type == ClientMessage) &&
+ !((event->xclient.message_type == spec->improtocolid) ||
+ (event->xclient.message_type == spec->immoredataid))) {
+ /* This event has nothing to do with us,
+ * FIXME should not have gotten here then...
+ */
+ return False;
+ } else if ((event->type == ClientMessage) && (event->xclient.format == 8)) {
+ data = event->xclient.data.b;
+ if (buf_len >= XIM_CM_DATA_SIZE) {
+ (void)memcpy(buf, data, XIM_CM_DATA_SIZE);
+ *ret_len = XIM_CM_DATA_SIZE;
+ } else {
+ (void)memcpy(buf, data, buf_len);
+ len = XIM_CM_DATA_SIZE - buf_len;
+ (void)memcpy(tmp_buf, &data[buf_len], len);
+ bzero(data, XIM_CM_DATA_SIZE);
+ (void)memcpy(data, tmp_buf, len);
+ XPutBackEvent(im->core.display, event);
+ *ret_len = buf_len;
+ }
+ } else if ((event->type == ClientMessage)
+ && (event->xclient.format == 32)) {
+ length = (unsigned long)event->xclient.data.l[0];
+ prop = (Atom)event->xclient.data.l[1];
+ return_code = XGetWindowProperty(im->core.display,
+ spec->lib_connect_wid, prop, 0L,
+ (long)((length + 3)/ 4), True, AnyPropertyType,
+ &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret);
+ if (return_code != Success || format_ret == 0 || nitems == 0) {
+ if (return_code == Success)
+ XFree(prop_ret);
+ return False;
+ }
+ if (buf_len >= length) {
+ (void)memcpy(buf, prop_ret, (int)nitems);
+ *ret_len = (int)nitems;
+ if (bytes_after_ret > 0) {
+ XFree(prop_ret);
+ if (XGetWindowProperty(im->core.display,
+ spec->lib_connect_wid, prop, 0L,
+ ((length + bytes_after_ret + 3)/ 4),
+ True, AnyPropertyType,
+ &type_ret, &format_ret, &nitems,
+ &bytes_after_ret,
+ &prop_ret) == Success) {
+ XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
+ XA_STRING, 8, PropModePrepend, &prop_ret[length],
+ (nitems - length));
+ } else {
+ return False;
+ }
+ }
+ } else {
+ (void)memcpy(buf, prop_ret, buf_len);
+ *ret_len = buf_len;
+ len = nitems - buf_len;
+
+ if (bytes_after_ret > 0) {
+ XFree(prop_ret);
+ if (XGetWindowProperty(im->core.display,
+ spec->lib_connect_wid, prop, 0L,
+ ((length + bytes_after_ret + 3)/ 4),
+ True, AnyPropertyType,
+ &type_ret, &format_ret, &nitems,
+ &bytes_after_ret, &prop_ret) != Success) {
+ return False;
+ }
+ }
+ XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
+ XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len);
+ event->xclient.data.l[0] = (long)len;
+ event->xclient.data.l[1] = (long)prop;
+ XPutBackEvent(im->core.display, event);
+ }
+ XFree(prop_ret);
+ } else if (event->type == PropertyNotify) {
+ prop = event->xproperty.atom;
+ return_code = XGetWindowProperty(im->core.display,
+ spec->lib_connect_wid, prop, 0L,
+ 1000000L, True, AnyPropertyType,
+ &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret);
+ if (return_code != Success || format_ret == 0 || nitems == 0) {
+ if (return_code == Success)
+ XFree(prop_ret);
+ return False;
+ }
+ if (buf_len >= nitems) {
+ (void)memcpy(buf, prop_ret, (int)nitems);
+ *ret_len = (int)nitems;
+ } else {
+ (void)memcpy(buf, prop_ret, buf_len);
+ *ret_len = buf_len;
+ len = nitems - buf_len;
+ XChangeProperty(im->core.display, spec->lib_connect_wid, prop,
+ XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len);
+ }
+ XFree(prop_ret);
+ }
+ return True;
+}
+
+Private Bool
+_CheckCMEvent(
+ Display *display,
+ XEvent *event,
+ XPointer xim)
+{
+ Xim im = (Xim)xim;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ CARD32 major_code = spec->major_code;
+
+ if ((event->type == ClientMessage)
+ &&((event->xclient.message_type == spec->improtocolid) ||
+ (event->xclient.message_type == spec->immoredataid)))
+ return True;
+ if((major_code == 1 || major_code == 2) &&
+ (event->type == PropertyNotify) &&
+ (event->xproperty.state == PropertyNewValue))
+ return True;
+ return False;
+}
+
+Private Bool
+_XimXRead(Xim im, XPointer recv_buf, int buf_len, int *ret_len)
+{
+ XEvent *ev;
+ XEvent event;
+ int len = 0;
+ XSpecRec *spec = (XSpecRec *)im->private.proto.spec;
+ XPointer arg = spec->ev;
+
+ if (!arg) {
+ bzero(&event, sizeof(XEvent));
+ ev = &event;
+ XIfEvent(im->core.display, ev, _CheckCMEvent, (XPointer)im);
+ } else {
+ ev = (XEvent *)arg;
+ spec->ev = (XPointer)NULL;
+ }
+ if (!(_XimXGetReadData(im, recv_buf, buf_len, &len, ev)))
+ return False;
+ *ret_len = len;
+ return True;
+}
+
+Private void
+_XimXFlush(Xim im)
+{
+ XFlush(im->core.display);
+ return;
+}
+
+Public Bool
+_XimXConf(Xim im, char *address)
+{
+ XSpecRec *spec;
+
+ if (!(spec = Xcalloc(1, sizeof(XSpecRec))))
+ return False;
+
+ spec->improtocolid = XInternAtom(im->core.display, _XIM_PROTOCOL, False);
+ spec->imconnectid = XInternAtom(im->core.display, _XIM_XCONNECT, False);
+ spec->immoredataid = XInternAtom(im->core.display, _XIM_MOREDATA, False);
+ spec->major_code = MAJOR_TRANSPORT_VERSION;
+ spec->minor_code = MINOR_TRANSPORT_VERSION;
+
+ im->private.proto.spec = (XPointer)spec;
+ im->private.proto.connect = _XimXConnect;
+ im->private.proto.shutdown = _XimXShutdown;
+ im->private.proto.write = _XimXWrite;
+ im->private.proto.read = _XimXRead;
+ im->private.proto.flush = _XimXFlush;
+ im->private.proto.register_dispatcher = _XimXRegisterDispatcher;
+ im->private.proto.call_dispatcher = _XimXCallDispatcher;
+
+ return True;
+}
diff --git a/libX11/modules/im/ximcp/imTrans.c b/libX11/modules/im/ximcp/imTrans.c index 0ac08aa60..a601affda 100644 --- a/libX11/modules/im/ximcp/imTrans.c +++ b/libX11/modules/im/ximcp/imTrans.c @@ -1,313 +1,315 @@ -/* - * Copyright 1992 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ -/****************************************************************** - - Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -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 FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED 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. - - Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc. - Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - -******************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xatom.h> -#include <X11/Xmd.h> -#include "Xlibint.h" -#include <X11/Xtrans/Xtrans.h> -#include "Xlcint.h" -#include "Ximint.h" -#include "XimTrans.h" -#include "XimTrInt.h" - -#ifdef WIN32 -#include <X11/Xwindows.h> -#endif - - -#ifndef XIM_CONNECTION_RETRIES -#define XIM_CONNECTION_RETRIES 5 -#endif - - -Private Bool -_XimTransConnect( - Xim im) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - int connect_stat, retry; - Window window; - - for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--) - { - if ((spec->trans_conn = _XimXTransOpenCOTSClient ( - spec->address)) == NULL) - { - break; - } - - if ((connect_stat = _XimXTransConnect ( - spec->trans_conn, spec->address)) < 0) - { - _XimXTransClose (spec->trans_conn); - spec->trans_conn = NULL; - - if (connect_stat == TRANS_TRY_CONNECT_AGAIN) - continue; - else - break; - } - else - break; - } - - if (spec->trans_conn == NULL) - return False; - - spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn); - - if (!(window = XCreateSimpleWindow(im->core.display, - DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0))) - return False; - spec->window = window; - - _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress, - _XimTransFilterWaitEvent, (XPointer)im); - - return _XRegisterInternalConnection(im->core.display, spec->fd, - (_XInternalConnectionProc)_XimTransInternalConnection, - (XPointer)im); -} - - -Private Bool -_XimTransShutdown( - Xim im) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - - _XimXTransDisconnect(spec->trans_conn); - (void)_XimXTransClose(spec->trans_conn); - _XimFreeTransIntrCallback(im); - _XUnregisterInternalConnection(im->core.display, spec->fd); - _XUnregisterFilter(im->core.display, spec->window, - _XimTransFilterWaitEvent, (XPointer)im); - XDestroyWindow(im->core.display, spec->window); - Xfree(spec->address); - Xfree(spec); - return True; -} - - - -Public Bool -_XimTransRegisterDispatcher( - Xim im, - Bool (*callback)( - Xim, INT16, XPointer, XPointer - ), - XPointer call_data) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - TransIntrCallbackPtr rec; - - if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec)))) - return False; - - rec->func = callback; - rec->call_data = call_data; - rec->next = spec->intr_cb; - spec->intr_cb = rec; - return True; -} - - -Public void -_XimFreeTransIntrCallback( - Xim im) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - register TransIntrCallbackPtr rec, next; - - for (rec = spec->intr_cb; rec;) { - next = rec->next; - Xfree(rec); - rec = next; - } - return; -} - - -Public Bool -_XimTransCallDispatcher(Xim im, INT16 len, XPointer data) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - TransIntrCallbackRec *rec; - - for (rec = spec->intr_cb; rec; rec = rec->next) { - if ((*rec->func)(im, len, data, rec->call_data)) - return True; - } - return False; -} - - -Public Bool -_XimTransFilterWaitEvent( - Display *d, - Window w, - XEvent *ev, - XPointer arg) -{ - Xim im = (Xim)arg; - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - - spec->is_putback = False; - return _XimFilterWaitEvent(im); -} - - -Public void -_XimTransInternalConnection( - Display *d, - int fd, - XPointer arg) -{ - Xim im = (Xim)arg; - XEvent ev; - XKeyEvent *kev; - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - - if (spec->is_putback) - return; - kev = (XKeyEvent *)&ev; - kev->type = KeyPress; - kev->send_event = False; - kev->display = im->core.display; - kev->window = spec->window; - kev->keycode = 0; - XPutBackEvent(im->core.display, &ev); - XFlush(im->core.display); - spec->is_putback = True; - return; -} - - -Public Bool -_XimTransWrite(Xim im, INT16 len, XPointer data) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - char *buf = (char *)data; - register int nbyte; - - while (len > 0) { - if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0) - return False; - len -= nbyte; - buf += nbyte; - } - return True; -} - - -Public Bool -_XimTransRead( - Xim im, - XPointer recv_buf, - int buf_len, - int *ret_len) -{ - TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec; - int len; - - if (buf_len == 0) { - *ret_len = 0; - return True; - } - if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0) - return False; - *ret_len = len; - return True; -} - - -Public void -_XimTransFlush( - Xim im) -{ - return; -} - - - -Public Bool -_XimTransConf( - Xim im, - char *address) -{ - char *paddr; - TransSpecRec *spec; - - if (!(paddr = strdup(address))) - return False; - - if (!(spec = Xcalloc(1, sizeof(TransSpecRec)))) { - Xfree(paddr); - return False; - } - - spec->address = paddr; - - im->private.proto.spec = (XPointer)spec; - im->private.proto.connect = _XimTransConnect; - im->private.proto.shutdown = _XimTransShutdown; - im->private.proto.write = _XimTransWrite; - im->private.proto.read = _XimTransRead; - im->private.proto.flush = _XimTransFlush; - im->private.proto.register_dispatcher = _XimTransRegisterDispatcher; - im->private.proto.call_dispatcher = _XimTransCallDispatcher; - - return True; -} +/*
+ * Copyright 1992 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+/******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+
+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 FUJITSU LIMITED
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+FUJITSU LIMITED makes no representations about the suitability of
+this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL FUJITSU LIMITED 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.
+
+ Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
+ Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/Xatom.h>
+#include <X11/Xmd.h>
+#include "Xlibint.h"
+#include <X11/Xwindows.h>
+#include <X11/Xtrans/Xtrans.h>
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XimTrans.h"
+#include "XimTrInt.h"
+
+#ifdef WIN32
+#include <X11/Xwindows.h>
+#endif
+
+
+#ifndef XIM_CONNECTION_RETRIES
+#define XIM_CONNECTION_RETRIES 5
+#endif
+
+
+Private Bool
+_XimTransConnect(
+ Xim im)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ int connect_stat, retry;
+ Window window;
+
+ for (retry = XIM_CONNECTION_RETRIES; retry >= 0; retry--)
+ {
+ if ((spec->trans_conn = _XimXTransOpenCOTSClient (
+ spec->address)) == NULL)
+ {
+ break;
+ }
+
+ if ((connect_stat = _XimXTransConnect (
+ spec->trans_conn, spec->address)) < 0)
+ {
+ _XimXTransClose (spec->trans_conn);
+ spec->trans_conn = NULL;
+
+ if (connect_stat == TRANS_TRY_CONNECT_AGAIN)
+ continue;
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ if (spec->trans_conn == NULL)
+ return False;
+
+ spec->fd = _XimXTransGetConnectionNumber (spec->trans_conn);
+
+ if (!(window = XCreateSimpleWindow(im->core.display,
+ DefaultRootWindow(im->core.display), 0, 0, 1, 1, 1, 0, 0)))
+ return False;
+ spec->window = window;
+
+ _XRegisterFilterByType(im->core.display, window, KeyPress, KeyPress,
+ _XimTransFilterWaitEvent, (XPointer)im);
+
+ return _XRegisterInternalConnection(im->core.display, spec->fd,
+ (_XInternalConnectionProc)_XimTransInternalConnection,
+ (XPointer)im);
+}
+
+
+Private Bool
+_XimTransShutdown(
+ Xim im)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+
+ _XimXTransDisconnect(spec->trans_conn);
+ (void)_XimXTransClose(spec->trans_conn);
+ _XimFreeTransIntrCallback(im);
+ _XUnregisterInternalConnection(im->core.display, spec->fd);
+ _XUnregisterFilter(im->core.display, spec->window,
+ _XimTransFilterWaitEvent, (XPointer)im);
+ XDestroyWindow(im->core.display, spec->window);
+ Xfree(spec->address);
+ Xfree(spec);
+ return True;
+}
+
+
+
+Public Bool
+_XimTransRegisterDispatcher(
+ Xim im,
+ Bool (*callback)(
+ Xim, INT16, XPointer, XPointer
+ ),
+ XPointer call_data)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ TransIntrCallbackPtr rec;
+
+ if (!(rec = (TransIntrCallbackPtr)Xmalloc(sizeof(TransIntrCallbackRec))))
+ return False;
+
+ rec->func = callback;
+ rec->call_data = call_data;
+ rec->next = spec->intr_cb;
+ spec->intr_cb = rec;
+ return True;
+}
+
+
+Public void
+_XimFreeTransIntrCallback(
+ Xim im)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ register TransIntrCallbackPtr rec, next;
+
+ for (rec = spec->intr_cb; rec;) {
+ next = rec->next;
+ Xfree(rec);
+ rec = next;
+ }
+ return;
+}
+
+
+Public Bool
+_XimTransCallDispatcher(Xim im, INT16 len, XPointer data)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ TransIntrCallbackRec *rec;
+
+ for (rec = spec->intr_cb; rec; rec = rec->next) {
+ if ((*rec->func)(im, len, data, rec->call_data))
+ return True;
+ }
+ return False;
+}
+
+
+Public Bool
+_XimTransFilterWaitEvent(
+ Display *d,
+ Window w,
+ XEvent *ev,
+ XPointer arg)
+{
+ Xim im = (Xim)arg;
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+
+ spec->is_putback = False;
+ return _XimFilterWaitEvent(im);
+}
+
+
+Public void
+_XimTransInternalConnection(
+ Display *d,
+ int fd,
+ XPointer arg)
+{
+ Xim im = (Xim)arg;
+ XEvent ev;
+ XKeyEvent *kev;
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+
+ if (spec->is_putback)
+ return;
+ kev = (XKeyEvent *)&ev;
+ kev->type = KeyPress;
+ kev->send_event = False;
+ kev->display = im->core.display;
+ kev->window = spec->window;
+ kev->keycode = 0;
+ XPutBackEvent(im->core.display, &ev);
+ XFlush(im->core.display);
+ spec->is_putback = True;
+ return;
+}
+
+
+Public Bool
+_XimTransWrite(Xim im, INT16 len, XPointer data)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ char *buf = (char *)data;
+ register int nbyte;
+
+ while (len > 0) {
+ if ((nbyte = _XimXTransWrite(spec->trans_conn, buf, len)) <= 0)
+ return False;
+ len -= nbyte;
+ buf += nbyte;
+ }
+ return True;
+}
+
+
+Public Bool
+_XimTransRead(
+ Xim im,
+ XPointer recv_buf,
+ int buf_len,
+ int *ret_len)
+{
+ TransSpecRec *spec = (TransSpecRec *)im->private.proto.spec;
+ int len;
+
+ if (buf_len == 0) {
+ *ret_len = 0;
+ return True;
+ }
+ if ((len = _XimXTransRead(spec->trans_conn, recv_buf, buf_len)) <= 0)
+ return False;
+ *ret_len = len;
+ return True;
+}
+
+
+Public void
+_XimTransFlush(
+ Xim im)
+{
+ return;
+}
+
+
+
+Public Bool
+_XimTransConf(
+ Xim im,
+ char *address)
+{
+ char *paddr;
+ TransSpecRec *spec;
+
+ if (!(paddr = strdup(address)))
+ return False;
+
+ if (!(spec = Xcalloc(1, sizeof(TransSpecRec)))) {
+ Xfree(paddr);
+ return False;
+ }
+
+ spec->address = paddr;
+
+ im->private.proto.spec = (XPointer)spec;
+ im->private.proto.connect = _XimTransConnect;
+ im->private.proto.shutdown = _XimTransShutdown;
+ im->private.proto.write = _XimTransWrite;
+ im->private.proto.read = _XimTransRead;
+ im->private.proto.flush = _XimTransFlush;
+ im->private.proto.register_dispatcher = _XimTransRegisterDispatcher;
+ im->private.proto.call_dispatcher = _XimTransCallDispatcher;
+
+ return True;
+}
diff --git a/libX11/modules/im/ximcp/makefile b/libX11/modules/im/ximcp/makefile new file mode 100644 index 000000000..ca80ad90e --- /dev/null +++ b/libX11/modules/im/ximcp/makefile @@ -0,0 +1,34 @@ +DEFINES += XIM_t TRANS_CLIENT + +LIBRARY=libximcp + +CSRCS = \ + imCallbk.c \ + imDefFlt.c \ + imDefIc.c \ + imDefIm.c \ + imDefLkup.c \ + imDispch.c \ + imEvToWire.c \ + imExten.c \ + imImSw.c \ + imInsClbk.c \ + imInt.c \ + imLcFlt.c \ + imLcGIc.c \ + imLcIc.c \ + imLcIm.c \ + imLcLkup.c \ + imLcPrs.c \ + imLcSIc.c \ + imRmAttr.c \ + imRm.c \ + imThaiFlt.c \ + imThaiIc.c \ + imThaiIm.c \ + imTrans.c \ + imTransR.c \ + imTrX.c + +INCLUDES += ..\..\..\include\X11 ..\..\..\src\xlibi18n + diff --git a/libX11/modules/lc/Utf8/makefile b/libX11/modules/lc/Utf8/makefile new file mode 100644 index 000000000..6f814c760 --- /dev/null +++ b/libX11/modules/lc/Utf8/makefile @@ -0,0 +1,6 @@ +LIBRARY = libxlcUTF8Load + +CSRCS=lcUTF8Load.c + +INCLUDES += ..\..\..\include\X11 ..\..\..\src\xlibi18n ..\..\..\src + diff --git a/libX11/modules/lc/def/makefile b/libX11/modules/lc/def/makefile new file mode 100644 index 000000000..b89ce455d --- /dev/null +++ b/libX11/modules/lc/def/makefile @@ -0,0 +1,5 @@ +LIBRARY = libxlcDef +CSRCS = lcDefConv.c + +INCLUDES += ..\..\..\include\X11 ..\..\..\src\xlibi18n ..\..\..\src + diff --git a/libX11/modules/lc/gen/lcGenConv.c b/libX11/modules/lc/gen/lcGenConv.c index 7a113a78a..c222c1f2a 100644 --- a/libX11/modules/lc/gen/lcGenConv.c +++ b/libX11/modules/lc/gen/lcGenConv.c @@ -1,3148 +1,3148 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ -/* - * (c) Copyright 1995 FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - * - * Modifier: Masayoshi Shimamura FUJITSU LIMITED - * - */ -/* - * 2000 - * Modifier: Ivan Pascal The XFree86 Project - */ - -/* - * A generic locale loader for all kinds of ISO-2022 based codesets. - * Supports: all locales. - * How: Provides generic converters for ISO-2022 based codesets. Extensible as - * far as ISO-2022 is extensible: codesets can be given by name in the - * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff). - * In every chunk between escape sequences, the number of bytes per - * character (char_size) is constant. - * Platforms: all systems. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "XlcGeneric.h" -#include <stdio.h> - -#if !defined(Lynx_22) && !defined(X_LOCALE) -#define STDCVT -#endif - -typedef struct _CTDataRec { - const char *name; - const char *encoding; /* Compound Text encoding */ -} CTDataRec, *CTData; - -static CTDataRec directionality_data[] = -{ - { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" }, - { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" }, - { "END_OF_STRING", "\233]" }, -}; - -typedef struct _StateRec { - XLCd lcd; - /* CT state */ - XlcCharSet charset; /* charset of current state */ - XlcCharSet GL_charset; /* charset of initial state in GL */ - XlcCharSet GR_charset; /* charset of initial state in GR */ - /* MB shift state */ - CodeSet GL_codeset; - CodeSet GR_codeset; -} StateRec, *State; - -#define GR 0x80 /* begins right-side (non-ascii) region */ -#define GL 0x7f /* ends left-side (ascii) region */ -#define ESC 0x1b -#define CSI 0x9b -#define STX 0x02 - -#define isrightside(c) ((c) & GR) -#define isleftside(c) (!isrightside(c)) - -/* Forward declarations for local routines. */ -static int mbstocts (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); -static int ctstombs (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); -static int cstombs (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); - -/* ------------------------------------------------------------------------- */ -/* Misc */ -/* ------------------------------------------------------------------------- */ - -static int -compare( - const char *src, - const char *encoding, - int length) -{ - const char *start = src; - - while (length-- > 0) { - if (*src++ != *encoding++) - return 0; - if (*encoding == '\0') - return src - start; - } - - return 0; -} - -static unsigned long -conv_to_dest( - Conversion conv, - unsigned long code) -{ - int i; - int conv_num = conv->conv_num; - FontScope convlist = conv->convlist; - - for (i = 0; i < conv_num; i++) { - if (convlist[i].start <= code && code <= convlist[i].end) { - switch (convlist[i].shift_direction) { - case '+': - return(code + convlist[i].shift); - case '-': - return(code - convlist[i].shift); - default: - return(code); - } - } - } - - return(code); -} - -static unsigned long -conv_to_source( - Conversion conv, - unsigned long code) -{ - int i; - int conv_num; - FontScope convlist; - unsigned long start_p; - unsigned long start_m; - unsigned long end_p; - unsigned long end_m; - - if (!conv) - return(code); - - conv_num = conv->conv_num; - convlist = conv->convlist; - - for (i = 0; i < conv_num; i++) { - switch (convlist[i].shift_direction) { - case '+': - start_p = convlist[i].start + convlist[i].shift; - end_p = convlist[i].end + convlist[i].shift; - if (start_p <= code && code <= end_p) - return(code - convlist[i].shift); - break; - case '-': - start_m = convlist[i].start - convlist[i].shift; - end_m = convlist[i].end - convlist[i].shift; - if (start_m <= code && code <= end_m) - return(code + convlist[i].shift); - break; - default: - continue; - } - } - - return(code); -} - -static unsigned long -mb_to_gi( - unsigned long mb, - CodeSet codeset) -{ - int i; - unsigned long mb_tmp, mask = 0; - - if (codeset->mbconv) { - mb_tmp = conv_to_dest(codeset->mbconv, mb); - if (mb_tmp != mb) - return(mb_tmp); - } - - if (codeset->side == XlcC0 || codeset->side == XlcGL || - codeset->side == XlcC1 || codeset->side == XlcGR) { - - for (i = 0; i < codeset->length; i++) - mask = (mask << 8) | GL; - mb = mb & mask; - } - - return(mb); -} - -static unsigned long -gi_to_mb( - unsigned long glyph_index, - CodeSet codeset) -{ - int i; - unsigned long mask = 0; - - if (codeset->side == XlcC1 || codeset->side == XlcGR) { - for (i = 0; i < codeset->length; i++) - mask = (mask << 8) | GR; - glyph_index = glyph_index | mask; - } - - if (codeset->mbconv) - return( conv_to_source(codeset->mbconv, glyph_index) ); - - return(glyph_index); -} - -static Bool -gi_to_wc( - XLCd lcd, - unsigned long glyph_index, - CodeSet codeset, - wchar_t *wc) -{ - unsigned char mask = 0; - unsigned long wc_encoding = codeset->wc_encoding; - int length = codeset->length; - unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - - mask = (1 << wc_shift_bits) - 1 ; - - for (*wc = 0, length--; length >= 0; length--) - *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask); - - *wc = *wc | wc_encoding; - - return(True); -} - -static Bool -wc_to_gi( - XLCd lcd, - wchar_t wc, - unsigned long *glyph_index, - CodeSet *codeset) -{ - int i; - unsigned char mask = 0; - unsigned long wc_encoding; - unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask); - unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - wc_encoding = wc & wc_encode_mask; - for (*codeset = NULL, i = 0; i < codeset_num; i++) { - if (wc_encoding == codeset_list[i]->wc_encoding) { - *codeset = codeset_list[i]; - break; - } - } - if (*codeset == NULL) - return(False); - - mask = (1 << wc_shift_bits) - 1 ; - - wc = wc & ~wc_encode_mask; - for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--) - *glyph_index = (*glyph_index << 8) | - ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask ); - - return(True); -} - -static CodeSet -mb_parse_codeset( - State state, - int num, - const char **inbufptr, - int *from_left) -{ - int len; - int from_len = (*from_left) + 1; - const char *src = (*inbufptr) - 1; - ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list); - ParseInfo parse_info; - CodeSet codeset; - - for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) { - len = compare(src, parse_info->encoding, from_len); - if (len > 0) { - codeset = parse_info->codeset; - if (parse_info->type == E_LSL) - state->GL_codeset = codeset; - else if (parse_info->type == E_LSR) - state->GR_codeset = codeset; - --len; - *inbufptr += len; - *from_left -= len; - return codeset; - } - } - return (CodeSet) NULL; -} - -static CodeSet -byteM_parse_codeset( - XLCd lcd, - const char *inbufptr) -{ - unsigned char ch; - CodeSet codeset; - ByteInfoList byteM; - ByteInfoListRec byteM_rec; - ByteInfo byteinfo; - ByteInfoRec byteinfo_rec; - Bool hit = False; - int i, j, k; - - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - byteM = codeset->byteM; - if (codeset->side != XlcNONE || byteM == NULL) - continue; - - for (j = 0; j < codeset->length; j++) { - ch = *((unsigned char *)(inbufptr + j)); - byteM_rec = byteM[j]; - byteinfo = byteM_rec.byteinfo; - - for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) { - byteinfo_rec = byteinfo[k]; - if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) { - hit = True; - break; - } - } - - if (!hit) - break; - } - - if (hit) - return(codeset); - } - - return(NULL); -} - -#define GLGR_parse_codeset(ch) \ - (isrightside(ch) ? (state->GR_codeset) : \ - (state->GL_codeset) ) - -static XlcCharSet -gi_parse_charset( - unsigned long glyph_index, - CodeSet codeset) -{ - int i; - XlcCharSet *charset_list = codeset->charset_list; - int num_charsets = codeset->num_charsets; - ExtdSegment ctextseg = codeset->ctextseg; - XlcCharSet charset = NULL; - int area_num; - FontScope area; - - /* lockup ct sequence */ - for (i = 0; i < num_charsets; i++) { - charset = charset_list[i]; - if (*charset->ct_sequence != '\0') - break; - } - if (i >= num_charsets) - return(NULL); - - if (charset->source != CSsrcStd) - return (charset); - - if (!ctextseg) - return(charset); - - area = ctextseg->area; - area_num = ctextseg->area_num; - - for (i = 0; i < area_num; i++) { - - if (area[i].start <= glyph_index && glyph_index <= area[i].end) { - - charset = ctextseg->charset; - - if (*charset->ct_sequence == '\0') - return(NULL); - - break; - } - } - - return(charset); -} - -static Bool -ct_parse_csi( - const char *inbufptr, - int *ctr_seq_len) -{ - int i; - int num = sizeof(directionality_data) / sizeof(directionality_data[0]); - - for (i = 0; i < num; i++) { - if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) ) - continue; - - if ( strncmp(inbufptr, directionality_data[i].encoding, - *ctr_seq_len) == 0) - return(True); - } - - return(False); -} - -static int -cmp_esc_sequence( - const char *inbufptr, - XlcCharSet charset) -{ - int seq_len, name_len, total_len; - unsigned char byte_m, byte_l; - const char *ct_sequence = charset->ct_sequence; - const char *encoding_name = charset->encoding_name; - - /* check esc sequence */ - if ( !(seq_len = strlen(ct_sequence) ) ) - return(0); - if ( strncmp(inbufptr, ct_sequence, seq_len) != 0) - return(0); - - /* Standard Character Set Encoding ? */ - if (charset->source == CSsrcStd) - return(seq_len); - - /* - * Non-Standard Character Set Encoding - * - * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ - * | ctseq | M | L | encoding name | STX | contents | - * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ - * 4bytes 1byte 1byte variable length 1byte variable length - * | | - * +----------------------------------------------+ - * rest length = ((M - 128) * 128) + (L - 128) - */ - - /* get length of encoding name */ - inbufptr += seq_len; - byte_m = *inbufptr++; - byte_l = *inbufptr++; - name_len = strlen(encoding_name); - - if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len) - return(0); - - if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 ) - return(0); - - /* check STX (Start of Text) */ - inbufptr = inbufptr + name_len; - if ( *inbufptr != STX ) - return(0); - - total_len = seq_len + name_len + 3; - return(total_len); -} - -static Bool -ct_parse_charset( - XLCd lcd, - const char *inbufptr, - XlcCharSet *charset, - int *ctr_seq_len) -{ - int i, j; - ExtdSegment ctextseg; - int num_charsets; - XlcCharSet *charset_list; - CodeSet codeset; - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); - SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); - - /* get charset from XLC_XLOCALE by escape sequence */ - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - - num_charsets = codeset->num_charsets; - charset_list = codeset->charset_list; - ctextseg = codeset->ctextseg; - - for (j = 0; j < num_charsets; j++) { - *charset = charset_list[j]; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - - if (ctextseg) { - *charset = ctextseg->charset; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - } - - /* get charset from XLC_SEGMENTCONVERSION by escape sequence */ - - if (!segment_conv) - return(False); - - for (i = 0; i < segment_conv_num; i++) { - *charset = segment_conv[i].source; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - *charset = segment_conv[i].dest; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - - return(False); -} - -static Bool -segment_conversion( - XLCd lcd, - XlcCharSet *charset, - unsigned long *glyph_index) -{ - int i; - int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); - SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); - FontScopeRec range; - ConversionRec conv_rec; - - if (!segment_conv) - return(True); - - for (i = 0; i < segment_conv_num; i++) { - if (segment_conv[i].source == *charset) - break; - } - - if (i >= segment_conv_num) - return(True); - - range = segment_conv[i].range; - if (*glyph_index < range.start || range.end < *glyph_index) - return(True); - - *charset = segment_conv[i].dest; - conv_rec.conv_num = segment_conv[i].conv_num; - conv_rec.convlist = segment_conv[i].conv; - *glyph_index = conv_to_dest(&conv_rec, *glyph_index); - - return(True); -} - -static CodeSet -_XlcGetCodeSetFromName( - XLCd lcd, - const char *name) -{ - int i, j; - XlcCharSet charset; - int num_charsets; - XlcCharSet *charset_list; - CodeSet codeset; - - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - - num_charsets = codeset->num_charsets; - charset_list = codeset->charset_list; - - for (j = 0; j < num_charsets; j++) { - charset = charset_list[j]; - - if (!strlen(charset->name)) - continue; - if ( strcmp(charset->name, name) == 0) - return(codeset); - } - } - - return(NULL); -} - -static Bool -_XlcGetCodeSetFromCharSet( - XLCd lcd, - XlcCharSet charset, - CodeSet *codeset, - unsigned long *glyph_index) -{ - int j, num; - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - XlcCharSet *charset_list; - int codeset_num, num_charsets; - Conversion ctconv; - unsigned long glyph_index_tmp = 0; - ExtdSegment ctextseg; - - codeset_num = XLC_GENERIC(lcd, codeset_num); - - for (num = 0 ; num < codeset_num; num++) { - *codeset = codeset_list[num]; - ctconv = (*codeset)->ctconv; - ctextseg = (*codeset)->ctextseg; - - num_charsets = (*codeset)->num_charsets; - charset_list = (*codeset)->charset_list; - - glyph_index_tmp = conv_to_source(ctconv, *glyph_index); - - if (charset->source == CSsrcStd) { - - /* Standard Character Set Encoding */ - if (glyph_index_tmp == *glyph_index) { - for (j = 0; j < num_charsets; j++) { - if (charset_list[j] == charset) { - goto end_loop; - } - } - } - - } else { - - /* Non-Standard Character Set Encoding */ - for (j = 0; j < num_charsets; j++) { - if (charset_list[j] == charset) { - goto end_loop; - } - } - - if (glyph_index_tmp != *glyph_index) { - if (ctextseg && ctextseg->charset == charset) { - goto end_loop; - } - } - - } - - } - -end_loop: - if (num < codeset_num) { - *glyph_index = glyph_index_tmp; - return(True); - } - - return(False); -} - -#define check_string_encoding(codeset) (codeset->string_encoding) - -static void -output_ulong_value( - char *outbufptr, - unsigned long code, - int length, - XlcSide side) -{ - int i; - - for (i = (length - 1) * 8; i >= 0; i -= 8) { - *outbufptr = ( code >> i) & 0xff; - - if (side == XlcC0 || side == XlcGL) { - *outbufptr = *outbufptr & GL; - } else if (side == XlcC1 || side == XlcGR) { - *outbufptr = *outbufptr | GR; - } - - outbufptr++; - } -} - -/* -------------------------------------------------------------------------- */ -/* Init */ -/* -------------------------------------------------------------------------- */ - -static XlcCharSet default_GL_charset = 0; -static XlcCharSet default_GR_charset = 0; - -static void -init_state( - XlcConv conv) -{ - State state = (State) conv->state; - - /* for CT */ - state->charset = NULL; - state->GL_charset = default_GL_charset; - state->GR_charset = default_GR_charset; - - /* for MB shift state */ - state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL); - state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR); -} - -/* -------------------------------------------------------------------------- */ -/* Convert */ -/* -------------------------------------------------------------------------- */ - -static int -mbstowcs_org( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - wchar_t wc; - - int length = 0, len_left = 0; - int unconv_num = 0; - int num; - - CodeSet codeset = NULL; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (len_left) { - unconv_num += (length - len_left); - len_left = 0; - } - - continue; - } - - /* same mb char data */ - if (len_left) - goto output_one_wc; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next mb char data for byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next mb char data for GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num++; - continue; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output_one_wc: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - } /* end of while */ - - /* error check on last char */ - if (len_left) { - inbufptr -= (length - len_left); - (*from_left) += (length - len_left); - unconv_num += (length - len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_mbstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const char *src = *((const char **) from); - wchar_t *dst = *((wchar_t **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length, unconv_num = 0; - - while (src_left > 0 && dst_left > 0) { - length = mbtowc(dst, src, src_left); - - if (length > 0) { - src += length; - src_left -= length; - if (dst) - dst++; - dst_left--; - } else if (length < 0) { - src++; - src_left--; - unconv_num++; - } else { - /* null ? */ - src++; - src_left--; - if (dst) - *dst++ = L'\0'; - dst_left--; - } - } - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return unconv_num; -} - -static int -wcstombs_org( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - wchar_t wc; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - const char *default_string = XLC_PUBLIC(lcd, default_string); - int defstr_len = strlen(default_string); - - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - - /* output default_string of XDefaultString() */ - if (*to_left < defstr_len) - break; - if (outbufptr) { - strncpy((char *)outbufptr, default_string, defstr_len); - outbufptr += defstr_len; - } - (*to_left) -= defstr_len; - - unconv_num++; - - } else { - mb = gi_to_mb(glyph_index, codeset); - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - } - - } /* end of while */ - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - char *dst = *((char **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length, unconv_num = 0; - - while (src_left > 0 && dst_left >= MB_CUR_MAX) { - length = wctomb(dst, *src); /* XXX */ - - if (length > 0) { - src++; - src_left--; - if (dst) - dst += length; - dst_left -= length; - } else if (length < 0) { - src++; - src_left--; - unconv_num++; - } - } - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return unconv_num; -} - -static int -wcstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned long glyph_index; - wchar_t wc; - - int total_len, seq_len, name_len; - int unconv_num = 0; - Bool first_flag = True, standard_flag; - XlcSide side; - - CodeSet codeset; - XlcCharSet charset, old_charset = NULL; - const char *ct_sequence; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - char *ext_seg_len = NULL; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - unconv_num++; - continue; - } - - /* parse charset */ - if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { - unconv_num++; - continue; - } - - /* Standard Character Set Encoding ? */ - standard_flag = charset->source == CSsrcStd ? True : False; - - /* - * Non-Standard Character Set Encoding - * - * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ - * | esc sequence | M | L | encoding name | STX | - * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ - * 4bytes 1byte 1byte variable length 1byte - * | | - * +-----------------------------------------+ - * name length = ((M - 128) * 128) + (L - 128) - */ - - /* make encoding data */ - ct_sequence = charset->ct_sequence; - side = charset->side; - seq_len = strlen(ct_sequence); - if (standard_flag) { - name_len = 0; - total_len = seq_len; - } else { - name_len = strlen(charset->encoding_name) + 1; - total_len = seq_len + name_len + 2; - } - - /* output escape sequence of CT */ - if ( (charset != old_charset) && - !(first_flag && charset->string_encoding) ){ - - if ( (ext_seg_len != NULL) && outbufptr) { - int i = (outbufptr - ext_seg_len) - 2; - *ext_seg_len++ = i / 128 + 128; - *ext_seg_len = i % 128 + 128; - ext_seg_len = NULL; - } - - if (*to_left < total_len + 1) { - unconv_num++; - break; - } - - if (outbufptr) { - strcpy((char *)outbufptr, ct_sequence); - outbufptr += seq_len; - - if (!standard_flag) { - const char *i = charset->encoding_name; - ext_seg_len = outbufptr; - outbufptr += 2; - for (; *i ; i++) - *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? - *i - 'A' + 'a' : *i; - *outbufptr++ = STX; - } - } - - (*to_left) -= total_len; - - first_flag = False; - old_charset = charset; - } - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < charset->char_size) { - unconv_num++; - break; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, charset->char_size, side); - outbufptr += charset->char_size; - } - - (*to_left) -= charset->char_size; - - } /* end of while */ - - if ( (ext_seg_len != NULL) && outbufptr) { - int i = (outbufptr - ext_seg_len) - 2; - *ext_seg_len++ = i / 128 + 128; - *ext_seg_len = i % 128 + 128; - } - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = stdc_wcstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = mbstocts(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -ctstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index = 0; - wchar_t wc; - - int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; - int unconv_num = 0; - - CodeSet codeset = NULL; - XlcCharSet charset_tmp; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - _XlcResetConverter(conv); /* ??? */ - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (gi_len_left) { - unconv_num += (gi_len - gi_len_left); - gi_len_left = 0; - } - - continue; - } - - /* same glyph_index data */ - if (gi_len_left) - goto output_one_wc; - - /* control sequence ? */ - if (ch == CSI) { - if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) - goto skip_the_seg; - - if (*from_left + 1 < ctr_seq_len) { - inbufptr--; - (*from_left)++; - unconv_num += *from_left; - break; - } - - /* skip the control sequence */ - inbufptr += (ctr_seq_len - 1); - *from_left -= (ctr_seq_len - 1); - - continue; - } - - /* escape sequence ? */ - if (ch == ESC) { - if ( !ct_parse_charset(lcd, - inbufptr - 1, &state->charset, &ctr_seq_len) ) - goto skip_the_seg; - - if (state->charset->side == XlcC0 || - state->charset->side == XlcGL) - { - state->GL_charset = state->charset; - } - else if (state->charset->side == XlcC1 || - state->charset->side == XlcGR) - { - state->GR_charset = state->charset; - } - else if (state->charset->side == XlcGLGR) - { - state->GL_charset = state->charset; - state->GR_charset = state->charset; - } - - if (*from_left + 1 < ctr_seq_len) { - inbufptr--; - (*from_left)++; - unconv_num += *from_left; - break; - } - - /* skip the escape sequence */ - inbufptr += (ctr_seq_len - 1); - *from_left -= (ctr_seq_len - 1); - - continue; - } - - /* check current state */ - if (isleftside(ch)) - state->charset = state->GL_charset; - else - state->charset = state->GR_charset; - - gi_len = gi_len_left = state->charset->char_size; - glyph_index = 0; - -output_one_wc: - if (state->charset->side == XlcC1 || state->charset->side == XlcGR) - glyph_index = (glyph_index << 8) | (ch & GL); - else - glyph_index = (glyph_index << 8) | ch; - - gi_len_left--; - - /* last of one glyph_index data */ - if (!gi_len_left) { - - /* segment conversion */ - charset_tmp = state->charset; - segment_conversion(lcd, &charset_tmp, &glyph_index); - - /* get codeset */ - if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, - &codeset, &glyph_index) ) { - unconv_num += gi_len; - continue; - } - - /* convert glyph index to wicd char */ - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - continue; - -skip_the_seg: - /* skip until next escape or control sequence */ - while ( *from_left ) { - ch = *inbufptr++; - (*from_left)--; - unconv_num++; - - if (ch == ESC || ch == CSI) { - inbufptr--; - (*from_left)++; - unconv_num--; - break; - } - } - - if ( !(*from_left) ) - break; - - } /* end of while */ - - /* error check on last char */ - if (gi_len_left) { - inbufptr -= (gi_len - gi_len_left); - (*from_left) += (gi_len - gi_len_left); - unconv_num += (gi_len - gi_len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index = 0; - wchar_t wc; - int gi_len_left = 0, gi_len = 0; - - int unconv_num = 0; - - CodeSet codeset = NULL; - XlcCharSet charset, charset_tmp; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - if (from == NULL || *from == NULL) { - return( 0 ); - } - - charset = (XlcCharSet) args[0]; - - while (*from_left && *to_left) { - - if (!gi_len_left) { - gi_len_left = gi_len = charset->char_size; - glyph_index = 0; - } - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (gi_len_left) { - unconv_num += (gi_len - gi_len_left); - gi_len_left = 0; - } - continue; - } - - if (charset->side == XlcC1 || charset->side == XlcGR) - glyph_index = (glyph_index << 8) | (ch & GL); - else - glyph_index = (glyph_index << 8) | ch; - - gi_len_left--; - - /* last of one glyph_index data */ - if (!gi_len_left) { - - /* segment conversion */ - charset_tmp = charset; - segment_conversion(lcd, &charset_tmp, &glyph_index); - - /* get codeset */ - if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, - &codeset, &glyph_index) ) { - unconv_num += gi_len; - continue; - } - - /* convert glyph index to wicd char */ - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - } /* end of while */ - - /* error check on last char */ - if (gi_len_left) { - inbufptr -= (gi_len - gi_len_left); - (*from_left) += (gi_len - gi_len_left); - unconv_num += (gi_len - gi_len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_ctstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = ctstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -stdc_cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = cstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -mbstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = mbstowcs_org(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstocts(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -mbstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - - int length = 0, len_left = 0; - int unconv_num = 0; - int num; - - CodeSet codeset = NULL; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - /* error check */ - if (len_left) { - unconv_num += (length - len_left); - len_left = 0; - } - - continue; - } - - /* same mb char data */ - if (len_left) - goto output_one_mb; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next char data : byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next char data : GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num++; - continue; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output_one_mb: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - if (check_string_encoding(codeset)) { - if (outbufptr) {*outbufptr++ = mb & 0xff;} - (*to_left)--; - } else { - unconv_num++; - } - } - - } /* end of while */ - - /* error check on last char */ - if (len_left) { - inbufptr -= (length - len_left); - (*from_left) += (length - len_left); - unconv_num += (length - len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -mbtocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - unsigned long glyph_index; - - int length = 0, len_left = 0, char_len; - int unconv_num = 0; - int num; - XlcSide side; - - CodeSet codeset = NULL; - XlcCharSet charset = NULL; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - unconv_num = 1; - if (len_left) - unconv_num += (length - len_left); - break; - } - - /* same mb char data */ - if (len_left) - goto output; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next mb char data for byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next mb char data for GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num = 1; - break; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - glyph_index = mb_to_gi(mb, codeset); - if (!(charset = gi_parse_charset(glyph_index, codeset))) { - unconv_num = length; - break; - } - char_len = charset->char_size; - side = charset->side; - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < char_len) { - unconv_num = length; - break; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, char_len, side); - outbufptr += char_len; - } - - (*to_left) -= char_len; - - break; - } - - } /* end of while */ - - /* error end */ - if (unconv_num) { - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - return -1; - } - - /* nomal end */ - *from = (XPointer) inbufptr; - *to = (XPointer) outbufptr; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -mbstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const char *inbufptr; - int in_left; - char *outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left) { - inbufptr = *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -static int -wcstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - wchar_t wc; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - const char *default_string = XLC_PUBLIC(lcd, default_string); - int defstr_len = strlen(default_string); - - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - - /* output default_string of XDefaultString() */ - if (*to_left < defstr_len) - break; - if (outbufptr) { - strncpy((char *)outbufptr, default_string, defstr_len); - outbufptr += defstr_len; - } - (*to_left) -= defstr_len; - - unconv_num++; - - } else { - mb = gi_to_mb(glyph_index, codeset); - - if (check_string_encoding(codeset)) { - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - } else { - unconv_num++; - } - } - - } /* end of while */ - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = stdc_wcstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = mbstostr(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -wctocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - wchar_t wc; - unsigned long glyph_index; - - int char_len; - int unconv_num = 0; - XlcSide side; - - CodeSet codeset; - XlcCharSet charset = NULL; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - if (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - unconv_num = 1; - goto end; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - unconv_num = 1; - goto end; - } - - if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { - unconv_num = 1; - goto end; - } - char_len = charset->char_size; - side = charset->side; - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < char_len) { - unconv_num++; - goto end; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, char_len, side); - outbufptr += char_len; - } - - (*to_left) -= char_len; - - } - -end: - - /* error end */ - if (unconv_num) { - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - return -1; - } - - /* nomal end */ - *from = (XPointer) inbufptr; - *to = (XPointer) outbufptr; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -stdc_wctocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - wchar_t wch; - XPointer tmp_from, save_from = *from; - char tmp[32]; - int length, ret, src_left = *from_left; - int from_size = *from_left; - - if (src_left > 0 && *to_left > 0) { - if ((wch = *src)) { - length = wctomb(tmp, wch); - } else { - goto end; - } - - if (length < 0) - goto end; - - tmp_from = (XPointer) tmp; - ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); - if (ret < 0) - goto end; - - src++; - src_left--; - } - -end: - /* error end */ - if (save_from == (XPointer) src) { - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - return -1; - } - - /* nomal end */ - *from = (XPointer) src; - *from_left = src_left; - - return 0; -} - -static int -wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const wchar_t *inbufptr; - int in_left; - XPointer outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left) { - inbufptr = (const wchar_t *) *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -#ifdef STDCVT - -static int -stdc_wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const wchar_t *inbufptr; - int in_left; - XPointer outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left ) { - inbufptr = (const wchar_t *) *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -#endif - -static int -ctstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = ctstowcs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstombs_org(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -cstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = cstowcs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstombs_org(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -strtombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - unsigned char ch; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if (isleftside(ch)) { - glyph_index = ch; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); - } else { - glyph_index = ch & GL; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); - } - - if (!codeset) { - unconv_num++; - continue; - } - - mb = gi_to_mb(glyph_index, codeset); - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - - } /* end of while */ - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -strtowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index; - wchar_t wc; - - int unconv_num = 0; - CodeSet codeset; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *)*to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if (isleftside(ch)) { - glyph_index = ch; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); - } else { - glyph_index = ch & GL; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); - } - - if (!codeset) { - unconv_num++; - continue; - } - - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - - } /* end of while */ - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_strtowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = strtombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -/* -------------------------------------------------------------------------- */ -/* Close */ -/* -------------------------------------------------------------------------- */ - -static void -close_converter( - XlcConv conv) -{ - if (conv->state) { - Xfree((char *) conv->state); - } - - if (conv->methods) { - Xfree((char *) conv->methods); - } - - Xfree((char *) conv); -} - -/* -------------------------------------------------------------------------- */ -/* Open */ -/* -------------------------------------------------------------------------- */ - -static XlcConv -create_conv( - XLCd lcd, - XlcConvMethods methods) -{ - XlcConv conv; - State state; - - conv = (XlcConv) Xcalloc(1, sizeof(XlcConvRec)); - if (conv == NULL) - return (XlcConv) NULL; - - conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); - if (conv->methods == NULL) - goto err; - *conv->methods = *methods; - conv->methods->reset = init_state; - - conv->state = Xcalloc(1, sizeof(StateRec)); - if (conv->state == NULL) - goto err; - - state = (State) conv->state; - state->lcd = lcd; - - _XlcResetConverter(conv); - - return conv; - -err: - close_converter(conv); - - return (XlcConv) NULL; -} - -static XlcConvMethodsRec mbstocts_methods = { - close_converter, - mbstocts, - NULL -}; - -static XlcConv -open_mbstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocts_methods); -} - -static XlcConvMethodsRec mbstostr_methods = { - close_converter, - mbstostr, - NULL -}; - -static XlcConv -open_mbstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstostr_methods); -} - -static XlcConvMethodsRec mbstocs_methods = { - close_converter, - mbstocs, - NULL -}; - -static XlcConv -open_mbstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocs_methods); -} - -static XlcConvMethodsRec mbtocs_methods = { - close_converter, - mbtocs, - NULL -}; - -static XlcConv -open_mbtocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbtocs_methods); -} - -static XlcConvMethodsRec ctstombs_methods = { - close_converter, - ctstombs, - NULL -}; - -static XlcConv -open_ctstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &ctstombs_methods); -} - -static XlcConvMethodsRec cstombs_methods = { - close_converter, - cstombs, - NULL -}; - -static XlcConv -open_cstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstombs_methods); -} - -static XlcConvMethodsRec strtombs_methods = { - close_converter, - strtombs, - NULL -}; - -static XlcConv -open_strtombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &strtombs_methods); -} - -#ifdef STDCVT - -static XlcConvMethodsRec stdc_mbstowcs_methods = { - close_converter, - stdc_mbstowcs, - NULL -}; - -static XlcConv -open_stdc_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_mbstowcs_methods); -} - -static XlcConvMethodsRec stdc_wcstombs_methods = { - close_converter, - stdc_wcstombs, - NULL -}; - -static XlcConv -open_stdc_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstombs_methods); -} - -static XlcConvMethodsRec stdc_wcstocts_methods = { - close_converter, - stdc_wcstocts, - NULL -}; - -static XlcConv -open_stdc_wcstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocts_methods); -} - -static XlcConvMethodsRec stdc_wcstostr_methods = { - close_converter, - stdc_wcstostr, - NULL -}; - -static XlcConv -open_stdc_wcstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstostr_methods); -} - -static XlcConvMethodsRec stdc_wcstocs_methods = { - close_converter, - stdc_wcstocs, - NULL -}; - -static XlcConv -open_stdc_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocs_methods); -} - -static XlcConvMethodsRec stdc_wctocs_methods = { - close_converter, - stdc_wctocs, - NULL -}; - -static XlcConv -open_stdc_wctocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wctocs_methods); -} - -static XlcConvMethodsRec stdc_ctstowcs_methods = { - close_converter, - stdc_ctstowcs, - NULL -}; - -static XlcConv -open_stdc_ctstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_ctstowcs_methods); -} - -static XlcConvMethodsRec stdc_cstowcs_methods = { - close_converter, - stdc_cstowcs, - NULL -}; - -static XlcConv -open_stdc_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_cstowcs_methods); -} - -static XlcConvMethodsRec stdc_strtowcs_methods = { - close_converter, - stdc_strtowcs, - NULL -}; - -static XlcConv -open_stdc_strtowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_strtowcs_methods); -} - -#endif /* STDCVT */ - -static XlcConvMethodsRec mbstowcs_methods = { - close_converter, - mbstowcs_org, - NULL -}; - -static XlcConv -open_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstowcs_methods); -} - -static XlcConvMethodsRec wcstombs_methods = { - close_converter, - wcstombs_org, - NULL -}; - -static XlcConv -open_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstombs_methods); -} - -static XlcConvMethodsRec wcstocts_methods = { - close_converter, - wcstocts, - NULL -}; - -static XlcConv -open_wcstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocts_methods); -} - -static XlcConvMethodsRec wcstostr_methods = { - close_converter, - wcstostr, - NULL -}; - -static XlcConv -open_wcstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstostr_methods); -} - -static XlcConvMethodsRec wcstocs_methods = { - close_converter, - wcstocs, - NULL -}; - -static XlcConv -open_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocs_methods); -} - -static XlcConvMethodsRec wctocs_methods = { - close_converter, - wctocs, - NULL -}; - -static XlcConv -open_wctocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wctocs_methods); -} - -static XlcConvMethodsRec ctstowcs_methods = { - close_converter, - ctstowcs, - NULL -}; - -static XlcConv -open_ctstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &ctstowcs_methods); -} - -static XlcConvMethodsRec cstowcs_methods = { - close_converter, - cstowcs, - NULL -}; - -static XlcConv -open_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstowcs_methods); -} - -static XlcConvMethodsRec strtowcs_methods = { - close_converter, - strtowcs, - NULL -}; - -static XlcConv -open_strtowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &strtowcs_methods); -} - -/* -------------------------------------------------------------------------- */ -/* Loader */ -/* -------------------------------------------------------------------------- */ - -XLCd -_XlcGenericLoader( - const char *name) -{ - XLCd lcd; -#ifdef STDCVT - XLCdGenericPart *gen; -#endif - - lcd = _XlcCreateLC(name, _XlcGenericMethods); - - if (lcd == NULL) - return lcd; - - default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); - default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); - - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); - -#ifdef STDCVT - gen = XLC_GENERIC_PART(lcd); - - if (gen->use_stdc_env != True) { -#endif - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); -#ifdef STDCVT - } -#endif - -#ifdef STDCVT - if (gen->use_stdc_env == True) { - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); - } -#endif - - _XlcAddUtf8Converters(lcd); - - return lcd; -} +/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+/*
+ * (c) Copyright 1995 FUJITSU LIMITED
+ * This is source code modified by FUJITSU LIMITED under the Joint
+ * Development Agreement for the CDE/Motif PST.
+ *
+ * Modifier: Masayoshi Shimamura FUJITSU LIMITED
+ *
+ */
+/*
+ * 2000
+ * Modifier: Ivan Pascal The XFree86 Project
+ */
+
+/*
+ * A generic locale loader for all kinds of ISO-2022 based codesets.
+ * Supports: all locales.
+ * How: Provides generic converters for ISO-2022 based codesets. Extensible as
+ * far as ISO-2022 is extensible: codesets can be given by name in the
+ * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff).
+ * In every chunk between escape sequences, the number of bytes per
+ * character (char_size) is constant.
+ * Platforms: all systems.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+#include <stdio.h>
+
+#if !defined(Lynx_22) && !defined(X_LOCALE)
+#define STDCVT
+#endif
+
+typedef struct _CTDataRec {
+ const char *name;
+ const char *encoding; /* Compound Text encoding */
+} CTDataRec, *CTData;
+
+static CTDataRec directionality_data[] =
+{
+ { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" },
+ { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" },
+ { "END_OF_STRING", "\233]" },
+};
+
+typedef struct _StateRec {
+ XLCd lcd;
+ /* CT state */
+ XlcCharSet charset; /* charset of current state */
+ XlcCharSet GL_charset; /* charset of initial state in GL */
+ XlcCharSet GR_charset; /* charset of initial state in GR */
+ /* MB shift state */
+ CodeSet GL_codeset;
+ CodeSet GR_codeset;
+} StateRec, *State;
+
+#define GR 0x80 /* begins right-side (non-ascii) region */
+#define GL 0x7f /* ends left-side (ascii) region */
+#define ESC 0x1b
+#define CSI 0x9b
+#define STX 0x02
+
+#define isrightside(c) ((c) & GR)
+#define isleftside(c) (!isrightside(c))
+
+/* Forward declarations for local routines. */
+static int mbstocts (XlcConv conv, XPointer *from, int *from_left,
+ XPointer *to, int *to_left, XPointer *args, int num_args);
+static int ctstombs (XlcConv conv, XPointer *from, int *from_left,
+ XPointer *to, int *to_left, XPointer *args, int num_args);
+static int cstombs (XlcConv conv, XPointer *from, int *from_left,
+ XPointer *to, int *to_left, XPointer *args, int num_args);
+
+/* ------------------------------------------------------------------------- */
+/* Misc */
+/* ------------------------------------------------------------------------- */
+
+static int
+compare(
+ const char *src,
+ const char *encoding,
+ int length)
+{
+ const char *start = src;
+
+ while (length-- > 0) {
+ if (*src++ != *encoding++)
+ return 0;
+ if (*encoding == '\0')
+ return src - start;
+ }
+
+ return 0;
+}
+
+static unsigned long
+conv_to_dest(
+ Conversion conv,
+ unsigned long code)
+{
+ int i;
+ int conv_num = conv->conv_num;
+ FontScope convlist = conv->convlist;
+
+ for (i = 0; i < conv_num; i++) {
+ if (convlist[i].start <= code && code <= convlist[i].end) {
+ switch (convlist[i].shift_direction) {
+ case '+':
+ return(code + convlist[i].shift);
+ case '-':
+ return(code - convlist[i].shift);
+ default:
+ return(code);
+ }
+ }
+ }
+
+ return(code);
+}
+
+static unsigned long
+conv_to_source(
+ Conversion conv,
+ unsigned long code)
+{
+ int i;
+ int conv_num;
+ FontScope convlist;
+ unsigned long start_p;
+ unsigned long start_m;
+ unsigned long end_p;
+ unsigned long end_m;
+
+ if (!conv)
+ return(code);
+
+ conv_num = conv->conv_num;
+ convlist = conv->convlist;
+
+ for (i = 0; i < conv_num; i++) {
+ switch (convlist[i].shift_direction) {
+ case '+':
+ start_p = convlist[i].start + convlist[i].shift;
+ end_p = convlist[i].end + convlist[i].shift;
+ if (start_p <= code && code <= end_p)
+ return(code - convlist[i].shift);
+ break;
+ case '-':
+ start_m = convlist[i].start - convlist[i].shift;
+ end_m = convlist[i].end - convlist[i].shift;
+ if (start_m <= code && code <= end_m)
+ return(code + convlist[i].shift);
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return(code);
+}
+
+static unsigned long
+mb_to_gi(
+ unsigned long mb,
+ CodeSet codeset)
+{
+ int i;
+ unsigned long mb_tmp, mask = 0;
+
+ if (codeset->mbconv) {
+ mb_tmp = conv_to_dest(codeset->mbconv, mb);
+ if (mb_tmp != mb)
+ return(mb_tmp);
+ }
+
+ if (codeset->side == XlcC0 || codeset->side == XlcGL ||
+ codeset->side == XlcC1 || codeset->side == XlcGR) {
+
+ for (i = 0; i < codeset->length; i++)
+ mask = (mask << 8) | GL;
+ mb = mb & mask;
+ }
+
+ return(mb);
+}
+
+static unsigned long
+gi_to_mb(
+ unsigned long glyph_index,
+ CodeSet codeset)
+{
+ int i;
+ unsigned long mask = 0;
+
+ if (codeset->side == XlcC1 || codeset->side == XlcGR) {
+ for (i = 0; i < codeset->length; i++)
+ mask = (mask << 8) | GR;
+ glyph_index = glyph_index | mask;
+ }
+
+ if (codeset->mbconv)
+ return( conv_to_source(codeset->mbconv, glyph_index) );
+
+ return(glyph_index);
+}
+
+static Bool
+gi_to_wc(
+ XLCd lcd,
+ unsigned long glyph_index,
+ CodeSet codeset,
+ wchar_t *wc)
+{
+ unsigned char mask = 0;
+ unsigned long wc_encoding = codeset->wc_encoding;
+ int length = codeset->length;
+ unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
+
+ mask = (1 << wc_shift_bits) - 1 ;
+
+ for (*wc = 0, length--; length >= 0; length--)
+ *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask);
+
+ *wc = *wc | wc_encoding;
+
+ return(True);
+}
+
+static Bool
+wc_to_gi(
+ XLCd lcd,
+ wchar_t wc,
+ unsigned long *glyph_index,
+ CodeSet *codeset)
+{
+ int i;
+ unsigned char mask = 0;
+ unsigned long wc_encoding;
+ unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
+ unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
+ int codeset_num = XLC_GENERIC(lcd, codeset_num);
+ CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+
+ wc_encoding = wc & wc_encode_mask;
+ for (*codeset = NULL, i = 0; i < codeset_num; i++) {
+ if (wc_encoding == codeset_list[i]->wc_encoding) {
+ *codeset = codeset_list[i];
+ break;
+ }
+ }
+ if (*codeset == NULL)
+ return(False);
+
+ mask = (1 << wc_shift_bits) - 1 ;
+
+ wc = wc & ~wc_encode_mask;
+ for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--)
+ *glyph_index = (*glyph_index << 8) |
+ ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask );
+
+ return(True);
+}
+
+static CodeSet
+mb_parse_codeset(
+ State state,
+ int num,
+ const char **inbufptr,
+ int *from_left)
+{
+ int len;
+ int from_len = (*from_left) + 1;
+ const char *src = (*inbufptr) - 1;
+ ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list);
+ ParseInfo parse_info;
+ CodeSet codeset;
+
+ for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) {
+ len = compare(src, parse_info->encoding, from_len);
+ if (len > 0) {
+ codeset = parse_info->codeset;
+ if (parse_info->type == E_LSL)
+ state->GL_codeset = codeset;
+ else if (parse_info->type == E_LSR)
+ state->GR_codeset = codeset;
+ --len;
+ *inbufptr += len;
+ *from_left -= len;
+ return codeset;
+ }
+ }
+ return (CodeSet) NULL;
+}
+
+static CodeSet
+byteM_parse_codeset(
+ XLCd lcd,
+ const char *inbufptr)
+{
+ unsigned char ch;
+ CodeSet codeset;
+ ByteInfoList byteM;
+ ByteInfoListRec byteM_rec;
+ ByteInfo byteinfo;
+ ByteInfoRec byteinfo_rec;
+ Bool hit = False;
+ int i, j, k;
+
+ int codeset_num = XLC_GENERIC(lcd, codeset_num);
+ CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+
+ for (i = 0; i < codeset_num; i++) {
+ codeset = codeset_list[i];
+ byteM = codeset->byteM;
+ if (codeset->side != XlcNONE || byteM == NULL)
+ continue;
+
+ for (j = 0; j < codeset->length; j++) {
+ ch = *((unsigned char *)(inbufptr + j));
+ byteM_rec = byteM[j];
+ byteinfo = byteM_rec.byteinfo;
+
+ for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) {
+ byteinfo_rec = byteinfo[k];
+ if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) {
+ hit = True;
+ break;
+ }
+ }
+
+ if (!hit)
+ break;
+ }
+
+ if (hit)
+ return(codeset);
+ }
+
+ return(NULL);
+}
+
+#define GLGR_parse_codeset(ch) \
+ (isrightside(ch) ? (state->GR_codeset) : \
+ (state->GL_codeset) )
+
+static XlcCharSet
+gi_parse_charset(
+ unsigned long glyph_index,
+ CodeSet codeset)
+{
+ int i;
+ XlcCharSet *charset_list = codeset->charset_list;
+ int num_charsets = codeset->num_charsets;
+ ExtdSegment ctextseg = codeset->ctextseg;
+ XlcCharSet charset = NULL;
+ int area_num;
+ FontScope area;
+
+ /* lockup ct sequence */
+ for (i = 0; i < num_charsets; i++) {
+ charset = charset_list[i];
+ if (*charset->ct_sequence != '\0')
+ break;
+ }
+ if (i >= num_charsets)
+ return(NULL);
+
+ if (charset->source != CSsrcStd)
+ return (charset);
+
+ if (!ctextseg)
+ return(charset);
+
+ area = ctextseg->area;
+ area_num = ctextseg->area_num;
+
+ for (i = 0; i < area_num; i++) {
+
+ if (area[i].start <= glyph_index && glyph_index <= area[i].end) {
+
+ charset = ctextseg->charset;
+
+ if (*charset->ct_sequence == '\0')
+ return(NULL);
+
+ break;
+ }
+ }
+
+ return(charset);
+}
+
+static Bool
+ct_parse_csi(
+ const char *inbufptr,
+ int *ctr_seq_len)
+{
+ int i;
+ int num = sizeof(directionality_data) / sizeof(directionality_data[0]);
+
+ for (i = 0; i < num; i++) {
+ if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) )
+ continue;
+
+ if ( strncmp(inbufptr, directionality_data[i].encoding,
+ *ctr_seq_len) == 0)
+ return(True);
+ }
+
+ return(False);
+}
+
+static int
+cmp_esc_sequence(
+ const char *inbufptr,
+ XlcCharSet charset)
+{
+ int seq_len, name_len, total_len;
+ unsigned char byte_m, byte_l;
+ const char *ct_sequence = charset->ct_sequence;
+ const char *encoding_name = charset->encoding_name;
+
+ /* check esc sequence */
+ if ( !(seq_len = strlen(ct_sequence) ) )
+ return(0);
+ if ( strncmp(inbufptr, ct_sequence, seq_len) != 0)
+ return(0);
+
+ /* Standard Character Set Encoding ? */
+ if (charset->source == CSsrcStd)
+ return(seq_len);
+
+ /*
+ * Non-Standard Character Set Encoding
+ *
+ * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+
+ * | ctseq | M | L | encoding name | STX | contents |
+ * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+
+ * 4bytes 1byte 1byte variable length 1byte variable length
+ * | |
+ * +----------------------------------------------+
+ * rest length = ((M - 128) * 128) + (L - 128)
+ */
+
+ /* get length of encoding name */
+ inbufptr += seq_len;
+ byte_m = *inbufptr++;
+ byte_l = *inbufptr++;
+ name_len = strlen(encoding_name);
+
+ if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len)
+ return(0);
+
+ if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 )
+ return(0);
+
+ /* check STX (Start of Text) */
+ inbufptr = inbufptr + name_len;
+ if ( *inbufptr != STX )
+ return(0);
+
+ total_len = seq_len + name_len + 3;
+ return(total_len);
+}
+
+static Bool
+ct_parse_charset(
+ XLCd lcd,
+ const char *inbufptr,
+ XlcCharSet *charset,
+ int *ctr_seq_len)
+{
+ int i, j;
+ ExtdSegment ctextseg;
+ int num_charsets;
+ XlcCharSet *charset_list;
+ CodeSet codeset;
+ int codeset_num = XLC_GENERIC(lcd, codeset_num);
+ CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+ int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num);
+ SegConv segment_conv = XLC_GENERIC(lcd, segment_conv);
+
+ /* get charset from XLC_XLOCALE by escape sequence */
+
+ for (i = 0; i < codeset_num; i++) {
+ codeset = codeset_list[i];
+
+ num_charsets = codeset->num_charsets;
+ charset_list = codeset->charset_list;
+ ctextseg = codeset->ctextseg;
+
+ for (j = 0; j < num_charsets; j++) {
+ *charset = charset_list[j];
+ if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+ return(True);
+ }
+
+ if (ctextseg) {
+ *charset = ctextseg->charset;
+ if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+ return(True);
+ }
+ }
+
+ /* get charset from XLC_SEGMENTCONVERSION by escape sequence */
+
+ if (!segment_conv)
+ return(False);
+
+ for (i = 0; i < segment_conv_num; i++) {
+ *charset = segment_conv[i].source;
+ if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+ return(True);
+ *charset = segment_conv[i].dest;
+ if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
+ return(True);
+ }
+
+ return(False);
+}
+
+static Bool
+segment_conversion(
+ XLCd lcd,
+ XlcCharSet *charset,
+ unsigned long *glyph_index)
+{
+ int i;
+ int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num);
+ SegConv segment_conv = XLC_GENERIC(lcd, segment_conv);
+ FontScopeRec range;
+ ConversionRec conv_rec;
+
+ if (!segment_conv)
+ return(True);
+
+ for (i = 0; i < segment_conv_num; i++) {
+ if (segment_conv[i].source == *charset)
+ break;
+ }
+
+ if (i >= segment_conv_num)
+ return(True);
+
+ range = segment_conv[i].range;
+ if (*glyph_index < range.start || range.end < *glyph_index)
+ return(True);
+
+ *charset = segment_conv[i].dest;
+ conv_rec.conv_num = segment_conv[i].conv_num;
+ conv_rec.convlist = segment_conv[i].conv;
+ *glyph_index = conv_to_dest(&conv_rec, *glyph_index);
+
+ return(True);
+}
+
+static CodeSet
+_XlcGetCodeSetFromName(
+ XLCd lcd,
+ const char *name)
+{
+ int i, j;
+ XlcCharSet charset;
+ int num_charsets;
+ XlcCharSet *charset_list;
+ CodeSet codeset;
+
+ int codeset_num = XLC_GENERIC(lcd, codeset_num);
+ CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+
+ for (i = 0; i < codeset_num; i++) {
+ codeset = codeset_list[i];
+
+ num_charsets = codeset->num_charsets;
+ charset_list = codeset->charset_list;
+
+ for (j = 0; j < num_charsets; j++) {
+ charset = charset_list[j];
+
+ if (!strlen(charset->name))
+ continue;
+ if ( strcmp(charset->name, name) == 0)
+ return(codeset);
+ }
+ }
+
+ return(NULL);
+}
+
+static Bool
+_XlcGetCodeSetFromCharSet(
+ XLCd lcd,
+ XlcCharSet charset,
+ CodeSet *codeset,
+ unsigned long *glyph_index)
+{
+ int j, num;
+ CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
+ XlcCharSet *charset_list;
+ int codeset_num, num_charsets;
+ Conversion ctconv;
+ unsigned long glyph_index_tmp = 0;
+ ExtdSegment ctextseg;
+
+ codeset_num = XLC_GENERIC(lcd, codeset_num);
+
+ for (num = 0 ; num < codeset_num; num++) {
+ *codeset = codeset_list[num];
+ ctconv = (*codeset)->ctconv;
+ ctextseg = (*codeset)->ctextseg;
+
+ num_charsets = (*codeset)->num_charsets;
+ charset_list = (*codeset)->charset_list;
+
+ glyph_index_tmp = conv_to_source(ctconv, *glyph_index);
+
+ if (charset->source == CSsrcStd) {
+
+ /* Standard Character Set Encoding */
+ if (glyph_index_tmp == *glyph_index) {
+ for (j = 0; j < num_charsets; j++) {
+ if (charset_list[j] == charset) {
+ goto end_loop;
+ }
+ }
+ }
+
+ } else {
+
+ /* Non-Standard Character Set Encoding */
+ for (j = 0; j < num_charsets; j++) {
+ if (charset_list[j] == charset) {
+ goto end_loop;
+ }
+ }
+
+ if (glyph_index_tmp != *glyph_index) {
+ if (ctextseg && ctextseg->charset == charset) {
+ goto end_loop;
+ }
+ }
+
+ }
+
+ }
+
+end_loop:
+ if (num < codeset_num) {
+ *glyph_index = glyph_index_tmp;
+ return(True);
+ }
+
+ return(False);
+}
+
+#define check_string_encoding(codeset) (codeset->string_encoding)
+
+static void
+output_ulong_value(
+ char *outbufptr,
+ unsigned long code,
+ int length,
+ XlcSide side)
+{
+ int i;
+
+ for (i = (length - 1) * 8; i >= 0; i -= 8) {
+ *outbufptr = ( code >> i) & 0xff;
+
+ if (side == XlcC0 || side == XlcGL) {
+ *outbufptr = *outbufptr & GL;
+ } else if (side == XlcC1 || side == XlcGR) {
+ *outbufptr = *outbufptr | GR;
+ }
+
+ outbufptr++;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+/* Init */
+/* -------------------------------------------------------------------------- */
+
+static XlcCharSet default_GL_charset = 0;
+static XlcCharSet default_GR_charset = 0;
+
+static void
+init_state(
+ XlcConv conv)
+{
+ State state = (State) conv->state;
+
+ /* for CT */
+ state->charset = NULL;
+ state->GL_charset = default_GL_charset;
+ state->GR_charset = default_GR_charset;
+
+ /* for MB shift state */
+ state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL);
+ state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Convert */
+/* -------------------------------------------------------------------------- */
+
+static int
+mbstowcs_org(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long mb = 0;
+ wchar_t wc;
+
+ int length = 0, len_left = 0;
+ int unconv_num = 0;
+ int num;
+
+ CodeSet codeset = NULL;
+
+ const char *inbufptr = *from;
+ wchar_t *outbufptr = (wchar_t *) *to;
+ int from_size = *from_left;
+
+ unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+ if (from == NULL || *from == NULL) {
+ _XlcResetConverter(conv);
+ return( 0 );
+ }
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = L'\0';}
+ (*to_left)--;
+
+ /* error check */
+ if (len_left) {
+ unconv_num += (length - len_left);
+ len_left = 0;
+ }
+
+ continue;
+ }
+
+ /* same mb char data */
+ if (len_left)
+ goto output_one_wc;
+
+ /* next mb char data for single shift ? */
+ if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+ codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+ if (codeset != NULL) {
+ length = len_left = codeset->length;
+ mb = 0;
+ continue;
+ }
+ }
+
+ /* next mb char data for byteM ? */
+ if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+ goto next_mb_char;
+
+ /* next mb char data for GL or GR side ? */
+ if ((codeset = GLGR_parse_codeset(ch)))
+ goto next_mb_char;
+
+ /* can't find codeset for the ch */
+ unconv_num++;
+ continue;
+
+next_mb_char:
+ length = len_left = codeset->length;
+ mb = 0;
+
+output_one_wc:
+ mb = (mb << 8) | ch; /* 1 byte left shift */
+ len_left--;
+
+ /* last of one mb char data */
+ if (!len_left) {
+ gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc);
+ if (outbufptr) {*outbufptr++ = wc;}
+ (*to_left)--;
+ }
+
+ } /* end of while */
+
+ /* error check on last char */
+ if (len_left) {
+ inbufptr -= (length - len_left);
+ (*from_left) += (length - len_left);
+ unconv_num += (length - len_left);
+ }
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_mbstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = *((const char **) from);
+ wchar_t *dst = *((wchar_t **) to);
+ int src_left = *from_left;
+ int dst_left = *to_left;
+ int length, unconv_num = 0;
+
+ while (src_left > 0 && dst_left > 0) {
+ length = mbtowc(dst, src, src_left);
+
+ if (length > 0) {
+ src += length;
+ src_left -= length;
+ if (dst)
+ dst++;
+ dst_left--;
+ } else if (length < 0) {
+ src++;
+ src_left--;
+ unconv_num++;
+ } else {
+ /* null ? */
+ src++;
+ src_left--;
+ if (dst)
+ *dst++ = L'\0';
+ dst_left--;
+ }
+ }
+
+ *from = (XPointer) src;
+ if (dst)
+ *to = (XPointer) dst;
+ *from_left = src_left;
+ *to_left = dst_left;
+
+ return unconv_num;
+}
+
+static int
+wcstombs_org(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ char *encoding;
+ unsigned long mb, glyph_index;
+ wchar_t wc;
+
+ int length;
+ int unconv_num = 0;
+
+ CodeSet codeset;
+
+ const wchar_t *inbufptr = (const wchar_t *) *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ const char *default_string = XLC_PUBLIC(lcd, default_string);
+ int defstr_len = strlen(default_string);
+
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ wc = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!wc) {
+ if (outbufptr) {*outbufptr++ = '\0';}
+ (*to_left)--;
+
+ continue;
+ }
+
+ /* convert */
+ if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+
+ /* output default_string of XDefaultString() */
+ if (*to_left < defstr_len)
+ break;
+ if (outbufptr) {
+ strncpy((char *)outbufptr, default_string, defstr_len);
+ outbufptr += defstr_len;
+ }
+ (*to_left) -= defstr_len;
+
+ unconv_num++;
+
+ } else {
+ mb = gi_to_mb(glyph_index, codeset);
+ if (codeset->parse_info) {
+ Bool need_shift = False;
+ switch (codeset->parse_info->type) {
+ case E_LSL :
+ if (codeset != state->GL_codeset) {
+ need_shift = True;
+ state->GL_codeset = codeset;
+ }
+ break;
+ case E_LSR :
+ if (codeset != state->GR_codeset) {
+ need_shift = True;
+ state->GR_codeset = codeset;
+ }
+ break;
+ /* case E_SS */
+ default:
+ need_shift = True;
+ }
+
+ /* output shift sequence */
+ if (need_shift) {
+ encoding = codeset->parse_info->encoding;
+ length = strlen(encoding);
+ if (*to_left < length)
+ break;
+ if (outbufptr) {
+ strncpy((char *)outbufptr, encoding, length);
+ outbufptr += length;
+ }
+ (*to_left) -= length;
+ }
+ }
+
+ /* output characters */
+ length = codeset->length;
+ if (*to_left < length)
+ break;
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, mb, length, XlcNONE);
+ outbufptr += length;
+ }
+
+ (*to_left) -= length;
+ }
+
+ } /* end of while */
+
+ *from = (XPointer) ((const wchar_t *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_wcstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const wchar_t *src = *((const wchar_t **) from);
+ char *dst = *((char **) to);
+ int src_left = *from_left;
+ int dst_left = *to_left;
+ int length, unconv_num = 0;
+
+ while (src_left > 0 && dst_left >= MB_CUR_MAX) {
+ length = wctomb(dst, *src); /* XXX */
+
+ if (length > 0) {
+ src++;
+ src_left--;
+ if (dst)
+ dst += length;
+ dst_left -= length;
+ } else if (length < 0) {
+ src++;
+ src_left--;
+ unconv_num++;
+ }
+ }
+
+ *from = (XPointer) src;
+ if (dst)
+ *to = (XPointer) dst;
+ *from_left = src_left;
+ *to_left = dst_left;
+
+ return unconv_num;
+}
+
+static int
+wcstocts(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned long glyph_index;
+ wchar_t wc;
+
+ int total_len, seq_len, name_len;
+ int unconv_num = 0;
+ Bool first_flag = True, standard_flag;
+ XlcSide side;
+
+ CodeSet codeset;
+ XlcCharSet charset, old_charset = NULL;
+ const char *ct_sequence;
+
+ const wchar_t *inbufptr = (const wchar_t *) *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+ char *ext_seg_len = NULL;
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ wc = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!wc) {
+ if (outbufptr) {*outbufptr++ = '\0';}
+ (*to_left)--;
+
+ continue;
+ }
+
+ /* convert */
+ if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+ unconv_num++;
+ continue;
+ }
+
+ /* parse charset */
+ if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
+ unconv_num++;
+ continue;
+ }
+
+ /* Standard Character Set Encoding ? */
+ standard_flag = charset->source == CSsrcStd ? True : False;
+
+ /*
+ * Non-Standard Character Set Encoding
+ *
+ * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+
+ * | esc sequence | M | L | encoding name | STX |
+ * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+
+ * 4bytes 1byte 1byte variable length 1byte
+ * | |
+ * +-----------------------------------------+
+ * name length = ((M - 128) * 128) + (L - 128)
+ */
+
+ /* make encoding data */
+ ct_sequence = charset->ct_sequence;
+ side = charset->side;
+ seq_len = strlen(ct_sequence);
+ if (standard_flag) {
+ name_len = 0;
+ total_len = seq_len;
+ } else {
+ name_len = strlen(charset->encoding_name) + 1;
+ total_len = seq_len + name_len + 2;
+ }
+
+ /* output escape sequence of CT */
+ if ( (charset != old_charset) &&
+ !(first_flag && charset->string_encoding) ){
+
+ if ( (ext_seg_len != NULL) && outbufptr) {
+ int i = (outbufptr - ext_seg_len) - 2;
+ *ext_seg_len++ = i / 128 + 128;
+ *ext_seg_len = i % 128 + 128;
+ ext_seg_len = NULL;
+ }
+
+ if (*to_left < total_len + 1) {
+ unconv_num++;
+ break;
+ }
+
+ if (outbufptr) {
+ strcpy((char *)outbufptr, ct_sequence);
+ outbufptr += seq_len;
+
+ if (!standard_flag) {
+ const char *i = charset->encoding_name;
+ ext_seg_len = outbufptr;
+ outbufptr += 2;
+ for (; *i ; i++)
+ *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ?
+ *i - 'A' + 'a' : *i;
+ *outbufptr++ = STX;
+ }
+ }
+
+ (*to_left) -= total_len;
+
+ first_flag = False;
+ old_charset = charset;
+ }
+
+ /* output glyph index */
+ if (codeset->ctconv)
+ glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+ if (*to_left < charset->char_size) {
+ unconv_num++;
+ break;
+ }
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, glyph_index, charset->char_size, side);
+ outbufptr += charset->char_size;
+ }
+
+ (*to_left) -= charset->char_size;
+
+ } /* end of while */
+
+ if ( (ext_seg_len != NULL) && outbufptr) {
+ int i = (outbufptr - ext_seg_len) - 2;
+ *ext_seg_len++ = i / 128 + 128;
+ *ext_seg_len = i % 128 + 128;
+ }
+
+ *from = (XPointer) ((const wchar_t *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_wcstocts(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left) * MB_CUR_MAX;
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = stdc_wcstombs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = buf_ptr1 - buf_ptr2;
+
+ unconv_num2 = mbstocts(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+ctstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long glyph_index = 0;
+ wchar_t wc;
+
+ int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0;
+ int unconv_num = 0;
+
+ CodeSet codeset = NULL;
+ XlcCharSet charset_tmp;
+
+ const char *inbufptr = *from;
+ wchar_t *outbufptr = (wchar_t *) *to;
+ int from_size = *from_left;
+
+ _XlcResetConverter(conv); /* ??? */
+
+ if (from == NULL || *from == NULL) {
+ _XlcResetConverter(conv);
+ return( 0 );
+ }
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = L'\0';}
+ (*to_left)--;
+
+ /* error check */
+ if (gi_len_left) {
+ unconv_num += (gi_len - gi_len_left);
+ gi_len_left = 0;
+ }
+
+ continue;
+ }
+
+ /* same glyph_index data */
+ if (gi_len_left)
+ goto output_one_wc;
+
+ /* control sequence ? */
+ if (ch == CSI) {
+ if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) )
+ goto skip_the_seg;
+
+ if (*from_left + 1 < ctr_seq_len) {
+ inbufptr--;
+ (*from_left)++;
+ unconv_num += *from_left;
+ break;
+ }
+
+ /* skip the control sequence */
+ inbufptr += (ctr_seq_len - 1);
+ *from_left -= (ctr_seq_len - 1);
+
+ continue;
+ }
+
+ /* escape sequence ? */
+ if (ch == ESC) {
+ if ( !ct_parse_charset(lcd,
+ inbufptr - 1, &state->charset, &ctr_seq_len) )
+ goto skip_the_seg;
+
+ if (state->charset->side == XlcC0 ||
+ state->charset->side == XlcGL)
+ {
+ state->GL_charset = state->charset;
+ }
+ else if (state->charset->side == XlcC1 ||
+ state->charset->side == XlcGR)
+ {
+ state->GR_charset = state->charset;
+ }
+ else if (state->charset->side == XlcGLGR)
+ {
+ state->GL_charset = state->charset;
+ state->GR_charset = state->charset;
+ }
+
+ if (*from_left + 1 < ctr_seq_len) {
+ inbufptr--;
+ (*from_left)++;
+ unconv_num += *from_left;
+ break;
+ }
+
+ /* skip the escape sequence */
+ inbufptr += (ctr_seq_len - 1);
+ *from_left -= (ctr_seq_len - 1);
+
+ continue;
+ }
+
+ /* check current state */
+ if (isleftside(ch))
+ state->charset = state->GL_charset;
+ else
+ state->charset = state->GR_charset;
+
+ gi_len = gi_len_left = state->charset->char_size;
+ glyph_index = 0;
+
+output_one_wc:
+ if (state->charset->side == XlcC1 || state->charset->side == XlcGR)
+ glyph_index = (glyph_index << 8) | (ch & GL);
+ else
+ glyph_index = (glyph_index << 8) | ch;
+
+ gi_len_left--;
+
+ /* last of one glyph_index data */
+ if (!gi_len_left) {
+
+ /* segment conversion */
+ charset_tmp = state->charset;
+ segment_conversion(lcd, &charset_tmp, &glyph_index);
+
+ /* get codeset */
+ if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
+ &codeset, &glyph_index) ) {
+ unconv_num += gi_len;
+ continue;
+ }
+
+ /* convert glyph index to wicd char */
+ gi_to_wc(lcd, glyph_index, codeset, &wc);
+ if (outbufptr) {*outbufptr++ = wc;}
+ (*to_left)--;
+ }
+
+ continue;
+
+skip_the_seg:
+ /* skip until next escape or control sequence */
+ while ( *from_left ) {
+ ch = *inbufptr++;
+ (*from_left)--;
+ unconv_num++;
+
+ if (ch == ESC || ch == CSI) {
+ inbufptr--;
+ (*from_left)++;
+ unconv_num--;
+ break;
+ }
+ }
+
+ if ( !(*from_left) )
+ break;
+
+ } /* end of while */
+
+ /* error check on last char */
+ if (gi_len_left) {
+ inbufptr -= (gi_len - gi_len_left);
+ (*from_left) += (gi_len - gi_len_left);
+ unconv_num += (gi_len - gi_len_left);
+ }
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+cstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long glyph_index = 0;
+ wchar_t wc;
+ int gi_len_left = 0, gi_len = 0;
+
+ int unconv_num = 0;
+
+ CodeSet codeset = NULL;
+ XlcCharSet charset, charset_tmp;
+
+ const char *inbufptr = *from;
+ wchar_t *outbufptr = (wchar_t *) *to;
+ int from_size = *from_left;
+
+ if (from == NULL || *from == NULL) {
+ return( 0 );
+ }
+
+ charset = (XlcCharSet) args[0];
+
+ while (*from_left && *to_left) {
+
+ if (!gi_len_left) {
+ gi_len_left = gi_len = charset->char_size;
+ glyph_index = 0;
+ }
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = L'\0';}
+ (*to_left)--;
+
+ /* error check */
+ if (gi_len_left) {
+ unconv_num += (gi_len - gi_len_left);
+ gi_len_left = 0;
+ }
+ continue;
+ }
+
+ if (charset->side == XlcC1 || charset->side == XlcGR)
+ glyph_index = (glyph_index << 8) | (ch & GL);
+ else
+ glyph_index = (glyph_index << 8) | ch;
+
+ gi_len_left--;
+
+ /* last of one glyph_index data */
+ if (!gi_len_left) {
+
+ /* segment conversion */
+ charset_tmp = charset;
+ segment_conversion(lcd, &charset_tmp, &glyph_index);
+
+ /* get codeset */
+ if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
+ &codeset, &glyph_index) ) {
+ unconv_num += gi_len;
+ continue;
+ }
+
+ /* convert glyph index to wicd char */
+ gi_to_wc(lcd, glyph_index, codeset, &wc);
+ if (outbufptr) {*outbufptr++ = wc;}
+ (*to_left)--;
+ }
+
+ } /* end of while */
+
+ /* error check on last char */
+ if (gi_len_left) {
+ inbufptr -= (gi_len - gi_len_left);
+ (*from_left) += (gi_len - gi_len_left);
+ unconv_num += (gi_len - gi_len_left);
+ }
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_ctstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left) * MB_CUR_MAX;
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = ctstombs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = buf_ptr1 - buf_ptr2;
+
+ unconv_num2 = stdc_mbstowcs(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+stdc_cstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left) * MB_CUR_MAX;
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = cstombs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = buf_ptr1 - buf_ptr2;
+
+ unconv_num2 = stdc_mbstowcs(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+mbstocts(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left);
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = mbstowcs_org(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+ unconv_num2 += wcstocts(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+mbstostr(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long mb = 0;
+
+ int length = 0, len_left = 0;
+ int unconv_num = 0;
+ int num;
+
+ CodeSet codeset = NULL;
+
+ const char *inbufptr = *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+ if (from == NULL || *from == NULL) {
+ _XlcResetConverter(conv);
+ return( 0 );
+ }
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = '\0';}
+ (*to_left)--;
+
+ /* error check */
+ if (len_left) {
+ unconv_num += (length - len_left);
+ len_left = 0;
+ }
+
+ continue;
+ }
+
+ /* same mb char data */
+ if (len_left)
+ goto output_one_mb;
+
+ /* next mb char data for single shift ? */
+ if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+ codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+ if (codeset != NULL) {
+ length = len_left = codeset->length;
+ mb = 0;
+ continue;
+ }
+ }
+
+ /* next char data : byteM ? */
+ if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+ goto next_mb_char;
+
+ /* next char data : GL or GR side ? */
+ if ((codeset = GLGR_parse_codeset(ch)))
+ goto next_mb_char;
+
+ /* can't find codeset for the ch */
+ unconv_num++;
+ continue;
+
+next_mb_char:
+ length = len_left = codeset->length;
+ mb = 0;
+
+output_one_mb:
+ mb = (mb << 8) | ch; /* 1 byte left shift */
+ len_left--;
+
+ /* last of one mb char data */
+ if (!len_left) {
+ if (check_string_encoding(codeset)) {
+ if (outbufptr) {*outbufptr++ = mb & 0xff;}
+ (*to_left)--;
+ } else {
+ unconv_num++;
+ }
+ }
+
+ } /* end of while */
+
+ /* error check on last char */
+ if (len_left) {
+ inbufptr -= (length - len_left);
+ (*from_left) += (length - len_left);
+ unconv_num += (length - len_left);
+ }
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+mbtocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long mb = 0;
+ unsigned long glyph_index;
+
+ int length = 0, len_left = 0, char_len;
+ int unconv_num = 0;
+ int num;
+ XlcSide side;
+
+ CodeSet codeset = NULL;
+ XlcCharSet charset = NULL;
+
+ const char *inbufptr = *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+
+ if (from == NULL || *from == NULL) {
+ _XlcResetConverter(conv);
+ return( 0 );
+ }
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ unconv_num = 1;
+ if (len_left)
+ unconv_num += (length - len_left);
+ break;
+ }
+
+ /* same mb char data */
+ if (len_left)
+ goto output;
+
+ /* next mb char data for single shift ? */
+ if (mb_parse_table && (num = mb_parse_table[ch]) ) {
+ codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
+ if (codeset != NULL) {
+ length = len_left = codeset->length;
+ mb = 0;
+ continue;
+ }
+ }
+
+ /* next mb char data for byteM ? */
+ if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+ goto next_mb_char;
+
+ /* next mb char data for GL or GR side ? */
+ if ((codeset = GLGR_parse_codeset(ch)))
+ goto next_mb_char;
+
+ /* can't find codeset for the ch */
+ unconv_num = 1;
+ break;
+
+next_mb_char:
+ length = len_left = codeset->length;
+ mb = 0;
+
+output:
+ mb = (mb << 8) | ch; /* 1 byte left shift */
+ len_left--;
+
+ /* last of one mb char data */
+ if (!len_left) {
+ glyph_index = mb_to_gi(mb, codeset);
+ if (!(charset = gi_parse_charset(glyph_index, codeset))) {
+ unconv_num = length;
+ break;
+ }
+ char_len = charset->char_size;
+ side = charset->side;
+
+ /* output glyph index */
+ if (codeset->ctconv)
+ glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+ if (*to_left < char_len) {
+ unconv_num = length;
+ break;
+ }
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, glyph_index, char_len, side);
+ outbufptr += char_len;
+ }
+
+ (*to_left) -= char_len;
+
+ break;
+ }
+
+ } /* end of while */
+
+ /* error end */
+ if (unconv_num) {
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+ return -1;
+ }
+
+ /* nomal end */
+ *from = (XPointer) inbufptr;
+ *to = (XPointer) outbufptr;
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset;
+
+ return 0;
+}
+
+static int
+mbstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ int ret;
+ XlcCharSet charset_old, charset = NULL;
+ XPointer tmp_args[1];
+
+ const char *inbufptr;
+ int in_left;
+ char *outbufptr;
+ int out_left;
+ tmp_args[0] = (XPointer) &charset;
+
+ ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ charset_old = charset;
+
+ while ( ret == 0 && *from_left && *to_left) {
+ inbufptr = *from;
+ in_left = *from_left;
+ outbufptr = *to;
+ out_left = *to_left;
+ ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ if (charset_old != charset) {
+ *from = (XPointer) inbufptr;
+ *from_left = in_left;
+ *to = (XPointer) outbufptr;
+ *to_left = out_left;
+ break;
+ }
+ }
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset_old;
+
+ /* error end */
+ if (ret != 0)
+ return( -1 );
+
+ return(0);
+}
+
+static int
+wcstostr(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ char *encoding;
+ unsigned long mb, glyph_index;
+ wchar_t wc;
+
+ int length;
+ int unconv_num = 0;
+
+ CodeSet codeset;
+
+ const wchar_t *inbufptr = (const wchar_t *) *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ const char *default_string = XLC_PUBLIC(lcd, default_string);
+ int defstr_len = strlen(default_string);
+
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ wc = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!wc) {
+ if (outbufptr) {*outbufptr++ = '\0';}
+ (*to_left)--;
+
+ continue;
+ }
+
+ /* convert */
+ if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+
+ /* output default_string of XDefaultString() */
+ if (*to_left < defstr_len)
+ break;
+ if (outbufptr) {
+ strncpy((char *)outbufptr, default_string, defstr_len);
+ outbufptr += defstr_len;
+ }
+ (*to_left) -= defstr_len;
+
+ unconv_num++;
+
+ } else {
+ mb = gi_to_mb(glyph_index, codeset);
+
+ if (check_string_encoding(codeset)) {
+ if (codeset->parse_info) {
+ Bool need_shift = False;
+ switch (codeset->parse_info->type) {
+ case E_LSL :
+ if (codeset != state->GL_codeset) {
+ need_shift = True;
+ state->GL_codeset = codeset;
+ }
+ break;
+ case E_LSR :
+ if (codeset != state->GR_codeset) {
+ need_shift = True;
+ state->GR_codeset = codeset;
+ }
+ break;
+ /* case E_SS */
+ default:
+ need_shift = True;
+ }
+
+ /* output shift sequence */
+ if (need_shift) {
+ encoding = codeset->parse_info->encoding;
+ length = strlen(encoding);
+ if (*to_left < length)
+ break;
+
+ if (outbufptr) {
+ strncpy((char *)outbufptr, encoding, length);
+ outbufptr += length;
+ }
+ (*to_left) -= length;
+ }
+ }
+
+ /* output characters */
+ length = codeset->length;
+ if (*to_left < length)
+ break;
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, mb, length, XlcNONE);
+ outbufptr += length;
+ }
+
+ (*to_left) -= length;
+ } else {
+ unconv_num++;
+ }
+ }
+
+ } /* end of while */
+
+ *from = (XPointer) ((const wchar_t *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_wcstostr(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left) * MB_CUR_MAX;
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = stdc_wcstombs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = buf_ptr1 - buf_ptr2;
+
+ unconv_num2 = mbstostr(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+wctocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ wchar_t wc;
+ unsigned long glyph_index;
+
+ int char_len;
+ int unconv_num = 0;
+ XlcSide side;
+
+ CodeSet codeset;
+ XlcCharSet charset = NULL;
+
+ const wchar_t *inbufptr = (const wchar_t *) *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ if (*from_left && *to_left) {
+
+ wc = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!wc) {
+ unconv_num = 1;
+ goto end;
+ }
+
+ /* convert */
+ if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
+ unconv_num = 1;
+ goto end;
+ }
+
+ if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
+ unconv_num = 1;
+ goto end;
+ }
+ char_len = charset->char_size;
+ side = charset->side;
+
+ /* output glyph index */
+ if (codeset->ctconv)
+ glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
+ if (*to_left < char_len) {
+ unconv_num++;
+ goto end;
+ }
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, glyph_index, char_len, side);
+ outbufptr += char_len;
+ }
+
+ (*to_left) -= char_len;
+
+ }
+
+end:
+
+ /* error end */
+ if (unconv_num) {
+ *from = (XPointer) ((const wchar_t *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+ return -1;
+ }
+
+ /* nomal end */
+ *from = (XPointer) inbufptr;
+ *to = (XPointer) outbufptr;
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset;
+
+ return 0;
+}
+
+static int
+stdc_wctocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const wchar_t *src = *((const wchar_t **) from);
+ wchar_t wch;
+ XPointer tmp_from, save_from = *from;
+ char tmp[32];
+ int length, ret, src_left = *from_left;
+ int from_size = *from_left;
+
+ if (src_left > 0 && *to_left > 0) {
+ if ((wch = *src)) {
+ length = wctomb(tmp, wch);
+ } else {
+ goto end;
+ }
+
+ if (length < 0)
+ goto end;
+
+ tmp_from = (XPointer) tmp;
+ ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args);
+ if (ret < 0)
+ goto end;
+
+ src++;
+ src_left--;
+ }
+
+end:
+ /* error end */
+ if (save_from == (XPointer) src) {
+ *from = (XPointer) ((const wchar_t *) *from + from_size);
+ *from_left = 0;
+ return -1;
+ }
+
+ /* nomal end */
+ *from = (XPointer) src;
+ *from_left = src_left;
+
+ return 0;
+}
+
+static int
+wcstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ int ret;
+ XlcCharSet charset_old, charset = NULL;
+ XPointer tmp_args[1];
+
+ const wchar_t *inbufptr;
+ int in_left;
+ XPointer outbufptr;
+ int out_left;
+ tmp_args[0] = (XPointer) &charset;
+
+ ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ charset_old = charset;
+
+ while ( ret == 0 && *from_left && *to_left) {
+ inbufptr = (const wchar_t *) *from;
+ in_left = *from_left;
+ outbufptr = *to;
+ out_left = *to_left;
+ ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ if (charset_old != charset) {
+ *from = (XPointer) inbufptr;
+ *from_left = in_left;
+ *to = (XPointer) outbufptr;
+ *to_left = out_left;
+ break;
+ }
+ }
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset_old;
+
+ /* error end */
+ if (ret != 0)
+ return( -1 );
+
+ return(0);
+}
+
+#ifdef STDCVT
+
+static int
+stdc_wcstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ int ret;
+ XlcCharSet charset_old, charset = NULL;
+ XPointer tmp_args[1];
+
+ const wchar_t *inbufptr;
+ int in_left;
+ XPointer outbufptr;
+ int out_left;
+ tmp_args[0] = (XPointer) &charset;
+
+ ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ charset_old = charset;
+
+ while ( ret == 0 && *from_left && *to_left ) {
+ inbufptr = (const wchar_t *) *from;
+ in_left = *from_left;
+ outbufptr = *to;
+ out_left = *to_left;
+ ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
+ if (charset_old != charset) {
+ *from = (XPointer) inbufptr;
+ *from_left = in_left;
+ *to = (XPointer) outbufptr;
+ *to_left = out_left;
+ break;
+ }
+ }
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset_old;
+
+ /* error end */
+ if (ret != 0)
+ return( -1 );
+
+ return(0);
+}
+
+#endif
+
+static int
+ctstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left);
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = ctstowcs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+ unconv_num2 += wcstombs_org(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+cstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left);
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = cstowcs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
+
+ unconv_num2 += wcstombs_org(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+static int
+strtombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ char *encoding;
+ unsigned long mb, glyph_index;
+ unsigned char ch;
+
+ int length;
+ int unconv_num = 0;
+
+ CodeSet codeset;
+
+ const char *inbufptr = *from;
+ char *outbufptr = *to;
+ int from_size = *from_left;
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = '\0';}
+ (*to_left)--;
+
+ continue;
+ }
+
+ /* convert */
+ if (isleftside(ch)) {
+ glyph_index = ch;
+ codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
+ } else {
+ glyph_index = ch & GL;
+ codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
+ }
+
+ if (!codeset) {
+ unconv_num++;
+ continue;
+ }
+
+ mb = gi_to_mb(glyph_index, codeset);
+ if (codeset->parse_info) {
+ Bool need_shift = False;
+ switch (codeset->parse_info->type) {
+ case E_LSL :
+ if (codeset != state->GL_codeset) {
+ need_shift = True;
+ state->GL_codeset = codeset;
+ }
+ break;
+ case E_LSR :
+ if (codeset != state->GR_codeset) {
+ need_shift = True;
+ state->GR_codeset = codeset;
+ }
+ break;
+ /* case E_SS */
+ default:
+ need_shift = True;
+ }
+
+ /* output shift sequence */
+ if (need_shift) {
+ encoding = codeset->parse_info->encoding;
+ length = strlen(encoding);
+ if (*to_left < length)
+ break;
+ if (outbufptr) {
+ strncpy((char *)outbufptr, encoding, length);
+ outbufptr += length;
+ }
+ (*to_left) -= length;
+ }
+ }
+
+ /* output characters */
+ length = codeset->length;
+ if (*to_left < length)
+ break;
+
+ if (outbufptr) {
+ output_ulong_value(outbufptr, mb, length, XlcNONE);
+ outbufptr += length;
+ }
+
+ (*to_left) -= length;
+
+ } /* end of while */
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+strtowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+
+ unsigned char ch;
+ unsigned long glyph_index;
+ wchar_t wc;
+
+ int unconv_num = 0;
+ CodeSet codeset;
+
+ const char *inbufptr = *from;
+ wchar_t *outbufptr = (wchar_t *)*to;
+ int from_size = *from_left;
+
+ if (*from_left > *to_left)
+ *from_left = *to_left;
+
+ while (*from_left && *to_left) {
+
+ ch = *inbufptr++;
+ (*from_left)--;
+
+ /* null ? */
+ if (!ch) {
+ if (outbufptr) {*outbufptr++ = L'\0';}
+ (*to_left)--;
+
+ continue;
+ }
+
+ /* convert */
+ if (isleftside(ch)) {
+ glyph_index = ch;
+ codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
+ } else {
+ glyph_index = ch & GL;
+ codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
+ }
+
+ if (!codeset) {
+ unconv_num++;
+ continue;
+ }
+
+ gi_to_wc(lcd, glyph_index, codeset, &wc);
+ if (outbufptr) {*outbufptr++ = wc;}
+ (*to_left)--;
+
+ } /* end of while */
+
+ *from = (XPointer) ((const char *) *from + from_size);
+ *from_left = 0;
+ *to = (XPointer) outbufptr;
+
+ return unconv_num;
+}
+
+static int
+stdc_strtowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
+ char *buf_ptr1 = buf;
+ int buf_left1 = (*from_left) * MB_CUR_MAX;
+ char *buf_ptr2 = buf_ptr1;
+ int buf_left2;
+ int unconv_num1 = 0, unconv_num2 = 0;
+
+ unconv_num1 = strtombs(conv,
+ from, from_left, &buf_ptr1, &buf_left1, args, num_args);
+ if (unconv_num1 < 0)
+ goto ret;
+
+ buf_left2 = buf_ptr1 - buf_ptr2;
+
+ unconv_num2 = stdc_mbstowcs(conv,
+ &buf_ptr2, &buf_left2, to, to_left, args, num_args);
+ if (unconv_num2 < 0)
+ goto ret;
+
+ret:
+ if (buf)
+ Xfree((char *)buf);
+
+ return (unconv_num1 + unconv_num2);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Close */
+/* -------------------------------------------------------------------------- */
+
+static void
+close_converter(
+ XlcConv conv)
+{
+ if (conv->state) {
+ Xfree((char *) conv->state);
+ }
+
+ if (conv->methods) {
+ Xfree((char *) conv->methods);
+ }
+
+ Xfree((char *) conv);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Open */
+/* -------------------------------------------------------------------------- */
+
+static XlcConv
+create_conv(
+ XLCd lcd,
+ XlcConvMethods methods)
+{
+ XlcConv conv;
+ State state;
+
+ conv = (XlcConv) Xcalloc(1, sizeof(XlcConvRec));
+ if (conv == NULL)
+ return (XlcConv) NULL;
+
+ conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec));
+ if (conv->methods == NULL)
+ goto err;
+ *conv->methods = *methods;
+ conv->methods->reset = init_state;
+
+ conv->state = Xcalloc(1, sizeof(StateRec));
+ if (conv->state == NULL)
+ goto err;
+
+ state = (State) conv->state;
+ state->lcd = lcd;
+
+ _XlcResetConverter(conv);
+
+ return conv;
+
+err:
+ close_converter(conv);
+
+ return (XlcConv) NULL;
+}
+
+static XlcConvMethodsRec mbstocts_methods = {
+ close_converter,
+ mbstocts,
+ NULL
+};
+
+static XlcConv
+open_mbstocts(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbstocts_methods);
+}
+
+static XlcConvMethodsRec mbstostr_methods = {
+ close_converter,
+ mbstostr,
+ NULL
+};
+
+static XlcConv
+open_mbstostr(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbstostr_methods);
+}
+
+static XlcConvMethodsRec mbstocs_methods = {
+ close_converter,
+ mbstocs,
+ NULL
+};
+
+static XlcConv
+open_mbstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbstocs_methods);
+}
+
+static XlcConvMethodsRec mbtocs_methods = {
+ close_converter,
+ mbtocs,
+ NULL
+};
+
+static XlcConv
+open_mbtocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbtocs_methods);
+}
+
+static XlcConvMethodsRec ctstombs_methods = {
+ close_converter,
+ ctstombs,
+ NULL
+};
+
+static XlcConv
+open_ctstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &ctstombs_methods);
+}
+
+static XlcConvMethodsRec cstombs_methods = {
+ close_converter,
+ cstombs,
+ NULL
+};
+
+static XlcConv
+open_cstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &cstombs_methods);
+}
+
+static XlcConvMethodsRec strtombs_methods = {
+ close_converter,
+ strtombs,
+ NULL
+};
+
+static XlcConv
+open_strtombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &strtombs_methods);
+}
+
+#ifdef STDCVT
+
+static XlcConvMethodsRec stdc_mbstowcs_methods = {
+ close_converter,
+ stdc_mbstowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_mbstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_mbstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstombs_methods = {
+ close_converter,
+ stdc_wcstombs,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstombs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstocts_methods = {
+ close_converter,
+ stdc_wcstocts,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstocts(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstocts_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstostr_methods = {
+ close_converter,
+ stdc_wcstostr,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstostr(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstostr_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstocs_methods = {
+ close_converter,
+ stdc_wcstocs,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstocs_methods);
+}
+
+static XlcConvMethodsRec stdc_wctocs_methods = {
+ close_converter,
+ stdc_wctocs,
+ NULL
+};
+
+static XlcConv
+open_stdc_wctocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wctocs_methods);
+}
+
+static XlcConvMethodsRec stdc_ctstowcs_methods = {
+ close_converter,
+ stdc_ctstowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_ctstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_ctstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_cstowcs_methods = {
+ close_converter,
+ stdc_cstowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_cstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_cstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_strtowcs_methods = {
+ close_converter,
+ stdc_strtowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_strtowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_strtowcs_methods);
+}
+
+#endif /* STDCVT */
+
+static XlcConvMethodsRec mbstowcs_methods = {
+ close_converter,
+ mbstowcs_org,
+ NULL
+};
+
+static XlcConv
+open_mbstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbstowcs_methods);
+}
+
+static XlcConvMethodsRec wcstombs_methods = {
+ close_converter,
+ wcstombs_org,
+ NULL
+};
+
+static XlcConv
+open_wcstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wcstombs_methods);
+}
+
+static XlcConvMethodsRec wcstocts_methods = {
+ close_converter,
+ wcstocts,
+ NULL
+};
+
+static XlcConv
+open_wcstocts(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wcstocts_methods);
+}
+
+static XlcConvMethodsRec wcstostr_methods = {
+ close_converter,
+ wcstostr,
+ NULL
+};
+
+static XlcConv
+open_wcstostr(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wcstostr_methods);
+}
+
+static XlcConvMethodsRec wcstocs_methods = {
+ close_converter,
+ wcstocs,
+ NULL
+};
+
+static XlcConv
+open_wcstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wcstocs_methods);
+}
+
+static XlcConvMethodsRec wctocs_methods = {
+ close_converter,
+ wctocs,
+ NULL
+};
+
+static XlcConv
+open_wctocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wctocs_methods);
+}
+
+static XlcConvMethodsRec ctstowcs_methods = {
+ close_converter,
+ ctstowcs,
+ NULL
+};
+
+static XlcConv
+open_ctstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &ctstowcs_methods);
+}
+
+static XlcConvMethodsRec cstowcs_methods = {
+ close_converter,
+ cstowcs,
+ NULL
+};
+
+static XlcConv
+open_cstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &cstowcs_methods);
+}
+
+static XlcConvMethodsRec strtowcs_methods = {
+ close_converter,
+ strtowcs,
+ NULL
+};
+
+static XlcConv
+open_strtowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &strtowcs_methods);
+}
+
+/* -------------------------------------------------------------------------- */
+/* Loader */
+/* -------------------------------------------------------------------------- */
+
+XLCd
+_XlcGenericLoader(
+ const char *name)
+{
+ XLCd lcd;
+#ifdef STDCVT
+ XLCdGenericPart *gen;
+#endif
+
+ lcd = _XlcCreateLC(name, _XlcGenericMethods);
+
+ if (lcd == NULL)
+ return lcd;
+
+ default_GL_charset = _XlcGetCharSet("ISO8859-1:GL");
+ default_GR_charset = _XlcGetCharSet("ISO8859-1:GR");
+
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
+ _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
+ _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
+
+#ifdef STDCVT
+ gen = XLC_GENERIC_PART(lcd);
+
+ if (gen->use_stdc_env != True) {
+#endif
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs);
+ _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs);
+ _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
+#ifdef STDCVT
+ }
+#endif
+
+#ifdef STDCVT
+ if (gen->use_stdc_env == True) {
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs);
+ _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs);
+ _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs);
+ }
+#endif
+
+ _XlcAddUtf8Converters(lcd);
+
+ return lcd;
+}
diff --git a/libX11/modules/lc/gen/makefile b/libX11/modules/lc/gen/makefile new file mode 100644 index 000000000..8fe90a5e6 --- /dev/null +++ b/libX11/modules/lc/gen/makefile @@ -0,0 +1,6 @@ +LIBRARY = liblcGenConvLoad + +CSRCS=lcGenConv.c + +INCLUDES += ..\..\..\include\X11 ..\..\..\src\xlibi18n ..\..\..\src + diff --git a/libX11/modules/lc/xlocale/lcJis.c b/libX11/modules/lc/xlocale/lcJis.c index 551862d9b..c2ca2f560 100644 --- a/libX11/modules/lc/xlocale/lcJis.c +++ b/libX11/modules/lc/xlocale/lcJis.c @@ -1,944 +1,944 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ - -/* - * A Japanese JIS locale. - * Supports: all locales with codeset JIS7. - * How: Provides converters for JIS. - * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2). - */ - -#ifdef X_LOCALE - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "XlcGeneric.h" -#include <stdio.h> - -#if !defined(X_LOCALE) -#define STDCVT -#endif - -typedef struct _StateRec { - XLCd lcd; - XlcCharSet charset; - XlcCharSet GL_charset; - XlcCharSet GR_charset; -} StateRec, *State; - -static void -init_state( - XlcConv conv) -{ - State state = (State) conv->state; - XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd); - CodeSet codeset; - - codeset = gen->initial_state_GL; - if (codeset && codeset->charset_list) - state->GL_charset = *codeset->charset_list; - codeset = gen->initial_state_GR; - if (codeset && codeset->charset_list) - state->GR_charset = *codeset->charset_list; - - if (state->GL_charset == NULL) - if ((codeset = *gen->codeset_list) != NULL) - state->GL_charset = *codeset->charset_list; -} - -static int -compare( - const char *src, - const char *encoding, - int length) -{ - const char *start = src; - - while (length-- > 0) { - if (*src++ != *encoding++) - return 0; - if (*encoding == '\0') - return src - start; - } - - return 0; -} - -static int -mbtocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const char *src; - char *dst; - unsigned char *mb_parse_table; - ParseInfo *parse_list, parse_info; - XlcCharSet charset; - int length, number, encoding_len = 0; - int i; - - src = *((const char **) from); - dst = *((char **) to); - - mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - if (mb_parse_table != NULL) { - number = mb_parse_table[(unsigned char) *src]; - if (number > 0) { - parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1; - for ( ; (parse_info = *parse_list) != NULL; parse_list++) { - encoding_len = compare(src, parse_info->encoding, *from_left); - if (encoding_len > 0) { - switch (parse_info->type) { - case E_SS: - src += encoding_len; - charset = *parse_info->codeset->charset_list; - goto found; - case E_LSL: - case E_LSR: - src += encoding_len; - charset = *parse_info->codeset->charset_list; - if (parse_info->type == E_LSL) - state->GL_charset = charset; - else - state->GR_charset = charset; - length = 0; - goto end; - case E_GL: - charset = state->GL_charset; - goto found; - case E_GR: - charset = state->GR_charset; - goto found; - default: - break; - } - } - } - } - } - - if ((*src & 0x80) && state->GR_charset) - charset = state->GR_charset; - else - charset = state->GL_charset; - -found: - if (charset == NULL || - (num_args == 2 && (XlcCharSet) args[1] != charset)) - return -1; - - length = charset->char_size; - if (length > *from_left - encoding_len) - return -1; - - if (dst) { - if (length > *to_left) - return -1; - if (charset->side == XlcGL) { - for (i = 0; i < length; i++) - *dst++ = *src++ & 0x7f; - } else if (charset->side == XlcGR) { - for (i = 0; i < length; i++) - *dst++ = *src++ | 0x80; - } else { - for (i = 0; i < length; i++) - *dst++ = *src++; - } - *to = (XPointer) dst; - *to_left -= length; - } -end: - *from = (XPointer) src; - *from_left -= encoding_len + length; - state->charset = charset; - if (num_args == 1) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -mbstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XlcCharSet charset = NULL; - XPointer tmp_args[2], save_from = *from; - int ret, unconv_num = 0, tmp_num = 1; - - tmp_args[0] = (XPointer) &charset; - - while (*from_left > 0 && *to_left > 0) { - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num); - if (ret < 0) - break; - unconv_num += ret; - if (tmp_num == 1 && charset) { - tmp_args[1] = (XPointer) charset; - tmp_num = 2; - } - } - - if (save_from == *from) - return -1; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return unconv_num; -} - -static CodeSet -wc_parse_codeset( - XLCd lcd, - const wchar_t *wcstr) -{ - CodeSet *codeset; - unsigned long wc_encoding; - int num; - - wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask); - num = XLC_GENERIC(lcd, codeset_num); - codeset = XLC_GENERIC(lcd, codeset_list); - while (num-- > 0) { - if (wc_encoding == (*codeset)->wc_encoding) - return *codeset; - codeset++; - } - - return NULL; -} - -static int -wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const wchar_t *wcptr; - char *bufptr; - wchar_t wch; - char *tmpptr; - int length; - CodeSet codeset; - unsigned long wc_encoding; - int wcstr_len, buf_len; - - if (from == NULL || *from == NULL) - return 0; - - wcptr = *((const wchar_t **) from); - bufptr = *((char **) to); - wcstr_len = *from_left; - buf_len = *to_left; - - codeset = wc_parse_codeset(lcd, wcptr); - if (codeset == NULL) - return -1; - wc_encoding = codeset->wc_encoding; - - if (wcstr_len < buf_len / codeset->length) - buf_len = wcstr_len * codeset->length; - - for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) { - wch = *wcptr; - if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding) - break; - length = codeset->length; - buf_len -= length; - bufptr += length; - - tmpptr = bufptr - 1; - if ((*codeset->charset_list)->side == XlcGL) { - while (length--) { - *tmpptr-- = (unsigned char) (wch & 0x7f); - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } else if ((*codeset->charset_list)->side == XlcGR) { - while (length--) { - *tmpptr-- = (unsigned char) (wch | 0x80); - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } else { - while (length--) { - *tmpptr-- = (unsigned char) wch; - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = *codeset->charset_list; - - *from_left -= wcptr - *((wchar_t **) from); - *from = (XPointer) wcptr; - - *to_left -= bufptr - *((char **) to); - *to = bufptr; - - return 0; -} - -static CodeSet -GetCodeSetFromCharSet( - XLCd lcd, - XlcCharSet charset) -{ - CodeSet *codeset = XLC_GENERIC(lcd, codeset_list); - XlcCharSet *charset_list; - int codeset_num, num_charsets; - - codeset_num = XLC_GENERIC(lcd, codeset_num); - - for ( ; codeset_num-- > 0; codeset++) { - num_charsets = (*codeset)->num_charsets; - charset_list = (*codeset)->charset_list; - - for ( ; num_charsets-- > 0; charset_list++) - if (*charset_list == charset) - return *codeset; - } - - return (CodeSet) NULL; -} - -static int -cstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - const char *csptr; - char *bufptr; - int csstr_len; - int buf_len; - int num, encoding_len = 0; - CodeSet codeset; - XlcCharSet charset; - EncodingType type; - int cvt_length; - - csptr = *((const char **) from); - bufptr = *((char **) to); - csstr_len = *from_left; - buf_len = *to_left; - - if (num_args < 1) - return -1; - - charset = (XlcCharSet) args[0]; - - codeset = GetCodeSetFromCharSet(state->lcd, charset); - if (codeset == NULL) - return -1; - - cvt_length = 0; - if (codeset->parse_info) { - switch (type = codeset->parse_info->type) { - case E_SS: - encoding_len = strlen(codeset->parse_info->encoding); - break; - case E_LSL: - case E_LSR: - if (type == E_LSL) { - if (charset == state->GL_charset) - break; - } else { - if (charset == state->GR_charset) - break; - } - encoding_len = strlen(codeset->parse_info->encoding); - if (encoding_len > buf_len) - return -1; - cvt_length += encoding_len; - if (bufptr) { - strcpy(bufptr, codeset->parse_info->encoding); - bufptr += encoding_len; - } - buf_len -= encoding_len; - encoding_len = 0; - if (type == E_LSL) - state->GL_charset = charset; - else - state->GR_charset = charset; - break; - default: - break; - } - } - - csstr_len /= codeset->length; - buf_len /= codeset->length + encoding_len; - if (csstr_len < buf_len) - buf_len = csstr_len; - - cvt_length += buf_len * (encoding_len + codeset->length); - if (bufptr) { - while (buf_len--) { - if (encoding_len) { - strcpy(bufptr, codeset->parse_info->encoding); - bufptr += encoding_len; - } - num = codeset->length; - if (codeset->side == XlcGL) { - while (num--) - *bufptr++ = *csptr++ & 0x7f; - } else if (codeset->side == XlcGR) { - while (num--) - *bufptr++ = *csptr++ | 0x80; - } else { - while (num--) - *bufptr++ = *csptr++; - } - } - } - - *from_left -= csptr - *((char **) from); - *from = (XPointer) csptr; - - if (bufptr) - *to = (XPointer) bufptr; - *to_left -= cvt_length; - - return 0; -} - -static int -cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const char *csptr; - wchar_t *bufptr; - int csstr_len; - int buf_len; - wchar_t wch; - unsigned long code_mask, wc_encoding; - int num, length, wc_shift_bits; - CodeSet codeset; - - csptr = *((const char **) from); - bufptr = *((wchar_t **) to); - csstr_len = *from_left; - buf_len = *to_left; - - if (num_args < 1) - return -1; - - codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]); - if (codeset == NULL) - return -1; - - length = codeset->length; - csstr_len /= length; - if (csstr_len < buf_len) - buf_len = csstr_len; - - code_mask = ~XLC_GENERIC(lcd, wc_encode_mask); - wc_encoding = codeset->wc_encoding; - wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - - *to_left -= buf_len; - - if (bufptr) { - while (buf_len--) { - wch = (wchar_t) (*csptr++ & 0x7f); - num = length - 1; - while (num--) - wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f); - - *bufptr++ = (wch & code_mask) | wc_encoding; - } - } - - *from_left -= csptr - *((char **) from); - *from = (XPointer) csptr; - - if (bufptr) - *to = (XPointer) bufptr; - - return 0; -} - - -static void -close_converter( - XlcConv conv) -{ - if (conv->state) { - Xfree((char *) conv->state); - } - - Xfree((char *) conv); -} - -static XlcConv -create_conv( - XLCd lcd, - XlcConvMethods methods) -{ - XlcConv conv; - State state; - - conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); - if (conv == NULL) - return (XlcConv) NULL; - - conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); - if (conv->methods == NULL) - goto err; - *conv->methods = *methods; - if (XLC_PUBLIC(lcd, is_state_depend)) - conv->methods->reset = init_state; - - conv->state = Xcalloc(1, sizeof(StateRec)); - if (conv->state == NULL) - goto err; - - state = (State) conv->state; - state->lcd = lcd; - init_state(conv); - - return conv; - -err: - close_converter(conv); - - return (XlcConv) NULL; -} - -static XlcConvMethodsRec mbstocs_methods = { - close_converter, - mbstocs, - NULL -}; - -static XlcConv -open_mbstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocs_methods); -} - -static XlcConvMethodsRec wcstocs_methods = { - close_converter, - wcstocs, - NULL -}; - -static XlcConv -open_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocs_methods); -} - -static XlcConvMethodsRec mbtocs_methods = { - close_converter, - mbtocs, - NULL -}; - -static XlcConv -open_mbtocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbtocs_methods); -} - -static XlcConvMethodsRec cstombs_methods = { - close_converter, - cstombs, - NULL -}; - -static XlcConv -open_cstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstombs_methods); -} - -static XlcConvMethodsRec cstowcs_methods = { - close_converter, - cstowcs, - NULL -}; - -static XlcConv -open_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstowcs_methods); -} - -#ifdef STDCVT -static int -stdc_mbstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const char *src = *((const char **) from); - wchar_t *dst = *((wchar_t **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length; - - while (src_left > 0 && dst_left > 0) { - length = mbtowc(dst, src, src_left); - if (length < 0) - break; - - src += length; - src_left -= length; - if (dst) - dst++; - dst_left--; - - if (length == 0) { - src++; - src_left--; - break; - } - } - - if (*from_left == src_left) - return -1; - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return 0; -} - -static int -stdc_wcstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - char *dst = *((char **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length; - - while (src_left > 0 && dst_left > 0) { - length = wctomb(dst, *src); /* XXX */ - if (length < 0 || dst_left < length) - break; - - src++; - src_left--; - dst += length; - dst_left -= length; - - if (length == 0) { - dst++; - dst_left--; - break; - } - } - - if (*from_left == src_left) - return -1; - - *from = (XPointer) src; - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return 0; -} - -static int -stdc_wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - wchar_t wch; - XlcCharSet charset = NULL; - XPointer tmp_args[2], tmp_from, save_from = *from; - char tmp[32]; - int length, ret, src_left = *from_left; - int unconv_num = 0, tmp_num = 1; - - tmp_args[0] = (XPointer) &charset; - - while (src_left > 0 && *to_left > 0) { - if (wch = *src) { - length = wctomb(tmp, wch); - } else { - length = 1; - *tmp = '\0'; - } - - if (length < 0) - break; - - tmp_from = (XPointer) tmp; - ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num); - if (ret < 0) - break; - unconv_num += ret; - if (tmp_num == 1 && charset) { - tmp_args[1] = (XPointer) charset; - tmp_num = 2; - } - - src++; - src_left--; - } - - if (save_from == (XPointer) src) - return -1; - - *from = (XPointer) src; - *from_left = src_left; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return unconv_num; -} - -#define DefineLocalBuf char local_buf[BUFSIZ] -#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf) -#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) - -static int -stdc_cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XLCd lcd = ((State) conv->state)->lcd; - DefineLocalBuf; - XPointer buf, save_buf; - int length, left, ret; - - left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max); - buf = save_buf = (XPointer) AllocLocalBuf(length); - if (buf == NULL) - return -1; - - ret = cstombs(conv, from, from_left, &buf, &left, args, num_args); - if (ret < 0) - goto err; - - buf = save_buf; - length -= left; - if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0) - ret = -1; - -err: - FreeLocalBuf(save_buf); - - return ret; -} - -static XlcConvMethodsRec stdc_mbstowcs_methods = { - close_converter, - stdc_mbstowcs, - NULL -}; - -static XlcConv -open_stdc_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_mbstowcs_methods); -} - -static XlcConvMethodsRec stdc_wcstombs_methods = { - close_converter, - stdc_wcstombs, - NULL -}; - -static XlcConv -open_stdc_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstombs_methods); -} - -static XlcConvMethodsRec stdc_wcstocs_methods = { - close_converter, - stdc_wcstocs, - NULL -}; - -static XlcConv -open_stdc_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocs_methods); -} - -static XlcConvMethodsRec stdc_cstowcs_methods = { - close_converter, - stdc_cstowcs, - NULL -}; - -static XlcConv -open_stdc_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_cstowcs_methods); -} -#endif /* STDCVT */ - -XLCd -_XlcJisLoader( - const char *name) -{ - XLCd lcd; -#ifdef STDCVT - XLCdGenericPart *gen; -#endif - - lcd = _XlcCreateLC(name, _XlcGenericMethods); - if (lcd == NULL) - return lcd; - - if (!XLC_PUBLIC_PART(lcd)->codeset || - (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) { - _XlcDestroyLC(lcd); - return (XLCd) NULL; - } - - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); - -#ifdef STDCVT - gen = XLC_GENERIC_PART(lcd); - - if (gen->use_stdc_env == True) { - _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs); - _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs); - } - if (gen->force_convert_to_mb == True) { - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs); - } else { -#endif - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); -#ifdef STDCVT - } -#endif - - _XlcAddUtf8Converters(lcd); - - return lcd; -} - -#else -typedef int dummy; -#endif /* X_LOCALE */ +/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+
+/*
+ * A Japanese JIS locale.
+ * Supports: all locales with codeset JIS7.
+ * How: Provides converters for JIS.
+ * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
+ */
+
+#ifdef X_LOCALE
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+#include <stdio.h>
+
+#if !defined(X_LOCALE)
+#define STDCVT
+#endif
+
+typedef struct _StateRec {
+ XLCd lcd;
+ XlcCharSet charset;
+ XlcCharSet GL_charset;
+ XlcCharSet GR_charset;
+} StateRec, *State;
+
+static void
+init_state(
+ XlcConv conv)
+{
+ State state = (State) conv->state;
+ XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd);
+ CodeSet codeset;
+
+ codeset = gen->initial_state_GL;
+ if (codeset && codeset->charset_list)
+ state->GL_charset = *codeset->charset_list;
+ codeset = gen->initial_state_GR;
+ if (codeset && codeset->charset_list)
+ state->GR_charset = *codeset->charset_list;
+
+ if (state->GL_charset == NULL)
+ if ((codeset = *gen->codeset_list) != NULL)
+ state->GL_charset = *codeset->charset_list;
+}
+
+static int
+compare(
+ const char *src,
+ const char *encoding,
+ int length)
+{
+ const char *start = src;
+
+ while (length-- > 0) {
+ if (*src++ != *encoding++)
+ return 0;
+ if (*encoding == '\0')
+ return src - start;
+ }
+
+ return 0;
+}
+
+static int
+mbtocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+ const char *src;
+ char *dst;
+ unsigned char *mb_parse_table;
+ ParseInfo *parse_list, parse_info;
+ XlcCharSet charset;
+ int length, number, encoding_len = 0;
+ int i;
+
+ src = *((const char **) from);
+ dst = *((char **) to);
+
+ mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
+ if (mb_parse_table != NULL) {
+ number = mb_parse_table[(unsigned char) *src];
+ if (number > 0) {
+ parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1;
+ for ( ; (parse_info = *parse_list) != NULL; parse_list++) {
+ encoding_len = compare(src, parse_info->encoding, *from_left);
+ if (encoding_len > 0) {
+ switch (parse_info->type) {
+ case E_SS:
+ src += encoding_len;
+ charset = *parse_info->codeset->charset_list;
+ goto found;
+ case E_LSL:
+ case E_LSR:
+ src += encoding_len;
+ charset = *parse_info->codeset->charset_list;
+ if (parse_info->type == E_LSL)
+ state->GL_charset = charset;
+ else
+ state->GR_charset = charset;
+ length = 0;
+ goto end;
+ case E_GL:
+ charset = state->GL_charset;
+ goto found;
+ case E_GR:
+ charset = state->GR_charset;
+ goto found;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if ((*src & 0x80) && state->GR_charset)
+ charset = state->GR_charset;
+ else
+ charset = state->GL_charset;
+
+found:
+ if (charset == NULL ||
+ (num_args == 2 && (XlcCharSet) args[1] != charset))
+ return -1;
+
+ length = charset->char_size;
+ if (length > *from_left - encoding_len)
+ return -1;
+
+ if (dst) {
+ if (length > *to_left)
+ return -1;
+ if (charset->side == XlcGL) {
+ for (i = 0; i < length; i++)
+ *dst++ = *src++ & 0x7f;
+ } else if (charset->side == XlcGR) {
+ for (i = 0; i < length; i++)
+ *dst++ = *src++ | 0x80;
+ } else {
+ for (i = 0; i < length; i++)
+ *dst++ = *src++;
+ }
+ *to = (XPointer) dst;
+ *to_left -= length;
+ }
+end:
+ *from = (XPointer) src;
+ *from_left -= encoding_len + length;
+ state->charset = charset;
+ if (num_args == 1)
+ *((XlcCharSet *) args[0]) = charset;
+
+ return 0;
+}
+
+static int
+mbstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XlcCharSet charset = NULL;
+ XPointer tmp_args[2], save_from = *from;
+ int ret, unconv_num = 0, tmp_num = 1;
+
+ tmp_args[0] = (XPointer) &charset;
+
+ while (*from_left > 0 && *to_left > 0) {
+ ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num);
+ if (ret < 0)
+ break;
+ unconv_num += ret;
+ if (tmp_num == 1 && charset) {
+ tmp_args[1] = (XPointer) charset;
+ tmp_num = 2;
+ }
+ }
+
+ if (save_from == *from)
+ return -1;
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset;
+
+ return unconv_num;
+}
+
+static CodeSet
+wc_parse_codeset(
+ XLCd lcd,
+ const wchar_t *wcstr)
+{
+ CodeSet *codeset;
+ unsigned long wc_encoding;
+ int num;
+
+ wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask);
+ num = XLC_GENERIC(lcd, codeset_num);
+ codeset = XLC_GENERIC(lcd, codeset_list);
+ while (num-- > 0) {
+ if (wc_encoding == (*codeset)->wc_encoding)
+ return *codeset;
+ codeset++;
+ }
+
+ return NULL;
+}
+
+static int
+wcstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+ const wchar_t *wcptr;
+ char *bufptr;
+ wchar_t wch;
+ char *tmpptr;
+ int length;
+ CodeSet codeset;
+ unsigned long wc_encoding;
+ int wcstr_len, buf_len;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ wcptr = *((const wchar_t **) from);
+ bufptr = *((char **) to);
+ wcstr_len = *from_left;
+ buf_len = *to_left;
+
+ codeset = wc_parse_codeset(lcd, wcptr);
+ if (codeset == NULL)
+ return -1;
+ wc_encoding = codeset->wc_encoding;
+
+ if (wcstr_len < buf_len / codeset->length)
+ buf_len = wcstr_len * codeset->length;
+
+ for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
+ wch = *wcptr;
+ if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
+ break;
+ length = codeset->length;
+ buf_len -= length;
+ bufptr += length;
+
+ tmpptr = bufptr - 1;
+ if ((*codeset->charset_list)->side == XlcGL) {
+ while (length--) {
+ *tmpptr-- = (unsigned char) (wch & 0x7f);
+ wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
+ }
+ } else if ((*codeset->charset_list)->side == XlcGR) {
+ while (length--) {
+ *tmpptr-- = (unsigned char) (wch | 0x80);
+ wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
+ }
+ } else {
+ while (length--) {
+ *tmpptr-- = (unsigned char) wch;
+ wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
+ }
+ }
+ }
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = *codeset->charset_list;
+
+ *from_left -= wcptr - *((wchar_t **) from);
+ *from = (XPointer) wcptr;
+
+ *to_left -= bufptr - *((char **) to);
+ *to = bufptr;
+
+ return 0;
+}
+
+static CodeSet
+GetCodeSetFromCharSet(
+ XLCd lcd,
+ XlcCharSet charset)
+{
+ CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
+ XlcCharSet *charset_list;
+ int codeset_num, num_charsets;
+
+ codeset_num = XLC_GENERIC(lcd, codeset_num);
+
+ for ( ; codeset_num-- > 0; codeset++) {
+ num_charsets = (*codeset)->num_charsets;
+ charset_list = (*codeset)->charset_list;
+
+ for ( ; num_charsets-- > 0; charset_list++)
+ if (*charset_list == charset)
+ return *codeset;
+ }
+
+ return (CodeSet) NULL;
+}
+
+static int
+cstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ const char *csptr;
+ char *bufptr;
+ int csstr_len;
+ int buf_len;
+ int num, encoding_len = 0;
+ CodeSet codeset;
+ XlcCharSet charset;
+ EncodingType type;
+ int cvt_length;
+
+ csptr = *((const char **) from);
+ bufptr = *((char **) to);
+ csstr_len = *from_left;
+ buf_len = *to_left;
+
+ if (num_args < 1)
+ return -1;
+
+ charset = (XlcCharSet) args[0];
+
+ codeset = GetCodeSetFromCharSet(state->lcd, charset);
+ if (codeset == NULL)
+ return -1;
+
+ cvt_length = 0;
+ if (codeset->parse_info) {
+ switch (type = codeset->parse_info->type) {
+ case E_SS:
+ encoding_len = strlen(codeset->parse_info->encoding);
+ break;
+ case E_LSL:
+ case E_LSR:
+ if (type == E_LSL) {
+ if (charset == state->GL_charset)
+ break;
+ } else {
+ if (charset == state->GR_charset)
+ break;
+ }
+ encoding_len = strlen(codeset->parse_info->encoding);
+ if (encoding_len > buf_len)
+ return -1;
+ cvt_length += encoding_len;
+ if (bufptr) {
+ strcpy(bufptr, codeset->parse_info->encoding);
+ bufptr += encoding_len;
+ }
+ buf_len -= encoding_len;
+ encoding_len = 0;
+ if (type == E_LSL)
+ state->GL_charset = charset;
+ else
+ state->GR_charset = charset;
+ break;
+ default:
+ break;
+ }
+ }
+
+ csstr_len /= codeset->length;
+ buf_len /= codeset->length + encoding_len;
+ if (csstr_len < buf_len)
+ buf_len = csstr_len;
+
+ cvt_length += buf_len * (encoding_len + codeset->length);
+ if (bufptr) {
+ while (buf_len--) {
+ if (encoding_len) {
+ strcpy(bufptr, codeset->parse_info->encoding);
+ bufptr += encoding_len;
+ }
+ num = codeset->length;
+ if (codeset->side == XlcGL) {
+ while (num--)
+ *bufptr++ = *csptr++ & 0x7f;
+ } else if (codeset->side == XlcGR) {
+ while (num--)
+ *bufptr++ = *csptr++ | 0x80;
+ } else {
+ while (num--)
+ *bufptr++ = *csptr++;
+ }
+ }
+ }
+
+ *from_left -= csptr - *((char **) from);
+ *from = (XPointer) csptr;
+
+ if (bufptr)
+ *to = (XPointer) bufptr;
+ *to_left -= cvt_length;
+
+ return 0;
+}
+
+static int
+cstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ State state = (State) conv->state;
+ XLCd lcd = state->lcd;
+ const char *csptr;
+ wchar_t *bufptr;
+ int csstr_len;
+ int buf_len;
+ wchar_t wch;
+ unsigned long code_mask, wc_encoding;
+ int num, length, wc_shift_bits;
+ CodeSet codeset;
+
+ csptr = *((const char **) from);
+ bufptr = *((wchar_t **) to);
+ csstr_len = *from_left;
+ buf_len = *to_left;
+
+ if (num_args < 1)
+ return -1;
+
+ codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]);
+ if (codeset == NULL)
+ return -1;
+
+ length = codeset->length;
+ csstr_len /= length;
+ if (csstr_len < buf_len)
+ buf_len = csstr_len;
+
+ code_mask = ~XLC_GENERIC(lcd, wc_encode_mask);
+ wc_encoding = codeset->wc_encoding;
+ wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
+
+ *to_left -= buf_len;
+
+ if (bufptr) {
+ while (buf_len--) {
+ wch = (wchar_t) (*csptr++ & 0x7f);
+ num = length - 1;
+ while (num--)
+ wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f);
+
+ *bufptr++ = (wch & code_mask) | wc_encoding;
+ }
+ }
+
+ *from_left -= csptr - *((char **) from);
+ *from = (XPointer) csptr;
+
+ if (bufptr)
+ *to = (XPointer) bufptr;
+
+ return 0;
+}
+
+
+static void
+close_converter(
+ XlcConv conv)
+{
+ if (conv->state) {
+ Xfree((char *) conv->state);
+ }
+
+ Xfree((char *) conv);
+}
+
+static XlcConv
+create_conv(
+ XLCd lcd,
+ XlcConvMethods methods)
+{
+ XlcConv conv;
+ State state;
+
+ conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
+ if (conv == NULL)
+ return (XlcConv) NULL;
+
+ conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec));
+ if (conv->methods == NULL)
+ goto err;
+ *conv->methods = *methods;
+ if (XLC_PUBLIC(lcd, is_state_depend))
+ conv->methods->reset = init_state;
+
+ conv->state = Xcalloc(1, sizeof(StateRec));
+ if (conv->state == NULL)
+ goto err;
+
+ state = (State) conv->state;
+ state->lcd = lcd;
+ init_state(conv);
+
+ return conv;
+
+err:
+ close_converter(conv);
+
+ return (XlcConv) NULL;
+}
+
+static XlcConvMethodsRec mbstocs_methods = {
+ close_converter,
+ mbstocs,
+ NULL
+};
+
+static XlcConv
+open_mbstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbstocs_methods);
+}
+
+static XlcConvMethodsRec wcstocs_methods = {
+ close_converter,
+ wcstocs,
+ NULL
+};
+
+static XlcConv
+open_wcstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &wcstocs_methods);
+}
+
+static XlcConvMethodsRec mbtocs_methods = {
+ close_converter,
+ mbtocs,
+ NULL
+};
+
+static XlcConv
+open_mbtocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &mbtocs_methods);
+}
+
+static XlcConvMethodsRec cstombs_methods = {
+ close_converter,
+ cstombs,
+ NULL
+};
+
+static XlcConv
+open_cstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &cstombs_methods);
+}
+
+static XlcConvMethodsRec cstowcs_methods = {
+ close_converter,
+ cstowcs,
+ NULL
+};
+
+static XlcConv
+open_cstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &cstowcs_methods);
+}
+
+#ifdef STDCVT
+static int
+stdc_mbstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = *((const char **) from);
+ wchar_t *dst = *((wchar_t **) to);
+ int src_left = *from_left;
+ int dst_left = *to_left;
+ int length;
+
+ while (src_left > 0 && dst_left > 0) {
+ length = mbtowc(dst, src, src_left);
+ if (length < 0)
+ break;
+
+ src += length;
+ src_left -= length;
+ if (dst)
+ dst++;
+ dst_left--;
+
+ if (length == 0) {
+ src++;
+ src_left--;
+ break;
+ }
+ }
+
+ if (*from_left == src_left)
+ return -1;
+
+ *from = (XPointer) src;
+ if (dst)
+ *to = (XPointer) dst;
+ *from_left = src_left;
+ *to_left = dst_left;
+
+ return 0;
+}
+
+static int
+stdc_wcstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const wchar_t *src = *((const wchar_t **) from);
+ char *dst = *((char **) to);
+ int src_left = *from_left;
+ int dst_left = *to_left;
+ int length;
+
+ while (src_left > 0 && dst_left > 0) {
+ length = wctomb(dst, *src); /* XXX */
+ if (length < 0 || dst_left < length)
+ break;
+
+ src++;
+ src_left--;
+ dst += length;
+ dst_left -= length;
+
+ if (length == 0) {
+ dst++;
+ dst_left--;
+ break;
+ }
+ }
+
+ if (*from_left == src_left)
+ return -1;
+
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ *from_left = src_left;
+ *to_left = dst_left;
+
+ return 0;
+}
+
+static int
+stdc_wcstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const wchar_t *src = *((const wchar_t **) from);
+ wchar_t wch;
+ XlcCharSet charset = NULL;
+ XPointer tmp_args[2], tmp_from, save_from = *from;
+ char tmp[32];
+ int length, ret, src_left = *from_left;
+ int unconv_num = 0, tmp_num = 1;
+
+ tmp_args[0] = (XPointer) &charset;
+
+ while (src_left > 0 && *to_left > 0) {
+ if (wch = *src) {
+ length = wctomb(tmp, wch);
+ } else {
+ length = 1;
+ *tmp = '\0';
+ }
+
+ if (length < 0)
+ break;
+
+ tmp_from = (XPointer) tmp;
+ ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num);
+ if (ret < 0)
+ break;
+ unconv_num += ret;
+ if (tmp_num == 1 && charset) {
+ tmp_args[1] = (XPointer) charset;
+ tmp_num = 2;
+ }
+
+ src++;
+ src_left--;
+ }
+
+ if (save_from == (XPointer) src)
+ return -1;
+
+ *from = (XPointer) src;
+ *from_left = src_left;
+
+ if (num_args > 0)
+ *((XlcCharSet *) args[0]) = charset;
+
+ return unconv_num;
+}
+
+#define DefineLocalBuf char local_buf[BUFSIZ]
+#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf)
+#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr)
+
+static int
+stdc_cstowcs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ XLCd lcd = ((State) conv->state)->lcd;
+ DefineLocalBuf;
+ XPointer buf, save_buf;
+ int length, left, ret;
+
+ left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max);
+ buf = save_buf = (XPointer) AllocLocalBuf(length);
+ if (buf == NULL)
+ return -1;
+
+ ret = cstombs(conv, from, from_left, &buf, &left, args, num_args);
+ if (ret < 0)
+ goto err;
+
+ buf = save_buf;
+ length -= left;
+ if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0)
+ ret = -1;
+
+err:
+ FreeLocalBuf(save_buf);
+
+ return ret;
+}
+
+static XlcConvMethodsRec stdc_mbstowcs_methods = {
+ close_converter,
+ stdc_mbstowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_mbstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_mbstowcs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstombs_methods = {
+ close_converter,
+ stdc_wcstombs,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstombs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstombs_methods);
+}
+
+static XlcConvMethodsRec stdc_wcstocs_methods = {
+ close_converter,
+ stdc_wcstocs,
+ NULL
+};
+
+static XlcConv
+open_stdc_wcstocs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_wcstocs_methods);
+}
+
+static XlcConvMethodsRec stdc_cstowcs_methods = {
+ close_converter,
+ stdc_cstowcs,
+ NULL
+};
+
+static XlcConv
+open_stdc_cstowcs(
+ XLCd from_lcd,
+ const char *from_type,
+ XLCd to_lcd,
+ const char *to_type)
+{
+ return create_conv(from_lcd, &stdc_cstowcs_methods);
+}
+#endif /* STDCVT */
+
+XLCd
+_XlcJisLoader(
+ const char *name)
+{
+ XLCd lcd;
+#ifdef STDCVT
+ XLCdGenericPart *gen;
+#endif
+
+ lcd = _XlcCreateLC(name, _XlcGenericMethods);
+ if (lcd == NULL)
+ return lcd;
+
+ if (!XLC_PUBLIC_PART(lcd)->codeset ||
+ (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) {
+ _XlcDestroyLC(lcd);
+ return (XLCd) NULL;
+ }
+
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
+
+#ifdef STDCVT
+ gen = XLC_GENERIC_PART(lcd);
+
+ if (gen->use_stdc_env == True) {
+ _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs);
+ _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs);
+ }
+ if (gen->force_convert_to_mb == True) {
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs);
+ } else {
+#endif
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
+#ifdef STDCVT
+ }
+#endif
+
+ _XlcAddUtf8Converters(lcd);
+
+ return lcd;
+}
+
+#else
+typedef int dummy;
+#endif /* X_LOCALE */
diff --git a/libX11/modules/lc/xlocale/makefile b/libX11/modules/lc/xlocale/makefile new file mode 100644 index 000000000..9649982bd --- /dev/null +++ b/libX11/modules/lc/xlocale/makefile @@ -0,0 +1,8 @@ +LIBRARY = libxlocale + +CSRCS = \ + lcEuc.c \ + lcJis.c \ + lcSjis.c + +INCLUDES += ..\..\..\include ..\..\..\include\X11 ..\..\..\src\xlibi18n ..\..\..\src\xkb ..\..\..\src\xcms ..\..\..\src diff --git a/libX11/modules/om/generic/makefile b/libX11/modules/om/generic/makefile new file mode 100644 index 000000000..cb8e59dfe --- /dev/null +++ b/libX11/modules/om/generic/makefile @@ -0,0 +1,15 @@ +LIBRARY = libxomGeneric + +CSRCS = \ + omDefault.c \ + omGeneric.c \ + omImText.c \ + omText.c \ + omTextEsc.c \ + omTextExt.c \ + omTextPer.c \ + omXChar.c + +INCLUDES += ..\..\..\include\X11 ..\..\..\src\xlibi18n ..\..\..\src ..\..\..\src\xlibi18n + + diff --git a/libX11/modules/om/generic/omGeneric.c b/libX11/modules/om/generic/omGeneric.c index 7f02c8565..9f060cd5e 100644 --- a/libX11/modules/om/generic/omGeneric.c +++ b/libX11/modules/om/generic/omGeneric.c @@ -1,2169 +1,2170 @@ -/* #define FONTDEBUG */ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ -/* - * Copyright 1995 by FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - * - * Modifier: Takanori Tateno FUJITSU LIMITED - * - */ - -/* - * Fixed the algorithms in parse_fontname() and parse_fontdata() - * to improve the logic for determining which font should be - * returned for a given CharSet. We even added some comments - * so that you can figure out what in the heck we're doing. We - * realize this is a departure from the norm, but hey, we're - * rebels! :-) :-) - * - * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD - */ -/* - * Cleaned up mess, removed some blabla - * Egbert Eich, SuSE Linux AG - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "XomGeneric.h" -#include "XlcGeneric.h" -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#define MAXFONTS 100 -#define PIXEL_SIZE_FIELD 7 -#define POINT_SIZE_FIELD 8 -#define CHARSET_ENCODING_FIELD 14 -#define XLFD_MAX_LEN 255 - -#if 0 -extern int _XmbDefaultTextEscapement(), _XwcDefaultTextEscapement(), - _Xutf8DefaultTextEscapement(); -extern int _XmbDefaultTextExtents(), _XwcDefaultTextExtents(), - _Xutf8DefaultTextExtents(); -extern Status _XmbDefaultTextPerCharExtents(), _XwcDefaultTextPerCharExtents(), - _Xutf8DefaultTextPerCharExtents(); -extern int _XmbDefaultDrawString(), _XwcDefaultDrawString(), - _Xutf8DefaultDrawString(); -extern void _XmbDefaultDrawImageString(), _XwcDefaultDrawImageString(), - _Xutf8DefaultDrawImageString(); - -extern int _XmbGenericTextEscapement(), _XwcGenericTextEscapement(), - _Xutf8GenericTextEscapement(); -extern int _XmbGenericTextExtents(), _XwcGenericTextExtents(), - _Xutf8GenericTextExtents(); -extern Status _XmbGenericTextPerCharExtents(), _XwcGenericTextPerCharExtents(), - _Xutf8GenericTextPerCharExtents(); -extern int _XmbGenericDrawString(), _XwcGenericDrawString(), - _Xutf8GenericDrawString(); -extern void _XmbGenericDrawImageString(), _XwcGenericDrawImageString(), - _Xutf8GenericDrawImageString(); - -extern void _XlcDbg_printValue (const char *str, char **value, int num); -#endif - -/* For VW/UDC start */ - -static FontData -init_fontdata( - FontData font_data, - int font_data_count) -{ - FontData fd; - int i; - - fd = (FontData)Xmalloc(sizeof(FontDataRec) * font_data_count); - if(fd == (FontData) NULL) - return False; - - memset(fd, 0x00, sizeof(FontData) * font_data_count); - for(i = 0 ; i < font_data_count ; i++) - fd[i] = font_data[i]; - - return fd; -} - -static VRotate -init_vrotate( - FontData font_data, - int font_data_count, - int type, - CodeRange code_range, - int code_range_num) -{ - VRotate vrotate; - int i; - - if(type == VROTATE_NONE) - return (VRotate)NULL; - - vrotate = (VRotate)Xmalloc(sizeof(VRotateRec) * font_data_count); - if(vrotate == (VRotate) NULL) - return False; - - memset(vrotate, 0x00, sizeof(VRotateRec) * font_data_count); - for(i = 0 ; i < font_data_count ; i++) { - vrotate[i].charset_name = font_data[i].name; - vrotate[i].side = font_data[i].side; - if(type == VROTATE_PART) { - vrotate[i].num_cr = code_range_num; - vrotate[i].code_range = code_range; - } - } - - return vrotate; -} - -static Bool -init_fontset( - XOC oc) -{ - XOCGenericPart *gen; - FontSet font_set; - OMData data; - int count; - - count = XOM_GENERIC(oc->core.om)->data_num; - data = XOM_GENERIC(oc->core.om)->data; - - font_set = (FontSet) Xmalloc(sizeof(FontSetRec) * count); - if (font_set == NULL) - return False; - memset((char *) font_set, 0x00, sizeof(FontSetRec) * count); - - gen = XOC_GENERIC(oc); - gen->font_set_num = count; - gen->font_set = font_set; - - for ( ; count-- > 0; data++, font_set++) { - font_set->charset_count = data->charset_count; - font_set->charset_list = data->charset_list; - - if((font_set->font_data = init_fontdata(data->font_data, - data->font_data_count)) == NULL) - goto err; - font_set->font_data_count = data->font_data_count; - if((font_set->substitute = init_fontdata(data->substitute, - data->substitute_num)) == NULL) - goto err; - font_set->substitute_num = data->substitute_num; - if((font_set->vmap = init_fontdata(data->vmap, - data->vmap_num)) == NULL) - goto err; - font_set->vmap_num = data->vmap_num; - - if(data->vrotate_type != VROTATE_NONE) { - /* A vrotate member is specified primary font data */ - /* as initial value. */ - if((font_set->vrotate = init_vrotate(data->font_data, - data->font_data_count, - data->vrotate_type, - data->vrotate, - data->vrotate_num)) == NULL) - goto err; - font_set->vrotate_num = data->font_data_count; - } - } - return True; - -err: - if(font_set->font_data) - Xfree(font_set->font_data); - if(font_set->substitute) - Xfree(font_set->substitute); - if(font_set->vmap) - Xfree(font_set->vmap); - if(font_set->vrotate) - Xfree(font_set->vrotate); - if(font_set) - Xfree(font_set); - gen->font_set = (FontSet) NULL; - gen->font_set_num = 0; - return False; -} - -/* For VW/UDC end */ - -static char * -get_prop_name( - Display *dpy, - XFontStruct *fs) -{ - unsigned long fp; - - if (XGetFontProperty(fs, XA_FONT, &fp)) - return XGetAtomName(dpy, fp); - - return (char *) NULL; -} - -/* For VW/UDC start */ - -static Bool -load_fontdata( - XOC oc, - FontData font_data, - int font_data_num) -{ - Display *dpy = oc->core.om->core.display; - FontData fd = font_data; - - if(font_data == NULL) return(True); - for( ; font_data_num-- ; fd++) { - if(fd->xlfd_name != (char *) NULL && fd->font == NULL) { - fd->font = XLoadQueryFont(dpy, fd->xlfd_name); - if (fd->font == NULL){ - return False; - } - } - } - return True; -} - -static Bool -load_fontset_data( - XOC oc, - FontSet font_set) -{ - Display *dpy = oc->core.om->core.display; - - if(font_set->font_name == (char *)NULL) return False ; - - /* If font_set->font is not NULL, it contains the *best* - * match font for this FontSet. - * -- jjw/pma (HP) - */ - if(font_set->font == NULL) { - font_set->font = XLoadQueryFont(dpy, font_set->font_name); - if (font_set->font == NULL){ - return False; - } - } - return True; -} - -static Bool -load_font( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - int num = gen->font_set_num; - - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - if (load_fontset_data (oc, font_set) != True) - return False; -#ifndef TESTVERSION - if(load_fontdata(oc, font_set->font_data, - font_set->font_data_count) != True) - return False; - - if(load_fontdata(oc, font_set->substitute, - font_set->substitute_num) != True) - return False; -#endif - -/* Add 1996.05.20 */ - if( oc->core.orientation == XOMOrientation_TTB_RTL || - oc->core.orientation == XOMOrientation_TTB_LTR ){ - if (font_set->vpart_initialize == 0) { - load_fontdata(oc, font_set->vmap, font_set->vmap_num); - load_fontdata(oc, (FontData) font_set->vrotate, - font_set->vrotate_num); - font_set->vpart_initialize = 1; - } - } - - if (font_set->font->min_byte1 || font_set->font->max_byte1) - font_set->is_xchar2b = True; - else - font_set->is_xchar2b = False; - } - - return True; -} - -/* For VW/UDC end */ - -static Bool -load_font_info( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - char **fn_list; - int fn_num, num = gen->font_set_num; - - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - if (font_set->info == NULL) { - fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, - &font_set->info); - if (font_set->info == NULL) - return False; - - XFreeFontNames(fn_list); - } - } - - return True; -} - -/* For Vertical Writing start */ - -static void -check_fontset_extents( - XCharStruct *overall, - int *logical_ascent, - int *logical_descent, - XFontStruct *font) -{ - overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing); - overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing); - overall->ascent = max(overall->ascent, font->max_bounds.ascent); - overall->descent = max(overall->descent, font->max_bounds.descent); - overall->width = max(overall->width, font->max_bounds.width); - *logical_ascent = max(*logical_ascent, font->ascent); - *logical_descent = max(*logical_descent, font->descent); -} - -/* For Vertical Writing end */ - -static void -set_fontset_extents( - XOC oc) -{ - XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; - XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; - XFontStruct **font_list, *font; - XCharStruct overall; - int logical_ascent, logical_descent; - int num = oc->core.font_info.num_font; - - font_list = oc->core.font_info.font_struct_list; - font = *font_list++; - overall = font->max_bounds; - overall.lbearing = font->min_bounds.lbearing; - logical_ascent = font->ascent; - logical_descent = font->descent; - - /* For Vertical Writing start */ - - while (--num > 0) { - font = *font_list++; - check_fontset_extents(&overall, &logical_ascent, &logical_descent, - font); - } - - { - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - FontData font_data; - int font_set_num = gen->font_set_num; - int font_data_count; - - for( ; font_set_num-- ; font_set++) { - if(font_set->vmap_num > 0) { - font_data = font_set->vmap; - font_data_count = font_set->vmap_num; - for( ; font_data_count-- ; font_data++) { - if(font_data->font != NULL) { - check_fontset_extents(&overall, &logical_ascent, - &logical_descent, - font_data->font); - } - } - } - - if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) { - font_data = (FontData) font_set->vrotate; - font_data_count = font_set->vrotate_num; - for( ; font_data_count-- ; font_data++) { - if(font_data->font != NULL) { - check_fontset_extents(&overall, &logical_ascent, - &logical_descent, - font_data->font); - } - } - } - } - } - - /* For Vertical Writing start */ - - ink->x = overall.lbearing; - ink->y = -(overall.ascent); - ink->width = overall.rbearing - overall.lbearing; - ink->height = overall.ascent + overall.descent; - - logical->x = 0; - logical->y = -(logical_ascent); - logical->width = overall.width; - logical->height = logical_ascent + logical_descent; -} - -static Bool -init_core_part( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - int font_set_num; - XFontStruct **font_struct_list; - char **font_name_list, *font_name_buf; - int count, length; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - count = length = 0; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - length += strlen(font_set->font_name) + 1; - - count++; - } - if (count == 0) - return False; - - font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *) * count); - if (font_struct_list == NULL) - return False; - - font_name_list = (char **) Xmalloc(sizeof(char *) * count); - if (font_name_list == NULL) - goto err; - - font_name_buf = (char *) Xmalloc(length); - if (font_name_buf == NULL) - goto err; - - oc->core.font_info.num_font = count; - oc->core.font_info.font_name_list = font_name_list; - oc->core.font_info.font_struct_list = font_struct_list; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - - for (count = 0; font_set_num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - font_set->id = count; - if (font_set->font) - *font_struct_list++ = font_set->font; - else - *font_struct_list++ = font_set->info; - strcpy(font_name_buf, font_set->font_name); - Xfree(font_set->font_name); - *font_name_list++ = font_set->font_name = font_name_buf; - font_name_buf += strlen(font_name_buf) + 1; - - count++; - } - - set_fontset_extents(oc); - - return True; - -err: - if (font_name_list) - Xfree(font_name_list); - Xfree(font_struct_list); - - return False; -} - -static char * -get_font_name( - XOC oc, - char *pattern) -{ - char **list, *name; - int count = 0; - - list = XListFonts(oc->core.om->core.display, pattern, 1, &count); - if (list == NULL) - return NULL; - - name = strdup(*list); - - XFreeFontNames(list); - - return name; -} - -/* For VW/UDC start*/ - -static char * -get_rotate_fontname( - char *font_name) -{ - char *pattern = NULL, *ptr = NULL; - char *fields[CHARSET_ENCODING_FIELD]; - char str_pixel[32], str_point[4]; - char *rotate_font_ptr = NULL; - int pixel_size = 0; - int field_num = 0, len = 0; - - if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0 - || len > XLFD_MAX_LEN) - return NULL; - - pattern = strdup(font_name); - if(!pattern) - return NULL; - - memset(fields, 0, sizeof(char *) * 14); - ptr = pattern; - while(isspace(*ptr)) { - ptr++; - } - if(*ptr == '-') - ptr++; - - for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ; - ptr++, field_num++) { - fields[field_num] = ptr; - - if((ptr = strchr(ptr, '-'))) { - *ptr = '\0'; - } else { - field_num++; /* Count last field */ - break; - } - } - - if(field_num < CHARSET_ENCODING_FIELD) - goto free_pattern; - - /* Pixel Size field : fields[6] */ - for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) { - if(!isdigit(*ptr)) { - if(*ptr == '['){ /* 960730 */ - strcpy(pattern, font_name); - return(pattern); - } - goto free_pattern; - } - } - pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]); - sprintf(str_pixel, "[ 0 ~%d %d 0 ]", pixel_size, pixel_size); - fields[6] = str_pixel; - - /* Point Size field : fields[7] */ - strcpy(str_point, "*"); - fields[POINT_SIZE_FIELD - 1] = str_point; - - len = 0; - for (field_num = 0; field_num < CHARSET_ENCODING_FIELD && - fields[field_num]; field_num++) { - len += 1 + strlen(fields[field_num]); - } - - /* Max XLFD length is 255 */ - if (len > XLFD_MAX_LEN) - goto free_pattern; - - rotate_font_ptr = (char *)Xmalloc(len + 1); - if(!rotate_font_ptr) - goto free_pattern; - - rotate_font_ptr[0] = '\0'; - - for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && - fields[field_num] ; field_num++) { - strcat(rotate_font_ptr, "-"); - strcat(rotate_font_ptr, fields[field_num]); - } - -free_pattern: - Xfree(pattern); - - return rotate_font_ptr; -} - -static Bool -is_match_charset( - FontData font_data, - char *font_name) -{ - char *last; - int length, name_len; - - name_len = strlen(font_name); - last = font_name + name_len; - - length = strlen(font_data->name); - if (length > name_len) - return False; - - if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) - return True; - - return False; -} - -#if 0 -static char * -get_font_name_from_list( - XOC oc, - char *pattern, - FontData font_data) -{ - char **list, *name = (char *)NULL, *fname; - int count = 0, i; - - list = XListFonts(oc->core.om->core.display, pattern, MAXFONTS, &count); - if (list == NULL) - return NULL; - - for (i = 0; i < count; i++) { - fname = list[i]; - if(is_match_charset(font_data, fname) == True) { - name = strdup(fname); - break; - } - } - - XFreeFontNames(list); - - return name; -} -#endif - -static int -parse_all_name( - XOC oc, - FontData font_data, - char *pattern) -{ - -#ifdef OLDCODE - if(is_match_charset(font_data, pattern) != True) - return False; - - font_data->xlfd_name = strdup(pattern); - if(font_data->xlfd_name == NULL) - return (-1); - - return True; -#else /* OLDCODE */ - Display *dpy = oc->core.om->core.display; - char **fn_list = NULL, *prop_fname = NULL; - int list_num; - XFontStruct *fs_list; - if(is_match_charset(font_data, pattern) != True) { - /* - * pattern should not contain any wildcard (execpt '?') - * this was probably added to make this case insensitive. - */ - if ((fn_list = XListFontsWithInfo(dpy, pattern, - MAXFONTS, - &list_num, &fs_list)) == NULL) { - return False; - } - /* shouldn't we loop here ? */ - else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) { - XFreeFontInfo(fn_list, fs_list, list_num); - return False; - } - else if ((is_match_charset(font_data, prop_fname) != True)) { - XFree(prop_fname); - XFreeFontInfo(fn_list, fs_list, list_num); - return False; - } - else { - font_data->xlfd_name = prop_fname; - XFreeFontInfo(fn_list, fs_list, list_num); - return True; - } - } - - font_data->xlfd_name = strdup(pattern); - if(font_data->xlfd_name == NULL) - return (-1); - - return True; -#endif /* OLDCODE */ -} - -static int -parse_omit_name( - XOC oc, - FontData font_data, - char *pattern) -{ - char* last = (char *) NULL; - char* base_name; - char buf[XLFD_MAX_LEN + 1]; - int length = 0; - int num_fields; - /* - * If the font specified by "pattern" is expandable to be - * a member of "font_data"'s FontSet, we've found a match. - */ - if(is_match_charset(font_data, pattern) == True) { - if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) { - return True; - } - } - - length = strlen (pattern); - - if (length > XLFD_MAX_LEN) - return -1; - - strcpy(buf, pattern); - last = buf + length - 1; - - /* Replace the original encoding with the encoding for this FontSet. */ - - /* Figure out how many fields have been specified in this xlfd. */ - for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) - if (*base_name == '-') num_fields++; - - switch (num_fields) { - case 12: - /* This is the best way to have specifed the fontset. In this - * case, there is no original encoding. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-* - * To this, we'll append a dash: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - /* - * Take care of: - * -*-*-*-*-*-*-14-*-*-*-*- - */ - if (*(last) == '-') - *++last = '*'; - - *++last = '-'; - break; - case 13: - /* Got the charset, not the encoding, zap the charset In this - * case, there is no original encoding, but there is a charset. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990 - * To this, we remove the charset: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the new encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - last = strrchr (buf, '-'); - num_fields = 12; - break; - case 14: - /* Both the charset and the encoding are specified. Get rid - * of them so that we can append the new charset encoding. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0 - * To this, we'll remove the encoding and charset to get: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the new encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - last = strrchr (buf, '-'); - *last = '\0'; - last = strrchr (buf, '-'); - num_fields = 12; - break; - default: - if (*last != '-') - *++last = '-'; - break; - } - - /* At this point, "last" is pointing to the last "-" in the - * xlfd, and all xlfd's at this point take a form similar to: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * (i.e., no encoding). - * After the strcpy, we'll end up with something similar to: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - * - * If the modified font is found in the current FontSet, - * we've found a match. - */ - - last++; - - if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN) - return -1; - - strcpy(last, font_data->name); - if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) - return True; - - /* This may mot be needed anymore as XListFonts() takes care of this */ - while (num_fields < 12) { - if ((last - buf) > (XLFD_MAX_LEN - 2)) - return -1; - *last = '*'; - *(last + 1) = '-'; - strcpy(last + 2, font_data->name); - num_fields++; - last+=2; - if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) - return True; - } - - - return False; -} - - -typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType; - -static int -parse_fontdata( - XOC oc, - FontSet font_set, - FontData font_data, - int font_data_count, - char **name_list, - int name_list_count, - ClassType class, - FontDataRec *font_data_return) -{ - - char **cur_name_list = name_list; - char *font_name = (char *) NULL; - char *pattern = (char *) NULL; - int found_num = 0, ret = 0; - int count = name_list_count; - - if(name_list == NULL || count <= 0) { - return False; - } - - if(font_data == NULL || font_data_count <= 0) { - return False; - } - - /* Loop through each font encoding defined in the "font_data" FontSet. */ - for ( ; font_data_count-- > 0; font_data++) { - Bool is_found = False; - font_name = (char *) NULL; - count = name_list_count; - cur_name_list = name_list; - - /* - * Loop through each font specified by the user - * in the call to XCreateFontset(). - */ - while (count-- > 0) { - pattern = *cur_name_list++; - if (pattern == NULL || *pattern == '\0') - continue; -#ifdef FONTDEBUG - fprintf(stderr,"Font pattern: %s %s\n", - pattern,font_data->name); -#endif - - /* - * If the current font is fully specified (i.e., the - * xlfd contains no wildcards) and the font exists on - * the X Server, we have a match. - */ - if (strchr(pattern, '*') == NULL && - (font_name = get_font_name(oc, pattern))) { - /* - * Find the full xlfd name for this font. If the font is - * already in xlfd format, it is simply returned. If the - * font is an alias for another font, the xlfd of the - * aliased font is returned. - */ - ret = parse_all_name(oc, font_data, font_name); - Xfree(font_name); - - if (ret == -1) return -1; - if (ret == False) continue; - /* - * Since there was an exact match of a fully-specified font - * or a font alias, we can return now since the desired font - * was found for the current font encoding for this FontSet. - * - * Previous implementations of this algorithm would - * not return here. Instead, they continued searching - * through the font encodings for this FontSet. The side-effect - * of that behavior is you may return a "substitute" match - * instead of an "exact" match. We believe there should be a - * preference on exact matches. Therefore, as soon as we - * find one, we bail. - * - * Also, previous implementations seemed to think it was - * important to find either a primary or substitute font - * for each Font encoding in the FontSet before returning an - * acceptable font. We don't believe this is necessary. - * All the client cares about is finding a reasonable font - * for what was passed in. If we find an exact match, - * there's no reason to look any further. - * - * -- jjw/pma (HP) - */ - if (font_data_return) { - font_data_return->xlfd_name = strdup(font_data->xlfd_name); - if (!font_data_return->xlfd_name) return -1; - - font_data_return->side = font_data->side; - } -#ifdef FONTDEBUG - fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); -#endif - - return True; - } - /* - * If the font name is not fully specified - * (i.e., it has wildcards), we have more work to do. - * See the comments in parse_omit_name() - * for the list of things to do. - */ - ret = parse_omit_name(oc, font_data, pattern); - - if (ret == -1) return -1; - if (ret == False) continue; - - /* - * A font which matched the wild-carded specification was found. - * Only update the return data if a font has not yet been found. - * This maintains the convention that FontSets listed higher in - * a CodeSet in the Locale Database have higher priority than - * those FontSets listed lower in the CodeSet. In the following - * example: - * - * fs1 { - * charset HP-JIS:GR - * font JISX0208.1990-0:GL;\ - * JISX0208.1990-1:GR;\ - * JISX0208.1983-0:GL;\ - * JISX0208.1983-1:GR - * } - * - * a font found in the JISX0208.1990-0 FontSet will have a - * higher priority than a font found in the JISX0208.1983-0 - * FontSet. - */ - if (font_data_return && font_data_return->xlfd_name == NULL) { - -#ifdef FONTDEBUG - fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); -#endif - font_data_return->xlfd_name = strdup(font_data->xlfd_name); - if (!font_data_return->xlfd_name) return -1; - - font_data_return->side = font_data->side; - } - - found_num++; - is_found = True; - - break; - } - - switch(class) { - case C_PRIMARY: - if(is_found == False) { - /* - * Did not find a font for the current FontSet. Check the - * FontSet's "substitute" font for a match. If we find a - * match, we'll keep searching in hopes of finding an exact - * match later down the FontSet list. - * - * when we return and we have found a font font_data_return - * contains the first (ie. best) match no matter if this - * is a C_PRIMARY or a C_SUBSTITUTE font - */ - ret = parse_fontdata(oc, font_set, font_set->substitute, - font_set->substitute_num, name_list, - name_list_count, C_SUBSTITUTE, - font_data_return); - if (ret == -1) return -1; - if (ret == False) continue; - - found_num++; - is_found = True; - } -#ifdef TESTVERSION - else - return True; -#endif - break; - - case C_SUBSTITUTE: - case C_VMAP: - if(is_found == True) - return True; - break; - - case C_VROTATE: - if(is_found == True) { - char *rotate_name; - - if((rotate_name = get_rotate_fontname(font_data->xlfd_name)) - != NULL) { - Xfree(font_data->xlfd_name); - font_data->xlfd_name = rotate_name; - - return True; - } - Xfree(font_data->xlfd_name); - font_data->xlfd_name = NULL; - return False; - } - break; - } - } - - if(class == C_PRIMARY && found_num >= 1) - return True; - - return False; -} - - -static int -parse_vw( - XOC oc, - FontSet font_set, - char **name_list, - int count) -{ - FontData vmap = font_set->vmap; - VRotate vrotate = font_set->vrotate; - int vmap_num = font_set->vmap_num; - int vrotate_num = font_set->vrotate_num; - int ret = 0, i = 0; - - if(vmap_num > 0) { - if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list, - count, C_VMAP,NULL) == -1) - return (-1); - } - - if(vrotate_num > 0) { - ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, - name_list, count, C_VROTATE, NULL); - if(ret == -1) { - return (-1); - } else if(ret == False) { - CodeRange code_range; - int num_cr; - int sub_num = font_set->substitute_num; - - code_range = vrotate[0].code_range; /* ? */ - num_cr = vrotate[0].num_cr; /* ? */ - for(i = 0 ; i < vrotate_num ; i++) { - if(vrotate[i].xlfd_name) - Xfree(vrotate[i].xlfd_name); - } - Xfree(vrotate); - - if(sub_num > 0) { - vrotate = font_set->vrotate = (VRotate)Xmalloc - (sizeof(VRotateRec) * sub_num); - if(font_set->vrotate == (VRotate)NULL) - return (-1); - memset(font_set->vrotate, 0x00, sizeof(VRotateRec) * sub_num); - - for(i = 0 ; i < sub_num ; i++) { - vrotate[i].charset_name = font_set->substitute[i].name; - vrotate[i].side = font_set->substitute[i].side; - vrotate[i].code_range = code_range; - vrotate[i].num_cr = num_cr; - } - vrotate_num = font_set->vrotate_num = sub_num; - } else { - vrotate = font_set->vrotate = (VRotate)NULL; - } - - ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, - name_list, count, C_VROTATE, NULL); - if(ret == -1) - return (-1); - } - } - - return True; -} - -static int -parse_fontname( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - FontDataRec font_data_return; - char *base_name, **name_list; - int font_set_num = 0; - int found_num = 0; - int count = 0; - int ret; - int i; - - name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); - if (name_list == NULL) - return -1; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - - /* Loop through all of the CharSets defined in the Locale - * database for the current Locale. - */ - for( ; font_set_num-- > 0 ; font_set++) { - if(font_set->font_name) - continue; - - if(font_set->font_data_count > 0) { - - /* - * If there are a non-zero number of FontSets defined - * for this CharSet. - * Try to find a font for this CharSet. If we find an - * acceptable font, we save the information for return - * to the client. If we do not find an acceptable font, - * a "missing_charset" will be reported to the client - * for this CharSet. - */ - font_data_return. xlfd_name = NULL; - font_data_return.side = XlcUnknown; - - ret = parse_fontdata(oc, font_set, font_set->font_data, - font_set->font_data_count, - name_list, count, C_PRIMARY, - &font_data_return); - if(ret == -1) { - goto err; - } else if(ret == True) { - /* - * We can't just loop thru fontset->font_data to - * find the first (ie. best) match: parse_fontdata - * will try a substitute font if no primary one could - * be matched. It returns the required information in - * font_data_return. - */ - font_set->font_name = strdup(font_data_return.xlfd_name); - if(font_set->font_name == (char *) NULL) - goto err; - - font_set->side = font_data_return.side; - - Xfree (font_data_return.xlfd_name); - font_data_return.xlfd_name = NULL; - - if(parse_vw(oc, font_set, name_list, count) == -1) - goto err; - found_num++; - } - - } else if(font_set->substitute_num > 0) { - /* - * If there are no FontSets defined for this - * CharSet. We can only find "substitute" fonts. - */ - ret = parse_fontdata(oc, font_set, font_set->substitute, - font_set->substitute_num, - name_list, count, C_SUBSTITUTE, NULL); - if(ret == -1) { - goto err; - } else if(ret == True) { - for(i=0;i<font_set->substitute_num;i++){ - if(font_set->substitute[i].xlfd_name != NULL){ - break; - } - } - font_set->font_name = strdup(font_set->substitute[i].xlfd_name); - if(font_set->font_name == (char *) NULL) - goto err; - - font_set->side = font_set->substitute[i].side; - if(parse_vw(oc, font_set, name_list, count) == -1) - goto err; - - found_num++; - } - } - } - - base_name = strdup(oc->core.base_name_list); - if (base_name == NULL) - goto err; - - oc->core.base_name_list = base_name; - - XFreeStringList(name_list); - - return found_num; - -err: - XFreeStringList(name_list); - /* Prevent this from being freed twice */ - oc->core.base_name_list = NULL; - - return -1; -} - -/* For VW/UDC end*/ - -static Bool -set_missing_list( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - char **charset_list, *charset_buf; - int count, length, font_set_num; - int result = 1; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - count = length = 0; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->info || font_set->font) { - continue; - } - - /* Change 1996.01.23 start */ - if(font_set->font_data_count <= 0 || - font_set->font_data == (FontData)NULL) { - if(font_set->substitute_num <= 0 || - font_set->substitute == (FontData)NULL) { - if(font_set->charset_list != NULL){ - length += - strlen(font_set->charset_list[0]->encoding_name) + 1; - } else { - length += 1; - } - } else { - length += strlen(font_set->substitute->name) + 1; - } - } else { - length += strlen(font_set->font_data->name) + 1; - } - /* Change 1996.01.23 end */ - count++; - } - - if (count < 1) { - return True; - } - - charset_list = (char **) Xmalloc(sizeof(char *) * count); - if (charset_list == NULL) { - return False; - } - - charset_buf = (char *) Xmalloc(length); - if (charset_buf == NULL) { - Xfree(charset_list); - return False; - } - - oc->core.missing_list.charset_list = charset_list; - oc->core.missing_list.charset_count = count; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->info || font_set->font) { - continue; - } - - /* Change 1996.01.23 start */ - if(font_set->font_data_count <= 0 || - font_set->font_data == (FontData)NULL) { - if(font_set->substitute_num <= 0 || - font_set->substitute == (FontData)NULL) { - if(font_set->charset_list != NULL){ - strcpy(charset_buf, - font_set->charset_list[0]->encoding_name); - } else { - strcpy(charset_buf, ""); - } - result = 0; - } else { - strcpy(charset_buf, font_set->substitute->name); - } - } else { - strcpy(charset_buf, font_set->font_data->name); - } - /* Change 1996.01.23 end */ - *charset_list++ = charset_buf; - charset_buf += strlen(charset_buf) + 1; - } - - if(result == 0) { - return(False); - } - - return True; -} - -static Bool -create_fontset( - XOC oc) -{ - XOMGenericPart *gen = XOM_GENERIC(oc->core.om); - int found_num; - - if (init_fontset(oc) == False) - return False; - - found_num = parse_fontname(oc); - if (found_num <= 0) { - if (found_num == 0) - set_missing_list(oc); - return False; - } - - if (gen->on_demand_loading == True) { - if (load_font_info(oc) == False) - return False; - } else { - if (load_font(oc) == False) - return False; - } - - if (init_core_part(oc) == False) - return False; - - if (set_missing_list(oc) == False) - return False; - - return True; -} - -/* For VW/UDC start */ -static void -free_fontdataOC( - Display *dpy, - FontData font_data, - int font_data_count) -{ - for( ; font_data_count-- ; font_data++) { - if(font_data->xlfd_name){ - Xfree(font_data->xlfd_name); - font_data->xlfd_name = NULL; - } - if(font_data->font){ /* ADD 1996.01.7 */ - if(font_data->font->fid) /* Add 1996.01.23 */ - XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */ - else /* Add 1996.01.23 */ - XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */ - font_data->font = NULL; - } -/* - * font_data->name and font_data->scopes belong to the OM not OC. - * To save space this data is shared between OM and OC. We are - * not allowed to free it here. - * It has been moved to free_fontdataOM() - */ -/* - if(font_data->scopes){ - Xfree(font_data->scopes); - font_data->scopes = NULL; - } - if(font_data->name){ - Xfree(font_data->name); - font_data->name = NULL; - } -*/ - } -} - -static void destroy_fontdata( - XOCGenericPart *gen, - Display *dpy) -{ - FontSet font_set = (FontSet) NULL; - int font_set_num = 0; - - if (gen->font_set) { - font_set = gen->font_set; - font_set_num = gen->font_set_num; - for( ; font_set_num-- ; font_set++) { - if (font_set->font) { - if(font_set->font->fid) - XFreeFont(dpy,font_set->font); - else - XFreeFontInfo(NULL, font_set->font, 1); - font_set->font = NULL; - } - if(font_set->font_data) { - if (font_set->info) - XFreeFontInfo(NULL, font_set->info, 1); - free_fontdataOC(dpy, - font_set->font_data, font_set->font_data_count); - Xfree(font_set->font_data); - font_set->font_data = NULL; - } - if(font_set->substitute) { - free_fontdataOC(dpy, - font_set->substitute, font_set->substitute_num); - Xfree(font_set->substitute); - font_set->substitute = NULL; - } - if(font_set->vmap) { - free_fontdataOC(dpy, - font_set->vmap, font_set->vmap_num); - Xfree(font_set->vmap); - font_set->vmap = NULL; - } - if(font_set->vrotate) { - free_fontdataOC(dpy, - (FontData)font_set->vrotate, - font_set->vrotate_num); - Xfree(font_set->vrotate); - font_set->vrotate = NULL; - } - } - Xfree(gen->font_set); - gen->font_set = NULL; - } -} -/* For VW/UDC end */ - -static void -destroy_oc( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - - if (gen->mbs_to_cs) - _XlcCloseConverter(gen->mbs_to_cs); - - if (gen->wcs_to_cs) - _XlcCloseConverter(gen->wcs_to_cs); - - if (gen->utf8_to_cs) - _XlcCloseConverter(gen->utf8_to_cs); - -/* For VW/UDC start */ /* Change 1996.01.8 */ - destroy_fontdata(gen,dpy); -/* -*/ -/* For VW/UDC end */ - - if (oc->core.base_name_list) - Xfree(oc->core.base_name_list); - - if (oc->core.font_info.font_name_list) - XFreeStringList(oc->core.font_info.font_name_list); - - if (oc->core.font_info.font_struct_list) { - Xfree(oc->core.font_info.font_struct_list); - } - - if (oc->core.missing_list.charset_list) - XFreeStringList(oc->core.missing_list.charset_list); - -#ifdef notdef - if (oc->core.res_name) - Xfree(oc->core.res_name); - if (oc->core.res_class) - Xfree(oc->core.res_class); -#endif - - Xfree(oc); -} - -static char * -set_oc_values( - XOC oc, - XlcArgList args, - int num_args) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - char *ret; - int num = gen->font_set_num; - - if (oc->core.resources == NULL) - return NULL; - - ret = _XlcSetValues((XPointer) oc, oc->core.resources, - oc->core.num_resources, args, num_args, XlcSetMask); - if(ret != NULL){ - return(ret); - } else { - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - if (font_set->vpart_initialize != 0) - continue; - if( oc->core.orientation == XOMOrientation_TTB_RTL || - oc->core.orientation == XOMOrientation_TTB_LTR ){ - load_fontdata(oc, font_set->vmap, font_set->vmap_num); - load_fontdata(oc, (FontData) font_set->vrotate, - font_set->vrotate_num); - font_set->vpart_initialize = 1; - } - } - return(NULL); - } -} - -static char * -get_oc_values( - XOC oc, - XlcArgList args, - int num_args) -{ - if (oc->core.resources == NULL) - return NULL; - - return _XlcGetValues((XPointer) oc, oc->core.resources, - oc->core.num_resources, args, num_args, XlcGetMask); -} - -static XOCMethodsRec oc_default_methods = { - destroy_oc, - set_oc_values, - get_oc_values, - _XmbDefaultTextEscapement, - _XmbDefaultTextExtents, - _XmbDefaultTextPerCharExtents, - _XmbDefaultDrawString, - _XmbDefaultDrawImageString, - _XwcDefaultTextEscapement, - _XwcDefaultTextExtents, - _XwcDefaultTextPerCharExtents, - _XwcDefaultDrawString, - _XwcDefaultDrawImageString, - _Xutf8DefaultTextEscapement, - _Xutf8DefaultTextExtents, - _Xutf8DefaultTextPerCharExtents, - _Xutf8DefaultDrawString, - _Xutf8DefaultDrawImageString -}; - -static XOCMethodsRec oc_generic_methods = { - destroy_oc, - set_oc_values, - get_oc_values, - _XmbGenericTextEscapement, - _XmbGenericTextExtents, - _XmbGenericTextPerCharExtents, - _XmbGenericDrawString, - _XmbGenericDrawImageString, - _XwcGenericTextEscapement, - _XwcGenericTextExtents, - _XwcGenericTextPerCharExtents, - _XwcGenericDrawString, - _XwcGenericDrawImageString, - _Xutf8GenericTextEscapement, - _Xutf8GenericTextExtents, - _Xutf8GenericTextPerCharExtents, - _Xutf8GenericDrawString, - _Xutf8GenericDrawImageString -}; - -typedef struct _XOCMethodsListRec { - const char *name; - XOCMethods methods; -} XOCMethodsListRec, *XOCMethodsList; - -static XOCMethodsListRec oc_methods_list[] = { - { "default", &oc_default_methods }, - { "generic", &oc_generic_methods } -}; - -static XlcResource oc_resources[] = { - { XNBaseFontName, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, - { XNOMAutomatic, NULLQUARK, sizeof(Bool), - XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, - { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), - XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, - { XNDefaultString, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.default_string), XlcGetMask }, - { XNOrientation, NULLQUARK, sizeof(XOrientation), - XOffsetOf(XOCRec, core.orientation), XlcDefaultMask | XlcSetMask | XlcGetMask }, - { XNResourceName, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, - { XNResourceClass, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, - { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), - XOffsetOf(XOCRec, core.font_info), XlcGetMask } -}; - -static XOC -create_oc( - XOM om, - XlcArgList args, - int num_args) -{ - XOC oc; - XOMGenericPart *gen = XOM_GENERIC(om); - XOCMethodsList methods_list = oc_methods_list; - int count; - - oc = Xcalloc(1, sizeof(XOCGenericRec)); - if (oc == NULL) - return (XOC) NULL; - - oc->core.om = om; - - if (oc_resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); - - if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), - args, num_args, XlcCreateMask | XlcDefaultMask)) - goto err; - - if (oc->core.base_name_list == NULL) - goto err; - - oc->core.resources = oc_resources; - oc->core.num_resources = XlcNumber(oc_resources); - - if (create_fontset(oc) == False) - goto err; - - oc->methods = &oc_generic_methods; - - if (gen->object_name) { - count = XlcNumber(oc_methods_list); - - for ( ; count-- > 0; methods_list++) { - if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) { - oc->methods = methods_list->methods; - break; - } - } - } - - return oc; - -err: - destroy_oc(oc); - - return (XOC) NULL; -} - -static void -free_fontdataOM( - FontData font_data, - int font_data_count) -{ - for( ; font_data_count-- ; font_data++) { - if(font_data->name){ - Xfree(font_data->name); - font_data->name = NULL; - } - if(font_data->scopes){ - Xfree(font_data->scopes); - font_data->scopes = NULL; - } - } -} - -static Status -close_om( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - int count; - - if ((data = gen->data)) { - for (count = gen->data_num; count-- > 0; data++) { - if (data->charset_list){ - Xfree(data->charset_list); - data->charset_list = NULL; - } - /* free font_data for om */ - if (data->font_data) { - free_fontdataOM(data->font_data,data->font_data_count); - Xfree(data->font_data); - data->font_data = NULL; - } - /* free substitute for om */ - if (data->substitute) { - free_fontdataOM(data->substitute,data->substitute_num); - Xfree(data->substitute); - data->substitute = NULL; - } - /* free vmap for om */ - if (data->vmap) { - free_fontdataOM(data->vmap,data->vmap_num); - Xfree(data->vmap); - data->vmap = NULL; - } - /* free vrotate for om */ - if (data->vrotate) { - Xfree(data->vrotate); - data->vrotate = NULL; - } - } - Xfree(gen->data); - gen->data = NULL; - } - - if (gen->object_name){ - Xfree(gen->object_name); - gen->object_name = NULL; - } - - if (om->core.res_name){ - Xfree(om->core.res_name); - om->core.res_name = NULL; - } - if (om->core.res_class){ - Xfree(om->core.res_class); - om->core.res_class = NULL; - } - if (om->core.required_charset.charset_list && - om->core.required_charset.charset_count > 0){ - XFreeStringList(om->core.required_charset.charset_list); - om->core.required_charset.charset_list = NULL; - } else { - Xfree((char*)om->core.required_charset.charset_list); - om->core.required_charset.charset_list = NULL; - } - if (om->core.orientation_list.orientation){ - Xfree(om->core.orientation_list.orientation); - om->core.orientation_list.orientation = NULL; - } - - Xfree(om); - - return 1; -} - -static char * -set_om_values( - XOM om, - XlcArgList args, - int num_args) -{ - if (om->core.resources == NULL) - return NULL; - - return _XlcSetValues((XPointer) om, om->core.resources, - om->core.num_resources, args, num_args, XlcSetMask); -} - -static char * -get_om_values( - XOM om, - XlcArgList args, - int num_args) -{ - if (om->core.resources == NULL) - return NULL; - - return _XlcGetValues((XPointer) om, om->core.resources, - om->core.num_resources, args, num_args, XlcGetMask); -} - -static XOMMethodsRec methods = { - close_om, - set_om_values, - get_om_values, - create_oc -}; - -static XlcResource om_resources[] = { - { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), - XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, - { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), - XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, - { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), - XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, - { XNContextualDrawing, NULLQUARK, sizeof(Bool), - XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } -}; - -static XOM -create_om( - XLCd lcd, - Display *dpy, - XrmDatabase rdb, - _Xconst char *res_name, - _Xconst char *res_class) -{ - XOM om; - - om = Xcalloc(1, sizeof(XOMGenericRec)); - if (om == NULL) - return (XOM) NULL; - - om->methods = &methods; - om->core.lcd = lcd; - om->core.display = dpy; - om->core.rdb = rdb; - if (res_name) { - om->core.res_name = strdup(res_name); - if (om->core.res_name == NULL) - goto err; - } - if (res_class) { - om->core.res_class = strdup(res_class); - if (om->core.res_class == NULL) - goto err; - } - - if (om_resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); - - om->core.resources = om_resources; - om->core.num_resources = XlcNumber(om_resources); - - return om; - -err: - close_om(om); - - return (XOM) NULL; -} - -static OMData -add_data( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData new; - int num; - - if ((num = gen->data_num)) - new = (OMData) Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec)); - else - new = (OMData) Xmalloc(sizeof(OMDataRec)); - - if (new == NULL) - return NULL; - - gen->data_num = num + 1; - gen->data = new; - - new += num; - bzero((char *) new, sizeof(OMDataRec)); - - return new; -} - -/* For VW/UDC */ - -FontData -read_EncodingInfo( - int count, - char **value) -{ - FontData font_data,ret; - char *buf, *bufptr,*scp; - int len; - font_data = Xcalloc(count, sizeof(FontDataRec)); - if (font_data == NULL) - return NULL; - - ret = font_data; - for ( ; count-- > 0; font_data++) { -/* - strcpy(buf, *value++); -*/ - buf = *value; value++; - if ((bufptr = strchr(buf, ':'))) { - len = (int)(bufptr - buf); - bufptr++ ; - } else - len = strlen(buf); - font_data->name = (char *) Xmalloc(len + 1); - if (font_data->name == NULL) { - Xfree(font_data); - return NULL; - } - strncpy(font_data->name, buf,len); - font_data->name[len] = 0; - if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0) - font_data->side = XlcGL; - else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0) - font_data->side = XlcGR; - else - font_data->side = XlcGLGR; - - if (bufptr && (scp = strchr(bufptr, '['))){ - font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num)); - } - } - return(ret); -} - -static CodeRange read_vrotate( - int count, - char **value, - int *type, - int *vrotate_num) -{ - CodeRange range; - if(!strcmp(value[0],"all")){ - *type = VROTATE_ALL ; - *vrotate_num = 0 ; - return (NULL); - } else if(*(value[0]) == '['){ - *type = VROTATE_PART ; - range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num); - return (range); - } else { - *type = VROTATE_NONE ; - *vrotate_num = 0 ; - return (NULL); - } -} - -static void read_vw( - XLCd lcd, - OMData font_set, - int num) -{ - char **value, buf[BUFSIZ]; - int count; - - sprintf(buf, "fs%d.font.vertical_map", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - _XlcDbg_printValue(buf,value,count); - font_set->vmap_num = count; - font_set->vmap = read_EncodingInfo(count,value); - } - - sprintf(buf, "fs%d.font.vertical_rotate", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - _XlcDbg_printValue(buf,value,count); - font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type), - &(font_set->vrotate_num)); - } -} -/* VW/UDC end */ -static Bool -init_om( - XOM om) -{ - XLCd lcd = om->core.lcd; - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - XlcCharSet *charset_list; - FontData font_data; - char **required_list; - XOrientation *orientation; - char **value, buf[BUFSIZ], *bufptr; - int count = 0, num = 0, length = 0; - - _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count); - if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0) - gen->on_demand_loading = True; - - _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count); - if (count > 0) { - gen->object_name = strdup(*value); - if (gen->object_name == NULL) - return False; - } - - for (num = 0; ; num++) { - - sprintf(buf, "fs%d.charset.name", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - - if( count < 1){ - sprintf(buf, "fs%d.charset", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) - break; - } - - data = add_data(om); - if (data == NULL) - return False; - - charset_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet) * count); - if (charset_list == NULL) - return False; - data->charset_list = charset_list; - data->charset_count = count; - - while (count-- > 0){ - *charset_list++ = _XlcGetCharSet(*value++); - } - sprintf(buf, "fs%d.charset.udc_area", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if( count > 0){ - UDCArea udc; - int i,flag = 0; - udc = (UDCArea)Xmalloc(count * sizeof(UDCAreaRec)); - if (udc == NULL) - return False; - for(i=0;i<count;i++){ - sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start), - &(udc[i].end)); - } - for(i=0;i<data->charset_count;i++){ - if(data->charset_list[i]->udc_area == NULL){ - data->charset_list[i]->udc_area = udc; - data->charset_list[i]->udc_area_num = count; - flag = 1; - } - } - if(flag == 0){ - Xfree(udc); - } - } - - sprintf(buf, "fs%d.font.primary", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1){ - sprintf(buf, "fs%d.font", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) - return False; - } - - font_data = read_EncodingInfo(count,value); - if (font_data == NULL) - return False; - - data->font_data = font_data; - data->font_data_count = count; - - sprintf(buf, "fs%d.font.substitute", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - font_data = read_EncodingInfo(count,value); - if (font_data == NULL) - return False; - data->substitute = font_data; - data->substitute_num = count; - } else { - sprintf(buf, "fs%d.font", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) { - data->substitute = NULL; - data->substitute_num = 0; - } else { - font_data = read_EncodingInfo(count,value); - data->substitute = font_data; - data->substitute_num = count; - } - } - read_vw(lcd,data,num); - length += strlen(data->font_data->name) + 1; - } - - /* required charset list */ - required_list = (char **) Xmalloc(sizeof(char *) * gen->data_num); - if (required_list == NULL) - return False; - - om->core.required_charset.charset_list = required_list; - om->core.required_charset.charset_count = gen->data_num; - - count = gen->data_num; - data = gen->data; - - if (count > 0) { - bufptr = (char *) Xmalloc(length); - if (bufptr == NULL) { - Xfree(required_list); - return False; - } - - for ( ; count-- > 0; data++) { - strcpy(bufptr, data->font_data->name); - *required_list++ = bufptr; - bufptr += strlen(bufptr) + 1; - } - } - - /* orientation list */ - orientation = (XOrientation *) Xmalloc(sizeof(XOrientation) * 2); - if (orientation == NULL) - return False; - - orientation[0] = XOMOrientation_LTR_TTB; - orientation[1] = XOMOrientation_TTB_RTL; - om->core.orientation_list.orientation = orientation; - om->core.orientation_list.num_orientation = 2; - - /* directional dependent drawing */ - om->core.directional_dependent = False; - - /* contexual drawing */ - om->core.contextual_drawing = False; - - /* context dependent */ - om->core.context_dependent = False; - - return True; -} - -XOM -_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, - _Xconst char *res_name, _Xconst char *res_class) -{ - XOM om; - - om = create_om(lcd, dpy, rdb, res_name, res_class); - if (om == NULL) - return (XOM) NULL; - - if (init_om(om) == False) - goto err; - - return om; - -err: - close_om(om); - - return (XOM) NULL; -} - -Bool -_XInitOM( - XLCd lcd) -{ - lcd->methods->open_om = _XomGenericOpenOM; - - return True; -} +/* #define FONTDEBUG */
+/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+/*
+ * Copyright 1995 by FUJITSU LIMITED
+ * This is source code modified by FUJITSU LIMITED under the Joint
+ * Development Agreement for the CDE/Motif PST.
+ *
+ * Modifier: Takanori Tateno FUJITSU LIMITED
+ *
+ */
+
+/*
+ * Fixed the algorithms in parse_fontname() and parse_fontdata()
+ * to improve the logic for determining which font should be
+ * returned for a given CharSet. We even added some comments
+ * so that you can figure out what in the heck we're doing. We
+ * realize this is a departure from the norm, but hey, we're
+ * rebels! :-) :-)
+ *
+ * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD
+ */
+/*
+ * Cleaned up mess, removed some blabla
+ * Egbert Eich, SuSE Linux AG
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XomGeneric.h"
+#include "XlcGeneric.h"
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+#define MAXFONTS 100
+#define PIXEL_SIZE_FIELD 7
+#define POINT_SIZE_FIELD 8
+#define CHARSET_ENCODING_FIELD 14
+#define XLFD_MAX_LEN 255
+
+#if 0
+extern int _XmbDefaultTextEscapement(), _XwcDefaultTextEscapement(),
+ _Xutf8DefaultTextEscapement();
+extern int _XmbDefaultTextExtents(), _XwcDefaultTextExtents(),
+ _Xutf8DefaultTextExtents();
+extern Status _XmbDefaultTextPerCharExtents(), _XwcDefaultTextPerCharExtents(),
+ _Xutf8DefaultTextPerCharExtents();
+extern int _XmbDefaultDrawString(), _XwcDefaultDrawString(),
+ _Xutf8DefaultDrawString();
+extern void _XmbDefaultDrawImageString(), _XwcDefaultDrawImageString(),
+ _Xutf8DefaultDrawImageString();
+
+extern int _XmbGenericTextEscapement(), _XwcGenericTextEscapement(),
+ _Xutf8GenericTextEscapement();
+extern int _XmbGenericTextExtents(), _XwcGenericTextExtents(),
+ _Xutf8GenericTextExtents();
+extern Status _XmbGenericTextPerCharExtents(), _XwcGenericTextPerCharExtents(),
+ _Xutf8GenericTextPerCharExtents();
+extern int _XmbGenericDrawString(), _XwcGenericDrawString(),
+ _Xutf8GenericDrawString();
+extern void _XmbGenericDrawImageString(), _XwcGenericDrawImageString(),
+ _Xutf8GenericDrawImageString();
+
+extern void _XlcDbg_printValue (const char *str, char **value, int num);
+#endif
+
+/* For VW/UDC start */
+
+static FontData
+init_fontdata(
+ FontData font_data,
+ int font_data_count)
+{
+ FontData fd;
+ int i;
+
+ fd = (FontData)Xmalloc(sizeof(FontDataRec) * font_data_count);
+ if(fd == (FontData) NULL)
+ return False;
+
+ memset(fd, 0x00, sizeof(FontData) * font_data_count);
+ for(i = 0 ; i < font_data_count ; i++)
+ fd[i] = font_data[i];
+
+ return fd;
+}
+
+static VRotate
+init_vrotate(
+ FontData font_data,
+ int font_data_count,
+ int type,
+ CodeRange code_range,
+ int code_range_num)
+{
+ VRotate vrotate;
+ int i;
+
+ if(type == VROTATE_NONE)
+ return (VRotate)NULL;
+
+ vrotate = (VRotate)Xmalloc(sizeof(VRotateRec) * font_data_count);
+ if(vrotate == (VRotate) NULL)
+ return False;
+
+ memset(vrotate, 0x00, sizeof(VRotateRec) * font_data_count);
+ for(i = 0 ; i < font_data_count ; i++) {
+ vrotate[i].charset_name = font_data[i].name;
+ vrotate[i].side = font_data[i].side;
+ if(type == VROTATE_PART) {
+ vrotate[i].num_cr = code_range_num;
+ vrotate[i].code_range = code_range;
+ }
+ }
+
+ return vrotate;
+}
+
+static Bool
+init_fontset(
+ XOC oc)
+{
+ XOCGenericPart *gen;
+ FontSet font_set;
+ OMData data;
+ int count;
+
+ count = XOM_GENERIC(oc->core.om)->data_num;
+ data = XOM_GENERIC(oc->core.om)->data;
+
+ font_set = (FontSet) Xmalloc(sizeof(FontSetRec) * count);
+ if (font_set == NULL)
+ return False;
+ memset((char *) font_set, 0x00, sizeof(FontSetRec) * count);
+
+ gen = XOC_GENERIC(oc);
+ gen->font_set_num = count;
+ gen->font_set = font_set;
+
+ for ( ; count-- > 0; data++, font_set++) {
+ font_set->charset_count = data->charset_count;
+ font_set->charset_list = data->charset_list;
+
+ if((font_set->font_data = init_fontdata(data->font_data,
+ data->font_data_count)) == NULL)
+ goto err;
+ font_set->font_data_count = data->font_data_count;
+ if((font_set->substitute = init_fontdata(data->substitute,
+ data->substitute_num)) == NULL)
+ goto err;
+ font_set->substitute_num = data->substitute_num;
+ if((font_set->vmap = init_fontdata(data->vmap,
+ data->vmap_num)) == NULL)
+ goto err;
+ font_set->vmap_num = data->vmap_num;
+
+ if(data->vrotate_type != VROTATE_NONE) {
+ /* A vrotate member is specified primary font data */
+ /* as initial value. */
+ if((font_set->vrotate = init_vrotate(data->font_data,
+ data->font_data_count,
+ data->vrotate_type,
+ data->vrotate,
+ data->vrotate_num)) == NULL)
+ goto err;
+ font_set->vrotate_num = data->font_data_count;
+ }
+ }
+ return True;
+
+err:
+ if(font_set->font_data)
+ Xfree(font_set->font_data);
+ if(font_set->substitute)
+ Xfree(font_set->substitute);
+ if(font_set->vmap)
+ Xfree(font_set->vmap);
+ if(font_set->vrotate)
+ Xfree(font_set->vrotate);
+ if(font_set)
+ Xfree(font_set);
+ gen->font_set = (FontSet) NULL;
+ gen->font_set_num = 0;
+ return False;
+}
+
+/* For VW/UDC end */
+
+static char *
+get_prop_name(
+ Display *dpy,
+ XFontStruct *fs)
+{
+ unsigned long fp;
+
+ if (XGetFontProperty(fs, XA_FONT, &fp))
+ return XGetAtomName(dpy, fp);
+
+ return (char *) NULL;
+}
+
+/* For VW/UDC start */
+
+static Bool
+load_fontdata(
+ XOC oc,
+ FontData font_data,
+ int font_data_num)
+{
+ Display *dpy = oc->core.om->core.display;
+ FontData fd = font_data;
+
+ if(font_data == NULL) return(True);
+ for( ; font_data_num-- ; fd++) {
+ if(fd->xlfd_name != (char *) NULL && fd->font == NULL) {
+ fd->font = XLoadQueryFont(dpy, fd->xlfd_name);
+ if (fd->font == NULL){
+ return False;
+ }
+ }
+ }
+ return True;
+}
+
+static Bool
+load_fontset_data(
+ XOC oc,
+ FontSet font_set)
+{
+ Display *dpy = oc->core.om->core.display;
+
+ if(font_set->font_name == (char *)NULL) return False ;
+
+ /* If font_set->font is not NULL, it contains the *best*
+ * match font for this FontSet.
+ * -- jjw/pma (HP)
+ */
+ if(font_set->font == NULL) {
+ font_set->font = XLoadQueryFont(dpy, font_set->font_name);
+ if (font_set->font == NULL){
+ return False;
+ }
+ }
+ return True;
+}
+
+static Bool
+load_font(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ int num = gen->font_set_num;
+
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ if (load_fontset_data (oc, font_set) != True)
+ return False;
+#ifndef TESTVERSION
+ if(load_fontdata(oc, font_set->font_data,
+ font_set->font_data_count) != True)
+ return False;
+
+ if(load_fontdata(oc, font_set->substitute,
+ font_set->substitute_num) != True)
+ return False;
+#endif
+
+/* Add 1996.05.20 */
+ if( oc->core.orientation == XOMOrientation_TTB_RTL ||
+ oc->core.orientation == XOMOrientation_TTB_LTR ){
+ if (font_set->vpart_initialize == 0) {
+ load_fontdata(oc, font_set->vmap, font_set->vmap_num);
+ load_fontdata(oc, (FontData) font_set->vrotate,
+ font_set->vrotate_num);
+ font_set->vpart_initialize = 1;
+ }
+ }
+
+ if (font_set->font->min_byte1 || font_set->font->max_byte1)
+ font_set->is_xchar2b = True;
+ else
+ font_set->is_xchar2b = False;
+ }
+
+ return True;
+}
+
+/* For VW/UDC end */
+
+static Bool
+load_font_info(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ char **fn_list;
+ int fn_num, num = gen->font_set_num;
+
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ if (font_set->info == NULL) {
+ fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
+ &font_set->info);
+ if (font_set->info == NULL)
+ return False;
+
+ XFreeFontNames(fn_list);
+ }
+ }
+
+ return True;
+}
+
+/* For Vertical Writing start */
+
+static void
+check_fontset_extents(
+ XCharStruct *overall,
+ int *logical_ascent,
+ int *logical_descent,
+ XFontStruct *font)
+{
+ overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing);
+ overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing);
+ overall->ascent = max(overall->ascent, font->max_bounds.ascent);
+ overall->descent = max(overall->descent, font->max_bounds.descent);
+ overall->width = max(overall->width, font->max_bounds.width);
+ *logical_ascent = max(*logical_ascent, font->ascent);
+ *logical_descent = max(*logical_descent, font->descent);
+}
+
+/* For Vertical Writing end */
+
+static void
+set_fontset_extents(
+ XOC oc)
+{
+ XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
+ XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
+ XFontStruct **font_list, *font;
+ XCharStruct overall;
+ int logical_ascent, logical_descent;
+ int num = oc->core.font_info.num_font;
+
+ font_list = oc->core.font_info.font_struct_list;
+ font = *font_list++;
+ overall = font->max_bounds;
+ overall.lbearing = font->min_bounds.lbearing;
+ logical_ascent = font->ascent;
+ logical_descent = font->descent;
+
+ /* For Vertical Writing start */
+
+ while (--num > 0) {
+ font = *font_list++;
+ check_fontset_extents(&overall, &logical_ascent, &logical_descent,
+ font);
+ }
+
+ {
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ FontData font_data;
+ int font_set_num = gen->font_set_num;
+ int font_data_count;
+
+ for( ; font_set_num-- ; font_set++) {
+ if(font_set->vmap_num > 0) {
+ font_data = font_set->vmap;
+ font_data_count = font_set->vmap_num;
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->font != NULL) {
+ check_fontset_extents(&overall, &logical_ascent,
+ &logical_descent,
+ font_data->font);
+ }
+ }
+ }
+
+ if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) {
+ font_data = (FontData) font_set->vrotate;
+ font_data_count = font_set->vrotate_num;
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->font != NULL) {
+ check_fontset_extents(&overall, &logical_ascent,
+ &logical_descent,
+ font_data->font);
+ }
+ }
+ }
+ }
+ }
+
+ /* For Vertical Writing start */
+
+ ink->x = overall.lbearing;
+ ink->y = -(overall.ascent);
+ ink->width = overall.rbearing - overall.lbearing;
+ ink->height = overall.ascent + overall.descent;
+
+ logical->x = 0;
+ logical->y = -(logical_ascent);
+ logical->width = overall.width;
+ logical->height = logical_ascent + logical_descent;
+}
+
+static Bool
+init_core_part(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ int font_set_num;
+ XFontStruct **font_struct_list;
+ char **font_name_list, *font_name_buf;
+ int count, length;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ count = length = 0;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ length += strlen(font_set->font_name) + 1;
+
+ count++;
+ }
+ if (count == 0)
+ return False;
+
+ font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *) * count);
+ if (font_struct_list == NULL)
+ return False;
+
+ font_name_list = (char **) Xmalloc(sizeof(char *) * count);
+ if (font_name_list == NULL)
+ goto err;
+
+ font_name_buf = (char *) Xmalloc(length);
+ if (font_name_buf == NULL)
+ goto err;
+
+ oc->core.font_info.num_font = count;
+ oc->core.font_info.font_name_list = font_name_list;
+ oc->core.font_info.font_struct_list = font_struct_list;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+
+ for (count = 0; font_set_num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ font_set->id = count;
+ if (font_set->font)
+ *font_struct_list++ = font_set->font;
+ else
+ *font_struct_list++ = font_set->info;
+ strcpy(font_name_buf, font_set->font_name);
+ Xfree(font_set->font_name);
+ *font_name_list++ = font_set->font_name = font_name_buf;
+ font_name_buf += strlen(font_name_buf) + 1;
+
+ count++;
+ }
+
+ set_fontset_extents(oc);
+
+ return True;
+
+err:
+ if (font_name_list)
+ Xfree(font_name_list);
+ Xfree(font_struct_list);
+
+ return False;
+}
+
+static char *
+get_font_name(
+ XOC oc,
+ char *pattern)
+{
+ char **list, *name;
+ int count = 0;
+
+ list = XListFonts(oc->core.om->core.display, pattern, 1, &count);
+ if (list == NULL)
+ return NULL;
+
+ name = strdup(*list);
+
+ XFreeFontNames(list);
+
+ return name;
+}
+
+/* For VW/UDC start*/
+
+static char *
+get_rotate_fontname(
+ char *font_name)
+{
+ char *pattern = NULL, *ptr = NULL;
+ char *fields[CHARSET_ENCODING_FIELD];
+ char str_pixel[32], str_point[4];
+ char *rotate_font_ptr = NULL;
+ int pixel_size = 0;
+ int field_num = 0, len = 0;
+
+ if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0
+ || len > XLFD_MAX_LEN)
+ return NULL;
+
+ pattern = strdup(font_name);
+ if(!pattern)
+ return NULL;
+
+ memset(fields, 0, sizeof(char *) * 14);
+ ptr = pattern;
+ while(isspace(*ptr)) {
+ ptr++;
+ }
+ if(*ptr == '-')
+ ptr++;
+
+ for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ;
+ ptr++, field_num++) {
+ fields[field_num] = ptr;
+
+ if((ptr = strchr(ptr, '-'))) {
+ *ptr = '\0';
+ } else {
+ field_num++; /* Count last field */
+ break;
+ }
+ }
+
+ if(field_num < CHARSET_ENCODING_FIELD)
+ goto free_pattern;
+
+ /* Pixel Size field : fields[6] */
+ for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) {
+ if(!isdigit(*ptr)) {
+ if(*ptr == '['){ /* 960730 */
+ strcpy(pattern, font_name);
+ return(pattern);
+ }
+ goto free_pattern;
+ }
+ }
+ pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]);
+ sprintf(str_pixel, "[ 0 ~%d %d 0 ]", pixel_size, pixel_size);
+ fields[6] = str_pixel;
+
+ /* Point Size field : fields[7] */
+ strcpy(str_point, "*");
+ fields[POINT_SIZE_FIELD - 1] = str_point;
+
+ len = 0;
+ for (field_num = 0; field_num < CHARSET_ENCODING_FIELD &&
+ fields[field_num]; field_num++) {
+ len += 1 + strlen(fields[field_num]);
+ }
+
+ /* Max XLFD length is 255 */
+ if (len > XLFD_MAX_LEN)
+ goto free_pattern;
+
+ rotate_font_ptr = (char *)Xmalloc(len + 1);
+ if(!rotate_font_ptr)
+ goto free_pattern;
+
+ rotate_font_ptr[0] = '\0';
+
+ for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD &&
+ fields[field_num] ; field_num++) {
+ strcat(rotate_font_ptr, "-");
+ strcat(rotate_font_ptr, fields[field_num]);
+ }
+
+free_pattern:
+ Xfree(pattern);
+
+ return rotate_font_ptr;
+}
+
+static Bool
+is_match_charset(
+ FontData font_data,
+ char *font_name)
+{
+ char *last;
+ int length, name_len;
+
+ name_len = strlen(font_name);
+ last = font_name + name_len;
+
+ length = strlen(font_data->name);
+ if (length > name_len)
+ return False;
+
+ if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
+ return True;
+
+ return False;
+}
+
+#if 0
+static char *
+get_font_name_from_list(
+ XOC oc,
+ char *pattern,
+ FontData font_data)
+{
+ char **list, *name = (char *)NULL, *fname;
+ int count = 0, i;
+
+ list = XListFonts(oc->core.om->core.display, pattern, MAXFONTS, &count);
+ if (list == NULL)
+ return NULL;
+
+ for (i = 0; i < count; i++) {
+ fname = list[i];
+ if(is_match_charset(font_data, fname) == True) {
+ name = strdup(fname);
+ break;
+ }
+ }
+
+ XFreeFontNames(list);
+
+ return name;
+}
+#endif
+
+static int
+parse_all_name(
+ XOC oc,
+ FontData font_data,
+ char *pattern)
+{
+
+#ifdef OLDCODE
+ if(is_match_charset(font_data, pattern) != True)
+ return False;
+
+ font_data->xlfd_name = strdup(pattern);
+ if(font_data->xlfd_name == NULL)
+ return (-1);
+
+ return True;
+#else /* OLDCODE */
+ Display *dpy = oc->core.om->core.display;
+ char **fn_list = NULL, *prop_fname = NULL;
+ int list_num;
+ XFontStruct *fs_list;
+ if(is_match_charset(font_data, pattern) != True) {
+ /*
+ * pattern should not contain any wildcard (execpt '?')
+ * this was probably added to make this case insensitive.
+ */
+ if ((fn_list = XListFontsWithInfo(dpy, pattern,
+ MAXFONTS,
+ &list_num, &fs_list)) == NULL) {
+ return False;
+ }
+ /* shouldn't we loop here ? */
+ else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) {
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return False;
+ }
+ else if ((is_match_charset(font_data, prop_fname) != True)) {
+ XFree(prop_fname);
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return False;
+ }
+ else {
+ font_data->xlfd_name = prop_fname;
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return True;
+ }
+ }
+
+ font_data->xlfd_name = strdup(pattern);
+ if(font_data->xlfd_name == NULL)
+ return (-1);
+
+ return True;
+#endif /* OLDCODE */
+}
+
+static int
+parse_omit_name(
+ XOC oc,
+ FontData font_data,
+ char *pattern)
+{
+ char* last = (char *) NULL;
+ char* base_name;
+ char buf[XLFD_MAX_LEN + 1];
+ int length = 0;
+ int num_fields;
+ /*
+ * If the font specified by "pattern" is expandable to be
+ * a member of "font_data"'s FontSet, we've found a match.
+ */
+ if(is_match_charset(font_data, pattern) == True) {
+ if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) {
+ return True;
+ }
+ }
+
+ length = strlen (pattern);
+
+ if (length > XLFD_MAX_LEN)
+ return -1;
+
+ strcpy(buf, pattern);
+ last = buf + length - 1;
+
+ /* Replace the original encoding with the encoding for this FontSet. */
+
+ /* Figure out how many fields have been specified in this xlfd. */
+ for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
+ if (*base_name == '-') num_fields++;
+
+ switch (num_fields) {
+ case 12:
+ /* This is the best way to have specifed the fontset. In this
+ * case, there is no original encoding. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*
+ * To this, we'll append a dash:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ /*
+ * Take care of:
+ * -*-*-*-*-*-*-14-*-*-*-*-
+ */
+ if (*(last) == '-')
+ *++last = '*';
+
+ *++last = '-';
+ break;
+ case 13:
+ /* Got the charset, not the encoding, zap the charset In this
+ * case, there is no original encoding, but there is a charset. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990
+ * To this, we remove the charset:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the new encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ last = strrchr (buf, '-');
+ num_fields = 12;
+ break;
+ case 14:
+ /* Both the charset and the encoding are specified. Get rid
+ * of them so that we can append the new charset encoding. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0
+ * To this, we'll remove the encoding and charset to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the new encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ last = strrchr (buf, '-');
+ *last = '\0';
+ last = strrchr (buf, '-');
+ num_fields = 12;
+ break;
+ default:
+ if (*last != '-')
+ *++last = '-';
+ break;
+ }
+
+ /* At this point, "last" is pointing to the last "-" in the
+ * xlfd, and all xlfd's at this point take a form similar to:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * (i.e., no encoding).
+ * After the strcpy, we'll end up with something similar to:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ *
+ * If the modified font is found in the current FontSet,
+ * we've found a match.
+ */
+
+ last++;
+
+ if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN)
+ return -1;
+
+ strcpy(last, font_data->name);
+ if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
+ return True;
+
+ /* This may mot be needed anymore as XListFonts() takes care of this */
+ while (num_fields < 12) {
+ if ((last - buf) > (XLFD_MAX_LEN - 2))
+ return -1;
+ *last = '*';
+ *(last + 1) = '-';
+ strcpy(last + 2, font_data->name);
+ num_fields++;
+ last+=2;
+ if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
+ return True;
+ }
+
+
+ return False;
+}
+
+
+typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType;
+
+static int
+parse_fontdata(
+ XOC oc,
+ FontSet font_set,
+ FontData font_data,
+ int font_data_count,
+ char **name_list,
+ int name_list_count,
+ ClassType class,
+ FontDataRec *font_data_return)
+{
+
+ char **cur_name_list = name_list;
+ char *font_name = (char *) NULL;
+ char *pattern = (char *) NULL;
+ int found_num = 0, ret = 0;
+ int count = name_list_count;
+
+ if(name_list == NULL || count <= 0) {
+ return False;
+ }
+
+ if(font_data == NULL || font_data_count <= 0) {
+ return False;
+ }
+
+ /* Loop through each font encoding defined in the "font_data" FontSet. */
+ for ( ; font_data_count-- > 0; font_data++) {
+ Bool is_found = False;
+ font_name = (char *) NULL;
+ count = name_list_count;
+ cur_name_list = name_list;
+
+ /*
+ * Loop through each font specified by the user
+ * in the call to XCreateFontset().
+ */
+ while (count-- > 0) {
+ pattern = *cur_name_list++;
+ if (pattern == NULL || *pattern == '\0')
+ continue;
+#ifdef FONTDEBUG
+ fprintf(stderr,"Font pattern: %s %s\n",
+ pattern,font_data->name);
+#endif
+
+ /*
+ * If the current font is fully specified (i.e., the
+ * xlfd contains no wildcards) and the font exists on
+ * the X Server, we have a match.
+ */
+ if (strchr(pattern, '*') == NULL &&
+ (font_name = get_font_name(oc, pattern))) {
+ /*
+ * Find the full xlfd name for this font. If the font is
+ * already in xlfd format, it is simply returned. If the
+ * font is an alias for another font, the xlfd of the
+ * aliased font is returned.
+ */
+ ret = parse_all_name(oc, font_data, font_name);
+ Xfree(font_name);
+
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+ /*
+ * Since there was an exact match of a fully-specified font
+ * or a font alias, we can return now since the desired font
+ * was found for the current font encoding for this FontSet.
+ *
+ * Previous implementations of this algorithm would
+ * not return here. Instead, they continued searching
+ * through the font encodings for this FontSet. The side-effect
+ * of that behavior is you may return a "substitute" match
+ * instead of an "exact" match. We believe there should be a
+ * preference on exact matches. Therefore, as soon as we
+ * find one, we bail.
+ *
+ * Also, previous implementations seemed to think it was
+ * important to find either a primary or substitute font
+ * for each Font encoding in the FontSet before returning an
+ * acceptable font. We don't believe this is necessary.
+ * All the client cares about is finding a reasonable font
+ * for what was passed in. If we find an exact match,
+ * there's no reason to look any further.
+ *
+ * -- jjw/pma (HP)
+ */
+ if (font_data_return) {
+ font_data_return->xlfd_name = strdup(font_data->xlfd_name);
+ if (!font_data_return->xlfd_name) return -1;
+
+ font_data_return->side = font_data->side;
+ }
+#ifdef FONTDEBUG
+ fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
+#endif
+
+ return True;
+ }
+ /*
+ * If the font name is not fully specified
+ * (i.e., it has wildcards), we have more work to do.
+ * See the comments in parse_omit_name()
+ * for the list of things to do.
+ */
+ ret = parse_omit_name(oc, font_data, pattern);
+
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+
+ /*
+ * A font which matched the wild-carded specification was found.
+ * Only update the return data if a font has not yet been found.
+ * This maintains the convention that FontSets listed higher in
+ * a CodeSet in the Locale Database have higher priority than
+ * those FontSets listed lower in the CodeSet. In the following
+ * example:
+ *
+ * fs1 {
+ * charset HP-JIS:GR
+ * font JISX0208.1990-0:GL;\
+ * JISX0208.1990-1:GR;\
+ * JISX0208.1983-0:GL;\
+ * JISX0208.1983-1:GR
+ * }
+ *
+ * a font found in the JISX0208.1990-0 FontSet will have a
+ * higher priority than a font found in the JISX0208.1983-0
+ * FontSet.
+ */
+ if (font_data_return && font_data_return->xlfd_name == NULL) {
+
+#ifdef FONTDEBUG
+ fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
+#endif
+ font_data_return->xlfd_name = strdup(font_data->xlfd_name);
+ if (!font_data_return->xlfd_name) return -1;
+
+ font_data_return->side = font_data->side;
+ }
+
+ found_num++;
+ is_found = True;
+
+ break;
+ }
+
+ switch(class) {
+ case C_PRIMARY:
+ if(is_found == False) {
+ /*
+ * Did not find a font for the current FontSet. Check the
+ * FontSet's "substitute" font for a match. If we find a
+ * match, we'll keep searching in hopes of finding an exact
+ * match later down the FontSet list.
+ *
+ * when we return and we have found a font font_data_return
+ * contains the first (ie. best) match no matter if this
+ * is a C_PRIMARY or a C_SUBSTITUTE font
+ */
+ ret = parse_fontdata(oc, font_set, font_set->substitute,
+ font_set->substitute_num, name_list,
+ name_list_count, C_SUBSTITUTE,
+ font_data_return);
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+
+ found_num++;
+ is_found = True;
+ }
+#ifdef TESTVERSION
+ else
+ return True;
+#endif
+ break;
+
+ case C_SUBSTITUTE:
+ case C_VMAP:
+ if(is_found == True)
+ return True;
+ break;
+
+ case C_VROTATE:
+ if(is_found == True) {
+ char *rotate_name;
+
+ if((rotate_name = get_rotate_fontname(font_data->xlfd_name))
+ != NULL) {
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = rotate_name;
+
+ return True;
+ }
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = NULL;
+ return False;
+ }
+ break;
+ }
+ }
+
+ if(class == C_PRIMARY && found_num >= 1)
+ return True;
+
+ return False;
+}
+
+
+static int
+parse_vw(
+ XOC oc,
+ FontSet font_set,
+ char **name_list,
+ int count)
+{
+ FontData vmap = font_set->vmap;
+ VRotate vrotate = font_set->vrotate;
+ int vmap_num = font_set->vmap_num;
+ int vrotate_num = font_set->vrotate_num;
+ int ret = 0, i = 0;
+
+ if(vmap_num > 0) {
+ if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list,
+ count, C_VMAP,NULL) == -1)
+ return (-1);
+ }
+
+ if(vrotate_num > 0) {
+ ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
+ name_list, count, C_VROTATE, NULL);
+ if(ret == -1) {
+ return (-1);
+ } else if(ret == False) {
+ CodeRange code_range;
+ int num_cr;
+ int sub_num = font_set->substitute_num;
+
+ code_range = vrotate[0].code_range; /* ? */
+ num_cr = vrotate[0].num_cr; /* ? */
+ for(i = 0 ; i < vrotate_num ; i++) {
+ if(vrotate[i].xlfd_name)
+ Xfree(vrotate[i].xlfd_name);
+ }
+ Xfree(vrotate);
+
+ if(sub_num > 0) {
+ vrotate = font_set->vrotate = (VRotate)Xmalloc
+ (sizeof(VRotateRec) * sub_num);
+ if(font_set->vrotate == (VRotate)NULL)
+ return (-1);
+ memset(font_set->vrotate, 0x00, sizeof(VRotateRec) * sub_num);
+
+ for(i = 0 ; i < sub_num ; i++) {
+ vrotate[i].charset_name = font_set->substitute[i].name;
+ vrotate[i].side = font_set->substitute[i].side;
+ vrotate[i].code_range = code_range;
+ vrotate[i].num_cr = num_cr;
+ }
+ vrotate_num = font_set->vrotate_num = sub_num;
+ } else {
+ vrotate = font_set->vrotate = (VRotate)NULL;
+ }
+
+ ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
+ name_list, count, C_VROTATE, NULL);
+ if(ret == -1)
+ return (-1);
+ }
+ }
+
+ return True;
+}
+
+static int
+parse_fontname(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ FontDataRec font_data_return;
+ char *base_name, **name_list;
+ int font_set_num = 0;
+ int found_num = 0;
+ int count = 0;
+ int ret;
+ int i;
+
+ name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
+ if (name_list == NULL)
+ return -1;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+
+ /* Loop through all of the CharSets defined in the Locale
+ * database for the current Locale.
+ */
+ for( ; font_set_num-- > 0 ; font_set++) {
+ if(font_set->font_name)
+ continue;
+
+ if(font_set->font_data_count > 0) {
+
+ /*
+ * If there are a non-zero number of FontSets defined
+ * for this CharSet.
+ * Try to find a font for this CharSet. If we find an
+ * acceptable font, we save the information for return
+ * to the client. If we do not find an acceptable font,
+ * a "missing_charset" will be reported to the client
+ * for this CharSet.
+ */
+ font_data_return. xlfd_name = NULL;
+ font_data_return.side = XlcUnknown;
+
+ ret = parse_fontdata(oc, font_set, font_set->font_data,
+ font_set->font_data_count,
+ name_list, count, C_PRIMARY,
+ &font_data_return);
+ if(ret == -1) {
+ goto err;
+ } else if(ret == True) {
+ /*
+ * We can't just loop thru fontset->font_data to
+ * find the first (ie. best) match: parse_fontdata
+ * will try a substitute font if no primary one could
+ * be matched. It returns the required information in
+ * font_data_return.
+ */
+ font_set->font_name = strdup(font_data_return.xlfd_name);
+ if(font_set->font_name == (char *) NULL)
+ goto err;
+
+ font_set->side = font_data_return.side;
+
+ Xfree (font_data_return.xlfd_name);
+ font_data_return.xlfd_name = NULL;
+
+ if(parse_vw(oc, font_set, name_list, count) == -1)
+ goto err;
+ found_num++;
+ }
+
+ } else if(font_set->substitute_num > 0) {
+ /*
+ * If there are no FontSets defined for this
+ * CharSet. We can only find "substitute" fonts.
+ */
+ ret = parse_fontdata(oc, font_set, font_set->substitute,
+ font_set->substitute_num,
+ name_list, count, C_SUBSTITUTE, NULL);
+ if(ret == -1) {
+ goto err;
+ } else if(ret == True) {
+ for(i=0;i<font_set->substitute_num;i++){
+ if(font_set->substitute[i].xlfd_name != NULL){
+ break;
+ }
+ }
+ font_set->font_name = strdup(font_set->substitute[i].xlfd_name);
+ if(font_set->font_name == (char *) NULL)
+ goto err;
+
+ font_set->side = font_set->substitute[i].side;
+ if(parse_vw(oc, font_set, name_list, count) == -1)
+ goto err;
+
+ found_num++;
+ }
+ }
+ }
+
+ base_name = strdup(oc->core.base_name_list);
+ if (base_name == NULL)
+ goto err;
+
+ oc->core.base_name_list = base_name;
+
+ XFreeStringList(name_list);
+
+ return found_num;
+
+err:
+ XFreeStringList(name_list);
+ /* Prevent this from being freed twice */
+ oc->core.base_name_list = NULL;
+
+ return -1;
+}
+
+/* For VW/UDC end*/
+
+static Bool
+set_missing_list(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ char **charset_list, *charset_buf;
+ int count, length, font_set_num;
+ int result = 1;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ count = length = 0;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->info || font_set->font) {
+ continue;
+ }
+
+ /* Change 1996.01.23 start */
+ if(font_set->font_data_count <= 0 ||
+ font_set->font_data == (FontData)NULL) {
+ if(font_set->substitute_num <= 0 ||
+ font_set->substitute == (FontData)NULL) {
+ if(font_set->charset_list != NULL){
+ length +=
+ strlen(font_set->charset_list[0]->encoding_name) + 1;
+ } else {
+ length += 1;
+ }
+ } else {
+ length += strlen(font_set->substitute->name) + 1;
+ }
+ } else {
+ length += strlen(font_set->font_data->name) + 1;
+ }
+ /* Change 1996.01.23 end */
+ count++;
+ }
+
+ if (count < 1) {
+ return True;
+ }
+
+ charset_list = (char **) Xmalloc(sizeof(char *) * count);
+ if (charset_list == NULL) {
+ return False;
+ }
+
+ charset_buf = (char *) Xmalloc(length);
+ if (charset_buf == NULL) {
+ Xfree(charset_list);
+ return False;
+ }
+
+ oc->core.missing_list.charset_list = charset_list;
+ oc->core.missing_list.charset_count = count;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->info || font_set->font) {
+ continue;
+ }
+
+ /* Change 1996.01.23 start */
+ if(font_set->font_data_count <= 0 ||
+ font_set->font_data == (FontData)NULL) {
+ if(font_set->substitute_num <= 0 ||
+ font_set->substitute == (FontData)NULL) {
+ if(font_set->charset_list != NULL){
+ strcpy(charset_buf,
+ font_set->charset_list[0]->encoding_name);
+ } else {
+ strcpy(charset_buf, "");
+ }
+ result = 0;
+ } else {
+ strcpy(charset_buf, font_set->substitute->name);
+ }
+ } else {
+ strcpy(charset_buf, font_set->font_data->name);
+ }
+ /* Change 1996.01.23 end */
+ *charset_list++ = charset_buf;
+ charset_buf += strlen(charset_buf) + 1;
+ }
+
+ if(result == 0) {
+ return(False);
+ }
+
+ return True;
+}
+
+static Bool
+create_fontset(
+ XOC oc)
+{
+ XOMGenericPart *gen = XOM_GENERIC(oc->core.om);
+ int found_num;
+
+ if (init_fontset(oc) == False)
+ return False;
+
+ found_num = parse_fontname(oc);
+ if (found_num <= 0) {
+ if (found_num == 0)
+ set_missing_list(oc);
+ return False;
+ }
+
+ if (gen->on_demand_loading == True) {
+ if (load_font_info(oc) == False)
+ return False;
+ } else {
+ if (load_font(oc) == False)
+ return False;
+ }
+
+ if (init_core_part(oc) == False)
+ return False;
+
+ if (set_missing_list(oc) == False)
+ return False;
+
+ return True;
+}
+
+/* For VW/UDC start */
+static void
+free_fontdataOC(
+ Display *dpy,
+ FontData font_data,
+ int font_data_count)
+{
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->xlfd_name){
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = NULL;
+ }
+ if(font_data->font){ /* ADD 1996.01.7 */
+ if(font_data->font->fid) /* Add 1996.01.23 */
+ XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */
+ else /* Add 1996.01.23 */
+ XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */
+ font_data->font = NULL;
+ }
+/*
+ * font_data->name and font_data->scopes belong to the OM not OC.
+ * To save space this data is shared between OM and OC. We are
+ * not allowed to free it here.
+ * It has been moved to free_fontdataOM()
+ */
+/*
+ if(font_data->scopes){
+ Xfree(font_data->scopes);
+ font_data->scopes = NULL;
+ }
+ if(font_data->name){
+ Xfree(font_data->name);
+ font_data->name = NULL;
+ }
+*/
+ }
+}
+
+static void destroy_fontdata(
+ XOCGenericPart *gen,
+ Display *dpy)
+{
+ FontSet font_set = (FontSet) NULL;
+ int font_set_num = 0;
+
+ if (gen->font_set) {
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ for( ; font_set_num-- ; font_set++) {
+ if (font_set->font) {
+ if(font_set->font->fid)
+ XFreeFont(dpy,font_set->font);
+ else
+ XFreeFontInfo(NULL, font_set->font, 1);
+ font_set->font = NULL;
+ }
+ if(font_set->font_data) {
+ if (font_set->info)
+ XFreeFontInfo(NULL, font_set->info, 1);
+ free_fontdataOC(dpy,
+ font_set->font_data, font_set->font_data_count);
+ Xfree(font_set->font_data);
+ font_set->font_data = NULL;
+ }
+ if(font_set->substitute) {
+ free_fontdataOC(dpy,
+ font_set->substitute, font_set->substitute_num);
+ Xfree(font_set->substitute);
+ font_set->substitute = NULL;
+ }
+ if(font_set->vmap) {
+ free_fontdataOC(dpy,
+ font_set->vmap, font_set->vmap_num);
+ Xfree(font_set->vmap);
+ font_set->vmap = NULL;
+ }
+ if(font_set->vrotate) {
+ free_fontdataOC(dpy,
+ (FontData)font_set->vrotate,
+ font_set->vrotate_num);
+ Xfree(font_set->vrotate);
+ font_set->vrotate = NULL;
+ }
+ }
+ Xfree(gen->font_set);
+ gen->font_set = NULL;
+ }
+}
+/* For VW/UDC end */
+
+static void
+destroy_oc(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+
+ if (gen->mbs_to_cs)
+ _XlcCloseConverter(gen->mbs_to_cs);
+
+ if (gen->wcs_to_cs)
+ _XlcCloseConverter(gen->wcs_to_cs);
+
+ if (gen->utf8_to_cs)
+ _XlcCloseConverter(gen->utf8_to_cs);
+
+/* For VW/UDC start */ /* Change 1996.01.8 */
+ destroy_fontdata(gen,dpy);
+/*
+*/
+/* For VW/UDC end */
+
+ if (oc->core.base_name_list)
+ Xfree(oc->core.base_name_list);
+
+ if (oc->core.font_info.font_name_list)
+ XFreeStringList(oc->core.font_info.font_name_list);
+
+ if (oc->core.font_info.font_struct_list) {
+ Xfree(oc->core.font_info.font_struct_list);
+ }
+
+ if (oc->core.missing_list.charset_list)
+ XFreeStringList(oc->core.missing_list.charset_list);
+
+#ifdef notdef
+ if (oc->core.res_name)
+ Xfree(oc->core.res_name);
+ if (oc->core.res_class)
+ Xfree(oc->core.res_class);
+#endif
+
+ Xfree(oc);
+}
+
+static char *
+set_oc_values(
+ XOC oc,
+ XlcArgList args,
+ int num_args)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ char *ret;
+ int num = gen->font_set_num;
+
+ if (oc->core.resources == NULL)
+ return NULL;
+
+ ret = _XlcSetValues((XPointer) oc, oc->core.resources,
+ oc->core.num_resources, args, num_args, XlcSetMask);
+ if(ret != NULL){
+ return(ret);
+ } else {
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+ if (font_set->vpart_initialize != 0)
+ continue;
+ if( oc->core.orientation == XOMOrientation_TTB_RTL ||
+ oc->core.orientation == XOMOrientation_TTB_LTR ){
+ load_fontdata(oc, font_set->vmap, font_set->vmap_num);
+ load_fontdata(oc, (FontData) font_set->vrotate,
+ font_set->vrotate_num);
+ font_set->vpart_initialize = 1;
+ }
+ }
+ return(NULL);
+ }
+}
+
+static char *
+get_oc_values(
+ XOC oc,
+ XlcArgList args,
+ int num_args)
+{
+ if (oc->core.resources == NULL)
+ return NULL;
+
+ return _XlcGetValues((XPointer) oc, oc->core.resources,
+ oc->core.num_resources, args, num_args, XlcGetMask);
+}
+
+static XOCMethodsRec oc_default_methods = {
+ destroy_oc,
+ set_oc_values,
+ get_oc_values,
+ _XmbDefaultTextEscapement,
+ _XmbDefaultTextExtents,
+ _XmbDefaultTextPerCharExtents,
+ _XmbDefaultDrawString,
+ _XmbDefaultDrawImageString,
+ _XwcDefaultTextEscapement,
+ _XwcDefaultTextExtents,
+ _XwcDefaultTextPerCharExtents,
+ _XwcDefaultDrawString,
+ _XwcDefaultDrawImageString,
+ _Xutf8DefaultTextEscapement,
+ _Xutf8DefaultTextExtents,
+ _Xutf8DefaultTextPerCharExtents,
+ _Xutf8DefaultDrawString,
+ _Xutf8DefaultDrawImageString
+};
+
+static XOCMethodsRec oc_generic_methods = {
+ destroy_oc,
+ set_oc_values,
+ get_oc_values,
+ _XmbGenericTextEscapement,
+ _XmbGenericTextExtents,
+ _XmbGenericTextPerCharExtents,
+ _XmbGenericDrawString,
+ _XmbGenericDrawImageString,
+ _XwcGenericTextEscapement,
+ _XwcGenericTextExtents,
+ _XwcGenericTextPerCharExtents,
+ _XwcGenericDrawString,
+ _XwcGenericDrawImageString,
+ _Xutf8GenericTextEscapement,
+ _Xutf8GenericTextExtents,
+ _Xutf8GenericTextPerCharExtents,
+ _Xutf8GenericDrawString,
+ _Xutf8GenericDrawImageString
+};
+
+typedef struct _XOCMethodsListRec {
+ const char *name;
+ XOCMethods methods;
+} XOCMethodsListRec, *XOCMethodsList;
+
+static XOCMethodsListRec oc_methods_list[] = {
+ { "default", &oc_default_methods },
+ { "generic", &oc_generic_methods }
+};
+
+static XlcResource oc_resources[] = {
+ { XNBaseFontName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
+ { XNOMAutomatic, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
+ { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
+ XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
+ { XNDefaultString, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.default_string), XlcGetMask },
+ { XNOrientation, NULLQUARK, sizeof(XOrientation),
+ XOffsetOf(XOCRec, core.orientation), XlcDefaultMask | XlcSetMask | XlcGetMask },
+ { XNResourceName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
+ { XNResourceClass, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
+ { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
+ XOffsetOf(XOCRec, core.font_info), XlcGetMask }
+};
+
+static XOC
+create_oc(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ XOC oc;
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ XOCMethodsList methods_list = oc_methods_list;
+ int count;
+
+ oc = Xcalloc(1, sizeof(XOCGenericRec));
+ if (oc == NULL)
+ return (XOC) NULL;
+
+ oc->core.om = om;
+
+ if (oc_resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
+
+ if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
+ args, num_args, XlcCreateMask | XlcDefaultMask))
+ goto err;
+
+ if (oc->core.base_name_list == NULL)
+ goto err;
+
+ oc->core.resources = oc_resources;
+ oc->core.num_resources = XlcNumber(oc_resources);
+
+ if (create_fontset(oc) == False)
+ goto err;
+
+ oc->methods = &oc_generic_methods;
+
+ if (gen->object_name) {
+ count = XlcNumber(oc_methods_list);
+
+ for ( ; count-- > 0; methods_list++) {
+ if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) {
+ oc->methods = methods_list->methods;
+ break;
+ }
+ }
+ }
+
+ return oc;
+
+err:
+ destroy_oc(oc);
+
+ return (XOC) NULL;
+}
+
+static void
+free_fontdataOM(
+ FontData font_data,
+ int font_data_count)
+{
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->name){
+ Xfree(font_data->name);
+ font_data->name = NULL;
+ }
+ if(font_data->scopes){
+ Xfree(font_data->scopes);
+ font_data->scopes = NULL;
+ }
+ }
+}
+
+static Status
+close_om(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ int count;
+
+ if ((data = gen->data)) {
+ for (count = gen->data_num; count-- > 0; data++) {
+ if (data->charset_list){
+ Xfree(data->charset_list);
+ data->charset_list = NULL;
+ }
+ /* free font_data for om */
+ if (data->font_data) {
+ free_fontdataOM(data->font_data,data->font_data_count);
+ Xfree(data->font_data);
+ data->font_data = NULL;
+ }
+ /* free substitute for om */
+ if (data->substitute) {
+ free_fontdataOM(data->substitute,data->substitute_num);
+ Xfree(data->substitute);
+ data->substitute = NULL;
+ }
+ /* free vmap for om */
+ if (data->vmap) {
+ free_fontdataOM(data->vmap,data->vmap_num);
+ Xfree(data->vmap);
+ data->vmap = NULL;
+ }
+ /* free vrotate for om */
+ if (data->vrotate) {
+ Xfree(data->vrotate);
+ data->vrotate = NULL;
+ }
+ }
+ Xfree(gen->data);
+ gen->data = NULL;
+ }
+
+ if (gen->object_name){
+ Xfree(gen->object_name);
+ gen->object_name = NULL;
+ }
+
+ if (om->core.res_name){
+ Xfree(om->core.res_name);
+ om->core.res_name = NULL;
+ }
+ if (om->core.res_class){
+ Xfree(om->core.res_class);
+ om->core.res_class = NULL;
+ }
+ if (om->core.required_charset.charset_list &&
+ om->core.required_charset.charset_count > 0){
+ XFreeStringList(om->core.required_charset.charset_list);
+ om->core.required_charset.charset_list = NULL;
+ } else {
+ Xfree((char*)om->core.required_charset.charset_list);
+ om->core.required_charset.charset_list = NULL;
+ }
+ if (om->core.orientation_list.orientation){
+ Xfree(om->core.orientation_list.orientation);
+ om->core.orientation_list.orientation = NULL;
+ }
+
+ Xfree(om);
+
+ return 1;
+}
+
+static char *
+set_om_values(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ if (om->core.resources == NULL)
+ return NULL;
+
+ return _XlcSetValues((XPointer) om, om->core.resources,
+ om->core.num_resources, args, num_args, XlcSetMask);
+}
+
+static char *
+get_om_values(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ if (om->core.resources == NULL)
+ return NULL;
+
+ return _XlcGetValues((XPointer) om, om->core.resources,
+ om->core.num_resources, args, num_args, XlcGetMask);
+}
+
+static XOMMethodsRec methods = {
+ close_om,
+ set_om_values,
+ get_om_values,
+ create_oc
+};
+
+static XlcResource om_resources[] = {
+ { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
+ XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
+ { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
+ XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
+ { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
+ { XNContextualDrawing, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
+};
+
+static XOM
+create_om(
+ XLCd lcd,
+ Display *dpy,
+ XrmDatabase rdb,
+ _Xconst char *res_name,
+ _Xconst char *res_class)
+{
+ XOM om;
+
+ om = Xcalloc(1, sizeof(XOMGenericRec));
+ if (om == NULL)
+ return (XOM) NULL;
+
+ om->methods = &methods;
+ om->core.lcd = lcd;
+ om->core.display = dpy;
+ om->core.rdb = rdb;
+ if (res_name) {
+ om->core.res_name = strdup(res_name);
+ if (om->core.res_name == NULL)
+ goto err;
+ }
+ if (res_class) {
+ om->core.res_class = strdup(res_class);
+ if (om->core.res_class == NULL)
+ goto err;
+ }
+
+ if (om_resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(om_resources, XlcNumber(om_resources));
+
+ om->core.resources = om_resources;
+ om->core.num_resources = XlcNumber(om_resources);
+
+ return om;
+
+err:
+ close_om(om);
+
+ return (XOM) NULL;
+}
+
+static OMData
+add_data(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData new;
+ int num;
+
+ if ((num = gen->data_num))
+ new = (OMData) Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec));
+ else
+ new = (OMData) Xmalloc(sizeof(OMDataRec));
+
+ if (new == NULL)
+ return NULL;
+
+ gen->data_num = num + 1;
+ gen->data = new;
+
+ new += num;
+ bzero((char *) new, sizeof(OMDataRec));
+
+ return new;
+}
+
+/* For VW/UDC */
+
+FontData
+read_EncodingInfo(
+ int count,
+ char **value)
+{
+ FontData font_data,ret;
+ char *buf, *bufptr,*scp;
+ int len;
+ font_data = Xcalloc(count, sizeof(FontDataRec));
+ if (font_data == NULL)
+ return NULL;
+
+ ret = font_data;
+ for ( ; count-- > 0; font_data++) {
+/*
+ strcpy(buf, *value++);
+*/
+ buf = *value; value++;
+ if ((bufptr = strchr(buf, ':'))) {
+ len = (int)(bufptr - buf);
+ bufptr++ ;
+ } else
+ len = strlen(buf);
+ font_data->name = (char *) Xmalloc(len + 1);
+ if (font_data->name == NULL) {
+ Xfree(font_data);
+ return NULL;
+ }
+ strncpy(font_data->name, buf,len);
+ font_data->name[len] = 0;
+ if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0)
+ font_data->side = XlcGL;
+ else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0)
+ font_data->side = XlcGR;
+ else
+ font_data->side = XlcGLGR;
+
+ if (bufptr && (scp = strchr(bufptr, '['))){
+ font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num));
+ }
+ }
+ return(ret);
+}
+
+static CodeRange read_vrotate(
+ int count,
+ char **value,
+ int *type,
+ int *vrotate_num)
+{
+ CodeRange range;
+ if(!strcmp(value[0],"all")){
+ *type = VROTATE_ALL ;
+ *vrotate_num = 0 ;
+ return (NULL);
+ } else if(*(value[0]) == '['){
+ *type = VROTATE_PART ;
+ range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num);
+ return (range);
+ } else {
+ *type = VROTATE_NONE ;
+ *vrotate_num = 0 ;
+ return (NULL);
+ }
+}
+
+static void read_vw(
+ XLCd lcd,
+ OMData font_set,
+ int num)
+{
+ char **value, buf[BUFSIZ];
+ int count;
+
+ sprintf(buf, "fs%d.font.vertical_map", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ _XlcDbg_printValue(buf,value,count);
+ font_set->vmap_num = count;
+ font_set->vmap = read_EncodingInfo(count,value);
+ }
+
+ sprintf(buf, "fs%d.font.vertical_rotate", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ _XlcDbg_printValue(buf,value,count);
+ font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type),
+ &(font_set->vrotate_num));
+ }
+}
+/* VW/UDC end */
+static Bool
+init_om(
+ XOM om)
+{
+ XLCd lcd = om->core.lcd;
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ XlcCharSet *charset_list;
+ FontData font_data;
+ char **required_list;
+ XOrientation *orientation;
+ char **value, buf[BUFSIZ], *bufptr;
+ int count = 0, num = 0, length = 0;
+
+ _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count);
+ if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0)
+ gen->on_demand_loading = True;
+
+ _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count);
+ if (count > 0) {
+ gen->object_name = strdup(*value);
+ if (gen->object_name == NULL)
+ return False;
+ }
+
+ for (num = 0; ; num++) {
+
+ sprintf(buf, "fs%d.charset.name", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+
+ if( count < 1){
+ sprintf(buf, "fs%d.charset", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1)
+ break;
+ }
+
+ data = add_data(om);
+ if (data == NULL)
+ return False;
+
+ charset_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet) * count);
+ if (charset_list == NULL)
+ return False;
+ data->charset_list = charset_list;
+ data->charset_count = count;
+
+ while (count-- > 0){
+ *charset_list++ = _XlcGetCharSet(*value++);
+ }
+ sprintf(buf, "fs%d.charset.udc_area", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if( count > 0){
+ UDCArea udc;
+ int i,flag = 0;
+ udc = (UDCArea)Xmalloc(count * sizeof(UDCAreaRec));
+ if (udc == NULL)
+ return False;
+ for(i=0;i<count;i++){
+ sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start),
+ &(udc[i].end));
+ }
+ for(i=0;i<data->charset_count;i++){
+ if(data->charset_list[i]->udc_area == NULL){
+ data->charset_list[i]->udc_area = udc;
+ data->charset_list[i]->udc_area_num = count;
+ flag = 1;
+ }
+ }
+ if(flag == 0){
+ Xfree(udc);
+ }
+ }
+
+ sprintf(buf, "fs%d.font.primary", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1){
+ sprintf(buf, "fs%d.font", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1)
+ return False;
+ }
+
+ font_data = read_EncodingInfo(count,value);
+ if (font_data == NULL)
+ return False;
+
+ data->font_data = font_data;
+ data->font_data_count = count;
+
+ sprintf(buf, "fs%d.font.substitute", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ font_data = read_EncodingInfo(count,value);
+ if (font_data == NULL)
+ return False;
+ data->substitute = font_data;
+ data->substitute_num = count;
+ } else {
+ sprintf(buf, "fs%d.font", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1) {
+ data->substitute = NULL;
+ data->substitute_num = 0;
+ } else {
+ font_data = read_EncodingInfo(count,value);
+ data->substitute = font_data;
+ data->substitute_num = count;
+ }
+ }
+ read_vw(lcd,data,num);
+ length += strlen(data->font_data->name) + 1;
+ }
+
+ /* required charset list */
+ required_list = (char **) Xmalloc(sizeof(char *) * gen->data_num);
+ if (required_list == NULL)
+ return False;
+
+ om->core.required_charset.charset_list = required_list;
+ om->core.required_charset.charset_count = gen->data_num;
+
+ count = gen->data_num;
+ data = gen->data;
+
+ if (count > 0) {
+ bufptr = (char *) Xmalloc(length);
+ if (bufptr == NULL) {
+ Xfree(required_list);
+ return False;
+ }
+
+ for ( ; count-- > 0; data++) {
+ strcpy(bufptr, data->font_data->name);
+ *required_list++ = bufptr;
+ bufptr += strlen(bufptr) + 1;
+ }
+ }
+
+ /* orientation list */
+ orientation = (XOrientation *) Xmalloc(sizeof(XOrientation) * 2);
+ if (orientation == NULL)
+ return False;
+
+ orientation[0] = XOMOrientation_LTR_TTB;
+ orientation[1] = XOMOrientation_TTB_RTL;
+ om->core.orientation_list.orientation = orientation;
+ om->core.orientation_list.num_orientation = 2;
+
+ /* directional dependent drawing */
+ om->core.directional_dependent = False;
+
+ /* contexual drawing */
+ om->core.contextual_drawing = False;
+
+ /* context dependent */
+ om->core.context_dependent = False;
+
+ return True;
+}
+
+XOM
+_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
+ _Xconst char *res_name, _Xconst char *res_class)
+{
+ XOM om;
+
+ om = create_om(lcd, dpy, rdb, res_name, res_class);
+ if (om == NULL)
+ return (XOM) NULL;
+
+ if (init_om(om) == False)
+ goto err;
+
+ return om;
+
+err:
+ close_om(om);
+
+ return (XOM) NULL;
+}
+
+Bool
+_XInitOM(
+ XLCd lcd)
+{
+ lcd->methods->open_om = _XomGenericOpenOM;
+
+ return True;
+}
diff --git a/libX11/nls/makefile b/libX11/nls/makefile new file mode 100644 index 000000000..e6bf47297 --- /dev/null +++ b/libX11/nls/makefile @@ -0,0 +1,85 @@ +X11_LOCALEDATADIR = ..\..\xorg-server\locale
+
+x11localedir = $(X11_LOCALEDATADIR)
+x11locale_DATA = locale.alias locale.dir compose.dir
+locales = \
+ am_ET.UTF-8 \
+ armscii-8 \
+ C \
+ el_GR.UTF-8 \
+ en_US.UTF-8 \
+ fi_FI.UTF-8 \
+ georgian-academy \
+ georgian-ps \
+ ibm-cp1133 \
+ iscii-dev \
+ isiri-3342 \
+ iso8859-1 \
+ iso8859-10 \
+ iso8859-11 \
+ iso8859-13 \
+ iso8859-14 \
+ iso8859-15 \
+ iso8859-2 \
+ iso8859-3 \
+ iso8859-4 \
+ iso8859-5 \
+ iso8859-6 \
+ iso8859-7 \
+ iso8859-8 \
+ iso8859-9 \
+ iso8859-9e \
+ ja \
+ ja.JIS \
+ ja_JP.UTF-8 \
+ ja.S90 \
+ ja.SJIS \
+ ja.U90 \
+ ko \
+ koi8-c \
+ koi8-r \
+ koi8-u \
+ ko_KR.UTF-8 \
+ microsoft-cp1251 \
+ microsoft-cp1255 \
+ microsoft-cp1256 \
+ mulelao-1 \
+ nokhchi-1 \
+ pt_BR.UTF-8 \
+ ru_RU.UTF-8 \
+ tatar-cyr \
+ th_TH \
+ th_TH.UTF-8 \
+ tscii-0 \
+ vi_VN.tcvn \
+ vi_VN.viscii \
+ zh_CN \
+ zh_CN.gb18030 \
+ zh_CN.gbk \
+ zh_CN.UTF-8 \
+ zh_HK.big5 \
+ zh_HK.big5hkscs \
+ zh_HK.UTF-8 \
+ zh_TW \
+ zh_TW.big5 \
+ zh_TW.UTF-8
+
+include ../cpprules.mak
+
+
+$(X11_LOCALEDATADIR)\%: %.pre
+ cl /nologo /EP $< -DXCOMM\#\# > $<.l1
+ sed -e "/^[^\#][^ ]*:/s/://" -e "/^[^\#].*[ ].*:/d" < $<.l1 > $<.l2
+ type $<.l2 $<.l1 > $@
+ del $<.l1
+ del $<.l2
+
+# Per-locale data files
+
+nobase_dist_x11locale_DATA = $(locales:%=%\XI18N_OBJS)
+
+nobase_x11locale_DATA = $(locales:%=%\XLC_LOCALE) $(locales:%=%\Compose)
+
+all_DATA = $(nobase_dist_x11locale_DATA) $(nobase_x11locale_DATA) $(x11locale_DATA)
+
+all: $(all_DATA:%=$(X11_LOCALEDATADIR)\%)
diff --git a/libX11/specs/XIM/Makefile.am b/libX11/specs/XIM/Makefile.am index 68b0b3f48..a7da39b6f 100644 --- a/libX11/specs/XIM/Makefile.am +++ b/libX11/specs/XIM/Makefile.am @@ -1,23 +1,23 @@ - -if ENABLE_SPECS - -# Main DocBook/XML files (DOCTYPE book) -docbook = xim.xml - -# Included chapters, appendix, images -chapters = \ - dynamicflowsampleseq.svg \ - dynamicflow.svg \ - eventflow.svg \ - sampleprotocolflow1.svg \ - sampleprotocolflow2.svg \ - staticflowsampleseq.svg \ - staticflow.svg - -# The location where the DocBook/XML files and their generated formats are installed -shelfdir = $(docdir)/XIM - -# Generate DocBook/XML output formats with or without stylesheets -include $(top_srcdir)/docbook.am - -endif ENABLE_SPECS +
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = xim.xml
+
+# Included chapters, appendix, images
+chapters = \
+ dynamicflowsampleseq.svg \
+ dynamicflow.svg \
+ eventflow.svg \
+ sampleprotocolflow1.svg \
+ sampleprotocolflow2.svg \
+ staticflowsampleseq.svg \
+ staticflow.svg
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)/XIM
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/libX11/specs/i18n/framework/Makefile.am b/libX11/specs/i18n/framework/Makefile.am index af7ae1d0e..38db989db 100644 --- a/libX11/specs/i18n/framework/Makefile.am +++ b/libX11/specs/i18n/framework/Makefile.am @@ -1,16 +1,16 @@ - -if ENABLE_SPECS - -# Main DocBook/XML files (DOCTYPE book) -docbook = framework.xml - -# Included chapters, appendix, images -chapters = framework.svg - -# The location where the DocBook/XML files and their generated formats are installed -shelfdir = $(docdir)/i18n/framework - -# Generate DocBook/XML output formats with or without stylesheets -include $(top_srcdir)/docbook.am - -endif ENABLE_SPECS +
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = framework.xml
+
+# Included chapters, appendix, images
+chapters = framework.svg
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)/i18n/framework
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/libX11/specs/i18n/localedb/Makefile.am b/libX11/specs/i18n/localedb/Makefile.am index 68a917c95..e7ae3523f 100644 --- a/libX11/specs/i18n/localedb/Makefile.am +++ b/libX11/specs/i18n/localedb/Makefile.am @@ -1,13 +1,13 @@ - -if ENABLE_SPECS - -# Main DocBook/XML files (DOCTYPE book) -docbook = localedb.xml - -# The location where the DocBook/XML files and their generated formats are installed -shelfdir = $(docdir)/i18n/localedb - -# Generate DocBook/XML output formats with or without stylesheets -include $(top_srcdir)/docbook.am - -endif ENABLE_SPECS +
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = localedb.xml
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)/i18n/localedb
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/libX11/specs/i18n/localedb/localedb.xml b/libX11/specs/i18n/localedb/localedb.xml index c4f6d1377..7b27d9f0c 100644 --- a/libX11/specs/i18n/localedb/localedb.xml +++ b/libX11/specs/i18n/localedb/localedb.xml @@ -1,777 +1,777 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> - -<book id="localedb"> - -<bookinfo> - <title>X Locale Database Specification</title> - <authorgroup> - <author> - <firstname>Yoshio</firstname><surname>Horiuchi</surname> - <affiliation><orgname>IBM Japan</orgname></affiliation> - </author> - </authorgroup> - <copyright><year>1994</year><holder>IBM Corporation</holder></copyright> - <copyright><year>1994</year><holder>X Consortium</holder></copyright> - - -<legalnotice> - -<para> -License to use, copy, modify, and distribute this software and its documentation for -any purpose and without fee is hereby granted, 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 IBM not be used in advertising -or publicity pertaining to distribution of the software without specific, written -prior permission. -</para> -<para> -IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY, FITNESS, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS, -IN NO EVENT SHALL IBM 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. -</para> - -<para> -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: -</para> - -<para> -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -</para> - -<para> -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 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -</para> - -<para> -Except as contained in this notice, the name of The Open Group shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from X Consortium. -</para> - -<para>X Window System is a trademark of The Open Group.</para> - -</legalnotice> -</bookinfo> - -<chapter id="localeDatabase"> -<title>LocaleDB</title> - -<sect1 id="General"> -<title>General</title> -<para> -An X Locale Database contains the subset of a user's environment that -depends on language, in X Window System. It is made up from one or more -categories. Each category consists of some classes and sub-classes. -</para> - -<para> -It is provided as a plain ASCII text file, so a user can change its -contents easily. It allows a user to customize the behavior of -internationalized portion of Xlib without changing Xlib itself. -</para> - -<para> -This document describes; -</para> - -<itemizedlist> - <listitem> - <para> -Database Format Definition - </para> - </listitem> - <listitem> - <para> -Contents of Database in sample implementation -<!-- .RE --> - </para> - </listitem> -</itemizedlist> - -<para> -Since it is hard to define the set of required information for all -platforms, only the flexible database format is defined. -The available entries in database are implementation dependent. -</para> - -</sect1> -<sect1 id="Database_Format_Definition"> -<title>Database Format Definition</title> -<para> -The X Locale Database contains one or more category definitions. -This section describes the format of each category definition. -</para> - -<para> -The category definition consists of one or more class definitions. -Each class definition has a pair of class name and class value, or -has several subclasses which are enclosed by the left brace ({) and -the right brace (}). -</para> - -<para> -Comments can be placed by using the number sign character (#). -Putting the number sign character on the top of the line indicates -that the entire line is comment. Also, putting any whitespace character -followed by the number sign character indicates that a part of the line -(from the number sign to the end of the line) is comment. -A line can be continued by placing backslash (\) character as the -last character on the line; this continuation character will be -discarded from the input. Comment lines cannot be continued on -a subsequent line using an escaped new line character. -</para> - -<para> -X Locale Database only accepts XPCS, the X Portable Character Set. -The reserved symbols are; the quotation mark("), the number sign (#), -the semicolon(;), the backslash(\), the left brace({) and -the right brace(}). -</para> - -<para> -The format of category definition is; -</para> - -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <colspec colname='c1' colwidth="3*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <colspec colname='c3' colwidth="6*" colsep="0"/> - <tbody> - <row rowsep="0"> - <entry>CategoryDefinition</entry> - <entry>::=</entry> - <entry>CategoryHeader CategorySpec CategoryTrailer</entry> - </row> - <row rowsep="0"> - <entry>CategoryHeader</entry> - <entry>::=</entry> - <entry>CategoryName NL</entry> - </row> - <row rowsep="0"> - <entry>CategorySpec</entry> - <entry>::=</entry> - <entry>{ ClassSpec }</entry> - </row> - <row rowsep="0"> - <entry>CategoryTrailer</entry> - <entry>::=</entry> - <entry>"END" Delimiter CategoryName NL</entry> - </row> - <row rowsep="0"> - <entry>CategoryName</entry> - <entry>::=</entry> - <entry>String</entry> - </row> - <row rowsep="0"> - <entry>ClassSpec</entry> - <entry>::=</entry> - <entry>ClassName Delimiter ClassValue NL</entry> - </row> - <row rowsep="0"> - <entry>ClassName</entry> - <entry>::=</entry> - <entry>String</entry> - </row> - <row rowsep="0"> - <entry>ClassValue</entry> - <entry>::=</entry> - <entry>ValueList | "{" NL { ClassSpec } "}"</entry> - </row> - <row rowsep="0"> - <entry>ValueList</entry> - <entry>::=</entry> - <entry>Value | Value ";" ValueList</entry> - </row> - <row rowsep="0"> - <entry>Value</entry> - <entry>::=</entry> - <entry>ValuePiece | ValuePiece Value</entry> - </row> - <row rowsep="0"> - <entry>ValuePiece</entry> - <entry>::=</entry> - <entry>String | QuotedString | NumericString</entry> - </row> - <row rowsep="0"> - <entry>String</entry> - <entry>::=</entry> - <entry>Char { Char }</entry> - </row> - <row rowsep="0"> - <entry>QuotedString</entry> - <entry>::=</entry> - <entry>""" QuotedChar { QuotedChar } """</entry> - </row> - <row rowsep="0"> - <entry>NumericString</entry> - <entry>::=</entry> - <entry>"\\o" OctDigit { OctDigit }</entry> - </row> - <row rowsep="0"> - <entry></entry> - <entry>|</entry> - <entry>"\\d" DecDigit { DecDigit }</entry> - </row> - <row rowsep="0"> - <entry></entry> - <entry>|</entry> - <entry>"\\x" HexDigit { HexDigit }</entry> - </row> - <row rowsep="0"> - <entry>Char</entry> - <entry>::=</entry> - <entry><XPCS except NL, Space or unescaped reserved symbols></entry> - </row> - <row rowsep="0"> - <entry>QuotedChar</entry> - <entry>::=</entry> - <entry><XPCS except unescaped """></entry> - </row> - <row rowsep="0"> - <entry>OctDigit</entry> - <entry>::=</entry> - <entry><character in the range of "0" - "7"></entry> - </row> - <row rowsep="0"> - <entry>DecDigit</entry> - <entry>::=</entry> - <entry><character in the range of "0" - "9"></entry> - </row> - <row rowsep="0"> - <entry>HexDigit</entry> - <entry>::=</entry> - <entry><character in the range of "0" - "9", "a" - "f", "A" - "F"></entry> - </row> - <row rowsep="0"> - <entry>Delimiter</entry> - <entry>::=</entry> - <entry>Space { Space }</entry> - </row> - <row rowsep="0"> - <entry>Space</entry> - <entry>::=</entry> - <entry><space> | <horizontal tab></entry> - </row> - <row rowsep="0"> - <entry>NL</entry> - <entry>::=</entry> - <entry><newline></entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -Elements separated by vertical bar (|) are alternatives. Curly -braces ({...}) indicate zero or more repetitions of the enclosed -elements. Square brackets ([...]) indicate that the enclosed element -is optional. Quotes ("...") are used around literal characters. -</para> - -<para> -The backslash, which is not the top character of the NumericString, is -recognized as an escape character, so that the next one character is -treated as a literal character. For example, the two-character -sequence, ""\"""(the backslash followed by the quotation mark) is -recognized and replaced with a quotation mark character. -Any whitespace character, that is not the Delimiter, unquoted and -unescaped, is ignored. -</para> - -</sect1> -<sect1 id="Contents_of_Database_"> -<title>Contents of Database </title> -<para> -The available categories and classes depend on implementation, because -different platform will require different information set. -For example, some platform have system locale but some platform don't. -Furthermore, there might be a difference in functionality even if the -platform has system locale. -</para> - -<para> -In current sample implementation, categories listed below are available. -</para> - -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <colspec colname='c1' colwidth="2*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <tbody> - <row rowsep="0"> - <entry>XLC_FONTSET:XFontSet relative information</entry> - </row> - <row rowsep="0"> - <entry>XLC_XLOCALE:Character classification and conversion information</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -</sect1> -<sect1 id="XLC_FONTSET_Category"> -<title>XLC_FONTSET Category</title> -<para> -The XLC_FONTSET category defines the XFontSet relative information. -It contains the CHARSET_REGISTRY-CHARSET_ENCODING name and character -mapping side (GL, GR, etc), and is used in Output Method (OM). -</para> - -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <thead> - <colspec colname='c1' colwidth="3*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <colspec colname='c3' colwidth="3*" colsep="0"/> - <row> - <entry>class</entry> - <entry>super class</entry> - <entry>description</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>fsN</entry> - <entry></entry> - <entry>Nth fontset (N=0,1,2, ...)</entry> - </row> - <row rowsep="0"> - <entry>charset</entry> - <entry>fsN</entry> - <entry>list of encoding name</entry> - </row> - <row rowsep="0"> - <entry>font</entry> - <entry>fsN</entry> - <entry>list of font encoding name</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<variablelist> - <varlistentry> - <term>fsN</term> - <listitem> - <para> -Includes an encoding information for Nth charset, where N is -the index number (0,1,2,...). If there are 4 charsets available -in current locale, 4 fontsets, fs0, fs1, fs2 and fs3, should be -defined. -This class has two subclasses, 'charset' and 'font'. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>charset</term> - <listitem> - <para> -Specifies an encoding information to be used internally in Xlib -for this fontset. The format of value is; - </para> -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <colspec colname='c1' colwidth="3*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <colspec colname='c3' colwidth="4*" colsep="0"/> - <tbody> - <row rowsep="0"> - <entry>EncodingInfo</entry> - <entry>::=</entry> - <entry>EncodingName [ ":" EncodingSide ]</entry> - </row> - <row rowsep="0"> - <entry>EncodingName</entry> - <entry>::=</entry> - <entry>CHARSET_REGISTRY-CHARSET_ENCODING</entry> - </row> - <row rowsep="0"> - <entry>EncodingSide</entry> - <entry>::=</entry> - <entry>"GL" | "GR"</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -For detail definition of CHARSET_REGISTRY-CHARSET_ENCODING, refer -"X Logical Font Descriptions" document. -</para> -<literallayout> -example: - ISO8859-1:GL -</literallayout> - </listitem> - </varlistentry> - <varlistentry> - <term>font</term> - <listitem> - <para> -Specifies a list of encoding information which is used for searching -appropriate font for this fontset. The left most entry has highest -priority. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect1> -<sect1 id="XLC_XLOCALE_Category"> -<title>XLC_XLOCALE Category</title> -<para> -The XLC_XLOCALE category defines character classification, conversion -and other character attributes. -</para> - -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <colspec colname='c1' colwidth="3*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <colspec colname='c3' colwidth="3*" colsep="0"/> - <thead> - <row> - <entry>class</entry> - <entry>super class</entry> - <entry>description</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>encoding_name</entry> - <entry></entry> - <entry>codeset name</entry> - </row> - <row rowsep="0"> - <entry>mb_cur_max</entry> - <entry></entry> - <entry>MB_CUR_MAX</entry> - </row> - <row rowsep="0"> - <entry>state_depend_encoding</entry> - <entry></entry> - <entry>state dependent or not</entry> - </row> - <row rowsep="0"> - <entry>wc_encoding_mask</entry> - <entry></entry> - <entry>for parsing wc string</entry> - </row> - <row rowsep="0"> - <entry>wc_shift_bits</entry> - <entry></entry> - <entry>for conversion between wc and mb</entry> - </row> - <row rowsep="0"> - <entry>csN</entry> - <entry></entry> - <entry>Nth charset (N=0,1,2,...)</entry> - </row> - <row rowsep="0"> - <entry>side</entry> - <entry>csN</entry> - <entry>mapping side (GL, etc)</entry> - </row> - <row rowsep="0"> - <entry>length</entry> - <entry>csN</entry> - <entry>length of a character</entry> - </row> - <row rowsep="0"> - <entry>mb_encoding</entry> - <entry>csN</entry> - <entry>for parsing mb string</entry> - </row> - <row rowsep="0"> - <entry>wc_encoding</entry> - <entry>csN</entry> - <entry>for parsing wc string</entry> - </row> - <row rowsep="0"> - <entry>ct_encoding</entry> - <entry>csN</entry> - <entry>list of encoding name for ct</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<variablelist> - <varlistentry> - <term>encoding_name</term> - <listitem> - <para> -Specifies a codeset name of current locale. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>mb_cur_max</term> - <listitem> - <para> -Specifies a maximum allowable number of bytes in a multi-byte character. -It is corresponding to MB_CUR_MAX of "ISO/IEC 9899:1990 C Language Standard". - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>state_depend_encoding</term> - <listitem> - <para> -Indicates a current locale is state dependent. The value should be -specified "True" or "False". - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>wc_encoding_mask</term> - <listitem> - <para> -Specifies a bit-mask for parsing wide-char string. Each wide character is -applied bit-and operation with this bit-mask, then is classified into -the unique charset, by using 'wc_encoding'. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>wc_shift_bits</term> - <listitem> - <para> -Specifies a number of bit to be shifted for converting from a multi-byte -character to a wide character, and vice-versa. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>csN</term> - <listitem> - <para> -<!-- .br --> -Includes a character set information for Nth charset, where N is the -index number (0,1,2,...). If there are 4 charsets available in current -locale, cs0, cs1, cs2 and cs3 should be defined. This class has five -subclasses, 'side', 'length', 'mb_encoding' 'wc_encoding' and 'ct_encoding'. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>side</term> - <listitem> - <para> -Specifies a mapping side of this charset. The format of this value is; - </para> - <literallayout> - Side ::= EncodingSide[":Default"] - </literallayout> - <para> -The suffix ":Default" can be specified. It indicates that a character -belongs to the specified side is mapped to this charset in initial state. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>length</term> - <listitem> - <para> -<!-- .br --> -Specifies a number of bytes of a multi-byte character of this charset. -It should not contain the length of any single-shift sequence. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>mb_encoding</term> - <listitem> - <para> -Specifies a list of shift sequence for parsing multi-byte string. -The format of this value is; - </para> -<informaltable frame="none"> - <tgroup cols='3' align='left'> - <colspec colname='c1' colwidth="3*" colsep="0"/> - <colspec colname='c2' colwidth="1*" colsep="0"/> - <colspec colname='c3' colwidth="5*" colsep="0"/> - <tbody> - <row rowsep="0"> - <entry>MBEncoding</entry> - <entry>::=</entry> - <entry>ShiftType ShiftSequence</entry> - </row> - <row rowsep="0"> - <entry></entry> - <entry>|</entry> - <entry>ShiftType ShiftSequence ";" MBEncoding</entry> - </row> - <row rowsep="0"> - <entry>ShiftType</entry> - <entry>::=</entry> - <entry>"<SS>"|"<LSL>"|"<LSR>"</entry> - </row> - <row rowsep="0"> - <entry>ShiftSequence</entry> - <entry>::=</entry> - <entry>SequenceValue|SequenceValue ShiftSequence</entry> - </row> - <row rowsep="0"> - <entry>SequenceValue</entry> - <entry>::=</entry> - <entry>NumericString</entry> - </row> - </tbody> - </tgroup> -</informaltable> - - <literallayout> -example: - <LSL> \x1b \x28 \x4a; <LSL> \x1b \x28 \x42 - </literallayout> - </listitem> - </varlistentry> - <varlistentry> - <term>wc_encoding</term> - <listitem> - <para> -Specifies an integer value for parsing wide-char string. -It is used to determine the charset for each wide character, after -applying bit-and operation using 'wc_encoding_mask'. -This value should be unique in all csN classes. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>ct_encoding</term> - <listitem> - <para> -Specifies a list of encoding information that can be used for Compound -Text. - </para> - </listitem> - </varlistentry> -</variablelist> -</sect1> - -<sect1 id="Sample_of_X_Locale_Database"> -<title>Sample of X Locale Database</title> -<para> -The following is sample X Locale Database file. -</para> - -<literallayout class="monospaced"> -# XLocale Database Sample for ja_JP.euc -# - -# -# XLC_FONTSET category -# -XLC_FONTSET -# fs0 class (7 bit ASCII) -fs0 { - charset ISO8859-1:GL - font ISO8859-1:GL; JISX0201.1976-0:GL -} -# fs1 class (Kanji) -fs1 { - charset JISX0208.1983-0:GL - font JISX0208.1983-0:GL -} -# fs2 class (Half Kana) -fs2 { - charset JISX0201.1976-0:GR - font JISX0201.1976-0:GR -} -# fs3 class (User Defined Character) -# fs3 { -# charset JISX0212.1990-0:GL -# font JISX0212.1990-0:GL -# } -END XLC_FONTSET - -# -# XLC_XLOCALE category -# -XLC_XLOCALE - -encoding_name ja.euc -mb_cur_max 3 -state_depend_encoding False - -wc_encoding_mask \x00008080 -wc_shift_bits 8 - -# cs0 class -cs0 { - side GL:Default - length 1 - wc_encoding \x00000000 - ct_encoding ISO8859-1:GL; JISX0201.1976-0:GL -} -# cs1 class -cs1 { - side GR:Default - length 2 - - wc_encoding \x00008080 - - ct_encoding JISX0208.1983-0:GL; JISX0208.1983-0:GR;\ - JISX0208.1983-1:GL; JISX0208.1983-1:GR -} - -# cs2 class -cs2 { - side GR - length 1 - mb_encoding <SS> \x8e - - wc_encoding \x00000080 - - ct_encoding JISX0201.1976-0:GR -} - -# cs3 class -# cs3 { -# side GL -# length 2 -# mb_encoding <SS> \x8f -# #if HasWChar32 -# wc_encoding \x20000000 -# #else -# wc_encoding \x00008000 -# #endif -# ct_encoding JISX0212.1990-0:GL; JISX0212.1990-0:GR -# } - -END XLC_XLOCALE -</literallayout> -</sect1> - -<sect1 id="Reference"> -<title>Reference</title> -<para> -[1] <emphasis remap='I'>ISO/IEC 9899:1990 C Language Standard</emphasis> -</para> -<para> -[2] <emphasis remap='I'>X Logical Font Descriptions</emphasis> -</para> - -</sect1> -</chapter> -</book> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<book id="localedb">
+
+<bookinfo>
+ <title>X Locale Database Specification</title>
+ <authorgroup>
+ <author>
+ <firstname>Yoshio</firstname><surname>Horiuchi</surname>
+ <affiliation><orgname>IBM Japan</orgname></affiliation>
+ </author>
+ </authorgroup>
+ <copyright><year>1994</year><holder>IBM Corporation</holder></copyright>
+ <copyright><year>1994</year><holder>X Consortium</holder></copyright>
+
+
+<legalnotice>
+
+<para>
+License to use, copy, modify, and distribute this software and its documentation for
+any purpose and without fee is hereby granted, 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 IBM not be used in advertising
+or publicity pertaining to distribution of the software without specific, written
+prior permission.
+</para>
+<para>
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS,
+IN NO EVENT SHALL IBM 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.
+</para>
+
+<para>
+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:
+</para>
+
+<para>
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+</para>
+
+<para>
+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 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+</para>
+
+<para>
+Except as contained in this notice, the name of The Open Group shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from X Consortium.
+</para>
+
+<para>X Window System is a trademark of The Open Group.</para>
+
+</legalnotice>
+</bookinfo>
+
+<chapter id="localeDatabase">
+<title>LocaleDB</title>
+
+<sect1 id="General">
+<title>General</title>
+<para>
+An X Locale Database contains the subset of a user's environment that
+depends on language, in X Window System. It is made up from one or more
+categories. Each category consists of some classes and sub-classes.
+</para>
+
+<para>
+It is provided as a plain ASCII text file, so a user can change its
+contents easily. It allows a user to customize the behavior of
+internationalized portion of Xlib without changing Xlib itself.
+</para>
+
+<para>
+This document describes;
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+Database Format Definition
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Contents of Database in sample implementation
+<!-- .RE -->
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+Since it is hard to define the set of required information for all
+platforms, only the flexible database format is defined.
+The available entries in database are implementation dependent.
+</para>
+
+</sect1>
+<sect1 id="Database_Format_Definition">
+<title>Database Format Definition</title>
+<para>
+The X Locale Database contains one or more category definitions.
+This section describes the format of each category definition.
+</para>
+
+<para>
+The category definition consists of one or more class definitions.
+Each class definition has a pair of class name and class value, or
+has several subclasses which are enclosed by the left brace ({) and
+the right brace (}).
+</para>
+
+<para>
+Comments can be placed by using the number sign character (#).
+Putting the number sign character on the top of the line indicates
+that the entire line is comment. Also, putting any whitespace character
+followed by the number sign character indicates that a part of the line
+(from the number sign to the end of the line) is comment.
+A line can be continued by placing backslash (\) character as the
+last character on the line; this continuation character will be
+discarded from the input. Comment lines cannot be continued on
+a subsequent line using an escaped new line character.
+</para>
+
+<para>
+X Locale Database only accepts XPCS, the X Portable Character Set.
+The reserved symbols are; the quotation mark("), the number sign (#),
+the semicolon(;), the backslash(\), the left brace({) and
+the right brace(}).
+</para>
+
+<para>
+The format of category definition is;
+</para>
+
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <colspec colname='c1' colwidth="3*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <colspec colname='c3' colwidth="6*" colsep="0"/>
+ <tbody>
+ <row rowsep="0">
+ <entry>CategoryDefinition</entry>
+ <entry>::=</entry>
+ <entry>CategoryHeader CategorySpec CategoryTrailer</entry>
+ </row>
+ <row rowsep="0">
+ <entry>CategoryHeader</entry>
+ <entry>::=</entry>
+ <entry>CategoryName NL</entry>
+ </row>
+ <row rowsep="0">
+ <entry>CategorySpec</entry>
+ <entry>::=</entry>
+ <entry>{ ClassSpec }</entry>
+ </row>
+ <row rowsep="0">
+ <entry>CategoryTrailer</entry>
+ <entry>::=</entry>
+ <entry>"END" Delimiter CategoryName NL</entry>
+ </row>
+ <row rowsep="0">
+ <entry>CategoryName</entry>
+ <entry>::=</entry>
+ <entry>String</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ClassSpec</entry>
+ <entry>::=</entry>
+ <entry>ClassName Delimiter ClassValue NL</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ClassName</entry>
+ <entry>::=</entry>
+ <entry>String</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ClassValue</entry>
+ <entry>::=</entry>
+ <entry>ValueList | "{" NL { ClassSpec } "}"</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ValueList</entry>
+ <entry>::=</entry>
+ <entry>Value | Value ";" ValueList</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Value</entry>
+ <entry>::=</entry>
+ <entry>ValuePiece | ValuePiece Value</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ValuePiece</entry>
+ <entry>::=</entry>
+ <entry>String | QuotedString | NumericString</entry>
+ </row>
+ <row rowsep="0">
+ <entry>String</entry>
+ <entry>::=</entry>
+ <entry>Char { Char }</entry>
+ </row>
+ <row rowsep="0">
+ <entry>QuotedString</entry>
+ <entry>::=</entry>
+ <entry>""" QuotedChar { QuotedChar } """</entry>
+ </row>
+ <row rowsep="0">
+ <entry>NumericString</entry>
+ <entry>::=</entry>
+ <entry>"\\o" OctDigit { OctDigit }</entry>
+ </row>
+ <row rowsep="0">
+ <entry></entry>
+ <entry>|</entry>
+ <entry>"\\d" DecDigit { DecDigit }</entry>
+ </row>
+ <row rowsep="0">
+ <entry></entry>
+ <entry>|</entry>
+ <entry>"\\x" HexDigit { HexDigit }</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Char</entry>
+ <entry>::=</entry>
+ <entry><XPCS except NL, Space or unescaped reserved symbols></entry>
+ </row>
+ <row rowsep="0">
+ <entry>QuotedChar</entry>
+ <entry>::=</entry>
+ <entry><XPCS except unescaped """></entry>
+ </row>
+ <row rowsep="0">
+ <entry>OctDigit</entry>
+ <entry>::=</entry>
+ <entry><character in the range of "0" - "7"></entry>
+ </row>
+ <row rowsep="0">
+ <entry>DecDigit</entry>
+ <entry>::=</entry>
+ <entry><character in the range of "0" - "9"></entry>
+ </row>
+ <row rowsep="0">
+ <entry>HexDigit</entry>
+ <entry>::=</entry>
+ <entry><character in the range of "0" - "9", "a" - "f", "A" - "F"></entry>
+ </row>
+ <row rowsep="0">
+ <entry>Delimiter</entry>
+ <entry>::=</entry>
+ <entry>Space { Space }</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Space</entry>
+ <entry>::=</entry>
+ <entry><space> | <horizontal tab></entry>
+ </row>
+ <row rowsep="0">
+ <entry>NL</entry>
+ <entry>::=</entry>
+ <entry><newline></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+Elements separated by vertical bar (|) are alternatives. Curly
+braces ({...}) indicate zero or more repetitions of the enclosed
+elements. Square brackets ([...]) indicate that the enclosed element
+is optional. Quotes ("...") are used around literal characters.
+</para>
+
+<para>
+The backslash, which is not the top character of the NumericString, is
+recognized as an escape character, so that the next one character is
+treated as a literal character. For example, the two-character
+sequence, ""\"""(the backslash followed by the quotation mark) is
+recognized and replaced with a quotation mark character.
+Any whitespace character, that is not the Delimiter, unquoted and
+unescaped, is ignored.
+</para>
+
+</sect1>
+<sect1 id="Contents_of_Database_">
+<title>Contents of Database </title>
+<para>
+The available categories and classes depend on implementation, because
+different platform will require different information set.
+For example, some platform have system locale but some platform don't.
+Furthermore, there might be a difference in functionality even if the
+platform has system locale.
+</para>
+
+<para>
+In current sample implementation, categories listed below are available.
+</para>
+
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <colspec colname='c1' colwidth="2*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <tbody>
+ <row rowsep="0">
+ <entry>XLC_FONTSET:XFontSet relative information</entry>
+ </row>
+ <row rowsep="0">
+ <entry>XLC_XLOCALE:Character classification and conversion information</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+</sect1>
+<sect1 id="XLC_FONTSET_Category">
+<title>XLC_FONTSET Category</title>
+<para>
+The XLC_FONTSET category defines the XFontSet relative information.
+It contains the CHARSET_REGISTRY-CHARSET_ENCODING name and character
+mapping side (GL, GR, etc), and is used in Output Method (OM).
+</para>
+
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <thead>
+ <colspec colname='c1' colwidth="3*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <colspec colname='c3' colwidth="3*" colsep="0"/>
+ <row>
+ <entry>class</entry>
+ <entry>super class</entry>
+ <entry>description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>fsN</entry>
+ <entry></entry>
+ <entry>Nth fontset (N=0,1,2, ...)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>charset</entry>
+ <entry>fsN</entry>
+ <entry>list of encoding name</entry>
+ </row>
+ <row rowsep="0">
+ <entry>font</entry>
+ <entry>fsN</entry>
+ <entry>list of font encoding name</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<variablelist>
+ <varlistentry>
+ <term>fsN</term>
+ <listitem>
+ <para>
+Includes an encoding information for Nth charset, where N is
+the index number (0,1,2,...). If there are 4 charsets available
+in current locale, 4 fontsets, fs0, fs1, fs2 and fs3, should be
+defined.
+This class has two subclasses, 'charset' and 'font'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>charset</term>
+ <listitem>
+ <para>
+Specifies an encoding information to be used internally in Xlib
+for this fontset. The format of value is;
+ </para>
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <colspec colname='c1' colwidth="3*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <colspec colname='c3' colwidth="4*" colsep="0"/>
+ <tbody>
+ <row rowsep="0">
+ <entry>EncodingInfo</entry>
+ <entry>::=</entry>
+ <entry>EncodingName [ ":" EncodingSide ]</entry>
+ </row>
+ <row rowsep="0">
+ <entry>EncodingName</entry>
+ <entry>::=</entry>
+ <entry>CHARSET_REGISTRY-CHARSET_ENCODING</entry>
+ </row>
+ <row rowsep="0">
+ <entry>EncodingSide</entry>
+ <entry>::=</entry>
+ <entry>"GL" | "GR"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+For detail definition of CHARSET_REGISTRY-CHARSET_ENCODING, refer
+"X Logical Font Descriptions" document.
+</para>
+<literallayout>
+example:
+ ISO8859-1:GL
+</literallayout>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>font</term>
+ <listitem>
+ <para>
+Specifies a list of encoding information which is used for searching
+appropriate font for this fontset. The left most entry has highest
+priority.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect1>
+<sect1 id="XLC_XLOCALE_Category">
+<title>XLC_XLOCALE Category</title>
+<para>
+The XLC_XLOCALE category defines character classification, conversion
+and other character attributes.
+</para>
+
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <colspec colname='c1' colwidth="3*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <colspec colname='c3' colwidth="3*" colsep="0"/>
+ <thead>
+ <row>
+ <entry>class</entry>
+ <entry>super class</entry>
+ <entry>description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>encoding_name</entry>
+ <entry></entry>
+ <entry>codeset name</entry>
+ </row>
+ <row rowsep="0">
+ <entry>mb_cur_max</entry>
+ <entry></entry>
+ <entry>MB_CUR_MAX</entry>
+ </row>
+ <row rowsep="0">
+ <entry>state_depend_encoding</entry>
+ <entry></entry>
+ <entry>state dependent or not</entry>
+ </row>
+ <row rowsep="0">
+ <entry>wc_encoding_mask</entry>
+ <entry></entry>
+ <entry>for parsing wc string</entry>
+ </row>
+ <row rowsep="0">
+ <entry>wc_shift_bits</entry>
+ <entry></entry>
+ <entry>for conversion between wc and mb</entry>
+ </row>
+ <row rowsep="0">
+ <entry>csN</entry>
+ <entry></entry>
+ <entry>Nth charset (N=0,1,2,...)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>side</entry>
+ <entry>csN</entry>
+ <entry>mapping side (GL, etc)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>length</entry>
+ <entry>csN</entry>
+ <entry>length of a character</entry>
+ </row>
+ <row rowsep="0">
+ <entry>mb_encoding</entry>
+ <entry>csN</entry>
+ <entry>for parsing mb string</entry>
+ </row>
+ <row rowsep="0">
+ <entry>wc_encoding</entry>
+ <entry>csN</entry>
+ <entry>for parsing wc string</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ct_encoding</entry>
+ <entry>csN</entry>
+ <entry>list of encoding name for ct</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<variablelist>
+ <varlistentry>
+ <term>encoding_name</term>
+ <listitem>
+ <para>
+Specifies a codeset name of current locale.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mb_cur_max</term>
+ <listitem>
+ <para>
+Specifies a maximum allowable number of bytes in a multi-byte character.
+It is corresponding to MB_CUR_MAX of "ISO/IEC 9899:1990 C Language Standard".
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>state_depend_encoding</term>
+ <listitem>
+ <para>
+Indicates a current locale is state dependent. The value should be
+specified "True" or "False".
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wc_encoding_mask</term>
+ <listitem>
+ <para>
+Specifies a bit-mask for parsing wide-char string. Each wide character is
+applied bit-and operation with this bit-mask, then is classified into
+the unique charset, by using 'wc_encoding'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wc_shift_bits</term>
+ <listitem>
+ <para>
+Specifies a number of bit to be shifted for converting from a multi-byte
+character to a wide character, and vice-versa.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>csN</term>
+ <listitem>
+ <para>
+<!-- .br -->
+Includes a character set information for Nth charset, where N is the
+index number (0,1,2,...). If there are 4 charsets available in current
+locale, cs0, cs1, cs2 and cs3 should be defined. This class has five
+subclasses, 'side', 'length', 'mb_encoding' 'wc_encoding' and 'ct_encoding'.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>side</term>
+ <listitem>
+ <para>
+Specifies a mapping side of this charset. The format of this value is;
+ </para>
+ <literallayout>
+ Side ::= EncodingSide[":Default"]
+ </literallayout>
+ <para>
+The suffix ":Default" can be specified. It indicates that a character
+belongs to the specified side is mapped to this charset in initial state.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>length</term>
+ <listitem>
+ <para>
+<!-- .br -->
+Specifies a number of bytes of a multi-byte character of this charset.
+It should not contain the length of any single-shift sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>mb_encoding</term>
+ <listitem>
+ <para>
+Specifies a list of shift sequence for parsing multi-byte string.
+The format of this value is;
+ </para>
+<informaltable frame="none">
+ <tgroup cols='3' align='left'>
+ <colspec colname='c1' colwidth="3*" colsep="0"/>
+ <colspec colname='c2' colwidth="1*" colsep="0"/>
+ <colspec colname='c3' colwidth="5*" colsep="0"/>
+ <tbody>
+ <row rowsep="0">
+ <entry>MBEncoding</entry>
+ <entry>::=</entry>
+ <entry>ShiftType ShiftSequence</entry>
+ </row>
+ <row rowsep="0">
+ <entry></entry>
+ <entry>|</entry>
+ <entry>ShiftType ShiftSequence ";" MBEncoding</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ShiftType</entry>
+ <entry>::=</entry>
+ <entry>"<SS>"|"<LSL>"|"<LSR>"</entry>
+ </row>
+ <row rowsep="0">
+ <entry>ShiftSequence</entry>
+ <entry>::=</entry>
+ <entry>SequenceValue|SequenceValue ShiftSequence</entry>
+ </row>
+ <row rowsep="0">
+ <entry>SequenceValue</entry>
+ <entry>::=</entry>
+ <entry>NumericString</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+ <literallayout>
+example:
+ <LSL> \x1b \x28 \x4a; <LSL> \x1b \x28 \x42
+ </literallayout>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>wc_encoding</term>
+ <listitem>
+ <para>
+Specifies an integer value for parsing wide-char string.
+It is used to determine the charset for each wide character, after
+applying bit-and operation using 'wc_encoding_mask'.
+This value should be unique in all csN classes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ct_encoding</term>
+ <listitem>
+ <para>
+Specifies a list of encoding information that can be used for Compound
+Text.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect1>
+
+<sect1 id="Sample_of_X_Locale_Database">
+<title>Sample of X Locale Database</title>
+<para>
+The following is sample X Locale Database file.
+</para>
+
+<literallayout class="monospaced">
+# XLocale Database Sample for ja_JP.euc
+#
+
+#
+# XLC_FONTSET category
+#
+XLC_FONTSET
+# fs0 class (7 bit ASCII)
+fs0 {
+ charset ISO8859-1:GL
+ font ISO8859-1:GL; JISX0201.1976-0:GL
+}
+# fs1 class (Kanji)
+fs1 {
+ charset JISX0208.1983-0:GL
+ font JISX0208.1983-0:GL
+}
+# fs2 class (Half Kana)
+fs2 {
+ charset JISX0201.1976-0:GR
+ font JISX0201.1976-0:GR
+}
+# fs3 class (User Defined Character)
+# fs3 {
+# charset JISX0212.1990-0:GL
+# font JISX0212.1990-0:GL
+# }
+END XLC_FONTSET
+
+#
+# XLC_XLOCALE category
+#
+XLC_XLOCALE
+
+encoding_name ja.euc
+mb_cur_max 3
+state_depend_encoding False
+
+wc_encoding_mask \x00008080
+wc_shift_bits 8
+
+# cs0 class
+cs0 {
+ side GL:Default
+ length 1
+ wc_encoding \x00000000
+ ct_encoding ISO8859-1:GL; JISX0201.1976-0:GL
+}
+# cs1 class
+cs1 {
+ side GR:Default
+ length 2
+
+ wc_encoding \x00008080
+
+ ct_encoding JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
+ JISX0208.1983-1:GL; JISX0208.1983-1:GR
+}
+
+# cs2 class
+cs2 {
+ side GR
+ length 1
+ mb_encoding <SS> \x8e
+
+ wc_encoding \x00000080
+
+ ct_encoding JISX0201.1976-0:GR
+}
+
+# cs3 class
+# cs3 {
+# side GL
+# length 2
+# mb_encoding <SS> \x8f
+# #if HasWChar32
+# wc_encoding \x20000000
+# #else
+# wc_encoding \x00008000
+# #endif
+# ct_encoding JISX0212.1990-0:GL; JISX0212.1990-0:GR
+# }
+
+END XLC_XLOCALE
+</literallayout>
+</sect1>
+
+<sect1 id="Reference">
+<title>Reference</title>
+<para>
+[1] <emphasis remap='I'>ISO/IEC 9899:1990 C Language Standard</emphasis>
+</para>
+<para>
+[2] <emphasis remap='I'>X Logical Font Descriptions</emphasis>
+</para>
+
+</sect1>
+</chapter>
+</book>
diff --git a/libX11/specs/i18n/trans/Makefile.am b/libX11/specs/i18n/trans/Makefile.am index 40a135a2f..e3c499744 100644 --- a/libX11/specs/i18n/trans/Makefile.am +++ b/libX11/specs/i18n/trans/Makefile.am @@ -1,13 +1,13 @@ - -if ENABLE_SPECS - -# Main DocBook/XML files (DOCTYPE book) -docbook = trans.xml - -# The location where the DocBook/XML files and their generated formats are installed -shelfdir = $(docdir)/i18n/trans - -# Generate DocBook/XML output formats with or without stylesheets -include $(top_srcdir)/docbook.am - -endif ENABLE_SPECS +
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = trans.xml
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)/i18n/trans
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/libX11/specs/i18n/trans/trans.xml b/libX11/specs/i18n/trans/trans.xml index 61e2e7976..a61be65bc 100644 --- a/libX11/specs/i18n/trans/trans.xml +++ b/libX11/specs/i18n/trans/trans.xml @@ -1,1979 +1,1979 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> - -<book id="trans"> - -<bookinfo> - <title>The XIM Transport Specification</title> - <subtitle>Revision 0.1</subtitle> - <releaseinfo>X Version 11, Release 7</releaseinfo> - <authorgroup> - <author> - <firstname>Takashi</firstname><surname>Fujiwara</surname> - <affiliation><orgname>FUJITSU LIMITED</orgname></affiliation> - </author> - </authorgroup> - <copyright><year>1994</year><holder>FUJITSU LIMITED</holder></copyright> - <copyright><year>1994</year><holder>X Consortium</holder></copyright> - - <productnumber>Revision 0.1</productnumber> - - -<abstract> -<para> -This specification describes the transport layer interfaces between Xlib and IM Server, -which makes various channels usable such as X protocol or TCP/IP, DECnet and etc. -</para> -</abstract> - -<legalnotice> - -<para> -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: -</para> - -<para> -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -</para> - -<para> -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 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -</para> - -<para> -Except as contained in this notice, the name of The Open Group shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from X Consortium. -</para> - -<para>X Window System is a trademark of The Open Group.</para> - -</legalnotice> -</bookinfo> - -<chapter id="xim_transport_specification"> -<title>X Transport Specification</title> - -<sect1 id="Introduction"> -<title>Introduction</title> -<!-- .XS --> -<!-- (SN Introduction --> -<!-- .XE --> -<para> -<!-- .LP --> -The Xlib XIM implementation is layered into three functions, a protocol -layer, an interface layer and a transport layer. The purpose of this -layering is to make the protocol independent of transport implementation. -Each function of these layers are: -<!-- .RS 3 --> -</para> -<variablelist> - <varlistentry> - <term><emphasis>The protocol layer</emphasis></term> - <listitem> - <para> -implements overall function of XIM and calls the interface layer -functions when it needs to communicate to IM Server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis>The interface layer</emphasis></term> - <listitem> - <para> -separates the implementation of the transport layer from the protocol -layer, in other words, it provides implementation independent hook for -the transport layer functions. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><emphasis>The transport layer</emphasis></term> - <listitem> - <para> -handles actual data communication with IM Server. It is done by a set -of several functions named transporters. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This specification describes the interface layer and the transport -layer, which makes various communication channels usable such as -X protocol or, TCP/IP, DECnet, STREAM, etc., and provides -the information needed for adding another new transport layer. -In addition, sample implementations for the transporter using the -X connection is described in section 4. <!-- xref --> -</para> -</sect1> - -<sect1 id="Initialization"> -<title>Initialization</title> - -<sect2 id="Registering_structure_to_initialize"> -<title>Registering structure to initialize</title> - -<para> -The structure typed as TransportSW contains the list of the transport -layer the specific implementations supports. -</para> - -<literallayout class="monospaced"> -typedef struct { - char *transport_name; - Bool (*config); -} TransportSW; -</literallayout> - -<informaltable frame="none"> - <tgroup cols="2"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="0"/> - <tbody> - <row rowsep="0"> - <entry><emphasis>transport_name</emphasis></entry> - <entry>name of transport<footnote><para>Refer to "The Input Method Protocol: Appendix B</para></footnote></entry> - </row> - <row rowsep="0"> - <entry><emphasis>config</emphasis></entry> - <entry>initial configuration function</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -A sample entry for the Xlib supporting transporters is shown below: -</para> - -<literallayout class="monospaced"> -TransportSW _XimTransportRec[] = { -/* char <emphasis remap='I'>*</emphasis>: - * transport_name, Bool <emphasis remap='I'>(*config)()</emphasis> - */ - "X", _XimXConf, - "tcp", _XimTransConf, - "local", _XimTransConf, - "decnet", _XimTransConf, - "streams", _XimTransConf, - (char *)NULL, (Bool (*)())NULL, -}; -</literallayout> - -</sect2> -<sect2 id="Initialization_function"> -<title>Initialization function</title> -<!-- .XS --> -<!-- (SN Initialization function --> -<!-- .XE --> -<para> -The following function will be called once when Xlib configures the -transporter functions. -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>(*config)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>char<parameter> *transport_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>transport_data</emphasis> - </term> - <listitem> - <para> -Specifies the data specific to the transporter, in IM Server address.<footnote><para>Refer to "The Input Method Protocol: Appendix B</para></footnote> - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This function must setup the transporter function pointers. -</para> - -<para> -<!-- .LP --> -The actual <emphasis remap='I'>config</emphasis> function will be chosen by IM Server at the -pre-connection time, matching by the <emphasis remap='I'>transport_name</emphasis> specified -in the <function>_XimTransportRec</function> array; The specific members of XimProto -structure listed below must be initialized so that point they -appropriate transporter functions. -</para> - -<para> -If the specified transporter has been configured successfully, this -function returns True. There is no Alternative Entry for config -function itself. -</para> - -<para> -The structure XimProto contains the following function pointers: -</para> - -<literallayout class="monospaced"> -Bool (*connect)(); /* Open connection */ -Bool (*shutdown)(); /* Close connection */ -Bool (*write)(); /* Write data */ -Bool (*read)(); /* Read data */ -Bool (*flush)(); /* Flush data buffer */ -Bool (*register_dispatcher)(); /* Register asynchronous data handler */ -Bool (*call_dispatcher)(); /* Call dispatcher */ -</literallayout> - -<para> -These functions are called when Xlib needs to communicate the -IM Server. These functions must process the appropriate procedure -described below. -</para> - -</sect2> -</sect1> -<sect1 id="The_interface_transport_layer_functions"> -<title>The interface/transport layer functions</title> -<para> -Following functions are used for the transport interface. -</para> - -<table frame="all" id="transport_layer_functions_2"> - <title>The Transport Layer Functions</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="3*" colsep="1"/> - <colspec colname="col2" colwidth="3*" colsep="1"/> - <colspec colname="col3" colwidth="1*" colsep="1"/> - <thead> - <row> - <entry align="center">Alternate Entry (Interface Layer)</entry> - <entry align="center">XimProto member (Transport Layer)</entry> - <entry align="center">Section</entry> - </row> - </thead> - <tbody> - <row> - <entry>_XimConnect</entry> - <entry>connect</entry> - <entry>3.1</entry> - </row> - <row> - <entry>_XimShutdown</entry> - <entry>shutdown</entry> - <entry>3.2</entry> - </row> - <row> - <entry>_XimWrite</entry> - <entry>write</entry> - <entry>3.3</entry> - </row> - <row> - <entry>_XimRead</entry> - <entry>read</entry> - <entry>3.4</entry> - </row> - <row> - <entry>_XimFlush</entry> - <entry>flush</entry> - <entry>3.5</entry> - </row> - <row> - <entry>_XimRegisterDispatcher</entry> - <entry>register_dispatcher</entry> - <entry>3.6</entry> - </row> - <row> - <entry>_XimCallDispatcher</entry> - <entry>call_dispatcher</entry> - <entry>3.7</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -The Protocol layer calls the above functions using the Alternative -Entry in the left column. The transport implementation defines -XimProto member function in the right column. The Alternative Entry is -provided so as to make easier to implement the Protocol Layer. -</para> - -<sect2 id="Opening_connection"> -<title>Opening connection</title> -<para> -<!-- .LP --> -When <function>XOpenIM</function> is called, the following function is called to connect -with the IM Server. -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>(*connect)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This function must establishes the connection to the IM Server. If the -connection is established successfully, this function returns True. -The Alternative Entry for this function is: -</para> - -<funcsynopsis id='_ximconnect'> -<funcprototype> - <funcdef>Bool <function> _XimConnect</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> -</sect2> - -<sect2 id="Closing_connection"> -<title>Closing connection</title> -<!-- .XS --> -<!-- (SN Closing connection --> -<!-- .XE --> -<para> -<!-- .LP --> -When <function>XCloseIM</function> is called, the following function is called to -disconnect the connection with the IM Server. The Alternative Entry -for this function is: -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function> (*shutdown)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -This function must close connection with the IM Server. If the -connection is closed successfully, this function returns True. The -Alternative Entry for this function is: -</para> - -<funcsynopsis id='_ximshutdown'> -<funcprototype> - <funcdef>Bool <function>_XimShutdown</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> - -<sect2 id="Writing_data"> -<title>Writing data</title> -<para> -The following function is called, when Xlib needs to write data to the -IM Server. -</para> - -<funcsynopsis id='_ximwrite'> -<funcprototype> - <funcdef>Bool <function> _XimWrite</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>len</emphasis> - </term> - <listitem> - <para> -Specifies the length of writing data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the writing data. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This function writes the <emphasis remap='I'>data</emphasis> to the IM Server, regardless -of the contents. The number of bytes is passed to <emphasis remap='I'>len</emphasis>. The -writing data is passed to <emphasis remap='I'>data</emphasis>. If data is sent successfully, -the function returns True. Refer to "The Input Method Protocol" for -the contents of the writing data. The Alternative Entry for this -function is: -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>_XimWrite</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>len</emphasis> - </term> - <listitem> - <para> -Specifies the length of writing data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the writing data. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> -<sect2 id="Reading_data"> -<title>Reading data</title> -<para> -The following function is called when Xlib waits for response from IM -server synchronously. -</para> - -<funcsynopsis id='_ximread'> -<funcprototype> - <funcdef>Bool <function> _XimRead</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>XPointer<parameter> read_buf</parameter></paramdef> - <paramdef>int<parameter> buf_len</parameter></paramdef> - <paramdef>int<parameter> *ret_len</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>read_buf</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to store data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buf_len</emphasis> - </term> - <listitem> - <para> -Specifies the size of the <emphasis remap='I'>buffer</emphasis> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ret_len</emphasis> - </term> - <listitem> - <para> -Specifies the length of stored data. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This function stores the read data in <emphasis remap='I'>read_buf</emphasis>, which size is -specified as <emphasis remap='I'>buf_len</emphasis>. The size of data is set to <emphasis remap='I'>ret_len</emphasis>. -This function return True, if the data is read normally or reading -data is completed. -</para> -<para> -The Alternative Entry for this function is: -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function> _XimRead</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> *ret_len</parameter></paramdef> - <paramdef>XPointer<parameter> buf</parameter></paramdef> - <paramdef>int<parameter> buf_len</parameter></paramdef> - <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef> - <paramdef>XPointer<parameter> predicate_arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ret_len</emphasis> - </term> - <listitem> - <para> -Specifies the size of the <emphasis remap='I'>data</emphasis> buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buf</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to store data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buf_len</emphasis> - </term> - <listitem> - <para> -Specifies the length of <emphasis remap='I'>buffer</emphasis>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate</emphasis> - </term> - <listitem> - <para> -Specifies the predicate for the XIM data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate_arg</emphasis> - </term> - <listitem> - <para> -Specifies the predicate specific data. -<!-- .sp 6p --> - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The predicate procedure indicates whether the <emphasis remap='I'>data</emphasis> is for the -XIM or not. <emphasis remap='I'>len</emphasis> -This function stores the read data in <emphasis remap='I'>buf</emphasis>, which size -is specified as <emphasis remap='I'>buf_len</emphasis>. The size of data is set to -<emphasis remap='I'>ret_len</emphasis>. If <emphasis remap='I'>preedicate()</emphasis> -returns True, this function returns True. If not, it calls the registered callback function. -</para> - -<para> -The procedure and its arguments are: -</para> - - -<funcsynopsis> -<funcprototype> - <funcdef>void <function>(*predicate)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> - <paramdef>XPointer<parameter> predicate_arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>len</emphasis> - </term> - <listitem> - <para> -Specifies the size of the <emphasis remap='I'>data</emphasis> buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to store data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate_arg</emphasis> - </term> - <listitem> - <para> -Specifies the predicate specific data. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> -<sect2 id="Flushing_buffer"> -<title>Flushing buffer</title> -<para> -The following function is called when Xlib needs to flush the data. -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>void <function>(*flush)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -This function must flush the data stored in internal buffer on the -transport layer. If data transfer is completed, the function returns -True. The Alternative Entry for this function is: -</para> - -<funcsynopsis id='_ximflush'> -<funcprototype> - <funcdef>void <function> _XimFlush</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> -<sect2 id="Registering_asynchronous_data_handler"> -<title>Registering asynchronous data handler</title> -<para> -Xlib needs to handle asynchronous response from IM Server. This is -because some of the XIM data occur asynchronously to X events. -</para> - -<para> -Those data will be handled in the <emphasis remap='I'>Filter</emphasis>, -and the <emphasis remap='I'>Filter</emphasis> -will call asynchronous data handler in the protocol layer. Then it -calls dispatchers in the transport layer. The dispatchers are -implemented by the protocol layer. This function must store the -information and prepare for later call of the dispatchers using -<function>_XimCallDispatcher</function>. -</para> - -<para> -When multiple dispatchers are registered, they will be called -sequentially in order of registration, on arrival of asynchronous -data. The register_dispatcher is declared as following: -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>(*register_dispatcher)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>Bool<parameter> (*dispatcher)()</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dispatcher</emphasis> - </term> - <listitem> - <para> -Specifies the dispatcher function to register. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies a parameter for the <emphasis remap='I'>dispatcher</emphasis>. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The dispatcher is a function of the following type: -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>(*dispatcher)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>len</emphasis> - </term> - <listitem> - <para> -Specifies the size of the <emphasis remap='I'>data</emphasis> buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to store data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies a parameter passed to the register_dispatcher. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The dispatcher is provided by the protocol layer. They are called once -for every asynchronous data, in order of registration. If the data is -used, it must return True. otherwise, it must return False. -</para> - -<para> -If the dispatcher function returns True, the Transport Layer assume -that the data has been processed by the upper layer. The Alternative -Entry for this function is: -</para> - -<funcsynopsis id='_ximregisterdispatcher'> -<funcprototype> - <funcdef>Bool <function> _XimRegisterDispatcher</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>Bool<parameter> (*dispatcher)()</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dispatcher</emphasis> - </term> - <listitem> - <para> -Specifies the dispatcher function to register. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies a parameter for the <emphasis remap='I'>dispatcher</emphasis>. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> -<sect2 id="Calling_dispatcher"> -<title>Calling dispatcher</title> -<para> -The following function is used to call the registered dispatcher -function, when the asynchronous response from IM Server has arrived. -</para> - -<funcsynopsis> -<funcprototype> - <funcdef>Bool <function>(*call_dispatcher)</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies XIM structure address. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>len</emphasis> - </term> - <listitem> - <para> -Specifies the size of <emphasis remap='I'>data</emphasis> buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to store data. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The call_dispatcher must call the dispatcher function, in order of -their registration. <emphasis remap='I'>len</emphasis> and <emphasis remap='I'>data</emphasis> are the data passed to -register_dispatcher. -</para> - -<para> -The return values are checked at each invocation, and if it finds -True, it immediately return with true for its return value. -</para> - -<para> -It is depend on the upper layer whether the read data is XIM -Protocol packet unit or not. -The Alternative Entry for this function is: -</para> - -<funcsynopsis id='_ximcalldispatcher'> -<funcprototype> - <funcdef>Bool <function> _XimCallDispatcher</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>INT16<parameter> len</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -</sect2> -</sect1> -<sect1 id="Sample_implementations_for_the_Transport_Layer"> -<title>Sample implementations for the Transport Layer</title> -<para> -Sample implementations for the transporter using the X connection is -described here. -</para> - -<sect2 id="X_Transport"> -<title>X Transport</title> -<para> -At the beginning of the X Transport connection for the XIM transport -mechanism, two different windows must be created either in an Xlib XIM -or in an IM Server, with which the Xlib and the IM Server exchange the -XIM transports by using the ClientMessage events and Window Properties. -In the following, the window created by the Xlib is referred as the -"client communication window", and on the other hand, the window created -by the IM Server is referred as the "IMS communication window". -</para> - -<sect3 id="Connection"> -<title>Connection</title> -<para> -In order to establish a connection, a communication window is created. -A ClientMessage in the following event's format is sent to the owner -window of XIM_SERVER selection, which the IM Server has created. -</para> - -<para> -<!-- .LP --> -Refer to "The Input Method Protocol" for the XIM_SERVER atom. -</para> - -<table frame="none" id="transport_layer_functions"> - <title>The ClientMessage sent to the IMS window.</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_CONNECT", false)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>32</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[0]</entry> - <entry>client communication window ID</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[1]</entry> - <entry>client-major-transport-version(*1)</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[2]</entry> - <entry>client-major-transport-version(*1)</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -In order to establish the connection (to notify the IM Server communication -window), the IM Server sends a ClientMessage in the following event's -format to the client communication window. -</para> - -<table frame="none" id="clientmessage_sent_by_im_server"> - <title>The ClientMessage sent by IM Server.</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_CONNECT", false)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>32</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[0]</entry> - <entry>client communication window ID</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[1]</entry> - <entry>client-major-transport-version(*1)</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[2]</entry> - <entry>client-major-transport-version(*1)</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[3]</entry> - <entry>dividing size between ClientMessage and Property(*2)</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -(*1) major/minor-transport-version -</para> - -<para> -The read/write method is decided by the combination of -major/minor-transport-version, as follows: -</para> - -<table frame="all" id="readwrite_method_and_the_majorminor_transport_version"> -<title>The read/write method and the major/minor-transport-version</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="1"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3*" colsep="1"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="center"/> - <thead> - <row> - <entry spanname="span-horiz">Transport-version</entry> - <entry>read/write</entry> - </row> - <row> - <entry>major</entry> - <entry>minor</entry> - <entry></entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry morerows="2">0</entry> - <entry>0</entry> - <entry>only-CM & Property-with-CM</entry> - </row> - <row rowsep="0"> - <entry>1</entry> - <entry>only-CM & multi-CM</entry> - </row> - <row rowsep="1"> - <entry>2</entry> - <entry>only-CM & multi-CM & Property-with-CM</entry> - </row> - <row rowsep="1"> - <entry>1</entry> - <entry>0</entry> - <entry>PropertyNotify</entry> - </row> - <row rowsep="0"> - <entry morerows="1">2</entry> - <entry>0</entry> - <entry>only-CM & PropertyNotify</entry> - </row> - <row> - <entry>1</entry> - <entry>only-CM & multi-CM & PropertyNotify</entry> - </row> - </tbody> - </tgroup> -</table> - -<literallayout class="monospaced"> -only-CM : data is sent via a ClientMessage -multi-CM : data is sent via multiple ClientMessages -Property-with-CM : data is written in Property, and its Atom - is send via ClientMessage -PropertyNotify : data is written in Property, and its Atom - is send via PropertyNotify - -</literallayout> - - -<para> -The method to decide major/minor-transport-version is as follows: -</para> - -<itemizedlist> - <listitem> - <para> -The client sends 0 as major/minor-transport-version to the IM Server. -The client must support all methods in Table 4-3. <!-- xref --> -The client may send another number as major/minor-transport-version to -use other method than the above in the future. - </para> - </listitem> - <listitem> - <para> -The IM Server sends its major/minor-transport-version number to -the client. The client sends data using the method specified by the -IM Server. - </para> - </listitem> - <listitem> - <para> -If major/minor-transport-version number is not available, it is regarded -as 0. - </para> - </listitem> -</itemizedlist> - -<para> -(*2) dividing size between ClientMessage and Property -</para> - -<para> -If data is sent via both of multi-CM and Property, specify the dividing -size between ClientMessage and Property. The data, which is smaller than -this size, is sent via multi-CM (or only-CM), and the data, which is -lager than this size, is sent via Property. -</para> - -</sect3> - -<sect3 id="read_write_"> -<title>read/write </title> -<para> -The data is transferred via either ClientMessage or Window Property in -the X Window System. -</para> - -<sect4 id="Format_for_the_data_from_the_Client_to_the_IM_Server"> -<title>Format for the data from the Client to the IM Server</title> -<para> -<emphasis role="bold">ClientMessage</emphasis> -</para> - -<para> -If data is sent via ClientMessage event, the format is as follows: -</para> - -<table frame="none" id="clientmessage_events_format_first_or_middle"> - <title>The ClientMessage event's format (first or middle)</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_MOREDATA", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>char</entry> - <entry>data.b[20]</entry> - <entry>(read/write DATA : 20 byte)</entry> - </row> - </tbody> - </tgroup> -</table> - - - -<table frame="none" id="clientmessage_events_format_only_or_last"> - <title>The ClientMessage event's format (only or last)</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>char</entry> - <entry>data.b[20]</entry> - <entry>(read/write DATA : MAX 20 byte) -<footnote><para>If the data is smaller -than 20 bytes, all data other than available data must be 0. -</para></footnote> - </entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -<emphasis role="bold">Property</emphasis> -</para> - -<para> -In the case of large data, data will be sent via the Window Property -for the efficiency. There are the following two methods to notify -Property, and transport-version is decided which method is used. -</para> - -<itemizedlist> - <listitem> - <para> -The XChangeProperty function is used to store data in the client -communication window, and Atom of the stored data is notified to the -IM Server via ClientMessage event. - </para> - </listitem> - <listitem> - <para> -The XChangeProperty function is used to store data in the client -communication window, and Atom of the stored data is notified to the -IM Server via PropertyNotify event. - </para> - </listitem> -</itemizedlist> - -<para> -The arguments of the XChangeProperty are as follows: -</para> - - -<table frame="none" id="xchangeproperty_events_format"> - <title>The XChangeProperty event's format</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Argument</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS communication window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>property</entry> - <entry>read/write property Atom (*1)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>mode</entry> - <entry>PropModeAppend</entry> - </row> - <row rowsep="0"> - <entry>u_char</entry> - <entry>*data</entry> - <entry>read/write DATA</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>nelements</entry> - <entry>length of DATA</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -(*1) The read/write property ATOM allocates the following strings by -<function>XInternAtom</function>. -"_clientXXX" -</para> - -<para> -The client changes the property with the mode of PropModeAppend and -the IM Server will read it with the delete mode i.e. (delete = True). -</para> - -<para> -If Atom is notified via ClientMessage event, the format of the ClientMessage -is as follows: -</para> - -<table frame="none" id="clientmessage_events_format_to_send_atom_of_property"> - <title>The ClientMessage event's format to send Atom of property</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[0]</entry> - <entry>length of read/write property Atom</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[1]</entry> - <entry>read/write property Atom</entry> - </row> - </tbody> - </tgroup> -</table> -</sect4> - -<sect4 id="Format_for_the_data_from_the_IM_Server_to_the_Client"> -<title>Format for the data from the IM Server to the Client</title> -<para> -<emphasis role="bold">ClientMessage</emphasis> -</para> - -<para> -The format of the ClientMessage is as follows: -</para> - -<table frame="none" id="clientmessage_events_format_first_or_middle_2"> - <title>The ClientMessage event's format (first or middle)</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_MOREDATA", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>char</entry> - <entry>data.b[20]</entry> - <entry>(read/write DATA : 20 byte)</entry> - </row> - </tbody> - </tgroup> -</table> - - - - - -<table frame="none" id="clientmessage_events_format_only_or_last_2"> - <title>The ClientMessage event's format (only or last)</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>char</entry> - <entry>data.b[20]</entry> - <entry>(read/write DATA : MAX 20 byte) (*1)</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -(*1) If the data size is smaller than 20 bytes, all data other than available -data must be 0. -</para> - -<para> -<emphasis role="bold">Property</emphasis> -</para> - -<para> -In the case of large data, data will be sent via the Window Property -for the efficiency. There are the following two methods to notify -Property, and transport-version is decided which method is used. -</para> - -<itemizedlist> - <listitem> - <para> -The XChangeProperty function is used to store data in the IMS -communication window, and Atom of the property is sent via the -ClientMessage event. - </para> - </listitem> - <listitem> - <para> -The XChangeProperty function is used to store data in the IMS -communication window, and Atom of the property is sent via -PropertyNotify event. - </para> - </listitem> -</itemizedlist> - -<para> -The arguments of the XChangeProperty are as follows: -</para> - -<table frame="none" id="xchangeproperty_events_format_b"> - <title>The XChangeProperty event's format</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Argument</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS communication window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>property</entry> - <entry>read/write property Atom (*1)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>mode</entry> - <entry>PropModeAppend</entry> - </row> - <row rowsep="0"> - <entry>u_char</entry> - <entry>*data</entry> - <entry>read/write DATA</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>nelements</entry> - <entry>length of DATA</entry> - </row> - </tbody> - </tgroup> -</table> - -<para> -(*1) The read/write property ATOM allocates some strings, which are not -allocated by the client, by <function>XInternAtom</function>. -</para> - -<para> -The IM Server changes the property with the mode of PropModeAppend and -the client reads it with the delete mode, i.e. (delete = True). -</para> - -<para> -If Atom is notified via ClientMessage event, the format of the ClientMessage -is as follows: -</para> - -<table frame="none" id="clientmessage_events_format_to_send_atom_of_property_2"> - <title>The ClientMessage event's format to send Atom of property</title> - <tgroup cols="3"> - <colspec colname="col1" colwidth="1*" colsep="0"/> - <colspec colname="col2" colwidth="1*" colsep="1"/> - <colspec colname="col3" colwidth="3.5*" colsep="0"/> - <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/> - <thead> - <row> - <entry align="left" spanname="span-horiz">Structure Member</entry> - <entry align="left">Contents</entry> - </row> - </thead> - <tbody> - <row rowsep="0"> - <entry>int</entry> - <entry>type</entry> - <entry>ClientMessage</entry> - </row> - <row rowsep="0"> - <entry>u_long</entry> - <entry>serial</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Bool</entry> - <entry>send_event</entry> - <entry>Set by the X Window System</entry> - </row> - <row rowsep="0"> - <entry>Display</entry> - <entry>*display</entry> - <entry>The display to which connects</entry> - </row> - <row rowsep="0"> - <entry>Window</entry> - <entry>window</entry> - <entry>IMS Window ID</entry> - </row> - <row rowsep="0"> - <entry>Atom</entry> - <entry>message_type</entry> - <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry> - </row> - <row rowsep="0"> - <entry>int</entry> - <entry>format</entry> - <entry>8</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[0]</entry> - <entry>length of read/write property Atom</entry> - </row> - <row rowsep="0"> - <entry>long</entry> - <entry>data.1[1]</entry> - <entry>read/write property Atom</entry> - </row> - </tbody> - </tgroup> -</table> - -</sect4> -</sect3> -<sect3 id="Closing_Connection"> -<title>Closing Connection</title> - -<para> -If the client disconnect with the IM Server, shutdown function should -free the communication window properties and etc.. -</para> - -</sect3> -</sect2> -</sect1> - -<sect1 id="References"> -<title>References</title> -<para> -[1] Masahiko Narita and Hideki Hiura, <emphasis remap='I'>"The Input Method Protocol"</emphasis> -</para> -</sect1> - -</chapter> -</book> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<book id="trans">
+
+<bookinfo>
+ <title>The XIM Transport Specification</title>
+ <subtitle>Revision 0.1</subtitle>
+ <releaseinfo>X Version 11, Release 7</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Takashi</firstname><surname>Fujiwara</surname>
+ <affiliation><orgname>FUJITSU LIMITED</orgname></affiliation>
+ </author>
+ </authorgroup>
+ <copyright><year>1994</year><holder>FUJITSU LIMITED</holder></copyright>
+ <copyright><year>1994</year><holder>X Consortium</holder></copyright>
+
+ <productnumber>Revision 0.1</productnumber>
+
+
+<abstract>
+<para>
+This specification describes the transport layer interfaces between Xlib and IM Server,
+which makes various channels usable such as X protocol or TCP/IP, DECnet and etc.
+</para>
+</abstract>
+
+<legalnotice>
+
+<para>
+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:
+</para>
+
+<para>
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+</para>
+
+<para>
+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 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+</para>
+
+<para>
+Except as contained in this notice, the name of The Open Group shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from X Consortium.
+</para>
+
+<para>X Window System is a trademark of The Open Group.</para>
+
+</legalnotice>
+</bookinfo>
+
+<chapter id="xim_transport_specification">
+<title>X Transport Specification</title>
+
+<sect1 id="Introduction">
+<title>Introduction</title>
+<!-- .XS -->
+<!-- (SN Introduction -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The Xlib XIM implementation is layered into three functions, a protocol
+layer, an interface layer and a transport layer. The purpose of this
+layering is to make the protocol independent of transport implementation.
+Each function of these layers are:
+<!-- .RS 3 -->
+</para>
+<variablelist>
+ <varlistentry>
+ <term><emphasis>The protocol layer</emphasis></term>
+ <listitem>
+ <para>
+implements overall function of XIM and calls the interface layer
+functions when it needs to communicate to IM Server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>The interface layer</emphasis></term>
+ <listitem>
+ <para>
+separates the implementation of the transport layer from the protocol
+layer, in other words, it provides implementation independent hook for
+the transport layer functions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis>The transport layer</emphasis></term>
+ <listitem>
+ <para>
+handles actual data communication with IM Server. It is done by a set
+of several functions named transporters.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This specification describes the interface layer and the transport
+layer, which makes various communication channels usable such as
+X protocol or, TCP/IP, DECnet, STREAM, etc., and provides
+the information needed for adding another new transport layer.
+In addition, sample implementations for the transporter using the
+X connection is described in section 4. <!-- xref -->
+</para>
+</sect1>
+
+<sect1 id="Initialization">
+<title>Initialization</title>
+
+<sect2 id="Registering_structure_to_initialize">
+<title>Registering structure to initialize</title>
+
+<para>
+The structure typed as TransportSW contains the list of the transport
+layer the specific implementations supports.
+</para>
+
+<literallayout class="monospaced">
+typedef struct {
+ char *transport_name;
+ Bool (*config);
+} TransportSW;
+</literallayout>
+
+<informaltable frame="none">
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="0"/>
+ <tbody>
+ <row rowsep="0">
+ <entry><emphasis>transport_name</emphasis></entry>
+ <entry>name of transport<footnote><para>Refer to "The Input Method Protocol: Appendix B</para></footnote></entry>
+ </row>
+ <row rowsep="0">
+ <entry><emphasis>config</emphasis></entry>
+ <entry>initial configuration function</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+A sample entry for the Xlib supporting transporters is shown below:
+</para>
+
+<literallayout class="monospaced">
+TransportSW _XimTransportRec[] = {
+/* char <emphasis remap='I'>*</emphasis>:
+ * transport_name, Bool <emphasis remap='I'>(*config)()</emphasis>
+ */
+ "X", _XimXConf,
+ "tcp", _XimTransConf,
+ "local", _XimTransConf,
+ "decnet", _XimTransConf,
+ "streams", _XimTransConf,
+ (char *)NULL, (Bool (*)())NULL,
+};
+</literallayout>
+
+</sect2>
+<sect2 id="Initialization_function">
+<title>Initialization function</title>
+<!-- .XS -->
+<!-- (SN Initialization function -->
+<!-- .XE -->
+<para>
+The following function will be called once when Xlib configures the
+transporter functions.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>(*config)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>char<parameter> *transport_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>transport_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data specific to the transporter, in IM Server address.<footnote><para>Refer to "The Input Method Protocol: Appendix B</para></footnote>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This function must setup the transporter function pointers.
+</para>
+
+<para>
+<!-- .LP -->
+The actual <emphasis remap='I'>config</emphasis> function will be chosen by IM Server at the
+pre-connection time, matching by the <emphasis remap='I'>transport_name</emphasis> specified
+in the <function>_XimTransportRec</function> array; The specific members of XimProto
+structure listed below must be initialized so that point they
+appropriate transporter functions.
+</para>
+
+<para>
+If the specified transporter has been configured successfully, this
+function returns True. There is no Alternative Entry for config
+function itself.
+</para>
+
+<para>
+The structure XimProto contains the following function pointers:
+</para>
+
+<literallayout class="monospaced">
+Bool (*connect)(); /* Open connection */
+Bool (*shutdown)(); /* Close connection */
+Bool (*write)(); /* Write data */
+Bool (*read)(); /* Read data */
+Bool (*flush)(); /* Flush data buffer */
+Bool (*register_dispatcher)(); /* Register asynchronous data handler */
+Bool (*call_dispatcher)(); /* Call dispatcher */
+</literallayout>
+
+<para>
+These functions are called when Xlib needs to communicate the
+IM Server. These functions must process the appropriate procedure
+described below.
+</para>
+
+</sect2>
+</sect1>
+<sect1 id="The_interface_transport_layer_functions">
+<title>The interface/transport layer functions</title>
+<para>
+Following functions are used for the transport interface.
+</para>
+
+<table frame="all" id="transport_layer_functions_2">
+ <title>The Transport Layer Functions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="3*" colsep="1"/>
+ <colspec colname="col2" colwidth="3*" colsep="1"/>
+ <colspec colname="col3" colwidth="1*" colsep="1"/>
+ <thead>
+ <row>
+ <entry align="center">Alternate Entry (Interface Layer)</entry>
+ <entry align="center">XimProto member (Transport Layer)</entry>
+ <entry align="center">Section</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>_XimConnect</entry>
+ <entry>connect</entry>
+ <entry>3.1</entry>
+ </row>
+ <row>
+ <entry>_XimShutdown</entry>
+ <entry>shutdown</entry>
+ <entry>3.2</entry>
+ </row>
+ <row>
+ <entry>_XimWrite</entry>
+ <entry>write</entry>
+ <entry>3.3</entry>
+ </row>
+ <row>
+ <entry>_XimRead</entry>
+ <entry>read</entry>
+ <entry>3.4</entry>
+ </row>
+ <row>
+ <entry>_XimFlush</entry>
+ <entry>flush</entry>
+ <entry>3.5</entry>
+ </row>
+ <row>
+ <entry>_XimRegisterDispatcher</entry>
+ <entry>register_dispatcher</entry>
+ <entry>3.6</entry>
+ </row>
+ <row>
+ <entry>_XimCallDispatcher</entry>
+ <entry>call_dispatcher</entry>
+ <entry>3.7</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+The Protocol layer calls the above functions using the Alternative
+Entry in the left column. The transport implementation defines
+XimProto member function in the right column. The Alternative Entry is
+provided so as to make easier to implement the Protocol Layer.
+</para>
+
+<sect2 id="Opening_connection">
+<title>Opening connection</title>
+<para>
+<!-- .LP -->
+When <function>XOpenIM</function> is called, the following function is called to connect
+with the IM Server.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>(*connect)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This function must establishes the connection to the IM Server. If the
+connection is established successfully, this function returns True.
+The Alternative Entry for this function is:
+</para>
+
+<funcsynopsis id='_ximconnect'>
+<funcprototype>
+ <funcdef>Bool <function> _XimConnect</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+
+<sect2 id="Closing_connection">
+<title>Closing connection</title>
+<!-- .XS -->
+<!-- (SN Closing connection -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When <function>XCloseIM</function> is called, the following function is called to
+disconnect the connection with the IM Server. The Alternative Entry
+for this function is:
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function> (*shutdown)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+This function must close connection with the IM Server. If the
+connection is closed successfully, this function returns True. The
+Alternative Entry for this function is:
+</para>
+
+<funcsynopsis id='_ximshutdown'>
+<funcprototype>
+ <funcdef>Bool <function>_XimShutdown</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+
+<sect2 id="Writing_data">
+<title>Writing data</title>
+<para>
+The following function is called, when Xlib needs to write data to the
+IM Server.
+</para>
+
+<funcsynopsis id='_ximwrite'>
+<funcprototype>
+ <funcdef>Bool <function> _XimWrite</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of writing data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the writing data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This function writes the <emphasis remap='I'>data</emphasis> to the IM Server, regardless
+of the contents. The number of bytes is passed to <emphasis remap='I'>len</emphasis>. The
+writing data is passed to <emphasis remap='I'>data</emphasis>. If data is sent successfully,
+the function returns True. Refer to "The Input Method Protocol" for
+the contents of the writing data. The Alternative Entry for this
+function is:
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>_XimWrite</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of writing data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the writing data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+<sect2 id="Reading_data">
+<title>Reading data</title>
+<para>
+The following function is called when Xlib waits for response from IM
+server synchronously.
+</para>
+
+<funcsynopsis id='_ximread'>
+<funcprototype>
+ <funcdef>Bool <function> _XimRead</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>XPointer<parameter> read_buf</parameter></paramdef>
+ <paramdef>int<parameter> buf_len</parameter></paramdef>
+ <paramdef>int<parameter> *ret_len</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>read_buf</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to store data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buf_len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the <emphasis remap='I'>buffer</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ret_len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of stored data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This function stores the read data in <emphasis remap='I'>read_buf</emphasis>, which size is
+specified as <emphasis remap='I'>buf_len</emphasis>. The size of data is set to <emphasis remap='I'>ret_len</emphasis>.
+This function return True, if the data is read normally or reading
+data is completed.
+</para>
+<para>
+The Alternative Entry for this function is:
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function> _XimRead</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> *ret_len</parameter></paramdef>
+ <paramdef>XPointer<parameter> buf</parameter></paramdef>
+ <paramdef>int<parameter> buf_len</parameter></paramdef>
+ <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> predicate_arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ret_len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the <emphasis remap='I'>data</emphasis> buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buf</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to store data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buf_len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of <emphasis remap='I'>buffer</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the predicate for the XIM data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate_arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the predicate specific data.
+<!-- .sp 6p -->
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The predicate procedure indicates whether the <emphasis remap='I'>data</emphasis> is for the
+XIM or not. <emphasis remap='I'>len</emphasis>
+This function stores the read data in <emphasis remap='I'>buf</emphasis>, which size
+is specified as <emphasis remap='I'>buf_len</emphasis>. The size of data is set to
+<emphasis remap='I'>ret_len</emphasis>. If <emphasis remap='I'>preedicate()</emphasis>
+returns True, this function returns True. If not, it calls the registered callback function.
+</para>
+
+<para>
+The procedure and its arguments are:
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function>(*predicate)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+ <paramdef>XPointer<parameter> predicate_arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the <emphasis remap='I'>data</emphasis> buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to store data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate_arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the predicate specific data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+<sect2 id="Flushing_buffer">
+<title>Flushing buffer</title>
+<para>
+The following function is called when Xlib needs to flush the data.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function>(*flush)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+This function must flush the data stored in internal buffer on the
+transport layer. If data transfer is completed, the function returns
+True. The Alternative Entry for this function is:
+</para>
+
+<funcsynopsis id='_ximflush'>
+<funcprototype>
+ <funcdef>void <function> _XimFlush</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+<sect2 id="Registering_asynchronous_data_handler">
+<title>Registering asynchronous data handler</title>
+<para>
+Xlib needs to handle asynchronous response from IM Server. This is
+because some of the XIM data occur asynchronously to X events.
+</para>
+
+<para>
+Those data will be handled in the <emphasis remap='I'>Filter</emphasis>,
+and the <emphasis remap='I'>Filter</emphasis>
+will call asynchronous data handler in the protocol layer. Then it
+calls dispatchers in the transport layer. The dispatchers are
+implemented by the protocol layer. This function must store the
+information and prepare for later call of the dispatchers using
+<function>_XimCallDispatcher</function>.
+</para>
+
+<para>
+When multiple dispatchers are registered, they will be called
+sequentially in order of registration, on arrival of asynchronous
+data. The register_dispatcher is declared as following:
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>(*register_dispatcher)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>Bool<parameter> (*dispatcher)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dispatcher</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the dispatcher function to register.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a parameter for the <emphasis remap='I'>dispatcher</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The dispatcher is a function of the following type:
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>(*dispatcher)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the <emphasis remap='I'>data</emphasis> buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to store data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a parameter passed to the register_dispatcher.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The dispatcher is provided by the protocol layer. They are called once
+for every asynchronous data, in order of registration. If the data is
+used, it must return True. otherwise, it must return False.
+</para>
+
+<para>
+If the dispatcher function returns True, the Transport Layer assume
+that the data has been processed by the upper layer. The Alternative
+Entry for this function is:
+</para>
+
+<funcsynopsis id='_ximregisterdispatcher'>
+<funcprototype>
+ <funcdef>Bool <function> _XimRegisterDispatcher</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>Bool<parameter> (*dispatcher)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dispatcher</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the dispatcher function to register.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a parameter for the <emphasis remap='I'>dispatcher</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+<sect2 id="Calling_dispatcher">
+<title>Calling dispatcher</title>
+<para>
+The following function is used to call the registered dispatcher
+function, when the asynchronous response from IM Server has arrived.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Bool <function>(*call_dispatcher)</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies XIM structure address.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>len</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of <emphasis remap='I'>data</emphasis> buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to store data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The call_dispatcher must call the dispatcher function, in order of
+their registration. <emphasis remap='I'>len</emphasis> and <emphasis remap='I'>data</emphasis> are the data passed to
+register_dispatcher.
+</para>
+
+<para>
+The return values are checked at each invocation, and if it finds
+True, it immediately return with true for its return value.
+</para>
+
+<para>
+It is depend on the upper layer whether the read data is XIM
+Protocol packet unit or not.
+The Alternative Entry for this function is:
+</para>
+
+<funcsynopsis id='_ximcalldispatcher'>
+<funcprototype>
+ <funcdef>Bool <function> _XimCallDispatcher</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>INT16<parameter> len</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+</sect2>
+</sect1>
+<sect1 id="Sample_implementations_for_the_Transport_Layer">
+<title>Sample implementations for the Transport Layer</title>
+<para>
+Sample implementations for the transporter using the X connection is
+described here.
+</para>
+
+<sect2 id="X_Transport">
+<title>X Transport</title>
+<para>
+At the beginning of the X Transport connection for the XIM transport
+mechanism, two different windows must be created either in an Xlib XIM
+or in an IM Server, with which the Xlib and the IM Server exchange the
+XIM transports by using the ClientMessage events and Window Properties.
+In the following, the window created by the Xlib is referred as the
+"client communication window", and on the other hand, the window created
+by the IM Server is referred as the "IMS communication window".
+</para>
+
+<sect3 id="Connection">
+<title>Connection</title>
+<para>
+In order to establish a connection, a communication window is created.
+A ClientMessage in the following event's format is sent to the owner
+window of XIM_SERVER selection, which the IM Server has created.
+</para>
+
+<para>
+<!-- .LP -->
+Refer to "The Input Method Protocol" for the XIM_SERVER atom.
+</para>
+
+<table frame="none" id="transport_layer_functions">
+ <title>The ClientMessage sent to the IMS window.</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_CONNECT", false)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>32</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[0]</entry>
+ <entry>client communication window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[1]</entry>
+ <entry>client-major-transport-version(*1)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[2]</entry>
+ <entry>client-major-transport-version(*1)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+In order to establish the connection (to notify the IM Server communication
+window), the IM Server sends a ClientMessage in the following event's
+format to the client communication window.
+</para>
+
+<table frame="none" id="clientmessage_sent_by_im_server">
+ <title>The ClientMessage sent by IM Server.</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_CONNECT", false)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>32</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[0]</entry>
+ <entry>client communication window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[1]</entry>
+ <entry>client-major-transport-version(*1)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[2]</entry>
+ <entry>client-major-transport-version(*1)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[3]</entry>
+ <entry>dividing size between ClientMessage and Property(*2)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+(*1) major/minor-transport-version
+</para>
+
+<para>
+The read/write method is decided by the combination of
+major/minor-transport-version, as follows:
+</para>
+
+<table frame="all" id="readwrite_method_and_the_majorminor_transport_version">
+<title>The read/write method and the major/minor-transport-version</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="1"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3*" colsep="1"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="center"/>
+ <thead>
+ <row>
+ <entry spanname="span-horiz">Transport-version</entry>
+ <entry>read/write</entry>
+ </row>
+ <row>
+ <entry>major</entry>
+ <entry>minor</entry>
+ <entry></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry morerows="2">0</entry>
+ <entry>0</entry>
+ <entry>only-CM & Property-with-CM</entry>
+ </row>
+ <row rowsep="0">
+ <entry>1</entry>
+ <entry>only-CM & multi-CM</entry>
+ </row>
+ <row rowsep="1">
+ <entry>2</entry>
+ <entry>only-CM & multi-CM & Property-with-CM</entry>
+ </row>
+ <row rowsep="1">
+ <entry>1</entry>
+ <entry>0</entry>
+ <entry>PropertyNotify</entry>
+ </row>
+ <row rowsep="0">
+ <entry morerows="1">2</entry>
+ <entry>0</entry>
+ <entry>only-CM & PropertyNotify</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>only-CM & multi-CM & PropertyNotify</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<literallayout class="monospaced">
+only-CM : data is sent via a ClientMessage
+multi-CM : data is sent via multiple ClientMessages
+Property-with-CM : data is written in Property, and its Atom
+ is send via ClientMessage
+PropertyNotify : data is written in Property, and its Atom
+ is send via PropertyNotify
+
+</literallayout>
+
+
+<para>
+The method to decide major/minor-transport-version is as follows:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+The client sends 0 as major/minor-transport-version to the IM Server.
+The client must support all methods in Table 4-3. <!-- xref -->
+The client may send another number as major/minor-transport-version to
+use other method than the above in the future.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The IM Server sends its major/minor-transport-version number to
+the client. The client sends data using the method specified by the
+IM Server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If major/minor-transport-version number is not available, it is regarded
+as 0.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+(*2) dividing size between ClientMessage and Property
+</para>
+
+<para>
+If data is sent via both of multi-CM and Property, specify the dividing
+size between ClientMessage and Property. The data, which is smaller than
+this size, is sent via multi-CM (or only-CM), and the data, which is
+lager than this size, is sent via Property.
+</para>
+
+</sect3>
+
+<sect3 id="read_write_">
+<title>read/write </title>
+<para>
+The data is transferred via either ClientMessage or Window Property in
+the X Window System.
+</para>
+
+<sect4 id="Format_for_the_data_from_the_Client_to_the_IM_Server">
+<title>Format for the data from the Client to the IM Server</title>
+<para>
+<emphasis role="bold">ClientMessage</emphasis>
+</para>
+
+<para>
+If data is sent via ClientMessage event, the format is as follows:
+</para>
+
+<table frame="none" id="clientmessage_events_format_first_or_middle">
+ <title>The ClientMessage event's format (first or middle)</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_MOREDATA", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>char</entry>
+ <entry>data.b[20]</entry>
+ <entry>(read/write DATA : 20 byte)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+
+
+<table frame="none" id="clientmessage_events_format_only_or_last">
+ <title>The ClientMessage event's format (only or last)</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>char</entry>
+ <entry>data.b[20]</entry>
+ <entry>(read/write DATA : MAX 20 byte)
+<footnote><para>If the data is smaller
+than 20 bytes, all data other than available data must be 0.
+</para></footnote>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+<emphasis role="bold">Property</emphasis>
+</para>
+
+<para>
+In the case of large data, data will be sent via the Window Property
+for the efficiency. There are the following two methods to notify
+Property, and transport-version is decided which method is used.
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+The XChangeProperty function is used to store data in the client
+communication window, and Atom of the stored data is notified to the
+IM Server via ClientMessage event.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The XChangeProperty function is used to store data in the client
+communication window, and Atom of the stored data is notified to the
+IM Server via PropertyNotify event.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+The arguments of the XChangeProperty are as follows:
+</para>
+
+
+<table frame="none" id="xchangeproperty_events_format">
+ <title>The XChangeProperty event's format</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Argument</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS communication window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>property</entry>
+ <entry>read/write property Atom (*1)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>mode</entry>
+ <entry>PropModeAppend</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_char</entry>
+ <entry>*data</entry>
+ <entry>read/write DATA</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>nelements</entry>
+ <entry>length of DATA</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+(*1) The read/write property ATOM allocates the following strings by
+<function>XInternAtom</function>.
+"_clientXXX"
+</para>
+
+<para>
+The client changes the property with the mode of PropModeAppend and
+the IM Server will read it with the delete mode i.e. (delete = True).
+</para>
+
+<para>
+If Atom is notified via ClientMessage event, the format of the ClientMessage
+is as follows:
+</para>
+
+<table frame="none" id="clientmessage_events_format_to_send_atom_of_property">
+ <title>The ClientMessage event's format to send Atom of property</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[0]</entry>
+ <entry>length of read/write property Atom</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[1]</entry>
+ <entry>read/write property Atom</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+</sect4>
+
+<sect4 id="Format_for_the_data_from_the_IM_Server_to_the_Client">
+<title>Format for the data from the IM Server to the Client</title>
+<para>
+<emphasis role="bold">ClientMessage</emphasis>
+</para>
+
+<para>
+The format of the ClientMessage is as follows:
+</para>
+
+<table frame="none" id="clientmessage_events_format_first_or_middle_2">
+ <title>The ClientMessage event's format (first or middle)</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_MOREDATA", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>char</entry>
+ <entry>data.b[20]</entry>
+ <entry>(read/write DATA : 20 byte)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+
+
+
+
+<table frame="none" id="clientmessage_events_format_only_or_last_2">
+ <title>The ClientMessage event's format (only or last)</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>char</entry>
+ <entry>data.b[20]</entry>
+ <entry>(read/write DATA : MAX 20 byte) (*1)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+(*1) If the data size is smaller than 20 bytes, all data other than available
+data must be 0.
+</para>
+
+<para>
+<emphasis role="bold">Property</emphasis>
+</para>
+
+<para>
+In the case of large data, data will be sent via the Window Property
+for the efficiency. There are the following two methods to notify
+Property, and transport-version is decided which method is used.
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+The XChangeProperty function is used to store data in the IMS
+communication window, and Atom of the property is sent via the
+ClientMessage event.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The XChangeProperty function is used to store data in the IMS
+communication window, and Atom of the property is sent via
+PropertyNotify event.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+The arguments of the XChangeProperty are as follows:
+</para>
+
+<table frame="none" id="xchangeproperty_events_format_b">
+ <title>The XChangeProperty event's format</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Argument</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS communication window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>property</entry>
+ <entry>read/write property Atom (*1)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>mode</entry>
+ <entry>PropModeAppend</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_char</entry>
+ <entry>*data</entry>
+ <entry>read/write DATA</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>nelements</entry>
+ <entry>length of DATA</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+<para>
+(*1) The read/write property ATOM allocates some strings, which are not
+allocated by the client, by <function>XInternAtom</function>.
+</para>
+
+<para>
+The IM Server changes the property with the mode of PropModeAppend and
+the client reads it with the delete mode, i.e. (delete = True).
+</para>
+
+<para>
+If Atom is notified via ClientMessage event, the format of the ClientMessage
+is as follows:
+</para>
+
+<table frame="none" id="clientmessage_events_format_to_send_atom_of_property_2">
+ <title>The ClientMessage event's format to send Atom of property</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*" colsep="0"/>
+ <colspec colname="col2" colwidth="1*" colsep="1"/>
+ <colspec colname="col3" colwidth="3.5*" colsep="0"/>
+ <spanspec namest="col1" nameend="col2" spanname="span-horiz" align="left"/>
+ <thead>
+ <row>
+ <entry align="left" spanname="span-horiz">Structure Member</entry>
+ <entry align="left">Contents</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>type</entry>
+ <entry>ClientMessage</entry>
+ </row>
+ <row rowsep="0">
+ <entry>u_long</entry>
+ <entry>serial</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Bool</entry>
+ <entry>send_event</entry>
+ <entry>Set by the X Window System</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Display</entry>
+ <entry>*display</entry>
+ <entry>The display to which connects</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Window</entry>
+ <entry>window</entry>
+ <entry>IMS Window ID</entry>
+ </row>
+ <row rowsep="0">
+ <entry>Atom</entry>
+ <entry>message_type</entry>
+ <entry>XInternAtom(display, "_XIM_PROTOCOL", False)</entry>
+ </row>
+ <row rowsep="0">
+ <entry>int</entry>
+ <entry>format</entry>
+ <entry>8</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[0]</entry>
+ <entry>length of read/write property Atom</entry>
+ </row>
+ <row rowsep="0">
+ <entry>long</entry>
+ <entry>data.1[1]</entry>
+ <entry>read/write property Atom</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+</sect4>
+</sect3>
+<sect3 id="Closing_Connection">
+<title>Closing Connection</title>
+
+<para>
+If the client disconnect with the IM Server, shutdown function should
+free the communication window properties and etc..
+</para>
+
+</sect3>
+</sect2>
+</sect1>
+
+<sect1 id="References">
+<title>References</title>
+<para>
+[1] Masahiko Narita and Hideki Hiura, <emphasis remap='I'>"The Input Method Protocol"</emphasis>
+</para>
+</sect1>
+
+</chapter>
+</book>
diff --git a/libX11/specs/libX11/AppC.xml b/libX11/specs/libX11/AppC.xml index 72103095b..cb2db3440 100644 --- a/libX11/specs/libX11/AppC.xml +++ b/libX11/specs/libX11/AppC.xml @@ -1,3313 +1,3313 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<appendix id="extensions"> -<title>Extensions</title> -<para> -<!-- .XE --> -Because X can evolve by extensions to the core protocol, -it is important that extensions not be perceived as second-class citizens. -At some point, -your favorite extensions may be adopted as additional parts of the -X Standard. -</para> -<para> -<!-- .LP --> -Therefore, there should be little to distinguish the use of an extension from -that of the core protocol. -To avoid having to initialize extensions explicitly in application programs, -it is also important that extensions perform lazy evaluations, -automatically initializing themselves when called for the first time. -</para> -<para> -<!-- .LP --> -This appendix describes techniques for writing extensions to Xlib that will -run at essentially the same performance as the core protocol requests. -</para> -<!-- .NT --> -<note><para> -It is expected that a given extension to X consists of multiple -requests. -Defining 10 new features as 10 separate extensions is a bad practice. -Rather, they should be packaged into a single extension -and should use minor opcodes to distinguish the requests. -</para></note> -<!-- .NE --> -<para> -<!-- .LP --> -The symbols and macros used for writing stubs to Xlib are listed in -<filename class="headerfile"><X11/Xlibint.h></filename>. -<!-- .SH --> -Basic Protocol Support Routines -</para> -<para> -The basic protocol requests for extensions are -<function>XQueryExtension</function> -and -<function>XListExtensions</function>. -</para> -<indexterm significance="preferred"><primary>XQueryExtension</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xqueryextension'> -<funcprototype> - <funcdef>Bool <function>XQueryExtension</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *name</parameter></paramdef> - <paramdef>int<parameter> *major_opcode_return</parameter></paramdef> - <paramdef>int<parameter> *first_event_return</parameter></paramdef> - <paramdef>int<parameter> *first_error_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term>display</term> - <listitem> - <para>Specifies the connection to the X server.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>name</term> - <listitem> - <para>Specifies the extension name.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>major_opcode_return</term> - <listitem> - <para>Returns the major opcode.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>first_event_return</term> - <listitem> - <para>Returns the first event code, if any.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>first_error_return</term> - <listitem> - <para>Returns the first error code, if any.</para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryExtension</function> -function determines if the named extension is present. -If the extension is not present, -<function>XQueryExtension</function> -returns -<symbol>False</symbol>; -otherwise, it returns -<symbol>True</symbol>. -If the extension is present, -<function>XQueryExtension</function> -returns the major opcode for the extension to major_opcode_return; -otherwise, -it returns zero. -Any minor opcode and the request formats are specific to the -extension. -If the extension involves additional event types, -<function>XQueryExtension</function> -returns the base event type code to first_event_return; -otherwise, -it returns zero. -The format of the events is specific to the extension. -If the extension involves additional error codes, -<function>XQueryExtension</function> -returns the base error code to first_error_return; -otherwise, -it returns zero. -The format of additional data in the errors is specific to the extension. -</para> -<para> -<!-- .LP --> -If the extension name is not in the Host Portable Character Encoding -the result is implementation-dependent. -Uppercase and lowercase matter; -the strings ``thing'', ``Thing'', and ``thinG'' -are all considered different names. -</para> -<indexterm significance="preferred"><primary>XListExtensions</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlistextensions'> -<funcprototype> - <funcdef>char **<function>XListExtensions</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *nextensions_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nextensions_return</emphasis> - </term> - <listitem> - <para> -Returns the number of extensions listed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListExtensions</function> -function returns a list of all extensions supported by the server. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned strings are in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -</para> -<indexterm significance="preferred"><primary>XFreeExtensionList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreeextensionlist'> -<funcprototype> - <funcdef><function>XFreeExtensionList</function></funcdef> - <paramdef>char<parameter> **list</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the list of extension names. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeExtensionList</function> -function frees the memory allocated by -<function>XListExtensions</function>. -<!-- .SH --> -Hooking into Xlib -</para> -<para> -<!-- .LP --> -These functions allow you to hook into the library. -They are not normally used by application programmers but are used -by people who need to extend the core X protocol and -the X library interface. -The functions, which generate protocol requests for X, are typically -called stubs. -</para> -<para> -<!-- .LP --> -In extensions, stubs first should check to see if they have initialized -themselves on a connection. -If they have not, they then should call -<function>XInitExtension</function> -to attempt to initialize themselves on the connection. -</para> -<para> -<!-- .LP --> -If the extension needs to be informed of GC/font allocation or -deallocation or if the extension defines new event types, -the functions described here allow the extension to be -called when these events occur. -</para> -<para> -<!-- .LP --> -The -<structname>XExtCodes</structname> -structure returns the information from -<function>XInitExtension</function> -and is defined in -<filename class="headerfile"><X11/Xlib.h></filename>: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XExtCodes</primary></indexterm> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<synopsis> -typedef struct _XExtCodes { /* public to extension, cannot be changed */ - int extension; /* extension number */ - int major_opcode; /* major op-code assigned by server */ - int first_event; /* first event number for the extension */ - int first_error; /* first error number for the extension */ -} XExtCodes; -</synopsis> -</para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XInitExtension</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinitextension'> -<funcprototype> - <funcdef>XExtCodes *<function>XInitExtension</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the extension name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInitExtension</function> -function determines if the named extension exists. -Then, it allocates storage for maintaining the -information about the extension on the connection, -chains this onto the extension list for the connection, -and returns the information the stub implementor will need to access -the extension. -If the extension does not exist, -<function>XInitExtension</function> -returns NULL. -</para> -<para> -<!-- .LP --> -If the extension name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Uppercase and lowercase matter; -the strings ``thing'', ``Thing'', and ``thinG'' -are all considered different names. -</para> -<para> -<!-- .LP --> -The extension number in the -<structname>XExtCodes</structname> -structure is -needed in the other calls that follow. -This extension number is unique only to a single connection. -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XAddExtension</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddextension'> -<funcprototype> - <funcdef>XExtCodes *<function>XAddExtension</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -For local Xlib extensions, the -<function>XAddExtension</function> -function allocates the -<structname>XExtCodes</structname> -structure, bumps the extension number count, -and chains the extension onto the extension list. -(This permits extensions to Xlib without requiring server extensions.) -<!-- .SH --> -Hooks into the Library -</para> -<para> -<!-- .LP --> -These functions allow you to define procedures that are to be -called when various circumstances occur. -The procedures include the creation of a new GC for a connection, -the copying of a GC, the freeing of a GC, the creating and freeing of fonts, -the conversion of events defined by extensions to and from wire -format, and the handling of errors. -</para> -<para> -<!-- .LP --> -All of these functions return the previous procedure defined for this -extension. -</para> -<indexterm significance="preferred"><primary>XESetCloseDisplay</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetclosedisplay'> -<funcprototype> - <funcdef>int <function>XESetCloseDisplay</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when the display is closed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetCloseDisplay</function> -function defines a procedure to be called whenever -<function>XCloseDisplay</function> -is called. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When -<function>XCloseDisplay</function> -is called, -your procedure is called -with these arguments: -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<indexterm significance="preferred"><primary>XESetCreateGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetcreategc'> -<funcprototype> - <funcdef>int *<function>XESetCreateGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a GC is closed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetCreateGC</function> -function defines a procedure to be called whenever -a new GC is created. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When a GC is created, -your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>GC <parameter>gc</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<indexterm significance="preferred"><primary>XESetCopyGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetcopygc'> -<funcprototype> - <funcdef>int *<function>XESetCopyGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when GC components are copied. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetCopyGC</function> -function defines a procedure to be called whenever -a GC is copied. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When a GC is copied, -your procedure is called with these arguments: -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>GC <parameter>gc</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<funcsynopsis id='xesetfreegc'> -<funcprototype> - <funcdef>int *<function>XESetFreeGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a GC is freed. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The -<function>XESetFreeGC</function> -function defines a procedure to be called whenever -a GC is freed. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When a GC is freed, -your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>GC <parameter>gc</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XESetCreateFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetcreatefont'> -<funcprototype> - <funcdef>int *<function>XESetCreateFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a font is created. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetCreateFont</function> -function defines a procedure to be called whenever -<function>XLoadQueryFont</function> -and -<function>XQueryFont</function> -are called. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When -<function>XLoadQueryFont</function> -or -<function>XQueryFont</function> -is called, -your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XFontStruct *<parameter>fs</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XESetFreeFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetfreefont'> -<funcprototype> - <funcdef>int *<function>XESetFreeFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a font is freed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetFreeFont</function> -function defines a procedure to be called whenever -<function>XFreeFont</function> -is called. -It returns any previously defined procedure, usually NULL. -</para> -<para> -<!-- .LP --> -When -<function>XFreeFont</function> -is called, your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XFontStruct *<parameter>fs</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetWireToEvent</function> -and -<function>XESetEventToWire</function> -functions allow you to define new events to the library. -An -<structname>XEvent</structname> -structure always has a type code (type -<type>int</type>) -as the first component. -This uniquely identifies what kind of event it is. -The second component is always the serial number (type -<type>unsigned</type> -<type>long</type>) -of the last request processed by the server. -The third component is always a Boolean (type -<type>Bool</type>) -indicating whether the event came from a -<systemitem>SendEvent</systemitem> -protocol request. -The fourth component is always a pointer to the display -the event was read from. -The fifth component is always a resource ID of one kind or another, -usually a window, carefully selected to be useful to toolkit dispatchers. -The fifth component should always exist, even if -the event does not have a natural destination; -if there is no value -from the protocol to put in this component, initialize it to zero. -<!-- .NT --> -There is an implementation limit such that your host event -structure size cannot be bigger than the size of the -<structname>XEvent</structname> -union of structures. -There also is no way to guarantee that more than 24 elements or 96 characters -in the structure will be fully portable between machines. -</para> -<!-- .NE --> -<indexterm significance="preferred"><primary>XESetWireToEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetwiretoevent'> -<funcprototype> - <funcdef>int *<function>XESetWireToEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> event_number</parameter></paramdef> - <paramdef>Status<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_number</emphasis> - </term> - <listitem> - <para> -Specifies the event code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when converting an event. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetWireToEvent</function> -function defines a procedure to be called when an event -needs to be converted from wire format -(<structname>xEvent</structname>) -to host format -(<structname>XEvent</structname>). -The event number defines which protocol event number to install a -conversion procedure for. -<function>XESetWireToEvent</function> -returns any previously defined procedure. -<!-- .NT --> -You can replace a core event conversion function with one -of your own, although this is not encouraged. -It would, however, allow you to intercept a core event -and modify it before being placed in the queue or otherwise examined. -<!-- .NE --> -When Xlib needs to convert an event from wire format to host -format, your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XEvent *<parameter>re</parameter></paramdef> - <paramdef>xEvent *<parameter>event</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -Your procedure must return status to indicate if the conversion succeeded. -The re argument is a pointer to where the host format event should be stored, -and the event argument is the 32-byte wire event structure. -In the -<structname>XEvent</structname> -structure you are creating, -you must fill in the five required members of the event structure. -You should fill in the type member with the type specified for the -<structname>xEvent</structname> -structure. -You should copy all other members from the -<structname>xEvent</structname> -structure (wire format) to the -<structname>XEvent</structname> -structure (host format). -Your conversion procedure should return -<symbol>True</symbol> -if the event should be placed in the queue or -<symbol>False</symbol> -if it should not be placed in the queue. -</para> -<para> -<!-- .LP --> -To initialize the serial number component of the event, call -<function>_XSetLastRequestRead</function> -with the event and use the return value. -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>_XSetLastRequestRead</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetlastrequestread'> -<funcprototype> - <funcdef>unsigned long<function>_XSetLastRequestRead</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>xGenericReply<parameter> *rep</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rep</emphasis> - </term> - <listitem> - <para> -Specifies the wire event structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XSetLastRequestRead</function> -function computes and returns a complete serial number from the partial -serial number in the event. -<!-- .sp --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XESetEventToWire</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xeseteventtowire'> -<funcprototype> - <funcdef>Status *<function>XESetEventToWire</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> event_number</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_number</emphasis> - </term> - <listitem> - <para> -Specifies the event code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when converting an event. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetEventToWire</function> -function defines a procedure to be called when an event -needs to be converted from host format -(<structname>XEvent</structname>) -to wire format -(<structname>xEvent</structname>) -form. -The event number defines which protocol event number to install a -conversion procedure for. -<function>XESetEventToWire</function> -returns any previously defined procedure. -It returns zero if the conversion fails or nonzero otherwise. -<!-- .NT --> -You can replace a core event conversion function with one -of your own, although this is not encouraged. -It would, however, allow you to intercept a core event -and modify it before being sent to another client. -<!-- .NE --> -When Xlib needs to convert an event from host format to wire format, -your procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XEvent *<parameter>re</parameter></paramdef> - <paramdef>xEvent *<parameter>event</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -The re argument is a pointer to the host format event, -and the event argument is a pointer to where the 32-byte wire event -structure should be stored. -You should fill in the type with the type from the -<structname>XEvent</structname> -structure. -All other members then should be copied from the host format to the -<structname>xEvent</structname> -structure. -</para> -<indexterm significance="preferred"><primary>XESetWireToError</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetwiretoerror'> -<funcprototype> - <funcdef>Bool *<function>XESetWireToError</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> error_number</parameter></paramdef> - <paramdef>Bool<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>error_number</emphasis> - </term> - <listitem> - <para> -Specifies the error code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when an error is received. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetWireToError</function> -function defines a procedure to be called when an extension -error needs to be converted from wire format to host format. -The error number defines which protocol error code to install -the conversion procedure for. -<function>XESetWireToError</function> -returns any previously defined procedure. -</para> -<para> -<!-- .LP --> -Use this function for extension errors that contain additional error values -beyond those in a core X error, when multiple wire errors must be combined -into a single Xlib error, or when it is necessary to intercept an -X error before it is otherwise examined. -</para> -<para> -<!-- .LP --> -When Xlib needs to convert an error from wire format to host format, -the procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XErrorEvent *<parameter>he</parameter></paramdef> - <paramdef>xError *<parameter>we</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -The he argument is a pointer to where the host format error should be stored. -The structure pointed at by he is guaranteed to be as large as an -<structname>XEvent</structname> -structure and so can be cast to a type larger than an -<structname>XErrorEvent</structname> -to store additional values. -If the error is to be completely ignored by Xlib -(for example, several protocol error structures will be combined into -one Xlib error), -then the function should return -<symbol>False</symbol>; -otherwise, it should return -<symbol>True</symbol>. -</para> -<indexterm significance="preferred"><primary>XESetError</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xeseterror'> -<funcprototype> - <funcdef>int *<function>XESetError</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when an error is received. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Inside Xlib, there are times that you may want to suppress the -calling of the external error handling when an error occurs. -This allows status to be returned on a call at the cost of the call -being synchronous (though most such functions are query operations, in any -case, and are typically programmed to be synchronous). -</para> -<para> -<!-- .LP --> -When Xlib detects a protocol error in -<function>_XReply</function>, -it calls your procedure with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>xError *<parameter>err</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> - <paramdef>int *<parameter>ret_code</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -The err argument is a pointer to the 32-byte wire format error. -The codes argument is a pointer to the extension codes structure. -The ret_code argument is the return code you may want -<function>_XReply</function> -returned to. -</para> -<para> -<!-- .LP --> -If your procedure returns a zero value, -the error is not suppressed, and -the client's error handler is called. -(For further information, -see <link linkend="Using_the_Default_Error_Handlers">section 11.8.2</link>.) -If your procedure returns nonzero, -the error is suppressed, and -<function>_XReply</function> -returns the value of ret_code. -</para> -<indexterm significance="preferred"><primary>XESetErrorString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xeseterrorstring'> -<funcprototype> - <funcdef>char *<function>XESetErrorString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>char<parameter> *(*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call to obtain an error string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetErrorText</function> -function returns a string to the user for an error. -<function>XESetErrorString</function> -allows you to define a procedure to be called that -should return a pointer to the error message. -The following is an example. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>int <parameter>code</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> - <paramdef>char *<parameter>buffer</parameter></paramdef> - <paramdef>int <parameter>nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -Your procedure is called with the error code for every error detected. -You should copy nbytes of a null-terminated string containing the -error message into buffer. -</para> -<indexterm significance="preferred"><primary>XESetPrintErrorValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetprinterrorvalues'> -<funcprototype> - <funcdef>void *<function>XESetPrintErrorValues</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>void<parameter> (*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when an error is printed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetPrintErrorValues</function> -function defines a procedure to be called when an extension -error is printed, to print the error values. -Use this function for extension errors that contain additional error values -beyond those in a core X error. -It returns any previously defined procedure. -</para> -<para> -<!-- .LP --> -When Xlib needs to print an error, -the procedure is called with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>void <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XErrorEvent *<parameter>ev</parameter></paramdef> - <paramdef>void *<parameter>fp</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -The structure pointed at by ev is guaranteed to be as large as an -<structname>XEvent</structname> -structure and so can be cast to a type larger than an -<structname>XErrorEvent</structname> -to obtain additional values set by using -<function>XESetWireToError</function>. -The underlying type of the fp argument is system dependent; -on a <acronym>POSIX</acronym>-compliant system, fp should be cast to type FILE*. -</para> -<indexterm significance="preferred"><primary>XESetFlushGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xesetflushgc'> -<funcprototype> - <funcdef>int *<function>XESetFlushGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> *(*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a GC is flushed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The procedure set by the -<function>XESetFlushGC</function> -function has the same interface as the procedure set by the -<function>XESetCopyGC</function> -function, but is called when a GC cache needs to be updated in the server. -</para> -<indexterm significance="preferred"><primary>XESetBeforeFlush</primary></indexterm> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef>int *<function>XESetCopyGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> extension</parameter></paramdef> - <paramdef>int<parameter> *(*proc)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extension</emphasis> - </term> - <listitem> - <para> -Specifies the extension number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to call when a buffer is flushed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XESetBeforeFlush</function> -function defines a procedure to be called when data is about to be -sent to the server. When data is about to be sent, your procedure is -called one or more times with these arguments: -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<!-- .R --> -<funcsynopsis> -<funcprototype> - <funcdef>void <function>(*<replaceable>proc</replaceable>)</function></funcdef> - <paramdef>Display *<parameter>display</parameter></paramdef> - <paramdef>XExtCodes *<parameter>codes</parameter></paramdef> - <paramdef>char *<parameter>data</parameter></paramdef> - <paramdef>long <parameter>len</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .LP --> -<!-- .eM --> -The data argument specifies a portion of the outgoing data buffer, -and its length in bytes is specified by the len argument. -Your procedure must not alter the contents of the data and must not -do additional protocol requests to the same display. -<!-- .SH --> -Hooks onto Xlib Data Structures -</para> -<para> -<!-- .LP --> -Various Xlib data structures have provisions for extension procedures -to chain extension supplied data onto a list. -These structures are -<structname>GC</structname>, -<structname>Visual</structname>, -<type>Screen</type>, -<structname>ScreenFormat</structname>, -<type>Display</type>, -and -<structname>XFontStruct</structname>. -Because the list pointer is always the first member in the structure, -a single set of procedures can be used to manipulate the data -on these lists. -</para> -<para> -<!-- .LP --> -The following structure is used in the functions in this section -and is defined in -<filename class="headerfile"><X11/Xlib.h></filename> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XExtData</primary></indexterm> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<synopsis> -typedef struct _XExtData { - int number; /* number returned by XInitExtension */ - struct _XExtData *next; /* next item on list of data for structure */ - int (*free_private)(); /* if defined, called to free private */ - XPointer private_data; /* data private to this extension. */ -} XExtData; -</synopsis> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -When any of the data structures listed above are freed, -the list is walked, and the structure's free procedure (if any) is called. -If free is NULL, -then the library frees both the data pointed to by the private_data member -and the structure itself. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<!-- .TA .5i --> -<!-- .ta .5i --> -<synopsis> -union { Display *display; - GC gc; - Visual *visual; - Screen *screen; - ScreenFormat *pixmap_format; - XFontStruct *font } XEDataObject; -</synopsis> -</para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XEHeadOfExtensionList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xeheadofextensionlist'> -<funcprototype> - <funcdef>XExtData **<function>XEHeadOfExtensionList</function></funcdef> - <paramdef>XEDataObject<parameter> object</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>object</emphasis> - </term> - <listitem> - <para> -Specifies the object. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XEHeadOfExtensionList</function> -function returns a pointer to the list of extension structures attached -to the specified object. -In concert with -<function>XAddToExtensionList</function>, -<function>XEHeadOfExtensionList</function> -allows an extension to attach arbitrary data to any of the structures -of types contained in -<structname>XEDataObject</structname>. -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XAddToExtensionList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddtoextensionlist'> -<funcprototype> - <funcdef><function>XAddToExtensionList</function></funcdef> - <paramdef>XExtData<parameter> **structure</parameter></paramdef> - <paramdef>XExtData<parameter> *ext_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>structure</emphasis> - </term> - <listitem> - <para> -Specifies the extension list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ext_data</emphasis> - </term> - <listitem> - <para> -Specifies the extension data structure to add. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The structure argument is a pointer to one of the data structures -enumerated above. -You must initialize ext_data->number with the extension number -before calling this function. -</para> -<indexterm significance="preferred"><primary>XFindOnExtensionList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfindonextensionlist'> -<funcprototype> - <funcdef>XExtData *<function>XFindOnExtensionList</function></funcdef> - <paramdef>struct_XExtData<parameter> **structure</parameter></paramdef> - <paramdef>int<parameter> number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>structure</emphasis> - </term> - <listitem> - <para> -Specifies the extension list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>number</emphasis> - </term> - <listitem> - <para> -Specifies the extension number from -<function>XInitExtension</function>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFindOnExtensionList</function> -function returns the first extension data structure -for the extension numbered number. -It is expected that an extension will add at most one extension -data structure to any single data structure's extension data list. -There is no way to find additional structures. -</para> -<para> -<!-- .LP --> -The -<function>XAllocID</function> -macro, which allocates and returns a resource ID, is defined in -<filename class="headerfile"><X11/Xlib.h></filename>. -</para> -<indexterm significance="preferred"><primary>XAllocID</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xallocid'> -<funcprototype> - <funcdef><function>XAllocID</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -This macro is a call through the -<type>Display</type> -structure to an internal resource ID allocator. -It returns a resource ID that you can use when creating new resources. -</para> -<para> -<!-- .LP --> -The -<function>XAllocIDs</function> -macro allocates and returns an array of resource ID. -</para> -<indexterm significance="preferred"><primary>XAllocIDs</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xallocids'> -<funcprototype> - <funcdef><function>XAllocIDs</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> *ids_return</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ids_return</emphasis> - </term> - <listitem> - <para> -Returns the resource IDs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rep</emphasis> - </term> - <listitem> - <para> -Specifies the number of resource IDs requested. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -This macro is a call through the -<type>Display</type> -structure to an internal resource ID allocator. -It returns resource IDs to the array supplied by the caller. -To correctly handle automatic reuse of resource IDs, you must call -<function>XAllocIDs</function> -when requesting multiple resource IDs. This call might generate -protocol requests. -<!-- .SH --> -GC Caching -</para> -<para> -<!-- .LP --> -GCs are cached by the library to allow merging of independent change -requests to the same GC into single protocol requests. -This is typically called a write-back cache. -Any extension procedure whose behavior depends on the contents of a GC -must flush the GC cache to make sure the server has up-to-date contents -in its GC. -</para> -<para> -<!-- .LP --> -The -<function>FlushGC</function> -macro checks the dirty bits in the library's GC structure and calls -<function>_XFlushGCCache</function> -if any elements have changed. -The -<function>FlushGC</function> -macro is defined as follows: -</para> -<indexterm significance="preferred"><primary>FlushGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='flushgc'> -<funcprototype> - <funcdef><function>FlushGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Note that if you extend the GC to add additional resource ID components, -you should ensure that the library stub sends the change request immediately. -This is because a client can free a resource immediately after -using it, so if you only stored the value in the cache without -forcing a protocol request, the resource might be destroyed before being -set into the GC. -You can use the -<function>_XFlushGCCache</function> -procedure -to force the cache to be flushed. -The -<function>_XFlushGCCache</function> -procedure -is defined as follows: -</para> -<indexterm significance="preferred"><primary>_XFlushGCCache</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='_xflushgccache'> -<funcprototype> - <funcdef><function>_XFlushGCCache</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .SH --> -Graphics Batching -</para> -<para> -<!-- .LP --> -If you extend X to add more poly graphics primitives, you may be able to -take advantage of facilities in the library to allow back-to-back -single calls to be transformed into poly requests. -This may dramatically improve performance of programs that are not -written using poly requests. -A pointer to an -<structname>xReq</structname>, -called last_req in the display structure, is the last request being processed. -By checking that the last request -type, drawable, gc, and other options are the same as the new one -and that there is enough space left in the buffer, you may be able -to just extend the previous graphics request by extending the length -field of the request and appending the data to the buffer. -This can improve performance by five times or more in naive programs. -For example, here is the source for the -<function>XDrawPoint</function> -stub. -(Writing extension stubs is discussed in the next section.) -</para> -<!-- .sM --> -<!-- .nf --> -<programlisting> -#include <X11/Xlibint.h> - -/* precompute the maximum size of batching request allowed */ - -static int size = sizeof(xPolyPointReq) + EPERBATCH * sizeof(xPoint); - -XDrawPoint(dpy, d, gc, x, y) - register Display *dpy; - Drawable d; - GC gc; - int x, y; /* INT16 */ -{ - xPoint *point; - LockDisplay(dpy); - FlushGC(dpy, gc); - { - register xPolyPointReq *req = (xPolyPointReq *) dpy->last_req; - /* if same as previous request, with same drawable, batch requests */ - if ( - (req->reqType == X_PolyPoint) - && (req->drawable == d) - && (req->gc == gc->gid) - && (req->coordMode == CoordModeOrigin) - && ((dpy->bufptr + sizeof (xPoint)) <= dpy->bufmax) - && (((char *)dpy->bufptr - (char *)req) < size) ) { - point = (xPoint *) dpy->bufptr; - req->length += sizeof (xPoint) >> 2; - dpy->bufptr += sizeof (xPoint); - } - - else { - GetReqExtra(PolyPoint, 4, req); /* 1 point = 4 bytes */ - req->drawable = d; - req->gc = gc->gid; - req->coordMode = CoordModeOrigin; - point = (xPoint *) (req + 1); - } - point->x = x; - point->y = y; - } - UnlockDisplay(dpy); - SyncHandle(); -} -</programlisting> -<!-- .fi --> -<para> -<!-- .LP --> -<!-- .eM --> -To keep clients from generating very long requests that may monopolize the -server, -there is a symbol defined in -<filename class="headerfile"><X11/Xlibint.h></filename> -of EPERBATCH on the number of requests batched. -Most of the performance benefit occurs in the first few merged requests. -Note that -<function>FlushGC</function> -is called <emphasis remap='I'>before</emphasis> picking up the value of last_req, -because it may modify this field. -<!-- .SH --> -Writing Extension Stubs -</para> -<para> -<!-- .LP --> -All X requests always contain the length of the request, -expressed as a 16-bit quantity of 32 bits. -This means that a single request can be no more than 256K bytes in -length. -Some servers may not support single requests of such a length. -The value of dpy->max_request_size contains the maximum length as -defined by the server implementation. -For further information, -see ``X Window System Protocol.'' -<!-- .SH --> -Requests, Replies, and Xproto.h -</para> -<para> -<!-- .LP --> -The -<filename class="headerfile"><X11/Xproto.h></filename> -file contains three sets of definitions that -are of interest to the stub implementor: -request names, request structures, and reply structures. -</para> -<para> -<!-- .LP --> -You need to generate a file equivalent to -<filename class="headerfile"><X11/Xproto.h></filename> -for your extension and need to include it in your stub procedure. -Each stub procedure also must include -<filename class="headerfile"><X11/Xlibint.h></filename>. -</para> -<para> -<!-- .LP --> -The identifiers are deliberately chosen in such a way that, if the -request is called X_DoSomething, then its request structure is -xDoSomethingReq, and its reply is xDoSomethingReply. -The GetReq family of macros, defined in -<filename class="headerfile"><X11/Xlibint.h></filename>, -takes advantage of this naming scheme. -</para> -<para> -<!-- .LP --> -For each X request, -there is a definition in -<filename class="headerfile"><X11/Xproto.h></filename> -that looks similar to this: -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -#define X_DoSomething 42 -</programlisting> -In your extension header file, -this will be a minor opcode, -instead of a major opcode. -<!-- .SH --> -Request Format -</para> -<para> -<!-- .LP --> -Every request contains an 8-bit major opcode and a 16-bit length field -expressed in units of 4 bytes. -Every request consists of 4 bytes of header -(containing the major opcode, the length field, and a data byte) followed by -zero or more additional bytes of data. -The length field defines the total length of the request, including the header. -The length field in a request must equal the minimum length required to contain -the request. -If the specified length is smaller or larger than the required length, -the server should generate a -<errorname>BadLength</errorname> -error. -Unused bytes in a request are not required to be zero. -Extensions should be designed in such a way that long protocol requests -can be split up into smaller requests, -if it is possible to exceed the maximum request size of the server. -The protocol guarantees the maximum request size to be no smaller than -4096 units (16384 bytes). -</para> -<para> -<!-- .LP --> -Major opcodes 128 through 255 are reserved for extensions. -Extensions are intended to contain multiple requests, -so extension requests typically have an additional minor opcode encoded -in the second data byte in the request header, -but the placement and interpretation of this minor opcode as well as all -other fields in extension requests are not defined by the core protocol. -Every request is implicitly assigned a sequence number (starting with one) -used in replies, errors, and events. -</para> -<para> -<!-- .LP --> -To help but not cure portability problems to certain machines, the -<symbol>B16</symbol> -and -<symbol>B32</symbol> -macros have been defined so that they can become bitfield specifications -on some machines. -For example, on a Cray, -these should be used for all 16-bit and 32-bit quantities, as discussed below. -</para> -<para> -<!-- .LP --> -Most protocol requests have a corresponding structure typedef in -<filename class="headerfile"><X11/Xproto.h></filename>, -which looks like: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>xDoSomethingReq</primary></indexterm> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<synopsis> -typedef struct _DoSomethingReq { - CARD8 reqType; /* X_DoSomething */ - CARD8 someDatum; /* used differently in different requests */ - CARD16 length B16; /* total # of bytes in request, divided by 4 */ - ... - /* request-specific data */ - ... -} xDoSomethingReq; -</synopsis> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -If a core protocol request has a single 32-bit argument, -you need not declare a request structure in your extension header file. -Instead, such requests use the -<structname>xResourceReq</structname> -structure in -<filename class="headerfile"><X11/Xproto.h></filename>. -This structure is used for any request whose single argument is a -<type>Window</type>, -<type>Pixmap</type>, -<type>Drawable</type>, -<type>GContext</type>, -<type>Font</type>, -<type>Cursor</type>, -<type>Colormap</type>, -<type>Atom</type>, -or -<type>VisualID</type>. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>xResourceReq</primary></indexterm> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<synopsis> -typedef struct _ResourceReq { - CARD8 reqType; /* the request type, e.g. X_DoSomething */ - BYTE pad; /* not used */ - CARD16 length B16; /* 2 (= total # of bytes in request, divided by 4) */ - CARD32 id B32; /* the Window, Drawable, Font, GContext, etc. */ -} xResourceReq; -</synopsis> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -If convenient, -you can do something similar in your extension header file. -</para> -<para> -<!-- .LP --> -In both of these structures, -the reqType field identifies the type of the request (for example, -X_MapWindow or X_CreatePixmap). -The length field tells how long the request is -in units of 4-byte longwords. -This length includes both the request structure itself and any -variable-length data, such as strings or lists, that follow the -request structure. -Request structures come in different sizes, -but all requests are padded to be multiples of four bytes long. -</para> -<para> -<!-- .LP --> -A few protocol requests take no arguments at all. -Instead, they use the -<structname>xReq</structname> -structure in -<filename class="headerfile"><X11/Xproto.h></filename>, -which contains only a reqType and a length (and a pad byte). -</para> -<para> -<!-- .LP --> -If the protocol request requires a reply, -then -<filename class="headerfile"><X11/Xproto.h></filename> -also contains a reply structure typedef: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>xDoSomethingReply</primary></indexterm> -<!-- .sM --> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -<synopsis> -typedef struct _DoSomethingReply { - BYTE type; /* always X_Reply */ - BYTE someDatum; /* used differently in different requests */ - CARD16 sequenceNumber B16; /* # of requests sent so far */ - CARD32 length B32; /* # of additional bytes, divided by 4 */ - ... - /* request-specific data */ - ... -} xDoSomethingReply; -</synopsis> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Most of these reply structures are 32 bytes long. -If there are not that many reply values, -then they contain a sufficient number of pad fields -to bring them up to 32 bytes. -The length field is the total number of bytes in the request minus 32, -divided by 4. -This length will be nonzero only if: -</para> -<itemizedlist> - <listitem> - <para> -The reply structure is followed by variable-length data, -such as a list or string. - </para> - </listitem> - <listitem> - <para> -The reply structure is longer than 32 bytes. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Only -<systemitem>GetWindowAttributesl</systemitem>, -<systemitem>QueryFont</systemitem>, -<systemitem>QueryKeymap</systemitem>, -and -<systemitem>GetKeyboardControl</systemitem> -have reply structures longer than 32 bytes in the core protocol. -</para> -<para> -<!-- .LP --> -A few protocol requests return replies that contain no data. -<filename class="headerfile"><X11/Xproto.h></filename> -does not define reply structures for these. -Instead, they use the -<structname>xGenericReply</structname> -structure, which contains only a type, length, -and sequence number (and sufficient padding to make it 32 bytes long). -<!-- .SH --> -Starting to Write a Stub Procedure -</para> -<para> -<!-- .LP --> -An Xlib stub procedure should start like this: -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -#include "<X11/Xlibint.h> - -XDoSomething (arguments, ... ) -/* argument declarations */ -{ - -register XDoSomethingReq *req; -... -</programlisting> -If the protocol request has a reply, -then the variable declarations should include the reply structure for the request. -The following is an example: -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -xDoSomethingReply rep; -</programlisting> -<!-- .SH --> -Locking Data Structures -</para> -<para> -<!-- .LP --> -To lock the display structure for systems that -want to support multithreaded access to a single display connection, -each stub will need to lock its critical section. -Generally, this section is the point from just before the appropriate GetReq -call until all arguments to the call have been stored into the buffer. -The precise instructions needed for this locking depend upon the machine -architecture. -Two calls, which are generally implemented as macros, have been provided. -<indexterm significance="preferred"><primary>LockDisplay</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='lockdisplay'> -<funcprototype> - <funcdef><function>LockDisplay</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>UnlockDisplay</primary></indexterm> -<funcsynopsis id='unlockdisplay'> -<funcprototype> - <funcdef><function>UnlockDisplay</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .SH --> -Sending the Protocol Request and Arguments -</para> -<para> -<!-- .LP --> -After the variable declarations, -a stub procedure should call one of four macros defined in -<filename class="headerfile"><X11/Xlibint.h></filename>: -<function>GetReq</function>, -<function>GetReqExtra</function>, -<function>GetResReq</function>, -or -<function>GetEmptyReq</function>. -All of these macros take, as their first argument, -the name of the protocol request as declared in -<filename class="headerfile"><X11/Xproto.h></filename> -except with X_ removed. -Each one declares a -<type>Display</type> -structure pointer, -called dpy, and a pointer to a request structure, called req, -which is of the appropriate type. -The macro then appends the request structure to the output buffer, -fills in its type and length field, and sets req to point to it. -</para> -<para> -<!-- .LP --> -If the protocol request has no arguments (for instance, X_GrabServer), -then use -<function>GetEmptyReq</function>. -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -GetEmptyReq (DoSomething, req); -</programlisting> -If the protocol request has a single 32-bit argument (such as a -<type>Pixmap</type>, -<type>Window</type>, -<type>Drawable</type>, -<type>Atom</type>, -and so on), -then use -<function>GetResReq</function>. -The second argument to the macro is the 32-bit object. -<symbol>X_MapWindow</symbol> -is a good example. -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -GetResReq (DoSomething, rid, req); -</programlisting> -The rid argument is the -<type>Pixmap</type>, -<type>Window</type>, -or other resource ID. -</para> -<para> -<!-- .LP --> -If the protocol request takes any other argument list, -then call -<function>GetReq</function>. -After the -<function>GetReq</function>, -you need to set all the other fields in the request structure, -usually from arguments to the stub procedure. -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -GetReq (DoSomething, req); -/* fill in arguments here */ -req->arg1 = arg1; -req->arg2 = arg2; -... -</programlisting> -A few stub procedures (such as -<function>XCreateGC</function> -and -<function>XCreatePixmap</function>) -return a resource ID to the caller but pass a resource ID as an argument -to the protocol request. -Such procedures use the macro -<function>XAllocID</function> -to allocate a resource ID from the range of IDs -that were assigned to this client when it opened the connection. -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -rid = req->rid = XAllocID(); -... -return (rid); -</programlisting> -Finally, some stub procedures transmit a fixed amount of variable-length -data after the request. -Typically, these procedures (such as -<function>XMoveWindow</function> -and -<function>XSetBackground</function>) -are special cases of more general functions like -<function>XMoveResizeWindow</function> -and -<function>XChangeGC</function>. -These procedures use -<function>GetReqExtra</function>, -which is the same as -<function>GetReq</function> -except that it takes an additional argument (the number of -extra bytes to allocate in the output buffer after the request structure). -This number should always be a multiple of four. -<!-- .SH --> -Variable Length Arguments -</para> -<para> -<!-- .LP --> -Some protocol requests take additional variable-length data that -follow the -<type>xDoSomethingReq</type> -structure. -The format of this data varies from request to request. -Some requests require a sequence of 8-bit bytes, -others a sequence of 16-bit or 32-bit entities, -and still others a sequence of structures. -</para> -<para> -<!-- .LP --> -It is necessary to add the length of any variable-length data to the -length field of the request structure. -That length field is in units of 32-bit longwords. -If the data is a string or other sequence of 8-bit bytes, -then you must round the length up and shift it before adding: -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -req->length += (nbytes+3)>>2; -</programlisting> -To transmit variable-length data, use the -<function>Data</function> -macros. -If the data fits into the output buffer, -then this macro copies it to the buffer. -If it does not fit, however, -the -<function>Data</function> -macro calls -<function>_XSend</function>, -which transmits first the contents of the buffer and then your data. -The -<function>Data</function> -macros take three arguments: -the display, a pointer to the beginning of the data, -and the number of bytes to be sent. -<!-- .sM --> -<funcsynopsis id='data'> -<funcprototype> - <funcdef><function>Data</function></funcdef> - <paramdef><parameter> display</parameter></paramdef> - <paramdef>(char<parameter> *</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<function>Data</function>, -<function>Data16</function>, -and -<function>Data32</function> -are macros that may use their last argument -more than once, so that argument should be a variable rather than -an expression such as ``nitems*sizeof(item)''. -You should do that kind of computation in a separate statement before calling -them. -Use the appropriate macro when sending byte, short, or long data. -</para> -<para> -<!-- .LP --> -If the protocol request requires a reply, -then call the procedure -<function>_XSend</function> -instead of the -<function>Data</function> -macro. -<function>_XSend</function> -takes the same arguments, but because it sends your data immediately instead of -copying it into the output buffer (which would later be flushed -anyway by the following call on -<function>_XReply</function>), -it is faster. -<!-- .SH --> -Replies -</para> -<para> -<!-- .LP --> -If the protocol request has a reply, -then call -<function>_XReply</function> -after you have finished dealing with -all the fixed-length and variable-length arguments. -<function>_XReply</function> -flushes the output buffer and waits for an -<structname>xReply</structname> -packet to arrive. -If any events arrive in the meantime, -<function>_XReply</function> -places them in the queue for later use. -</para> -<indexterm significance="preferred"><primary>_XReply</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='_xreply'> -<funcprototype> - <funcdef>Status <function>_XReply</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>xReply<parameter> *rep</parameter></paramdef> - <paramdef>int<parameter> extra</parameter></paramdef> - <paramdef>Bool<parameter> discard</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rep</emphasis> - </term> - <listitem> - <para> -Specifies the reply structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>extra</emphasis> - </term> - <listitem> - <para> -Specifies the number of 32-bit words expected after the replay. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>discard</emphasis> - </term> - <listitem> - <para> -Specifies if any data beyond that specified in the extra argument -should be discarded. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XReply</function> -function waits for a reply packet and copies its contents into the -specified rep. -<function>_XReply</function> -handles error and event packets that occur before the reply is received. -<function>_XReply</function> -takes four arguments: -</para> -<itemizedlist> - <listitem> - <para> -A -<type>Display</type> -* structure - </para> - </listitem> - <listitem> - <para> -A pointer to a reply structure (which must be cast to an -<structname>xReply</structname> -*) - </para> - </listitem> - <listitem> - <para> -The number of additional 32-bit words (beyond -<function>sizeof( xReply</function>) -= 32 bytes) -in the reply structure - </para> - </listitem> - <listitem> - <para> -A Boolean that indicates whether -<function>_XReply</function> -is to discard any additional bytes -beyond those it was told to read - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Because most reply structures are 32 bytes long, -the third argument is usually 0. -The only core protocol exceptions are the replies to -<systemitem>GetWindowAttributesl</systemitem>, -<systemitem>QueryFont</systemitem>, -<systemitem>QueryKeymap</systemitem>, -and -<systemitem>GetKeyboardControl</systemitem>, -which have longer replies. -</para> -<para> -<!-- .LP --> -The last argument should be -<symbol>False</symbol> -if the reply structure is followed -by additional variable-length data (such as a list or string). -It should be -<symbol>True</symbol> -if there is not any variable-length data. -<!-- .NT --> -This last argument is provided for upward-compatibility reasons -to allow a client to communicate properly with a hypothetical later -version of the server that sends more data than the client expected. -For example, some later version of -<systemitem>GetWindowAttributesl</systemitem> -might use a -larger, but compatible, -<structname>xGetWindowAttributesReply</structname> -that contains additional attribute data at the end. -<!-- .NE --> -<function>_XReply</function> -returns -<symbol>True</symbol> -if it received a reply successfully or -<symbol>False</symbol> -if it received any sort of error. -</para> -<para> -<!-- .LP --> -For a request with a reply that is not followed by variable-length -data, you write something like: -</para> -<para> -<!-- .LP --> -<!-- .R --> -<programlisting> -_XReply(display, (xReply *)&rep, 0, True); -*ret1 = rep.ret1; -*ret2 = rep.ret2; -*ret3 = rep.ret3; -... -UnlockDisplay(dpy); -SyncHandle(); -return (rep.ret4); -} -</programlisting> -If there is variable-length data after the reply, -change the -<symbol>True</symbol> -to -<symbol>False</symbol>, -and use the appropriate -<function>_XRead</function> -function to read the variable-length data. -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='_xread'> -<funcprototype> - <funcdef><function>_XRead</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *data_return</parameter></paramdef> - <paramdef>long<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Specifies the buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XRead</function> -function reads the specified number of bytes into data_return. -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='_xread16'> -<funcprototype> - <funcdef><function>_XRead16</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>short<parameter> *data_return</parameter></paramdef> - <paramdef>long<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Specifies the buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XRead16</function> -function reads the specified number of bytes, -unpacking them as 16-bit quantities, -into the specified array as shorts. -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='_xread32'> -<funcprototype> - <funcdef><function>_XRead32</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>long<parameter> *data_return</parameter></paramdef> - <paramdef>long<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Specifies the buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XRead32</function> -function reads the specified number of bytes, -unpacking them as 32-bit quantities, -into the specified array as longs. -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='_xread16pad'> -<funcprototype> - <funcdef><function>_XRead16Pad</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>short<parameter> *data_return</parameter></paramdef> - <paramdef>long<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Specifies the buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XRead16Pad</function> -function reads the specified number of bytes, -unpacking them as 16-bit quantities, -into the specified array as shorts. -If the number of bytes is not a multiple of four, -<function>_XRead16Pad</function> -reads and discards up to two additional pad bytes. -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='_xreadpad'> -<funcprototype> - <funcdef><function>_XReadPad</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *data_return</parameter></paramdef> - <paramdef>long<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Specifies the buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>_XReadPad</function> -function reads the specified number of bytes into data_return. -If the number of bytes is not a multiple of four, -<function>_XReadPad</function> -reads and discards up to three additional pad bytes. -</para> -<para> -<!-- .LP --> -Each protocol request is a little different. -For further information, -see the Xlib sources for examples. -<!-- .SH --> -Synchronous Calling -</para> -<para> -<!-- .LP --> -Each procedure should have a call, just before returning to the user, -to a macro called -<systemitem>SyncHandle</systemitem>. -If synchronous mode is enabled (see -<function>XSynchronize</function>), -the request is sent immediately. -The library, however, waits until any error the procedure could generate -at the server has been handled. -<!-- .SH --> -Allocating and Deallocating Memory -</para> -<para> -<!-- .LP --> -To support the possible reentry of these procedures, -you must observe several conventions when allocating and deallocating memory, -most often done when returning data to the user from the window -system of a size the caller could not know in advance -(for example, a list of fonts or a list of extensions). -The standard C library functions on many systems -are not protected against signals or other multithreaded uses. -The following analogies to standard I/O library functions -have been defined: -</para> -<para> -<!-- .LP --> -These should be used in place of any calls you would make to the normal -C library functions. -</para> -<para> -<!-- .LP --> -If you need a single scratch buffer inside a critical section -(for example, to pack and unpack data to and from the wire protocol), -the general memory allocators may be too expensive to use -(particularly in output functions, which are performance critical). -The following function returns a scratch buffer for use within a -critical section: -</para> -<indexterm significance="preferred"><primary>_XAllocScratch</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='_xallocscratch'> -<funcprototype> - <funcdef>char *<function>_XAllocScratch</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -This storage must only be used inside of a critical section of your -stub. The returned pointer cannot be assumed valid after any call -that might permit another thread to execute inside Xlib. For example, -the pointer cannot be assumed valid after any use of the -<function>GetReq</function> -or -<function>Data</function> -families of macros, -after any use of -<function>_XReply</function>, -or after any use of the -<function>_XSend</function> -or -<function>_XRead</function> -families of functions. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -The following function returns a scratch buffer for use across -critical sections: -</para> -<indexterm significance="preferred"><primary>_XAllocTemp</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='_xalloctemp'> -<funcprototype> - <funcdef>char *<function>_XAllocTemp</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes required. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -This storage can be used across calls that might permit another thread to -execute inside Xlib. The storage must be explicitly returned to Xlib. -The following function returns the storage: -</para> -<indexterm significance="preferred"><primary>_XFreeTemp</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='_xfreetemp'> -<funcprototype> - <funcdef>void <function>_XFreeTemp</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *buf</parameter></paramdef> - <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buf</emphasis> - </term> - <listitem> - <para> -Specifies the buffer to return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the size of the buffer. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -You must pass back the same pointer and size that were returned by -<function>_XAllocTemp</function>. -<!-- .SH --> -Portability Considerations -</para> -<para> -<!-- .LP --> -Many machine architectures, -including many of the more recent <acronym>RISC</acronym> architectures, -do not correctly access data at unaligned locations; -their compilers pad out structures to preserve this characteristic. -Many other machines capable of unaligned references pad inside of structures -as well to preserve alignment, because accessing aligned data is -usually much faster. -Because the library and the server use structures to access data at -arbitrary points in a byte stream, -all data in request and reply packets <emphasis remap='I'>must</emphasis> be naturally aligned; -that is, 16-bit data starts on 16-bit boundaries in the request -and 32-bit data on 32-bit boundaries. -All requests <emphasis remap='I'>must</emphasis> be a multiple of 32 bits in length to preserve -the natural alignment in the data stream. -You must pad structures out to 32-bit boundaries. -Pad information does not have to be zeroed unless you want to -preserve such fields for future use in your protocol requests. -Floating point varies radically between machines and should be -avoided completely if at all possible. -</para> -<para> -<!-- .LP --> -This code may run on machines with 16-bit ints. -So, if any integer argument, variable, or return value either can take -only nonnegative values or is declared as a -<type>CARD16</type> -in the protocol, be sure to declare it as -<type>unsigned</type> -<type>int</type> -and not as -<type>int</type>. -(This, of course, does not apply to Booleans or enumerations.) -</para> -<para> -<!-- .LP --> -Similarly, -if any integer argument or return value is declared -<type>CARD32</type> -in the protocol, -declare it as an -<type>unsigned</type> -<type>long</type> -and not as -<type>int</type> -or -<type>long</type>. -This also goes for any internal variables that may -take on values larger than the maximum 16-bit -<type>unsigned</type> -<type>int</type>. -</para> -<para> -<!-- .LP --> -The library currently assumes that a -<type>char</type> -is 8 bits, a -<type>short</type> -is 16 bits, an -<type>int</type> -is 16 or 32 bits, and a -<type>long</type> -is 32 bits. -The -<function>PackData</function> -macro is a half-hearted attempt to deal with the possibility of 32 bit shorts. -However, much more work is needed to make this work properly. -<!-- .SH --> -Deriving the Correct Extension Opcode -</para> -<para> -<!-- .LP --> -The remaining problem a writer of an extension stub procedure faces that -the core protocol does not face is to map from the call to the proper -major and minor opcodes. -While there are a number of strategies, -the simplest and fastest is outlined below. -</para> -<itemizedlist> - <listitem> - <para> -Declare an array of pointers, _NFILE long (this is normally found -in -<filename class="headerfile"><stdio.h></filename> -and is the number of file descriptors supported on the system) -of type -<structname>XExtCodes</structname>. -Make sure these are all initialized to NULL. - </para> - </listitem> - <listitem> - <para> -When your stub is entered, your initialization test is just to use -the display pointer passed in to access the file descriptor and an index -into the array. -If the entry is NULL, then this is the first time you -are entering the procedure for this display. -Call your initialization procedure and pass to it the display pointer. - </para> - </listitem> - <listitem> - <para> -Once in your initialization procedure, call -<function>XInitExtension</function>; -if it succeeds, store the pointer returned into this array. -Make sure to establish a close display handler to allow you to zero the entry. -Do whatever other initialization your extension requires. -(For example, install event handlers and so on.) -Your initialization procedure would normally return a pointer to the -<structname>XExtCodes</structname> -structure for this extension, which is what would normally -be found in your array of pointers. - </para> - </listitem> - <listitem> - <para> -After returning from your initialization procedure, -the stub can now continue normally, because it has its major opcode safely -in its hand in the -<structname>XExtCodes</structname> -structure. -<!-- .bp --> - </para> - </listitem> -</itemizedlist> -</appendix> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<appendix id="extensions">
+<title>Extensions</title>
+<para>
+<!-- .XE -->
+Because X can evolve by extensions to the core protocol,
+it is important that extensions not be perceived as second-class citizens.
+At some point,
+your favorite extensions may be adopted as additional parts of the
+X Standard.
+</para>
+<para>
+<!-- .LP -->
+Therefore, there should be little to distinguish the use of an extension from
+that of the core protocol.
+To avoid having to initialize extensions explicitly in application programs,
+it is also important that extensions perform lazy evaluations,
+automatically initializing themselves when called for the first time.
+</para>
+<para>
+<!-- .LP -->
+This appendix describes techniques for writing extensions to Xlib that will
+run at essentially the same performance as the core protocol requests.
+</para>
+<!-- .NT -->
+<note><para>
+It is expected that a given extension to X consists of multiple
+requests.
+Defining 10 new features as 10 separate extensions is a bad practice.
+Rather, they should be packaged into a single extension
+and should use minor opcodes to distinguish the requests.
+</para></note>
+<!-- .NE -->
+<para>
+<!-- .LP -->
+The symbols and macros used for writing stubs to Xlib are listed in
+<filename class="headerfile"><X11/Xlibint.h></filename>.
+<!-- .SH -->
+Basic Protocol Support Routines
+</para>
+<para>
+The basic protocol requests for extensions are
+<function>XQueryExtension</function>
+and
+<function>XListExtensions</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryExtension</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xqueryextension'>
+<funcprototype>
+ <funcdef>Bool <function>XQueryExtension</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+ <paramdef>int<parameter> *major_opcode_return</parameter></paramdef>
+ <paramdef>int<parameter> *first_event_return</parameter></paramdef>
+ <paramdef>int<parameter> *first_error_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>display</term>
+ <listitem>
+ <para>Specifies the connection to the X server.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>Specifies the extension name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>major_opcode_return</term>
+ <listitem>
+ <para>Returns the major opcode.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>first_event_return</term>
+ <listitem>
+ <para>Returns the first event code, if any.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>first_error_return</term>
+ <listitem>
+ <para>Returns the first error code, if any.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryExtension</function>
+function determines if the named extension is present.
+If the extension is not present,
+<function>XQueryExtension</function>
+returns
+<symbol>False</symbol>;
+otherwise, it returns
+<symbol>True</symbol>.
+If the extension is present,
+<function>XQueryExtension</function>
+returns the major opcode for the extension to major_opcode_return;
+otherwise,
+it returns zero.
+Any minor opcode and the request formats are specific to the
+extension.
+If the extension involves additional event types,
+<function>XQueryExtension</function>
+returns the base event type code to first_event_return;
+otherwise,
+it returns zero.
+The format of the events is specific to the extension.
+If the extension involves additional error codes,
+<function>XQueryExtension</function>
+returns the base error code to first_error_return;
+otherwise,
+it returns zero.
+The format of additional data in the errors is specific to the extension.
+</para>
+<para>
+<!-- .LP -->
+If the extension name is not in the Host Portable Character Encoding
+the result is implementation-dependent.
+Uppercase and lowercase matter;
+the strings ``thing'', ``Thing'', and ``thinG''
+are all considered different names.
+</para>
+<indexterm significance="preferred"><primary>XListExtensions</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlistextensions'>
+<funcprototype>
+ <funcdef>char **<function>XListExtensions</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *nextensions_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nextensions_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of extensions listed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListExtensions</function>
+function returns a list of all extensions supported by the server.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned strings are in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+</para>
+<indexterm significance="preferred"><primary>XFreeExtensionList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreeextensionlist'>
+<funcprototype>
+ <funcdef><function>XFreeExtensionList</function></funcdef>
+ <paramdef>char<parameter> **list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of extension names.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeExtensionList</function>
+function frees the memory allocated by
+<function>XListExtensions</function>.
+<!-- .SH -->
+Hooking into Xlib
+</para>
+<para>
+<!-- .LP -->
+These functions allow you to hook into the library.
+They are not normally used by application programmers but are used
+by people who need to extend the core X protocol and
+the X library interface.
+The functions, which generate protocol requests for X, are typically
+called stubs.
+</para>
+<para>
+<!-- .LP -->
+In extensions, stubs first should check to see if they have initialized
+themselves on a connection.
+If they have not, they then should call
+<function>XInitExtension</function>
+to attempt to initialize themselves on the connection.
+</para>
+<para>
+<!-- .LP -->
+If the extension needs to be informed of GC/font allocation or
+deallocation or if the extension defines new event types,
+the functions described here allow the extension to be
+called when these events occur.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XExtCodes</structname>
+structure returns the information from
+<function>XInitExtension</function>
+and is defined in
+<filename class="headerfile"><X11/Xlib.h></filename>:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XExtCodes</primary></indexterm>
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<synopsis>
+typedef struct _XExtCodes { /* public to extension, cannot be changed */
+ int extension; /* extension number */
+ int major_opcode; /* major op-code assigned by server */
+ int first_event; /* first event number for the extension */
+ int first_error; /* first error number for the extension */
+} XExtCodes;
+</synopsis>
+</para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XInitExtension</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinitextension'>
+<funcprototype>
+ <funcdef>XExtCodes *<function>XInitExtension</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInitExtension</function>
+function determines if the named extension exists.
+Then, it allocates storage for maintaining the
+information about the extension on the connection,
+chains this onto the extension list for the connection,
+and returns the information the stub implementor will need to access
+the extension.
+If the extension does not exist,
+<function>XInitExtension</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+If the extension name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Uppercase and lowercase matter;
+the strings ``thing'', ``Thing'', and ``thinG''
+are all considered different names.
+</para>
+<para>
+<!-- .LP -->
+The extension number in the
+<structname>XExtCodes</structname>
+structure is
+needed in the other calls that follow.
+This extension number is unique only to a single connection.
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XAddExtension</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddextension'>
+<funcprototype>
+ <funcdef>XExtCodes *<function>XAddExtension</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+For local Xlib extensions, the
+<function>XAddExtension</function>
+function allocates the
+<structname>XExtCodes</structname>
+structure, bumps the extension number count,
+and chains the extension onto the extension list.
+(This permits extensions to Xlib without requiring server extensions.)
+<!-- .SH -->
+Hooks into the Library
+</para>
+<para>
+<!-- .LP -->
+These functions allow you to define procedures that are to be
+called when various circumstances occur.
+The procedures include the creation of a new GC for a connection,
+the copying of a GC, the freeing of a GC, the creating and freeing of fonts,
+the conversion of events defined by extensions to and from wire
+format, and the handling of errors.
+</para>
+<para>
+<!-- .LP -->
+All of these functions return the previous procedure defined for this
+extension.
+</para>
+<indexterm significance="preferred"><primary>XESetCloseDisplay</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetclosedisplay'>
+<funcprototype>
+ <funcdef>int <function>XESetCloseDisplay</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when the display is closed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetCloseDisplay</function>
+function defines a procedure to be called whenever
+<function>XCloseDisplay</function>
+is called.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When
+<function>XCloseDisplay</function>
+is called,
+your procedure is called
+with these arguments:
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<indexterm significance="preferred"><primary>XESetCreateGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetcreategc'>
+<funcprototype>
+ <funcdef>int *<function>XESetCreateGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a GC is closed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetCreateGC</function>
+function defines a procedure to be called whenever
+a new GC is created.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When a GC is created,
+your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>GC <parameter>gc</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<indexterm significance="preferred"><primary>XESetCopyGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetcopygc'>
+<funcprototype>
+ <funcdef>int *<function>XESetCopyGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when GC components are copied.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetCopyGC</function>
+function defines a procedure to be called whenever
+a GC is copied.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When a GC is copied,
+your procedure is called with these arguments:
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>GC <parameter>gc</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<funcsynopsis id='xesetfreegc'>
+<funcprototype>
+ <funcdef>int *<function>XESetFreeGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a GC is freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The
+<function>XESetFreeGC</function>
+function defines a procedure to be called whenever
+a GC is freed.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When a GC is freed,
+your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>GC <parameter>gc</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XESetCreateFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetcreatefont'>
+<funcprototype>
+ <funcdef>int *<function>XESetCreateFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a font is created.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetCreateFont</function>
+function defines a procedure to be called whenever
+<function>XLoadQueryFont</function>
+and
+<function>XQueryFont</function>
+are called.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When
+<function>XLoadQueryFont</function>
+or
+<function>XQueryFont</function>
+is called,
+your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XFontStruct *<parameter>fs</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XESetFreeFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetfreefont'>
+<funcprototype>
+ <funcdef>int *<function>XESetFreeFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a font is freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetFreeFont</function>
+function defines a procedure to be called whenever
+<function>XFreeFont</function>
+is called.
+It returns any previously defined procedure, usually NULL.
+</para>
+<para>
+<!-- .LP -->
+When
+<function>XFreeFont</function>
+is called, your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XFontStruct *<parameter>fs</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetWireToEvent</function>
+and
+<function>XESetEventToWire</function>
+functions allow you to define new events to the library.
+An
+<structname>XEvent</structname>
+structure always has a type code (type
+<type>int</type>)
+as the first component.
+This uniquely identifies what kind of event it is.
+The second component is always the serial number (type
+<type>unsigned</type>
+<type>long</type>)
+of the last request processed by the server.
+The third component is always a Boolean (type
+<type>Bool</type>)
+indicating whether the event came from a
+<systemitem>SendEvent</systemitem>
+protocol request.
+The fourth component is always a pointer to the display
+the event was read from.
+The fifth component is always a resource ID of one kind or another,
+usually a window, carefully selected to be useful to toolkit dispatchers.
+The fifth component should always exist, even if
+the event does not have a natural destination;
+if there is no value
+from the protocol to put in this component, initialize it to zero.
+<!-- .NT -->
+There is an implementation limit such that your host event
+structure size cannot be bigger than the size of the
+<structname>XEvent</structname>
+union of structures.
+There also is no way to guarantee that more than 24 elements or 96 characters
+in the structure will be fully portable between machines.
+</para>
+<!-- .NE -->
+<indexterm significance="preferred"><primary>XESetWireToEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetwiretoevent'>
+<funcprototype>
+ <funcdef>int *<function>XESetWireToEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> event_number</parameter></paramdef>
+ <paramdef>Status<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event code.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when converting an event.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetWireToEvent</function>
+function defines a procedure to be called when an event
+needs to be converted from wire format
+(<structname>xEvent</structname>)
+to host format
+(<structname>XEvent</structname>).
+The event number defines which protocol event number to install a
+conversion procedure for.
+<function>XESetWireToEvent</function>
+returns any previously defined procedure.
+<!-- .NT -->
+You can replace a core event conversion function with one
+of your own, although this is not encouraged.
+It would, however, allow you to intercept a core event
+and modify it before being placed in the queue or otherwise examined.
+<!-- .NE -->
+When Xlib needs to convert an event from wire format to host
+format, your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XEvent *<parameter>re</parameter></paramdef>
+ <paramdef>xEvent *<parameter>event</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+Your procedure must return status to indicate if the conversion succeeded.
+The re argument is a pointer to where the host format event should be stored,
+and the event argument is the 32-byte wire event structure.
+In the
+<structname>XEvent</structname>
+structure you are creating,
+you must fill in the five required members of the event structure.
+You should fill in the type member with the type specified for the
+<structname>xEvent</structname>
+structure.
+You should copy all other members from the
+<structname>xEvent</structname>
+structure (wire format) to the
+<structname>XEvent</structname>
+structure (host format).
+Your conversion procedure should return
+<symbol>True</symbol>
+if the event should be placed in the queue or
+<symbol>False</symbol>
+if it should not be placed in the queue.
+</para>
+<para>
+<!-- .LP -->
+To initialize the serial number component of the event, call
+<function>_XSetLastRequestRead</function>
+with the event and use the return value.
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>_XSetLastRequestRead</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetlastrequestread'>
+<funcprototype>
+ <funcdef>unsigned long<function>_XSetLastRequestRead</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>xGenericReply<parameter> *rep</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rep</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the wire event structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XSetLastRequestRead</function>
+function computes and returns a complete serial number from the partial
+serial number in the event.
+<!-- .sp -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XESetEventToWire</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xeseteventtowire'>
+<funcprototype>
+ <funcdef>Status *<function>XESetEventToWire</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> event_number</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event code.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when converting an event.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetEventToWire</function>
+function defines a procedure to be called when an event
+needs to be converted from host format
+(<structname>XEvent</structname>)
+to wire format
+(<structname>xEvent</structname>)
+form.
+The event number defines which protocol event number to install a
+conversion procedure for.
+<function>XESetEventToWire</function>
+returns any previously defined procedure.
+It returns zero if the conversion fails or nonzero otherwise.
+<!-- .NT -->
+You can replace a core event conversion function with one
+of your own, although this is not encouraged.
+It would, however, allow you to intercept a core event
+and modify it before being sent to another client.
+<!-- .NE -->
+When Xlib needs to convert an event from host format to wire format,
+your procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XEvent *<parameter>re</parameter></paramdef>
+ <paramdef>xEvent *<parameter>event</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+The re argument is a pointer to the host format event,
+and the event argument is a pointer to where the 32-byte wire event
+structure should be stored.
+You should fill in the type with the type from the
+<structname>XEvent</structname>
+structure.
+All other members then should be copied from the host format to the
+<structname>xEvent</structname>
+structure.
+</para>
+<indexterm significance="preferred"><primary>XESetWireToError</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetwiretoerror'>
+<funcprototype>
+ <funcdef>Bool *<function>XESetWireToError</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> error_number</parameter></paramdef>
+ <paramdef>Bool<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>error_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the error code.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when an error is received.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetWireToError</function>
+function defines a procedure to be called when an extension
+error needs to be converted from wire format to host format.
+The error number defines which protocol error code to install
+the conversion procedure for.
+<function>XESetWireToError</function>
+returns any previously defined procedure.
+</para>
+<para>
+<!-- .LP -->
+Use this function for extension errors that contain additional error values
+beyond those in a core X error, when multiple wire errors must be combined
+into a single Xlib error, or when it is necessary to intercept an
+X error before it is otherwise examined.
+</para>
+<para>
+<!-- .LP -->
+When Xlib needs to convert an error from wire format to host format,
+the procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XErrorEvent *<parameter>he</parameter></paramdef>
+ <paramdef>xError *<parameter>we</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+The he argument is a pointer to where the host format error should be stored.
+The structure pointed at by he is guaranteed to be as large as an
+<structname>XEvent</structname>
+structure and so can be cast to a type larger than an
+<structname>XErrorEvent</structname>
+to store additional values.
+If the error is to be completely ignored by Xlib
+(for example, several protocol error structures will be combined into
+one Xlib error),
+then the function should return
+<symbol>False</symbol>;
+otherwise, it should return
+<symbol>True</symbol>.
+</para>
+<indexterm significance="preferred"><primary>XESetError</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xeseterror'>
+<funcprototype>
+ <funcdef>int *<function>XESetError</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when an error is received.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Inside Xlib, there are times that you may want to suppress the
+calling of the external error handling when an error occurs.
+This allows status to be returned on a call at the cost of the call
+being synchronous (though most such functions are query operations, in any
+case, and are typically programmed to be synchronous).
+</para>
+<para>
+<!-- .LP -->
+When Xlib detects a protocol error in
+<function>_XReply</function>,
+it calls your procedure with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>xError *<parameter>err</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+ <paramdef>int *<parameter>ret_code</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+The err argument is a pointer to the 32-byte wire format error.
+The codes argument is a pointer to the extension codes structure.
+The ret_code argument is the return code you may want
+<function>_XReply</function>
+returned to.
+</para>
+<para>
+<!-- .LP -->
+If your procedure returns a zero value,
+the error is not suppressed, and
+the client's error handler is called.
+(For further information,
+see <link linkend="Using_the_Default_Error_Handlers">section 11.8.2</link>.)
+If your procedure returns nonzero,
+the error is suppressed, and
+<function>_XReply</function>
+returns the value of ret_code.
+</para>
+<indexterm significance="preferred"><primary>XESetErrorString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xeseterrorstring'>
+<funcprototype>
+ <funcdef>char *<function>XESetErrorString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>char<parameter> *(*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call to obtain an error string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetErrorText</function>
+function returns a string to the user for an error.
+<function>XESetErrorString</function>
+allows you to define a procedure to be called that
+should return a pointer to the error message.
+The following is an example.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>int <parameter>code</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+ <paramdef>char *<parameter>buffer</parameter></paramdef>
+ <paramdef>int <parameter>nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+Your procedure is called with the error code for every error detected.
+You should copy nbytes of a null-terminated string containing the
+error message into buffer.
+</para>
+<indexterm significance="preferred"><primary>XESetPrintErrorValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetprinterrorvalues'>
+<funcprototype>
+ <funcdef>void *<function>XESetPrintErrorValues</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>void<parameter> (*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when an error is printed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetPrintErrorValues</function>
+function defines a procedure to be called when an extension
+error is printed, to print the error values.
+Use this function for extension errors that contain additional error values
+beyond those in a core X error.
+It returns any previously defined procedure.
+</para>
+<para>
+<!-- .LP -->
+When Xlib needs to print an error,
+the procedure is called with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XErrorEvent *<parameter>ev</parameter></paramdef>
+ <paramdef>void *<parameter>fp</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+The structure pointed at by ev is guaranteed to be as large as an
+<structname>XEvent</structname>
+structure and so can be cast to a type larger than an
+<structname>XErrorEvent</structname>
+to obtain additional values set by using
+<function>XESetWireToError</function>.
+The underlying type of the fp argument is system dependent;
+on a <acronym>POSIX</acronym>-compliant system, fp should be cast to type FILE*.
+</para>
+<indexterm significance="preferred"><primary>XESetFlushGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xesetflushgc'>
+<funcprototype>
+ <funcdef>int *<function>XESetFlushGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> *(*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a GC is flushed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The procedure set by the
+<function>XESetFlushGC</function>
+function has the same interface as the procedure set by the
+<function>XESetCopyGC</function>
+function, but is called when a GC cache needs to be updated in the server.
+</para>
+<indexterm significance="preferred"><primary>XESetBeforeFlush</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int *<function>XESetCopyGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> extension</parameter></paramdef>
+ <paramdef>int<parameter> *(*proc)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extension</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to call when a buffer is flushed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XESetBeforeFlush</function>
+function defines a procedure to be called when data is about to be
+sent to the server. When data is about to be sent, your procedure is
+called one or more times with these arguments:
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<!-- .R -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function>(*<replaceable>proc</replaceable>)</function></funcdef>
+ <paramdef>Display *<parameter>display</parameter></paramdef>
+ <paramdef>XExtCodes *<parameter>codes</parameter></paramdef>
+ <paramdef>char *<parameter>data</parameter></paramdef>
+ <paramdef>long <parameter>len</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .LP -->
+<!-- .eM -->
+The data argument specifies a portion of the outgoing data buffer,
+and its length in bytes is specified by the len argument.
+Your procedure must not alter the contents of the data and must not
+do additional protocol requests to the same display.
+<!-- .SH -->
+Hooks onto Xlib Data Structures
+</para>
+<para>
+<!-- .LP -->
+Various Xlib data structures have provisions for extension procedures
+to chain extension supplied data onto a list.
+These structures are
+<structname>GC</structname>,
+<structname>Visual</structname>,
+<type>Screen</type>,
+<structname>ScreenFormat</structname>,
+<type>Display</type>,
+and
+<structname>XFontStruct</structname>.
+Because the list pointer is always the first member in the structure,
+a single set of procedures can be used to manipulate the data
+on these lists.
+</para>
+<para>
+<!-- .LP -->
+The following structure is used in the functions in this section
+and is defined in
+<filename class="headerfile"><X11/Xlib.h></filename>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XExtData</primary></indexterm>
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<synopsis>
+typedef struct _XExtData {
+ int number; /* number returned by XInitExtension */
+ struct _XExtData *next; /* next item on list of data for structure */
+ int (*free_private)(); /* if defined, called to free private */
+ XPointer private_data; /* data private to this extension. */
+} XExtData;
+</synopsis>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When any of the data structures listed above are freed,
+the list is walked, and the structure's free procedure (if any) is called.
+If free is NULL,
+then the library frees both the data pointed to by the private_data member
+and the structure itself.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+<synopsis>
+union { Display *display;
+ GC gc;
+ Visual *visual;
+ Screen *screen;
+ ScreenFormat *pixmap_format;
+ XFontStruct *font } XEDataObject;
+</synopsis>
+</para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XEHeadOfExtensionList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xeheadofextensionlist'>
+<funcprototype>
+ <funcdef>XExtData **<function>XEHeadOfExtensionList</function></funcdef>
+ <paramdef>XEDataObject<parameter> object</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>object</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the object.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XEHeadOfExtensionList</function>
+function returns a pointer to the list of extension structures attached
+to the specified object.
+In concert with
+<function>XAddToExtensionList</function>,
+<function>XEHeadOfExtensionList</function>
+allows an extension to attach arbitrary data to any of the structures
+of types contained in
+<structname>XEDataObject</structname>.
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XAddToExtensionList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddtoextensionlist'>
+<funcprototype>
+ <funcdef><function>XAddToExtensionList</function></funcdef>
+ <paramdef>XExtData<parameter> **structure</parameter></paramdef>
+ <paramdef>XExtData<parameter> *ext_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>structure</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ext_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension data structure to add.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The structure argument is a pointer to one of the data structures
+enumerated above.
+You must initialize ext_data->number with the extension number
+before calling this function.
+</para>
+<indexterm significance="preferred"><primary>XFindOnExtensionList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfindonextensionlist'>
+<funcprototype>
+ <funcdef>XExtData *<function>XFindOnExtensionList</function></funcdef>
+ <paramdef>struct_XExtData<parameter> **structure</parameter></paramdef>
+ <paramdef>int<parameter> number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>structure</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the extension number from
+<function>XInitExtension</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFindOnExtensionList</function>
+function returns the first extension data structure
+for the extension numbered number.
+It is expected that an extension will add at most one extension
+data structure to any single data structure's extension data list.
+There is no way to find additional structures.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XAllocID</function>
+macro, which allocates and returns a resource ID, is defined in
+<filename class="headerfile"><X11/Xlib.h></filename>.
+</para>
+<indexterm significance="preferred"><primary>XAllocID</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xallocid'>
+<funcprototype>
+ <funcdef><function>XAllocID</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This macro is a call through the
+<type>Display</type>
+structure to an internal resource ID allocator.
+It returns a resource ID that you can use when creating new resources.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XAllocIDs</function>
+macro allocates and returns an array of resource ID.
+</para>
+<indexterm significance="preferred"><primary>XAllocIDs</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xallocids'>
+<funcprototype>
+ <funcdef><function>XAllocIDs</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> *ids_return</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ids_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the resource IDs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rep</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of resource IDs requested.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This macro is a call through the
+<type>Display</type>
+structure to an internal resource ID allocator.
+It returns resource IDs to the array supplied by the caller.
+To correctly handle automatic reuse of resource IDs, you must call
+<function>XAllocIDs</function>
+when requesting multiple resource IDs. This call might generate
+protocol requests.
+<!-- .SH -->
+GC Caching
+</para>
+<para>
+<!-- .LP -->
+GCs are cached by the library to allow merging of independent change
+requests to the same GC into single protocol requests.
+This is typically called a write-back cache.
+Any extension procedure whose behavior depends on the contents of a GC
+must flush the GC cache to make sure the server has up-to-date contents
+in its GC.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>FlushGC</function>
+macro checks the dirty bits in the library's GC structure and calls
+<function>_XFlushGCCache</function>
+if any elements have changed.
+The
+<function>FlushGC</function>
+macro is defined as follows:
+</para>
+<indexterm significance="preferred"><primary>FlushGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='flushgc'>
+<funcprototype>
+ <funcdef><function>FlushGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Note that if you extend the GC to add additional resource ID components,
+you should ensure that the library stub sends the change request immediately.
+This is because a client can free a resource immediately after
+using it, so if you only stored the value in the cache without
+forcing a protocol request, the resource might be destroyed before being
+set into the GC.
+You can use the
+<function>_XFlushGCCache</function>
+procedure
+to force the cache to be flushed.
+The
+<function>_XFlushGCCache</function>
+procedure
+is defined as follows:
+</para>
+<indexterm significance="preferred"><primary>_XFlushGCCache</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='_xflushgccache'>
+<funcprototype>
+ <funcdef><function>_XFlushGCCache</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .SH -->
+Graphics Batching
+</para>
+<para>
+<!-- .LP -->
+If you extend X to add more poly graphics primitives, you may be able to
+take advantage of facilities in the library to allow back-to-back
+single calls to be transformed into poly requests.
+This may dramatically improve performance of programs that are not
+written using poly requests.
+A pointer to an
+<structname>xReq</structname>,
+called last_req in the display structure, is the last request being processed.
+By checking that the last request
+type, drawable, gc, and other options are the same as the new one
+and that there is enough space left in the buffer, you may be able
+to just extend the previous graphics request by extending the length
+field of the request and appending the data to the buffer.
+This can improve performance by five times or more in naive programs.
+For example, here is the source for the
+<function>XDrawPoint</function>
+stub.
+(Writing extension stubs is discussed in the next section.)
+</para>
+<!-- .sM -->
+<!-- .nf -->
+<programlisting>
+#include <X11/Xlibint.h>
+
+/* precompute the maximum size of batching request allowed */
+
+static int size = sizeof(xPolyPointReq) + EPERBATCH * sizeof(xPoint);
+
+XDrawPoint(dpy, d, gc, x, y)
+ register Display *dpy;
+ Drawable d;
+ GC gc;
+ int x, y; /* INT16 */
+{
+ xPoint *point;
+ LockDisplay(dpy);
+ FlushGC(dpy, gc);
+ {
+ register xPolyPointReq *req = (xPolyPointReq *) dpy->last_req;
+ /* if same as previous request, with same drawable, batch requests */
+ if (
+ (req->reqType == X_PolyPoint)
+ && (req->drawable == d)
+ && (req->gc == gc->gid)
+ && (req->coordMode == CoordModeOrigin)
+ && ((dpy->bufptr + sizeof (xPoint)) <= dpy->bufmax)
+ && (((char *)dpy->bufptr - (char *)req) < size) ) {
+ point = (xPoint *) dpy->bufptr;
+ req->length += sizeof (xPoint) >> 2;
+ dpy->bufptr += sizeof (xPoint);
+ }
+
+ else {
+ GetReqExtra(PolyPoint, 4, req); /* 1 point = 4 bytes */
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->coordMode = CoordModeOrigin;
+ point = (xPoint *) (req + 1);
+ }
+ point->x = x;
+ point->y = y;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+</programlisting>
+<!-- .fi -->
+<para>
+<!-- .LP -->
+<!-- .eM -->
+To keep clients from generating very long requests that may monopolize the
+server,
+there is a symbol defined in
+<filename class="headerfile"><X11/Xlibint.h></filename>
+of EPERBATCH on the number of requests batched.
+Most of the performance benefit occurs in the first few merged requests.
+Note that
+<function>FlushGC</function>
+is called <emphasis remap='I'>before</emphasis> picking up the value of last_req,
+because it may modify this field.
+<!-- .SH -->
+Writing Extension Stubs
+</para>
+<para>
+<!-- .LP -->
+All X requests always contain the length of the request,
+expressed as a 16-bit quantity of 32 bits.
+This means that a single request can be no more than 256K bytes in
+length.
+Some servers may not support single requests of such a length.
+The value of dpy->max_request_size contains the maximum length as
+defined by the server implementation.
+For further information,
+see ``X Window System Protocol.''
+<!-- .SH -->
+Requests, Replies, and Xproto.h
+</para>
+<para>
+<!-- .LP -->
+The
+<filename class="headerfile"><X11/Xproto.h></filename>
+file contains three sets of definitions that
+are of interest to the stub implementor:
+request names, request structures, and reply structures.
+</para>
+<para>
+<!-- .LP -->
+You need to generate a file equivalent to
+<filename class="headerfile"><X11/Xproto.h></filename>
+for your extension and need to include it in your stub procedure.
+Each stub procedure also must include
+<filename class="headerfile"><X11/Xlibint.h></filename>.
+</para>
+<para>
+<!-- .LP -->
+The identifiers are deliberately chosen in such a way that, if the
+request is called X_DoSomething, then its request structure is
+xDoSomethingReq, and its reply is xDoSomethingReply.
+The GetReq family of macros, defined in
+<filename class="headerfile"><X11/Xlibint.h></filename>,
+takes advantage of this naming scheme.
+</para>
+<para>
+<!-- .LP -->
+For each X request,
+there is a definition in
+<filename class="headerfile"><X11/Xproto.h></filename>
+that looks similar to this:
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+#define X_DoSomething 42
+</programlisting>
+In your extension header file,
+this will be a minor opcode,
+instead of a major opcode.
+<!-- .SH -->
+Request Format
+</para>
+<para>
+<!-- .LP -->
+Every request contains an 8-bit major opcode and a 16-bit length field
+expressed in units of 4 bytes.
+Every request consists of 4 bytes of header
+(containing the major opcode, the length field, and a data byte) followed by
+zero or more additional bytes of data.
+The length field defines the total length of the request, including the header.
+The length field in a request must equal the minimum length required to contain
+the request.
+If the specified length is smaller or larger than the required length,
+the server should generate a
+<errorname>BadLength</errorname>
+error.
+Unused bytes in a request are not required to be zero.
+Extensions should be designed in such a way that long protocol requests
+can be split up into smaller requests,
+if it is possible to exceed the maximum request size of the server.
+The protocol guarantees the maximum request size to be no smaller than
+4096 units (16384 bytes).
+</para>
+<para>
+<!-- .LP -->
+Major opcodes 128 through 255 are reserved for extensions.
+Extensions are intended to contain multiple requests,
+so extension requests typically have an additional minor opcode encoded
+in the second data byte in the request header,
+but the placement and interpretation of this minor opcode as well as all
+other fields in extension requests are not defined by the core protocol.
+Every request is implicitly assigned a sequence number (starting with one)
+used in replies, errors, and events.
+</para>
+<para>
+<!-- .LP -->
+To help but not cure portability problems to certain machines, the
+<symbol>B16</symbol>
+and
+<symbol>B32</symbol>
+macros have been defined so that they can become bitfield specifications
+on some machines.
+For example, on a Cray,
+these should be used for all 16-bit and 32-bit quantities, as discussed below.
+</para>
+<para>
+<!-- .LP -->
+Most protocol requests have a corresponding structure typedef in
+<filename class="headerfile"><X11/Xproto.h></filename>,
+which looks like:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>xDoSomethingReq</primary></indexterm>
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<synopsis>
+typedef struct _DoSomethingReq {
+ CARD8 reqType; /* X_DoSomething */
+ CARD8 someDatum; /* used differently in different requests */
+ CARD16 length B16; /* total # of bytes in request, divided by 4 */
+ ...
+ /* request-specific data */
+ ...
+} xDoSomethingReq;
+</synopsis>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If a core protocol request has a single 32-bit argument,
+you need not declare a request structure in your extension header file.
+Instead, such requests use the
+<structname>xResourceReq</structname>
+structure in
+<filename class="headerfile"><X11/Xproto.h></filename>.
+This structure is used for any request whose single argument is a
+<type>Window</type>,
+<type>Pixmap</type>,
+<type>Drawable</type>,
+<type>GContext</type>,
+<type>Font</type>,
+<type>Cursor</type>,
+<type>Colormap</type>,
+<type>Atom</type>,
+or
+<type>VisualID</type>.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>xResourceReq</primary></indexterm>
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<synopsis>
+typedef struct _ResourceReq {
+ CARD8 reqType; /* the request type, e.g. X_DoSomething */
+ BYTE pad; /* not used */
+ CARD16 length B16; /* 2 (= total # of bytes in request, divided by 4) */
+ CARD32 id B32; /* the Window, Drawable, Font, GContext, etc. */
+} xResourceReq;
+</synopsis>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If convenient,
+you can do something similar in your extension header file.
+</para>
+<para>
+<!-- .LP -->
+In both of these structures,
+the reqType field identifies the type of the request (for example,
+X_MapWindow or X_CreatePixmap).
+The length field tells how long the request is
+in units of 4-byte longwords.
+This length includes both the request structure itself and any
+variable-length data, such as strings or lists, that follow the
+request structure.
+Request structures come in different sizes,
+but all requests are padded to be multiples of four bytes long.
+</para>
+<para>
+<!-- .LP -->
+A few protocol requests take no arguments at all.
+Instead, they use the
+<structname>xReq</structname>
+structure in
+<filename class="headerfile"><X11/Xproto.h></filename>,
+which contains only a reqType and a length (and a pad byte).
+</para>
+<para>
+<!-- .LP -->
+If the protocol request requires a reply,
+then
+<filename class="headerfile"><X11/Xproto.h></filename>
+also contains a reply structure typedef:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>xDoSomethingReply</primary></indexterm>
+<!-- .sM -->
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+<synopsis>
+typedef struct _DoSomethingReply {
+ BYTE type; /* always X_Reply */
+ BYTE someDatum; /* used differently in different requests */
+ CARD16 sequenceNumber B16; /* # of requests sent so far */
+ CARD32 length B32; /* # of additional bytes, divided by 4 */
+ ...
+ /* request-specific data */
+ ...
+} xDoSomethingReply;
+</synopsis>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Most of these reply structures are 32 bytes long.
+If there are not that many reply values,
+then they contain a sufficient number of pad fields
+to bring them up to 32 bytes.
+The length field is the total number of bytes in the request minus 32,
+divided by 4.
+This length will be nonzero only if:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The reply structure is followed by variable-length data,
+such as a list or string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The reply structure is longer than 32 bytes.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Only
+<systemitem>GetWindowAttributesl</systemitem>,
+<systemitem>QueryFont</systemitem>,
+<systemitem>QueryKeymap</systemitem>,
+and
+<systemitem>GetKeyboardControl</systemitem>
+have reply structures longer than 32 bytes in the core protocol.
+</para>
+<para>
+<!-- .LP -->
+A few protocol requests return replies that contain no data.
+<filename class="headerfile"><X11/Xproto.h></filename>
+does not define reply structures for these.
+Instead, they use the
+<structname>xGenericReply</structname>
+structure, which contains only a type, length,
+and sequence number (and sufficient padding to make it 32 bytes long).
+<!-- .SH -->
+Starting to Write a Stub Procedure
+</para>
+<para>
+<!-- .LP -->
+An Xlib stub procedure should start like this:
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+#include "<X11/Xlibint.h>
+
+XDoSomething (arguments, ... )
+/* argument declarations */
+{
+
+register XDoSomethingReq *req;
+...
+</programlisting>
+If the protocol request has a reply,
+then the variable declarations should include the reply structure for the request.
+The following is an example:
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+xDoSomethingReply rep;
+</programlisting>
+<!-- .SH -->
+Locking Data Structures
+</para>
+<para>
+<!-- .LP -->
+To lock the display structure for systems that
+want to support multithreaded access to a single display connection,
+each stub will need to lock its critical section.
+Generally, this section is the point from just before the appropriate GetReq
+call until all arguments to the call have been stored into the buffer.
+The precise instructions needed for this locking depend upon the machine
+architecture.
+Two calls, which are generally implemented as macros, have been provided.
+<indexterm significance="preferred"><primary>LockDisplay</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='lockdisplay'>
+<funcprototype>
+ <funcdef><function>LockDisplay</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>UnlockDisplay</primary></indexterm>
+<funcsynopsis id='unlockdisplay'>
+<funcprototype>
+ <funcdef><function>UnlockDisplay</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .SH -->
+Sending the Protocol Request and Arguments
+</para>
+<para>
+<!-- .LP -->
+After the variable declarations,
+a stub procedure should call one of four macros defined in
+<filename class="headerfile"><X11/Xlibint.h></filename>:
+<function>GetReq</function>,
+<function>GetReqExtra</function>,
+<function>GetResReq</function>,
+or
+<function>GetEmptyReq</function>.
+All of these macros take, as their first argument,
+the name of the protocol request as declared in
+<filename class="headerfile"><X11/Xproto.h></filename>
+except with X_ removed.
+Each one declares a
+<type>Display</type>
+structure pointer,
+called dpy, and a pointer to a request structure, called req,
+which is of the appropriate type.
+The macro then appends the request structure to the output buffer,
+fills in its type and length field, and sets req to point to it.
+</para>
+<para>
+<!-- .LP -->
+If the protocol request has no arguments (for instance, X_GrabServer),
+then use
+<function>GetEmptyReq</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+GetEmptyReq (DoSomething, req);
+</programlisting>
+If the protocol request has a single 32-bit argument (such as a
+<type>Pixmap</type>,
+<type>Window</type>,
+<type>Drawable</type>,
+<type>Atom</type>,
+and so on),
+then use
+<function>GetResReq</function>.
+The second argument to the macro is the 32-bit object.
+<symbol>X_MapWindow</symbol>
+is a good example.
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+GetResReq (DoSomething, rid, req);
+</programlisting>
+The rid argument is the
+<type>Pixmap</type>,
+<type>Window</type>,
+or other resource ID.
+</para>
+<para>
+<!-- .LP -->
+If the protocol request takes any other argument list,
+then call
+<function>GetReq</function>.
+After the
+<function>GetReq</function>,
+you need to set all the other fields in the request structure,
+usually from arguments to the stub procedure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+GetReq (DoSomething, req);
+/* fill in arguments here */
+req->arg1 = arg1;
+req->arg2 = arg2;
+...
+</programlisting>
+A few stub procedures (such as
+<function>XCreateGC</function>
+and
+<function>XCreatePixmap</function>)
+return a resource ID to the caller but pass a resource ID as an argument
+to the protocol request.
+Such procedures use the macro
+<function>XAllocID</function>
+to allocate a resource ID from the range of IDs
+that were assigned to this client when it opened the connection.
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+rid = req->rid = XAllocID();
+...
+return (rid);
+</programlisting>
+Finally, some stub procedures transmit a fixed amount of variable-length
+data after the request.
+Typically, these procedures (such as
+<function>XMoveWindow</function>
+and
+<function>XSetBackground</function>)
+are special cases of more general functions like
+<function>XMoveResizeWindow</function>
+and
+<function>XChangeGC</function>.
+These procedures use
+<function>GetReqExtra</function>,
+which is the same as
+<function>GetReq</function>
+except that it takes an additional argument (the number of
+extra bytes to allocate in the output buffer after the request structure).
+This number should always be a multiple of four.
+<!-- .SH -->
+Variable Length Arguments
+</para>
+<para>
+<!-- .LP -->
+Some protocol requests take additional variable-length data that
+follow the
+<type>xDoSomethingReq</type>
+structure.
+The format of this data varies from request to request.
+Some requests require a sequence of 8-bit bytes,
+others a sequence of 16-bit or 32-bit entities,
+and still others a sequence of structures.
+</para>
+<para>
+<!-- .LP -->
+It is necessary to add the length of any variable-length data to the
+length field of the request structure.
+That length field is in units of 32-bit longwords.
+If the data is a string or other sequence of 8-bit bytes,
+then you must round the length up and shift it before adding:
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+req->length += (nbytes+3)>>2;
+</programlisting>
+To transmit variable-length data, use the
+<function>Data</function>
+macros.
+If the data fits into the output buffer,
+then this macro copies it to the buffer.
+If it does not fit, however,
+the
+<function>Data</function>
+macro calls
+<function>_XSend</function>,
+which transmits first the contents of the buffer and then your data.
+The
+<function>Data</function>
+macros take three arguments:
+the display, a pointer to the beginning of the data,
+and the number of bytes to be sent.
+<!-- .sM -->
+<funcsynopsis id='data'>
+<funcprototype>
+ <funcdef><function>Data</function></funcdef>
+ <paramdef><parameter> display</parameter></paramdef>
+ <paramdef>(char<parameter> *</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>Data</function>,
+<function>Data16</function>,
+and
+<function>Data32</function>
+are macros that may use their last argument
+more than once, so that argument should be a variable rather than
+an expression such as ``nitems*sizeof(item)''.
+You should do that kind of computation in a separate statement before calling
+them.
+Use the appropriate macro when sending byte, short, or long data.
+</para>
+<para>
+<!-- .LP -->
+If the protocol request requires a reply,
+then call the procedure
+<function>_XSend</function>
+instead of the
+<function>Data</function>
+macro.
+<function>_XSend</function>
+takes the same arguments, but because it sends your data immediately instead of
+copying it into the output buffer (which would later be flushed
+anyway by the following call on
+<function>_XReply</function>),
+it is faster.
+<!-- .SH -->
+Replies
+</para>
+<para>
+<!-- .LP -->
+If the protocol request has a reply,
+then call
+<function>_XReply</function>
+after you have finished dealing with
+all the fixed-length and variable-length arguments.
+<function>_XReply</function>
+flushes the output buffer and waits for an
+<structname>xReply</structname>
+packet to arrive.
+If any events arrive in the meantime,
+<function>_XReply</function>
+places them in the queue for later use.
+</para>
+<indexterm significance="preferred"><primary>_XReply</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='_xreply'>
+<funcprototype>
+ <funcdef>Status <function>_XReply</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>xReply<parameter> *rep</parameter></paramdef>
+ <paramdef>int<parameter> extra</parameter></paramdef>
+ <paramdef>Bool<parameter> discard</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rep</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the reply structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>extra</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of 32-bit words expected after the replay.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>discard</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies if any data beyond that specified in the extra argument
+should be discarded.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XReply</function>
+function waits for a reply packet and copies its contents into the
+specified rep.
+<function>_XReply</function>
+handles error and event packets that occur before the reply is received.
+<function>_XReply</function>
+takes four arguments:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A
+<type>Display</type>
+* structure
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A pointer to a reply structure (which must be cast to an
+<structname>xReply</structname>
+*)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The number of additional 32-bit words (beyond
+<function>sizeof( xReply</function>)
+= 32 bytes)
+in the reply structure
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A Boolean that indicates whether
+<function>_XReply</function>
+is to discard any additional bytes
+beyond those it was told to read
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Because most reply structures are 32 bytes long,
+the third argument is usually 0.
+The only core protocol exceptions are the replies to
+<systemitem>GetWindowAttributesl</systemitem>,
+<systemitem>QueryFont</systemitem>,
+<systemitem>QueryKeymap</systemitem>,
+and
+<systemitem>GetKeyboardControl</systemitem>,
+which have longer replies.
+</para>
+<para>
+<!-- .LP -->
+The last argument should be
+<symbol>False</symbol>
+if the reply structure is followed
+by additional variable-length data (such as a list or string).
+It should be
+<symbol>True</symbol>
+if there is not any variable-length data.
+<!-- .NT -->
+This last argument is provided for upward-compatibility reasons
+to allow a client to communicate properly with a hypothetical later
+version of the server that sends more data than the client expected.
+For example, some later version of
+<systemitem>GetWindowAttributesl</systemitem>
+might use a
+larger, but compatible,
+<structname>xGetWindowAttributesReply</structname>
+that contains additional attribute data at the end.
+<!-- .NE -->
+<function>_XReply</function>
+returns
+<symbol>True</symbol>
+if it received a reply successfully or
+<symbol>False</symbol>
+if it received any sort of error.
+</para>
+<para>
+<!-- .LP -->
+For a request with a reply that is not followed by variable-length
+data, you write something like:
+</para>
+<para>
+<!-- .LP -->
+<!-- .R -->
+<programlisting>
+_XReply(display, (xReply *)&rep, 0, True);
+*ret1 = rep.ret1;
+*ret2 = rep.ret2;
+*ret3 = rep.ret3;
+...
+UnlockDisplay(dpy);
+SyncHandle();
+return (rep.ret4);
+}
+</programlisting>
+If there is variable-length data after the reply,
+change the
+<symbol>True</symbol>
+to
+<symbol>False</symbol>,
+and use the appropriate
+<function>_XRead</function>
+function to read the variable-length data.
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='_xread'>
+<funcprototype>
+ <funcdef><function>_XRead</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *data_return</parameter></paramdef>
+ <paramdef>long<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XRead</function>
+function reads the specified number of bytes into data_return.
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='_xread16'>
+<funcprototype>
+ <funcdef><function>_XRead16</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>short<parameter> *data_return</parameter></paramdef>
+ <paramdef>long<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XRead16</function>
+function reads the specified number of bytes,
+unpacking them as 16-bit quantities,
+into the specified array as shorts.
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='_xread32'>
+<funcprototype>
+ <funcdef><function>_XRead32</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>long<parameter> *data_return</parameter></paramdef>
+ <paramdef>long<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XRead32</function>
+function reads the specified number of bytes,
+unpacking them as 32-bit quantities,
+into the specified array as longs.
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='_xread16pad'>
+<funcprototype>
+ <funcdef><function>_XRead16Pad</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>short<parameter> *data_return</parameter></paramdef>
+ <paramdef>long<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XRead16Pad</function>
+function reads the specified number of bytes,
+unpacking them as 16-bit quantities,
+into the specified array as shorts.
+If the number of bytes is not a multiple of four,
+<function>_XRead16Pad</function>
+reads and discards up to two additional pad bytes.
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='_xreadpad'>
+<funcprototype>
+ <funcdef><function>_XReadPad</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *data_return</parameter></paramdef>
+ <paramdef>long<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>_XReadPad</function>
+function reads the specified number of bytes into data_return.
+If the number of bytes is not a multiple of four,
+<function>_XReadPad</function>
+reads and discards up to three additional pad bytes.
+</para>
+<para>
+<!-- .LP -->
+Each protocol request is a little different.
+For further information,
+see the Xlib sources for examples.
+<!-- .SH -->
+Synchronous Calling
+</para>
+<para>
+<!-- .LP -->
+Each procedure should have a call, just before returning to the user,
+to a macro called
+<systemitem>SyncHandle</systemitem>.
+If synchronous mode is enabled (see
+<function>XSynchronize</function>),
+the request is sent immediately.
+The library, however, waits until any error the procedure could generate
+at the server has been handled.
+<!-- .SH -->
+Allocating and Deallocating Memory
+</para>
+<para>
+<!-- .LP -->
+To support the possible reentry of these procedures,
+you must observe several conventions when allocating and deallocating memory,
+most often done when returning data to the user from the window
+system of a size the caller could not know in advance
+(for example, a list of fonts or a list of extensions).
+The standard C library functions on many systems
+are not protected against signals or other multithreaded uses.
+The following analogies to standard I/O library functions
+have been defined:
+</para>
+<para>
+<!-- .LP -->
+These should be used in place of any calls you would make to the normal
+C library functions.
+</para>
+<para>
+<!-- .LP -->
+If you need a single scratch buffer inside a critical section
+(for example, to pack and unpack data to and from the wire protocol),
+the general memory allocators may be too expensive to use
+(particularly in output functions, which are performance critical).
+The following function returns a scratch buffer for use within a
+critical section:
+</para>
+<indexterm significance="preferred"><primary>_XAllocScratch</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='_xallocscratch'>
+<funcprototype>
+ <funcdef>char *<function>_XAllocScratch</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This storage must only be used inside of a critical section of your
+stub. The returned pointer cannot be assumed valid after any call
+that might permit another thread to execute inside Xlib. For example,
+the pointer cannot be assumed valid after any use of the
+<function>GetReq</function>
+or
+<function>Data</function>
+families of macros,
+after any use of
+<function>_XReply</function>,
+or after any use of the
+<function>_XSend</function>
+or
+<function>_XRead</function>
+families of functions.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+The following function returns a scratch buffer for use across
+critical sections:
+</para>
+<indexterm significance="preferred"><primary>_XAllocTemp</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='_xalloctemp'>
+<funcprototype>
+ <funcdef>char *<function>_XAllocTemp</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes required.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This storage can be used across calls that might permit another thread to
+execute inside Xlib. The storage must be explicitly returned to Xlib.
+The following function returns the storage:
+</para>
+<indexterm significance="preferred"><primary>_XFreeTemp</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='_xfreetemp'>
+<funcprototype>
+ <funcdef>void <function>_XFreeTemp</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *buf</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buf</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer to return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+You must pass back the same pointer and size that were returned by
+<function>_XAllocTemp</function>.
+<!-- .SH -->
+Portability Considerations
+</para>
+<para>
+<!-- .LP -->
+Many machine architectures,
+including many of the more recent <acronym>RISC</acronym> architectures,
+do not correctly access data at unaligned locations;
+their compilers pad out structures to preserve this characteristic.
+Many other machines capable of unaligned references pad inside of structures
+as well to preserve alignment, because accessing aligned data is
+usually much faster.
+Because the library and the server use structures to access data at
+arbitrary points in a byte stream,
+all data in request and reply packets <emphasis remap='I'>must</emphasis> be naturally aligned;
+that is, 16-bit data starts on 16-bit boundaries in the request
+and 32-bit data on 32-bit boundaries.
+All requests <emphasis remap='I'>must</emphasis> be a multiple of 32 bits in length to preserve
+the natural alignment in the data stream.
+You must pad structures out to 32-bit boundaries.
+Pad information does not have to be zeroed unless you want to
+preserve such fields for future use in your protocol requests.
+Floating point varies radically between machines and should be
+avoided completely if at all possible.
+</para>
+<para>
+<!-- .LP -->
+This code may run on machines with 16-bit ints.
+So, if any integer argument, variable, or return value either can take
+only nonnegative values or is declared as a
+<type>CARD16</type>
+in the protocol, be sure to declare it as
+<type>unsigned</type>
+<type>int</type>
+and not as
+<type>int</type>.
+(This, of course, does not apply to Booleans or enumerations.)
+</para>
+<para>
+<!-- .LP -->
+Similarly,
+if any integer argument or return value is declared
+<type>CARD32</type>
+in the protocol,
+declare it as an
+<type>unsigned</type>
+<type>long</type>
+and not as
+<type>int</type>
+or
+<type>long</type>.
+This also goes for any internal variables that may
+take on values larger than the maximum 16-bit
+<type>unsigned</type>
+<type>int</type>.
+</para>
+<para>
+<!-- .LP -->
+The library currently assumes that a
+<type>char</type>
+is 8 bits, a
+<type>short</type>
+is 16 bits, an
+<type>int</type>
+is 16 or 32 bits, and a
+<type>long</type>
+is 32 bits.
+The
+<function>PackData</function>
+macro is a half-hearted attempt to deal with the possibility of 32 bit shorts.
+However, much more work is needed to make this work properly.
+<!-- .SH -->
+Deriving the Correct Extension Opcode
+</para>
+<para>
+<!-- .LP -->
+The remaining problem a writer of an extension stub procedure faces that
+the core protocol does not face is to map from the call to the proper
+major and minor opcodes.
+While there are a number of strategies,
+the simplest and fastest is outlined below.
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Declare an array of pointers, _NFILE long (this is normally found
+in
+<filename class="headerfile"><stdio.h></filename>
+and is the number of file descriptors supported on the system)
+of type
+<structname>XExtCodes</structname>.
+Make sure these are all initialized to NULL.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When your stub is entered, your initialization test is just to use
+the display pointer passed in to access the file descriptor and an index
+into the array.
+If the entry is NULL, then this is the first time you
+are entering the procedure for this display.
+Call your initialization procedure and pass to it the display pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Once in your initialization procedure, call
+<function>XInitExtension</function>;
+if it succeeds, store the pointer returned into this array.
+Make sure to establish a close display handler to allow you to zero the entry.
+Do whatever other initialization your extension requires.
+(For example, install event handlers and so on.)
+Your initialization procedure would normally return a pointer to the
+<structname>XExtCodes</structname>
+structure for this extension, which is what would normally
+be found in your array of pointers.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+After returning from your initialization procedure,
+the stub can now continue normally, because it has its major opcode safely
+in its hand in the
+<structname>XExtCodes</structname>
+structure.
+<!-- .bp -->
+ </para>
+ </listitem>
+</itemizedlist>
+</appendix>
diff --git a/libX11/specs/libX11/AppD.xml b/libX11/specs/libX11/AppD.xml index a8cd375c3..4cde16240 100644 --- a/libX11/specs/libX11/AppD.xml +++ b/libX11/specs/libX11/AppD.xml @@ -1,1888 +1,1888 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<appendix id="compatibility_functions"> -<title>Compatibility Functions</title> -<para> -The X Version 11 and X Version 10 functions discussed in this appendix -are obsolete, have been superseded by newer X Version 11 functions, -and are maintained for compatibility reasons only. -</para> -<sect1 id="X_Version_11_Compatibility_Functions"> -<title>X Version 11 Compatibility Functions</title> -<para> -You can use the X Version 11 compatibility functions to: -<itemizedlist> - <listitem> - <para> -Set standard properties - </para> - </listitem> - <listitem> - <para> -Set and get window sizing hints - </para> - </listitem> - <listitem> - <para> -Set and get an -<structname>XStandardColormap</structname> -structure - </para> - </listitem> - <listitem> - <para> -Parse window geometry - </para> - </listitem> - <listitem> - <para> -Get X environment defaults - </para> - </listitem> -</itemizedlist> -</para> -<sect2 id="Setting_Standard_Properties"> -<title>Setting Standard Properties</title> -<para> -To specify a minimum set of properties describing the simplest application, -use -<function>XSetStandardProperties</function>. -This function has been superseded by -<function>XSetWMProperties</function> -and sets all or portions of the -<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_COMMAND</property>, -and <property>WM_NORMAL_HINTS</property> properties. -</para> -<indexterm significance="preferred"><primary>XSetStandardProperties</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetstandardproperties'> -<funcprototype> - <funcdef><function>XSetStandardProperties</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> *window_name</parameter></paramdef> - <paramdef>char<parameter> *icon_name</parameter></paramdef> - <paramdef>Pixmap<parameter> icon_pixmap</parameter></paramdef> - <paramdef>char<parameter> **argv</parameter></paramdef> - <paramdef>int<parameter> argc</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_name</emphasis> - </term> - <listitem> - <para> -Specifies the window name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_name</emphasis> - </term> - <listitem> - <para> -Specifies the icon name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_pixmap</emphasis> - </term> - <listitem> - <para> -Specifies the bitmap that is to be used for the icon or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv</emphasis> - </term> - <listitem> - <para> -Specifies the application's argument list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc</emphasis> - </term> - <listitem> - <para> -Specifies the number of arguments. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetStandardProperties</function> -function provides a means by which simple applications set the -most essential properties with a single call. -<function>XSetStandardProperties</function> -should be used to give a window manager some information about -your program's preferences. -It should not be used by applications that need -to communicate more information than is possible with -<function>XSetStandardProperties</function>. -(Typically, argv is the argv array of your main program.) -If the strings are not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -<function>XSetStandardProperties</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_and_Getting_Window_Sizing_Hints"> -<title>Setting and Getting Window Sizing Hints</title> -<para> -Xlib provides functions that you can use to set or get window sizing hints. -The functions discussed in this section use the flags and the -<structname>XSizeHints</structname> -structure, as defined in the -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -header file and use the <property>WM_NORMAL_HINTS</property> property. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the size hints for a given window in its normal state, use -<function>XSetNormalHints</function>. -This function has been superseded by -<function>XSetWMNormalHints</function>. -</para> -<indexterm significance="preferred"><primary>XSetNormalHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetnormalhints'> -<funcprototype> - <funcdef><function>XSetNormalHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetNormalHints</function> -function sets the size hints structure for the specified window. -Applications use -<function>XSetNormalHints</function> -to inform the window manager of the size -or position desirable for that window. -In addition, -an application that wants to move or resize itself should call -<function>XSetNormalHints</function> -and specify its new desired location and size -as well as making direct Xlib calls to move or resize. -This is because window managers may ignore redirected -configure requests, but they pay attention to property changes. -</para> -<para> -<!-- .LP --> -To set size hints, -an application not only must assign values to the appropriate members -in the hints structure but also must set the flags member of the structure -to indicate which information is present and where it came from. -A call to -<function>XSetNormalHints</function> -is meaningless, unless the flags member is set to indicate which members of -the structure have been assigned values. -</para> -<para> -<!-- .LP --> -<function>XSetNormalHints</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return the size hints for a window in its normal state, use -<function>XGetNormalHints</function>. -This function has been superseded by -<function>XGetWMNormalHints</function>. -</para> -<indexterm significance="preferred"><primary>XGetNormalHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetnormalhints'> -<funcprototype> - <funcdef>Status <function>XGetNormalHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints_return</emphasis> - </term> - <listitem> - <para> -Returns the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetNormalHints</function> -function returns the size hints for a window in its normal state. -It returns a nonzero status if it succeeds or zero if -the application specified no normal size hints for this window. -</para> -<para> -<!-- .LP --> -<function>XGetNormalHints</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -The next two functions set and read the <property>WM_ZOOM_HINTS</property> property. -</para> -<para> -<!-- .LP --> -To set the zoom hints for a window, use -<function>XSetZoomHints</function>. -This function is no longer supported by the -<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>. -</para> -<indexterm significance="preferred"><primary>XSetZoomHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetzoomhints'> -<funcprototype> - <funcdef><function>XSetZoomHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *zhints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>zhints</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the zoom hints. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Many window managers think of windows in one of three states: -iconic, normal, or zoomed. -The -<function>XSetZoomHints</function> -function provides the window manager with information for the window in the -zoomed state. -</para> -<para> -<!-- .LP --> -<function>XSetZoomHints</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read the zoom hints for a window, use -<function>XGetZoomHints</function>. -This function is no longer supported by the -<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>. -</para> -<indexterm significance="preferred"><primary>XGetZoomHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetzoomhints'> -<funcprototype> - <funcdef>Status <function>XGetZoomHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *zhints_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>zhints_return</emphasis> - </term> - <listitem> - <para> -Returns the zoom hints. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetZoomHints</function> -function returns the size hints for a window in its zoomed state. -It returns a nonzero status if it succeeds or zero if -the application specified no zoom size hints for this window. -</para> -<para> -<!-- .LP --> -<function>XGetZoomHints</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the value of any property of type <property>WM_SIZE_HINTS</property>, use -<function>XSetSizeHints</function>. -This function has been superseded by -<function>XSetWMSizeHints</function>. -</para> -<indexterm significance="preferred"><primary>XSetSizeHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetsizehints'> -<funcprototype> - <funcdef><function>XSetSizeHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the size hints. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetSizeHints</function> -function sets the -<structname>XSizeHints</structname> -structure for the named property and the specified window. -This is used by -<function>XSetNormalHints</function> -and -<function>XSetZoomHints</function> -and can be used to set the value of any property of type <property>WM_SIZE_HINTS</property>. -Thus, it may be useful if other properties of that type get defined. -</para> -<para> -<!-- .LP --> -<function>XSetSizeHints</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read the value of any property of type <property>WM_SIZE_HINTS</property>, use -<function>XGetSizeHints</function>. -This function has been superseded by -<function>XGetWMSizeHints</function>. -</para> -<indexterm significance="preferred"><primary>XGetSizeHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetsizehints'> -<funcprototype> - <funcdef>Status <function>XGetSizeHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints_return</emphasis> - </term> - <listitem> - <para> -Returns the size hints. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetSizeHints</function> -function returns the -<structname>XSizeHints</structname> -structure for the named property and the specified window. -This is used by -<function>XGetNormalHints</function> -and -<function>XGetZoomHints</function>. -It also can be used to retrieve the value of any property of type -<property>WM_SIZE_HINTS</property>. -Thus, it may be useful if other properties of that type get defined. -<function>XGetSizeHints</function> -returns a nonzero status if a size hint was defined -or zero otherwise. -</para> -<para> -<!-- .LP --> -<function>XGetSizeHints</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Getting_and_Setting_an_XStandardColormap_Structure"> -<title>Getting and Setting an XStandardColormap Structure</title> -<para> -To get the -<structname>XStandardColormap</structname> -structure associated with one of the described atoms, use -<function>XGetStandardColormap</function>. -This function has been superseded by -<function>XGetRGBColormaps</function>. -</para> -<indexterm significance="preferred"><primary>XGetStandardColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetstandardcolormap'> -<funcprototype> - <funcdef>Status <function>XGetStandardColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XStandardColormap<parameter> *colormap_return</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap_return</emphasis> - </term> - <listitem> - <para> -Returns the colormap associated with the specified atom. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetStandardColormap</function> -function returns the colormap definition associated with the atom supplied -as the property argument. -<function>XGetStandardColormap</function> -returns a nonzero status if successful and zero otherwise. -For example, -to fetch the standard -<symbol>GrayScale</symbol> -colormap for a display, -you use -<function>XGetStandardColormap</function> -with the following syntax: -<programlisting> -XGetStandardColormap(dpy, DefaultRootWindow(dpy), &cmap, XA_RGB_GRAY_MAP); -</programlisting> -See <link linkend="Standard_Colormaps">section 14.3</link> for the -semantics of standard colormaps. -</para> -<para> -<!-- .LP --> -<function>XGetStandardColormap</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a standard colormap, use -<function>XSetStandardColormap</function>. -This function has been superseded by -<function>XSetRGBColormaps</function>. -</para> -<indexterm significance="preferred"><primary>XSetStandardColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetstandardcolormap'> -<funcprototype> - <funcdef><function>XSetStandardColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XStandardColormap<parameter> *colormap</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetStandardColormap</function> -function usually is only used by window or session managers. -</para> -<para> -<!-- .LP --> -<function>XSetStandardColormap</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -<errorname>BadDrawable</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Parsing_Window_Geometry"> -<title>Parsing Window Geometry</title> -<para> -To parse window geometry given a user-specified position -and a default position, use -<function>XGeometry</function>. -This function has been superseded by -<function>XWMGeometry</function>. -</para> -<indexterm><primary>Window</primary><secondary>determining location</secondary></indexterm> -<indexterm significance="preferred"><primary>XGeometry</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeometry'> -<funcprototype> - <funcdef>int <function>XGeometry</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen</parameter></paramdef> - <paramdef>char*position,<parameter> *default_position</parameter></paramdef> - <paramdef>unsignedint<parameter> bwidth</parameter></paramdef> - <paramdef>unsignedintfwidth,<parameter> fheight</parameter></paramdef> - <paramdef>intxadder,<parameter> yadder</parameter></paramdef> - <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef> - <paramdef>int*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>position</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>default_position</emphasis> - </term> - <listitem> - <para> -Specify the geometry specifications. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bwidth</emphasis> - </term> - <listitem> - <para> -Specifies the border width. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fheight</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fwidth</emphasis> - </term> - <listitem> - <para> -Specify the font height and width in pixels (increment size). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>xadder</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>yadder</emphasis> - </term> - <listitem> - <para> -Specify additional interior padding needed in the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_return</emphasis> - </term> - <listitem> - <para> -Return the x and y offsets. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height determined. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -You pass in the border width (bwidth), -size of the increments fwidth and fheight -(typically font width and height), -and any additional interior space (xadder and yadder) -to make it easy to compute the resulting size. -The -<function>XGeometry</function> -function returns the position the window should be placed given a position and -a default position. -<function>XGeometry</function> -determines the placement of -a window using a geometry specification as specified by -<function>XParseGeometry</function> -and the additional information about the window. -Given a fully qualified default geometry specification and -an incomplete geometry specification, -<function>XParseGeometry</function> -returns a bitmask value as defined above in the -<function>XParseGeometry</function> -call, -by using the position argument. -</para> -<para> -<!-- .LP --> -The returned width and height will be the width and height specified -by default_position as overridden by any user-specified position. -They are not affected by fwidth, fheight, xadder, or yadder. -The x and y coordinates are computed by using the border width, -the screen width and height, padding as specified by xadder and yadder, -and the fheight and fwidth times the width and height from the -geometry specifications. -</para> -</sect2> -<sect2 id="Getting_the_X_Environment_Defaults"> -<title>Getting the X Environment Defaults</title> -<para> -The -<function>XGetDefault</function> -function provides a primitive interface to the resource manager facilities -discussed in <link linkend="resource_manager_functions">chapter 15</link>. -It is only useful in very simple applications. -</para> -<!-- .LP --> -<!-- .sp --> -<indexterm significance="preferred"><primary>XGetDefault</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetdefault'> -<funcprototype> - <funcdef>char *<function>XGetDefault</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *program</parameter></paramdef> - <paramdef>char<parameter> *option</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>program</emphasis> - </term> - <listitem> - <para> -Specifies the program name for the Xlib defaults (usually argv[0] -of the main program). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>option</emphasis> - </term> - <listitem> - <para> -Specifies the option name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetDefault</function> -function returns the value of the resource <emphasis remap='I'>prog</emphasis>.<emphasis remap='I'>option</emphasis>, -where <emphasis remap='I'>prog</emphasis> is the program argument with the directory prefix removed -and <emphasis remap='I'>option</emphasis> must be a single component. -Note that multilevel resources cannot be used with -<function>XGetDefault</function>. -The class "Program.Name" is always used for the resource lookup. -If the specified option name does not exist for this program, -<function>XGetDefault</function> -returns NULL. -The strings returned by -<function>XGetDefault</function> -are owned by Xlib and should not be modified or freed by the client. -</para> -<para> -<!-- .LP --> -If a database has been set with -<function>XrmSetDatabase</function>, -that database is used for the lookup. -Otherwise, a database is created -and is set in the display (as if by calling -<function>XrmSetDatabase</function>). -The database is created in the current locale. -To create a database, -<function>XGetDefault</function> -uses resources from the RESOURCE_MANAGER property on the root -window of screen zero. -If no such property exists, -a resource file in the user's home directory is used. -On a <acronym>POSIX</acronym>-conformant system, -this file is -<function>"$HOME/.Xdefaults"</function>. -<indexterm><primary>Files</primary><secondary><filename>$HOME/.Xdefaults</filename></secondary></indexterm> -After loading these defaults, -<function>XGetDefault</function> -merges additional defaults specified by the XENVIRONMENT -environment variable. -If XENVIRONMENT is defined, -it contains a full path name for the additional resource file. -If XENVIRONMENT is not defined, -<function>XGetDefault</function> -looks for -"<filename>$HOME/.Xdefaults-<replaceable>name</replaceable></filename>" , -where <replaceable>name</replaceable> specifies the name of the machine on which the application -is running. -</para> -</sect2> -</sect1> -<sect1 id="X_Version_10_Compatibility_Functions"> -<title>X Version 10 Compatibility Functions</title> -<para> -You can use the X Version 10 compatibility functions to: -<itemizedlist> - <listitem> - <para> -Draw and fill polygons and curves - </para> - </listitem> - <listitem> - <para> -Associate user data with a value - </para> - </listitem> -</itemizedlist> -</para> -<sect2 id="Drawing_and_Filling_Polygons_and_Curves"> -<title>Drawing and Filling Polygons and Curves</title> -<para> -<!-- .LP --> -Xlib provides functions that you can use to draw or fill -arbitrary polygons or curves. -These functions are provided mainly for compatibility with X Version 10 -and have no server support. -That is, they call other Xlib functions, not the server directly. -Thus, if you just have straight lines to draw, using -<function>XDrawLines</function> -<indexterm><primary>XDrawLines</primary></indexterm> -or -<function>XDrawSegments</function> -<indexterm><primary>XDrawSegments</primary></indexterm> -is much faster. -</para> -<para> -<!-- .LP --> -The functions discussed here provide all the functionality of the -X Version 10 functions -<function>XDraw</function>, -<indexterm ><primary>X10 compatibility</primary><secondary>XDraw</secondary></indexterm> -<function>XDrawFilled</function>, -<indexterm><primary>X10 compatibility</primary><secondary>XDrawFilled</secondary></indexterm> -<function>XDrawPatterned</function>, -<indexterm ><primary>X10 compatibility</primary><secondary>XDrawPatterned</secondary></indexterm> -<function>XDrawDashed</function>, -<indexterm><primary>X10 compatibility</primary><secondary>XDrawDashed</secondary></indexterm> -and -<function>XDrawTiled</function>. -<indexterm><primary>X10 compatibility</primary><secondary>XDrawTiled</secondary></indexterm> -They are as compatible as possible given X Version 11's new line-drawing -functions. -One thing to note, however, is that -<function>VertexDrawLastPoint</function> -is no longer supported. -Also, the error status returned is the opposite of what it was under -X Version 10 (this is the X Version 11 standard error status). -<function>XAppendVertex</function> -and -<function>XClearVertexFlag</function> -from X Version 10 also are not supported. -</para> -<para> -<!-- .LP --> -Just how the graphics context you use is set up actually -determines whether you get dashes or not, and so on. -Lines are properly joined if they connect and include -the closing of a closed figure (see -<function>XDrawLines</function>). -The functions discussed here fail (return zero) only if they run out of memory -or are passed a -<structname>Vertex</structname> -list that has a -<structname>Vertex</structname> -with -<symbol>VertexStartClosed</symbol> -set that is not followed by a -<structname>Vertex</structname> -with -<symbol>VertexEndClosed</symbol> -set. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To achieve the effects of the X Version 10 -<function>XDraw</function>, -<indexterm ><primary>X10 compatibility</primary><secondary>XDraw</secondary></indexterm> -<function>XDrawDashed</function>, -<indexterm><primary>X10 compatibility</primary><secondary>XDrawDashed</secondary></indexterm> -and -<function>XDrawPatterned</function>, -<indexterm ><primary>X10 compatibility</primary><secondary>XDrawPatterned</secondary></indexterm> -use -<function>XDraw</function>. -</para> - -<para> -#include <X11/X10.h> -</para> - -<funcsynopsis id='xdraw'> -<funcprototype> - <funcdef>Status <function>XDraw</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Vertex<parameter> *vlist</parameter></paramdef> - <paramdef>int<parameter> vcount</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vlist</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the list of vertices that indicate what to draw. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vcount</emphasis> - </term> - <listitem> - <para> -Specifies how many vertices are in vlist. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDraw</function> -function draws an arbitrary polygon or curve. -The figure drawn is defined by the specified list of vertices (vlist). -The points are connected by lines as specified in the flags in the -vertex structure. -</para> -<para> -<!-- .LP --> -Each Vertex, as defined in -<filename class="headerfile"><X11/X10.h></filename>, -<indexterm type="file"><primary><filename class="headerfile">X11/X10.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm> -is a structure with the following members: -<indexterm significance="preferred"><primary>Vertex</primary></indexterm> -<synopsis> -typedef struct _Vertex { - short x,y; - unsigned short flags; -} Vertex; -</synopsis> -The x and y members are the coordinates of the vertex -that are relative to either the upper left inside corner of the drawable -(if -<symbol>VertexRelative</symbol> -is zero) or the previous vertex (if -<symbol>VertexRelative</symbol> -is one). -</para> -<para> -<!-- .LP --> -The flags, as defined in -<filename class="headerfile"><X11/X10.h></filename>, -<indexterm type="file"><primary><filename class="headerfile">X11/X10.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm> -are as follows: -<indexterm significance="preferred"><primary>VertexRelative</primary></indexterm> -<indexterm significance="preferred"><primary>VertexDontDraw</primary></indexterm> -<indexterm significance="preferred"><primary>VertexCurved</primary></indexterm> -<indexterm significance="preferred"><primary>VertexStartClosed</primary></indexterm> -<indexterm significance="preferred"><primary>VertexEndClosed</primary></indexterm> -<!-- .sM --> - -<synopsis> -VertexRelative 0x0001 /* else absolute */ -VertexDontDraw 0x0002 /* else draw */ -VertexCurved 0x0004 /* else straight */ -VertexStartClosed 0x0008 /* else not */ -VertexEndClosed 0x0010 /* else not */ -</synopsis> - -<itemizedlist> - <listitem> - <para> -If -<symbol>VertexRelative</symbol> -is not set, -the coordinates are absolute (that is, relative to the drawable's origin). -The first vertex must be an absolute vertex. - </para> - </listitem> - <listitem> - <para> -If -<symbol>VertexDontDraw</symbol> -is one, -no line or curve is drawn from the previous vertex to this one. -This is analogous to picking up the pen and moving to another place -before drawing another line. - </para> - </listitem> - <listitem> - <para> -If -<symbol>VertexCurved</symbol> -is one, -a spline algorithm is used to draw a smooth curve from the previous vertex -through this one to the next vertex. -Otherwise, a straight line is drawn from the previous vertex to this one. -It makes sense to set -<symbol>VertexCurved</symbol> -to one only if a previous and next vertex are both defined -(either explicitly in the array or through the definition of a closed -curve). - </para> - </listitem> - <listitem> - <para> -It is permissible for -<symbol>VertexDontDraw</symbol> -bits and -<symbol>VertexCurved</symbol> -bits both to be one. -This is useful if you want to define the previous point for the smooth curve -but do not want an actual curve drawing to start until this point. - </para> - </listitem> - <listitem> - <para> -If -<symbol>VertexStartClosed</symbol> -is one, -then this point marks the beginning of a closed curve. -This vertex must be followed later in the array by another vertex -whose effective coordinates are identical -and that has a -<symbol>VertexEndClosed</symbol> -bit of one. -The points in between form a cycle to determine predecessor -and successor vertices for the spline algorithm. - </para> - </listitem> -</itemizedlist> -</para> -<para> -<!-- .LP --> -This function uses these GC components: -function, plane-mask, line-width, line-style, cap-style, join-style, -fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and -clip-mask. -It also uses these GC mode-dependent components: -foreground, background, tile, stipple, -tile-stipple-x-origin, tile-stipple-y-origin, dash-offset, and dash-list. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To achieve the effects of the X Version 10 -<function>XDrawTiled</function> -<indexterm><primary>X10 compatibility</primary><secondary>XDrawTiled</secondary></indexterm> -and -<function>XDrawFilled</function>, -<indexterm><primary>X10 compatibility</primary><secondary>XDrawFilled</secondary></indexterm> -use -<function>XDrawFilled</function>. -</para> - -<para>#include <X11/X10.h></para> - -<funcsynopsis id='xdrawfilled'> -<funcprototype> - <funcdef>Status <function>XDrawFilled</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Vertex<parameter> *vlist</parameter></paramdef> - <paramdef>int<parameter> vcount</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vlist</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the list of vertices that indicate what to draw. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vcount</emphasis> - </term> - <listitem> - <para> -Specifies how many vertices are in vlist. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawFilled</function> -function draws arbitrary polygons or curves and then fills them. -</para> -<para> -<!-- .LP --> -This function uses these GC components: -function, plane-mask, line-width, line-style, cap-style, join-style, -fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and -clip-mask. -It also uses these GC mode-dependent components: -foreground, background, tile, stipple, -tile-stipple-x-origin, tile-stipple-y-origin, -dash-offset, dash-list, fill-style, and fill-rule. -</para> -</sect2> -<sect2 id="Associating_User_Data_with_a_Value"> -<title>Associating User Data with a Value</title> -<para> -<!-- .LP --> -These functions have been superseded by the context management functions -(see <link linkend="Using_the_Context_Manager">section 16.10</link>). -It is often necessary to associate arbitrary information with resource IDs. -Xlib provides the -<function>XAssocTable</function> -functions that you can use to make such an association. -<indexterm><primary>Hash Lookup</primary></indexterm> -<indexterm><primary>Window</primary><secondary>IDs</secondary></indexterm> -<indexterm><primary>Resource IDs</primary></indexterm> -Application programs often need to be able to easily refer to -their own data structures when an event arrives. -The -<function>XAssocTable</function> -system provides users of the X library with a method -for associating their own data structures with X resources -(<type>Pixmap</type>s, -<type>Font</type>s, -<type>Window</type>s, -and so on). -</para> -<para> -<!-- .LP --> -An -<function>XAssocTable</function> -can be used to type X resources. -For example, the user -may want to have three or four types of windows, -each with different properties. -This can be accomplished by associating each X window ID -with a pointer to a window property data structure defined by the -user. -A generic type has been defined in the X library for resource IDs. -It is called an XID. -</para> -<para> -<!-- .LP --> -There are a few guidelines that should be observed when using an -<function>XAssocTable</function> : -</para> -<itemizedlist> - <listitem> - <para> -All XIDs are relative to the specified display. - </para> - </listitem> - <listitem> - <para> -Because of the hashing scheme used by the association mechanism, -the following rules for determining the size of a -<function>XAssocTable</function> -should be followed. -Associations will be made and looked up more -efficiently if the table size (number of buckets in the hashing -system) is a power of two and if there are not more than 8 XIDs per -bucket. - </para> - </listitem> -</itemizedlist> - -<para> -<!-- .LP --> -<!-- .sp --> -To return a pointer to a new -<function>XAssocTable</function>, -use -<function>XCreateAssocTable</function>. -<indexterm significance="preferred"><primary>XCreateAssocTable</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xcreateassoctable'> -<funcprototype> - <funcdef>XAssocTable *<function>XCreateAssocTable</function></funcdef> - <paramdef>int<parameter> size</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>size</emphasis> - </term> - <listitem> - <para> -Specifies the number of buckets in the hash system of -<function>XAssocTable</function>. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The size argument specifies the number of buckets in the -hash system of -<function>XAssocTable</function>. -For reasons of efficiency the number of buckets -should be a power of two. -Some size suggestions might be: use 32 buckets per 100 objects, -and a reasonable maximum number of objects per buckets is 8. -If an error allocating memory for the -<function>XAssocTable</function> -occurs, -a NULL pointer is returned. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create an entry in a given -<function>XAssocTable</function>, -use -<function>XMakeAssoc</function>. -<indexterm significance="preferred"><primary>XMakeAssoc</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xmakeassoc'> -<funcprototype> - <funcdef><function>XMakeAssoc</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XAssocTable<parameter> *table</parameter></paramdef> - <paramdef>XID<parameter> x_id</parameter></paramdef> - <paramdef>char<parameter> *data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>table</emphasis> - </term> - <listitem> - <para> -Specifies the assoc table. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_id</emphasis> - </term> - <listitem> - <para> -Specifies the X resource ID. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the data to be associated with the X resource ID. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMakeAssoc</function> -function inserts data into an -<function>XAssocTable</function> -keyed on an XID. -Data is inserted into the table only once. -Redundant inserts are ignored. -The queue in each association bucket is sorted from the lowest XID to -the highest XID. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain data from a given -<function>XAssocTable</function>, -use -<function>XLookUpAssoc</function>. -</para> -<indexterm significance="preferred"><primary>XLookUpAssoc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlookupassoc'> -<funcprototype> - <funcdef>char *<function>XLookUpAssoc</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XAssocTable<parameter> *table</parameter></paramdef> - <paramdef>XID<parameter> x_id</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>table</emphasis> - </term> - <listitem> - <para> -Specifies the assoc table. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_id</emphasis> - </term> - <listitem> - <para> -Specifies the X resource ID. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLookUpAssoc</function> -function retrieves the data stored in an -<function>XAssocTable</function> -by its XID. -If an appropriately matching XID can be found in the table, -<function>XLookUpAssoc</function> -returns the data associated with it. -If the x_id cannot be found in the table, -it returns NULL. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To delete an entry from a given -<function>XAssocTable</function>, -use -<function>XDeleteAssoc</function>. -</para> -<indexterm significance="preferred"><primary>XDeleteAssoc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdeleteassoc'> -<funcprototype> - <funcdef><function>XDeleteAssoc</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XAssocTable<parameter> *table</parameter></paramdef> - <paramdef>XID<parameter> x_id</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>table</emphasis> - </term> - <listitem> - <para> -Specifies the assoc table. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_id</emphasis> - </term> - <listitem> - <para> -Specifies the X resource ID. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDeleteAssoc</function> -function deletes an association in an -<function>XAssocTable</function> -keyed on its XID. -Redundant deletes (and deletes of nonexistent XIDs) are ignored. -Deleting associations in no way impairs the performance of an -<function>XAssocTable</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free the memory associated with a given -<function>XAssocTable</function>, -use -<function>XDestroyAssocTable</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyAssocTable</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroyassoctable'> -<funcprototype> - <funcdef><function>XDestroyAssocTable</function></funcdef> - <paramdef>XAssocTable<parameter> *table</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>table</emphasis> - </term> - <listitem> - <para> -Specifies the assoc table. - </para> - </listitem> - </varlistentry> -</variablelist> -</sect2> -</sect1> -</appendix> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<appendix id="compatibility_functions">
+<title>Compatibility Functions</title>
+<para>
+The X Version 11 and X Version 10 functions discussed in this appendix
+are obsolete, have been superseded by newer X Version 11 functions,
+and are maintained for compatibility reasons only.
+</para>
+<sect1 id="X_Version_11_Compatibility_Functions">
+<title>X Version 11 Compatibility Functions</title>
+<para>
+You can use the X Version 11 compatibility functions to:
+<itemizedlist>
+ <listitem>
+ <para>
+Set standard properties
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and get window sizing hints
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and get an
+<structname>XStandardColormap</structname>
+structure
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Parse window geometry
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Get X environment defaults
+ </para>
+ </listitem>
+</itemizedlist>
+</para>
+<sect2 id="Setting_Standard_Properties">
+<title>Setting Standard Properties</title>
+<para>
+To specify a minimum set of properties describing the simplest application,
+use
+<function>XSetStandardProperties</function>.
+This function has been superseded by
+<function>XSetWMProperties</function>
+and sets all or portions of the
+<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_COMMAND</property>,
+and <property>WM_NORMAL_HINTS</property> properties.
+</para>
+<indexterm significance="preferred"><primary>XSetStandardProperties</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetstandardproperties'>
+<funcprototype>
+ <funcdef><function>XSetStandardProperties</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> *window_name</parameter></paramdef>
+ <paramdef>char<parameter> *icon_name</parameter></paramdef>
+ <paramdef>Pixmap<parameter> icon_pixmap</parameter></paramdef>
+ <paramdef>char<parameter> **argv</parameter></paramdef>
+ <paramdef>int<parameter> argc</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the icon name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_pixmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the bitmap that is to be used for the icon or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application's argument list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetStandardProperties</function>
+function provides a means by which simple applications set the
+most essential properties with a single call.
+<function>XSetStandardProperties</function>
+should be used to give a window manager some information about
+your program's preferences.
+It should not be used by applications that need
+to communicate more information than is possible with
+<function>XSetStandardProperties</function>.
+(Typically, argv is the argv array of your main program.)
+If the strings are not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetStandardProperties</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_and_Getting_Window_Sizing_Hints">
+<title>Setting and Getting Window Sizing Hints</title>
+<para>
+Xlib provides functions that you can use to set or get window sizing hints.
+The functions discussed in this section use the flags and the
+<structname>XSizeHints</structname>
+structure, as defined in the
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+header file and use the <property>WM_NORMAL_HINTS</property> property.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the size hints for a given window in its normal state, use
+<function>XSetNormalHints</function>.
+This function has been superseded by
+<function>XSetWMNormalHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetNormalHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetnormalhints'>
+<funcprototype>
+ <funcdef><function>XSetNormalHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetNormalHints</function>
+function sets the size hints structure for the specified window.
+Applications use
+<function>XSetNormalHints</function>
+to inform the window manager of the size
+or position desirable for that window.
+In addition,
+an application that wants to move or resize itself should call
+<function>XSetNormalHints</function>
+and specify its new desired location and size
+as well as making direct Xlib calls to move or resize.
+This is because window managers may ignore redirected
+configure requests, but they pay attention to property changes.
+</para>
+<para>
+<!-- .LP -->
+To set size hints,
+an application not only must assign values to the appropriate members
+in the hints structure but also must set the flags member of the structure
+to indicate which information is present and where it came from.
+A call to
+<function>XSetNormalHints</function>
+is meaningless, unless the flags member is set to indicate which members of
+the structure have been assigned values.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetNormalHints</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return the size hints for a window in its normal state, use
+<function>XGetNormalHints</function>.
+This function has been superseded by
+<function>XGetWMNormalHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetNormalHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetnormalhints'>
+<funcprototype>
+ <funcdef>Status <function>XGetNormalHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetNormalHints</function>
+function returns the size hints for a window in its normal state.
+It returns a nonzero status if it succeeds or zero if
+the application specified no normal size hints for this window.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetNormalHints</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+The next two functions set and read the <property>WM_ZOOM_HINTS</property> property.
+</para>
+<para>
+<!-- .LP -->
+To set the zoom hints for a window, use
+<function>XSetZoomHints</function>.
+This function is no longer supported by the
+<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>.
+</para>
+<indexterm significance="preferred"><primary>XSetZoomHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetzoomhints'>
+<funcprototype>
+ <funcdef><function>XSetZoomHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *zhints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>zhints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the zoom hints.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Many window managers think of windows in one of three states:
+iconic, normal, or zoomed.
+The
+<function>XSetZoomHints</function>
+function provides the window manager with information for the window in the
+zoomed state.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetZoomHints</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read the zoom hints for a window, use
+<function>XGetZoomHints</function>.
+This function is no longer supported by the
+<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>.
+</para>
+<indexterm significance="preferred"><primary>XGetZoomHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetzoomhints'>
+<funcprototype>
+ <funcdef>Status <function>XGetZoomHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *zhints_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>zhints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the zoom hints.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetZoomHints</function>
+function returns the size hints for a window in its zoomed state.
+It returns a nonzero status if it succeeds or zero if
+the application specified no zoom size hints for this window.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetZoomHints</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the value of any property of type <property>WM_SIZE_HINTS</property>, use
+<function>XSetSizeHints</function>.
+This function has been superseded by
+<function>XSetWMSizeHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetSizeHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetsizehints'>
+<funcprototype>
+ <funcdef><function>XSetSizeHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the size hints.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetSizeHints</function>
+function sets the
+<structname>XSizeHints</structname>
+structure for the named property and the specified window.
+This is used by
+<function>XSetNormalHints</function>
+and
+<function>XSetZoomHints</function>
+and can be used to set the value of any property of type <property>WM_SIZE_HINTS</property>.
+Thus, it may be useful if other properties of that type get defined.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetSizeHints</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read the value of any property of type <property>WM_SIZE_HINTS</property>, use
+<function>XGetSizeHints</function>.
+This function has been superseded by
+<function>XGetWMSizeHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetSizeHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetsizehints'>
+<funcprototype>
+ <funcdef>Status <function>XGetSizeHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the size hints.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetSizeHints</function>
+function returns the
+<structname>XSizeHints</structname>
+structure for the named property and the specified window.
+This is used by
+<function>XGetNormalHints</function>
+and
+<function>XGetZoomHints</function>.
+It also can be used to retrieve the value of any property of type
+<property>WM_SIZE_HINTS</property>.
+Thus, it may be useful if other properties of that type get defined.
+<function>XGetSizeHints</function>
+returns a nonzero status if a size hint was defined
+or zero otherwise.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetSizeHints</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Getting_and_Setting_an_XStandardColormap_Structure">
+<title>Getting and Setting an XStandardColormap Structure</title>
+<para>
+To get the
+<structname>XStandardColormap</structname>
+structure associated with one of the described atoms, use
+<function>XGetStandardColormap</function>.
+This function has been superseded by
+<function>XGetRGBColormaps</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetStandardColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetstandardcolormap'>
+<funcprototype>
+ <funcdef>Status <function>XGetStandardColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XStandardColormap<parameter> *colormap_return</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the colormap associated with the specified atom.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetStandardColormap</function>
+function returns the colormap definition associated with the atom supplied
+as the property argument.
+<function>XGetStandardColormap</function>
+returns a nonzero status if successful and zero otherwise.
+For example,
+to fetch the standard
+<symbol>GrayScale</symbol>
+colormap for a display,
+you use
+<function>XGetStandardColormap</function>
+with the following syntax:
+<programlisting>
+XGetStandardColormap(dpy, DefaultRootWindow(dpy), &cmap, XA_RGB_GRAY_MAP);
+</programlisting>
+See <link linkend="Standard_Colormaps">section 14.3</link> for the
+semantics of standard colormaps.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetStandardColormap</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a standard colormap, use
+<function>XSetStandardColormap</function>.
+This function has been superseded by
+<function>XSetRGBColormaps</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetStandardColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetstandardcolormap'>
+<funcprototype>
+ <funcdef><function>XSetStandardColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XStandardColormap<parameter> *colormap</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetStandardColormap</function>
+function usually is only used by window or session managers.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetStandardColormap</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+<errorname>BadDrawable</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Parsing_Window_Geometry">
+<title>Parsing Window Geometry</title>
+<para>
+To parse window geometry given a user-specified position
+and a default position, use
+<function>XGeometry</function>.
+This function has been superseded by
+<function>XWMGeometry</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>determining location</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGeometry</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeometry'>
+<funcprototype>
+ <funcdef>int <function>XGeometry</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen</parameter></paramdef>
+ <paramdef>char*position,<parameter> *default_position</parameter></paramdef>
+ <paramdef>unsignedint<parameter> bwidth</parameter></paramdef>
+ <paramdef>unsignedintfwidth,<parameter> fheight</parameter></paramdef>
+ <paramdef>intxadder,<parameter> yadder</parameter></paramdef>
+ <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef>
+ <paramdef>int*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>position</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>default_position</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the geometry specifications.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bwidth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the border width.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fheight</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fwidth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the font height and width in pixels (increment size).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>xadder</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>yadder</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify additional interior padding needed in the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the x and y offsets.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height determined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+You pass in the border width (bwidth),
+size of the increments fwidth and fheight
+(typically font width and height),
+and any additional interior space (xadder and yadder)
+to make it easy to compute the resulting size.
+The
+<function>XGeometry</function>
+function returns the position the window should be placed given a position and
+a default position.
+<function>XGeometry</function>
+determines the placement of
+a window using a geometry specification as specified by
+<function>XParseGeometry</function>
+and the additional information about the window.
+Given a fully qualified default geometry specification and
+an incomplete geometry specification,
+<function>XParseGeometry</function>
+returns a bitmask value as defined above in the
+<function>XParseGeometry</function>
+call,
+by using the position argument.
+</para>
+<para>
+<!-- .LP -->
+The returned width and height will be the width and height specified
+by default_position as overridden by any user-specified position.
+They are not affected by fwidth, fheight, xadder, or yadder.
+The x and y coordinates are computed by using the border width,
+the screen width and height, padding as specified by xadder and yadder,
+and the fheight and fwidth times the width and height from the
+geometry specifications.
+</para>
+</sect2>
+<sect2 id="Getting_the_X_Environment_Defaults">
+<title>Getting the X Environment Defaults</title>
+<para>
+The
+<function>XGetDefault</function>
+function provides a primitive interface to the resource manager facilities
+discussed in <link linkend="resource_manager_functions">chapter 15</link>.
+It is only useful in very simple applications.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm significance="preferred"><primary>XGetDefault</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetdefault'>
+<funcprototype>
+ <funcdef>char *<function>XGetDefault</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *program</parameter></paramdef>
+ <paramdef>char<parameter> *option</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>program</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the program name for the Xlib defaults (usually argv[0]
+of the main program).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>option</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the option name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetDefault</function>
+function returns the value of the resource <emphasis remap='I'>prog</emphasis>.<emphasis remap='I'>option</emphasis>,
+where <emphasis remap='I'>prog</emphasis> is the program argument with the directory prefix removed
+and <emphasis remap='I'>option</emphasis> must be a single component.
+Note that multilevel resources cannot be used with
+<function>XGetDefault</function>.
+The class "Program.Name" is always used for the resource lookup.
+If the specified option name does not exist for this program,
+<function>XGetDefault</function>
+returns NULL.
+The strings returned by
+<function>XGetDefault</function>
+are owned by Xlib and should not be modified or freed by the client.
+</para>
+<para>
+<!-- .LP -->
+If a database has been set with
+<function>XrmSetDatabase</function>,
+that database is used for the lookup.
+Otherwise, a database is created
+and is set in the display (as if by calling
+<function>XrmSetDatabase</function>).
+The database is created in the current locale.
+To create a database,
+<function>XGetDefault</function>
+uses resources from the RESOURCE_MANAGER property on the root
+window of screen zero.
+If no such property exists,
+a resource file in the user's home directory is used.
+On a <acronym>POSIX</acronym>-conformant system,
+this file is
+<function>"$HOME/.Xdefaults"</function>.
+<indexterm><primary>Files</primary><secondary><filename>$HOME/.Xdefaults</filename></secondary></indexterm>
+After loading these defaults,
+<function>XGetDefault</function>
+merges additional defaults specified by the XENVIRONMENT
+environment variable.
+If XENVIRONMENT is defined,
+it contains a full path name for the additional resource file.
+If XENVIRONMENT is not defined,
+<function>XGetDefault</function>
+looks for
+"<filename>$HOME/.Xdefaults-<replaceable>name</replaceable></filename>" ,
+where <replaceable>name</replaceable> specifies the name of the machine on which the application
+is running.
+</para>
+</sect2>
+</sect1>
+<sect1 id="X_Version_10_Compatibility_Functions">
+<title>X Version 10 Compatibility Functions</title>
+<para>
+You can use the X Version 10 compatibility functions to:
+<itemizedlist>
+ <listitem>
+ <para>
+Draw and fill polygons and curves
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Associate user data with a value
+ </para>
+ </listitem>
+</itemizedlist>
+</para>
+<sect2 id="Drawing_and_Filling_Polygons_and_Curves">
+<title>Drawing and Filling Polygons and Curves</title>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to draw or fill
+arbitrary polygons or curves.
+These functions are provided mainly for compatibility with X Version 10
+and have no server support.
+That is, they call other Xlib functions, not the server directly.
+Thus, if you just have straight lines to draw, using
+<function>XDrawLines</function>
+<indexterm><primary>XDrawLines</primary></indexterm>
+or
+<function>XDrawSegments</function>
+<indexterm><primary>XDrawSegments</primary></indexterm>
+is much faster.
+</para>
+<para>
+<!-- .LP -->
+The functions discussed here provide all the functionality of the
+X Version 10 functions
+<function>XDraw</function>,
+<indexterm ><primary>X10 compatibility</primary><secondary>XDraw</secondary></indexterm>
+<function>XDrawFilled</function>,
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawFilled</secondary></indexterm>
+<function>XDrawPatterned</function>,
+<indexterm ><primary>X10 compatibility</primary><secondary>XDrawPatterned</secondary></indexterm>
+<function>XDrawDashed</function>,
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawDashed</secondary></indexterm>
+and
+<function>XDrawTiled</function>.
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawTiled</secondary></indexterm>
+They are as compatible as possible given X Version 11's new line-drawing
+functions.
+One thing to note, however, is that
+<function>VertexDrawLastPoint</function>
+is no longer supported.
+Also, the error status returned is the opposite of what it was under
+X Version 10 (this is the X Version 11 standard error status).
+<function>XAppendVertex</function>
+and
+<function>XClearVertexFlag</function>
+from X Version 10 also are not supported.
+</para>
+<para>
+<!-- .LP -->
+Just how the graphics context you use is set up actually
+determines whether you get dashes or not, and so on.
+Lines are properly joined if they connect and include
+the closing of a closed figure (see
+<function>XDrawLines</function>).
+The functions discussed here fail (return zero) only if they run out of memory
+or are passed a
+<structname>Vertex</structname>
+list that has a
+<structname>Vertex</structname>
+with
+<symbol>VertexStartClosed</symbol>
+set that is not followed by a
+<structname>Vertex</structname>
+with
+<symbol>VertexEndClosed</symbol>
+set.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To achieve the effects of the X Version 10
+<function>XDraw</function>,
+<indexterm ><primary>X10 compatibility</primary><secondary>XDraw</secondary></indexterm>
+<function>XDrawDashed</function>,
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawDashed</secondary></indexterm>
+and
+<function>XDrawPatterned</function>,
+<indexterm ><primary>X10 compatibility</primary><secondary>XDrawPatterned</secondary></indexterm>
+use
+<function>XDraw</function>.
+</para>
+
+<para>
+#include <X11/X10.h>
+</para>
+
+<funcsynopsis id='xdraw'>
+<funcprototype>
+ <funcdef>Status <function>XDraw</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Vertex<parameter> *vlist</parameter></paramdef>
+ <paramdef>int<parameter> vcount</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vlist</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the list of vertices that indicate what to draw.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vcount</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies how many vertices are in vlist.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDraw</function>
+function draws an arbitrary polygon or curve.
+The figure drawn is defined by the specified list of vertices (vlist).
+The points are connected by lines as specified in the flags in the
+vertex structure.
+</para>
+<para>
+<!-- .LP -->
+Each Vertex, as defined in
+<filename class="headerfile"><X11/X10.h></filename>,
+<indexterm type="file"><primary><filename class="headerfile">X11/X10.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm>
+is a structure with the following members:
+<indexterm significance="preferred"><primary>Vertex</primary></indexterm>
+<synopsis>
+typedef struct _Vertex {
+ short x,y;
+ unsigned short flags;
+} Vertex;
+</synopsis>
+The x and y members are the coordinates of the vertex
+that are relative to either the upper left inside corner of the drawable
+(if
+<symbol>VertexRelative</symbol>
+is zero) or the previous vertex (if
+<symbol>VertexRelative</symbol>
+is one).
+</para>
+<para>
+<!-- .LP -->
+The flags, as defined in
+<filename class="headerfile"><X11/X10.h></filename>,
+<indexterm type="file"><primary><filename class="headerfile">X11/X10.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X10.h></filename></secondary></indexterm>
+are as follows:
+<indexterm significance="preferred"><primary>VertexRelative</primary></indexterm>
+<indexterm significance="preferred"><primary>VertexDontDraw</primary></indexterm>
+<indexterm significance="preferred"><primary>VertexCurved</primary></indexterm>
+<indexterm significance="preferred"><primary>VertexStartClosed</primary></indexterm>
+<indexterm significance="preferred"><primary>VertexEndClosed</primary></indexterm>
+<!-- .sM -->
+
+<synopsis>
+VertexRelative 0x0001 /* else absolute */
+VertexDontDraw 0x0002 /* else draw */
+VertexCurved 0x0004 /* else straight */
+VertexStartClosed 0x0008 /* else not */
+VertexEndClosed 0x0010 /* else not */
+</synopsis>
+
+<itemizedlist>
+ <listitem>
+ <para>
+If
+<symbol>VertexRelative</symbol>
+is not set,
+the coordinates are absolute (that is, relative to the drawable's origin).
+The first vertex must be an absolute vertex.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If
+<symbol>VertexDontDraw</symbol>
+is one,
+no line or curve is drawn from the previous vertex to this one.
+This is analogous to picking up the pen and moving to another place
+before drawing another line.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If
+<symbol>VertexCurved</symbol>
+is one,
+a spline algorithm is used to draw a smooth curve from the previous vertex
+through this one to the next vertex.
+Otherwise, a straight line is drawn from the previous vertex to this one.
+It makes sense to set
+<symbol>VertexCurved</symbol>
+to one only if a previous and next vertex are both defined
+(either explicitly in the array or through the definition of a closed
+curve).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It is permissible for
+<symbol>VertexDontDraw</symbol>
+bits and
+<symbol>VertexCurved</symbol>
+bits both to be one.
+This is useful if you want to define the previous point for the smooth curve
+but do not want an actual curve drawing to start until this point.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If
+<symbol>VertexStartClosed</symbol>
+is one,
+then this point marks the beginning of a closed curve.
+This vertex must be followed later in the array by another vertex
+whose effective coordinates are identical
+and that has a
+<symbol>VertexEndClosed</symbol>
+bit of one.
+The points in between form a cycle to determine predecessor
+and successor vertices for the spline algorithm.
+ </para>
+ </listitem>
+</itemizedlist>
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components:
+function, plane-mask, line-width, line-style, cap-style, join-style,
+fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and
+clip-mask.
+It also uses these GC mode-dependent components:
+foreground, background, tile, stipple,
+tile-stipple-x-origin, tile-stipple-y-origin, dash-offset, and dash-list.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To achieve the effects of the X Version 10
+<function>XDrawTiled</function>
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawTiled</secondary></indexterm>
+and
+<function>XDrawFilled</function>,
+<indexterm><primary>X10 compatibility</primary><secondary>XDrawFilled</secondary></indexterm>
+use
+<function>XDrawFilled</function>.
+</para>
+
+<para>#include <X11/X10.h></para>
+
+<funcsynopsis id='xdrawfilled'>
+<funcprototype>
+ <funcdef>Status <function>XDrawFilled</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Vertex<parameter> *vlist</parameter></paramdef>
+ <paramdef>int<parameter> vcount</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vlist</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the list of vertices that indicate what to draw.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vcount</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies how many vertices are in vlist.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawFilled</function>
+function draws arbitrary polygons or curves and then fills them.
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components:
+function, plane-mask, line-width, line-style, cap-style, join-style,
+fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and
+clip-mask.
+It also uses these GC mode-dependent components:
+foreground, background, tile, stipple,
+tile-stipple-x-origin, tile-stipple-y-origin,
+dash-offset, dash-list, fill-style, and fill-rule.
+</para>
+</sect2>
+<sect2 id="Associating_User_Data_with_a_Value">
+<title>Associating User Data with a Value</title>
+<para>
+<!-- .LP -->
+These functions have been superseded by the context management functions
+(see <link linkend="Using_the_Context_Manager">section 16.10</link>).
+It is often necessary to associate arbitrary information with resource IDs.
+Xlib provides the
+<function>XAssocTable</function>
+functions that you can use to make such an association.
+<indexterm><primary>Hash Lookup</primary></indexterm>
+<indexterm><primary>Window</primary><secondary>IDs</secondary></indexterm>
+<indexterm><primary>Resource IDs</primary></indexterm>
+Application programs often need to be able to easily refer to
+their own data structures when an event arrives.
+The
+<function>XAssocTable</function>
+system provides users of the X library with a method
+for associating their own data structures with X resources
+(<type>Pixmap</type>s,
+<type>Font</type>s,
+<type>Window</type>s,
+and so on).
+</para>
+<para>
+<!-- .LP -->
+An
+<function>XAssocTable</function>
+can be used to type X resources.
+For example, the user
+may want to have three or four types of windows,
+each with different properties.
+This can be accomplished by associating each X window ID
+with a pointer to a window property data structure defined by the
+user.
+A generic type has been defined in the X library for resource IDs.
+It is called an XID.
+</para>
+<para>
+<!-- .LP -->
+There are a few guidelines that should be observed when using an
+<function>XAssocTable</function> :
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+All XIDs are relative to the specified display.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Because of the hashing scheme used by the association mechanism,
+the following rules for determining the size of a
+<function>XAssocTable</function>
+should be followed.
+Associations will be made and looked up more
+efficiently if the table size (number of buckets in the hashing
+system) is a power of two and if there are not more than 8 XIDs per
+bucket.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return a pointer to a new
+<function>XAssocTable</function>,
+use
+<function>XCreateAssocTable</function>.
+<indexterm significance="preferred"><primary>XCreateAssocTable</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xcreateassoctable'>
+<funcprototype>
+ <funcdef>XAssocTable *<function>XCreateAssocTable</function></funcdef>
+ <paramdef>int<parameter> size</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>size</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of buckets in the hash system of
+<function>XAssocTable</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The size argument specifies the number of buckets in the
+hash system of
+<function>XAssocTable</function>.
+For reasons of efficiency the number of buckets
+should be a power of two.
+Some size suggestions might be: use 32 buckets per 100 objects,
+and a reasonable maximum number of objects per buckets is 8.
+If an error allocating memory for the
+<function>XAssocTable</function>
+occurs,
+a NULL pointer is returned.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create an entry in a given
+<function>XAssocTable</function>,
+use
+<function>XMakeAssoc</function>.
+<indexterm significance="preferred"><primary>XMakeAssoc</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xmakeassoc'>
+<funcprototype>
+ <funcdef><function>XMakeAssoc</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XAssocTable<parameter> *table</parameter></paramdef>
+ <paramdef>XID<parameter> x_id</parameter></paramdef>
+ <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the assoc table.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_id</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the X resource ID.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data to be associated with the X resource ID.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMakeAssoc</function>
+function inserts data into an
+<function>XAssocTable</function>
+keyed on an XID.
+Data is inserted into the table only once.
+Redundant inserts are ignored.
+The queue in each association bucket is sorted from the lowest XID to
+the highest XID.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain data from a given
+<function>XAssocTable</function>,
+use
+<function>XLookUpAssoc</function>.
+</para>
+<indexterm significance="preferred"><primary>XLookUpAssoc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlookupassoc'>
+<funcprototype>
+ <funcdef>char *<function>XLookUpAssoc</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XAssocTable<parameter> *table</parameter></paramdef>
+ <paramdef>XID<parameter> x_id</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the assoc table.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_id</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the X resource ID.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLookUpAssoc</function>
+function retrieves the data stored in an
+<function>XAssocTable</function>
+by its XID.
+If an appropriately matching XID can be found in the table,
+<function>XLookUpAssoc</function>
+returns the data associated with it.
+If the x_id cannot be found in the table,
+it returns NULL.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To delete an entry from a given
+<function>XAssocTable</function>,
+use
+<function>XDeleteAssoc</function>.
+</para>
+<indexterm significance="preferred"><primary>XDeleteAssoc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdeleteassoc'>
+<funcprototype>
+ <funcdef><function>XDeleteAssoc</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XAssocTable<parameter> *table</parameter></paramdef>
+ <paramdef>XID<parameter> x_id</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the assoc table.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_id</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the X resource ID.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDeleteAssoc</function>
+function deletes an association in an
+<function>XAssocTable</function>
+keyed on its XID.
+Redundant deletes (and deletes of nonexistent XIDs) are ignored.
+Deleting associations in no way impairs the performance of an
+<function>XAssocTable</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free the memory associated with a given
+<function>XAssocTable</function>,
+use
+<function>XDestroyAssocTable</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyAssocTable</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroyassoctable'>
+<funcprototype>
+ <funcdef><function>XDestroyAssocTable</function></funcdef>
+ <paramdef>XAssocTable<parameter> *table</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the assoc table.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect2>
+</sect1>
+</appendix>
diff --git a/libX11/specs/libX11/CH02.xml b/libX11/specs/libX11/CH02.xml index 4a57266bd..aa4389792 100644 --- a/libX11/specs/libX11/CH02.xml +++ b/libX11/specs/libX11/CH02.xml @@ -1,3498 +1,3498 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="display_functions"> -<title>Display Functions</title> -<para> -Before your program can use a display, you must establish a connection -to the X server. -Once you have established a connection, -you then can use the Xlib macros and functions discussed in this chapter -to return information about the display. -This chapter discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Open (connect to) the display - </para> - </listitem> - <listitem> - <para> -Obtain information about the display, image formats, or screens - </para> - </listitem> - <listitem> - <para> -Generate a -<systemitem>NoOperation</systemitem> -protocol request - </para> - </listitem> - <listitem> - <para> -Free client-created data - </para> - </listitem> - <listitem> - <para> -Close (disconnect from) a display - </para> - </listitem> - <listitem> - <para> -Use X Server connection close operations - </para> - </listitem> - <listitem> - <para> -Use Xlib with threads - </para> - </listitem> - <listitem> - <para> -Use internal connections - </para> - </listitem> -</itemizedlist> -<sect1 id="Opening_the_Display"> -<title>Opening the Display</title> -<!-- .XS --> -<!-- (SN Opening the Display --> -<!-- .XE --> -<para> -<!-- .LP --> -To open a connection to the X server that controls a display, use -<function>XOpenDisplay</function>. -<indexterm significance="preferred"><primary>XOpenDisplay</primary></indexterm> -</para> -<funcsynopsis id='xopendisplay'> -<funcprototype> - <funcdef>Display *<function>XOpenDisplay</function></funcdef> - <paramdef>char *<parameter>display_name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display_name</emphasis> - </term> - <listitem> - <para> -Specifies the hardware display name, which determines the display -and communications domain to be used. -On a <acronym>POSIX</acronym>-conformant system, if the display_name is NULL, -it defaults to the value of the DISPLAY environment variable. -<indexterm><primary>Environment</primary><secondary>DISPLAY</secondary></indexterm> - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The encoding and interpretation of the display name are -implementation-dependent. -Strings in the Host Portable Character Encoding are supported; -support for other characters is implementation-dependent. -On <acronym>POSIX</acronym>-conformant systems, -the display name or DISPLAY environment variable can be a string in the format: -</para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA 1i --> -<!-- .ta 1i --> - <emphasis remap='I'>protocol</emphasis>/<emphasis remap='I'>hostname</emphasis>:<emphasis remap='I'>number</emphasis>.<emphasis remap='I'>screen_number</emphasis> -</literallayout> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>protocol</emphasis> - </term> - <listitem> - <para> -Specifies a protocol family or an alias for a protocol family. Supported -protocol families are implementation dependent. The protocol entry is -optional. If protocol is not specified, the / separating protocol and -hostname must also not be specified. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hostname</emphasis> - </term> - <listitem> - <para> -Specifies the name of the host machine on which the display is physically -attached. -You follow the hostname with either a single colon (:) or a double colon (::). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>number</emphasis> - </term> - <listitem> - <para> -Specifies the number of the display server on that host machine. -You may optionally follow this display number with a period (.). -A single <acronym>CPU</acronym> can have more than one display. -Multiple displays are usually numbered starting with zero. -<indexterm><primary>Screen</primary></indexterm> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the screen to be used on that server. -Multiple screens can be controlled by a single X server. -The screen_number sets an internal variable that can be accessed by -using the -<function>DefaultScreen</function> -macro or the -<function>XDefaultScreen</function> -function if you are using languages other than C -(see <link linkend="Display_Macros_">section 2.2.1</link>). - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -For example, the following would specify screen 1 of display 0 on the -machine named ``dual-headed'': -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -dual-headed:0.1 -</literallayout> -</para> -<para> -<!-- .LP --> -The -<function>XOpenDisplay</function> -function returns a -<type>Display</type> -structure that serves as the -connection to the X server and that contains all the information -about that X server. -<function>XOpenDisplay</function> -connects your application to the X server through <acronym>TCP</acronym> -or DECnet communications protocols, -or through some local inter-process communication protocol. -<indexterm><primary>Protocol</primary><secondary><acronym>TCP</acronym></secondary></indexterm> -<indexterm><primary>Protocol</primary><secondary>DECnet</secondary></indexterm> -If the protocol is specified as "tcp", "inet", or "inet6", or -if no protocol is specified and the hostname is a host machine name and a single colon (:) -separates the hostname and display number, -<function>XOpenDisplay</function> -connects using <acronym>TCP</acronym> streams. (If the protocol is specified as "inet", <acronym>TCP</acronym> over -IPv4 is used. If the protocol is specified as "inet6", <acronym>TCP</acronym> over IPv6 is used. -Otherwise, the implementation determines which <acronym>IP</acronym> version is used.) -If the hostname and protocol are both not specified, -Xlib uses whatever it believes is the fastest transport. -If the hostname is a host machine name and a double colon (::) -separates the hostname and display number, -<function>XOpenDisplay</function> -connects using DECnet. -A single X server can support any or all of these transport mechanisms -simultaneously. -A particular Xlib implementation can support many more of these transport -mechanisms. -</para> -<para> -<!-- .LP --> -<indexterm><primary>Display</primary></indexterm> -If successful, -<function>XOpenDisplay</function> -returns a pointer to a -<type>Display</type> -structure, -which is defined in -<filename class="headerfile"><X11/Xlib.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -If -<function>XOpenDisplay</function> -does not succeed, it returns NULL. -After a successful call to -<function>XOpenDisplay</function>, -all of the screens in the display can be used by the client. -The screen number specified in the display_name argument is returned -by the -<function>DefaultScreen</function> -macro (or the -<function>XDefaultScreen</function> -function). -You can access elements of the -<type>Display</type> -and -<type>Screen</type> -structures only by using the information macros or functions. -For information about using macros and functions to obtain information from -the -<type>Display</type> -structure, -see <link linkend="Display_Macros_">section 2.2.1</link>. -</para> -<para> -<!-- .LP --> -X servers may implement various types of access control mechanisms -(see <link linkend="Controlling_Host_Access">section 9.8</link>). -</para> -</sect1> -<sect1 id="Obtaining_Information_about_the_Display_Image_Formats_or_Screens"> -<title>Obtaining Information about the Display, Image Formats, or Screens</title> -<!-- .XS --> -<!-- (SN Obtaining Information about the Display, Image Formats, or Screens --> -<!-- .XE --> -<para> -<!-- .LP --> -The Xlib library provides a number of useful macros -and corresponding functions that return data from the -<type>Display</type> -structure. -The macros are used for C programming, -and their corresponding function equivalents are for other language bindings. -This section discusses the: -</para> -<itemizedlist> - <listitem> - <para> -Display macros - </para> - </listitem> - <listitem> - <para> -Image format functions and macros - </para> - </listitem> - <listitem> - <para> -Screen information macros - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<indexterm ><primary>Display</primary><secondary>data structure</secondary></indexterm> -All other members of the -<type>Display</type> -structure (that is, those for which no macros are defined) are private to Xlib -and must not be used. -Applications must never directly modify or inspect these private members of the -<type>Display</type> -structure. -<!-- .NT Note --> -The -<function>XDisplayWidth</function>, -<function>XDisplayHeight</function>, -<function>XDisplayCells</function>, -<function>XDisplayPlanes</function>, -<function>XDisplayWidthMM</function>, -and -<function>XDisplayHeightMM</function> -functions in the next sections are misnamed. -These functions really should be named Screen<emphasis remap='I'>whatever</emphasis> -and XScreen<emphasis remap='I'>whatever</emphasis>, not Display<emphasis remap='I'>whatever</emphasis> or XDisplay<emphasis remap='I'>whatever</emphasis>. -Our apologies for the resulting confusion. -<!-- .NE --> -</para> -<sect2 id="Display_Macros_"> -<title>Display Macros </title> -<!-- .XS --> -<!-- (SN Display Macros --> -<!-- .XE --> -<para> -<!-- .LP --> -Applications should not directly modify any part of the -<type>Display</type> -and -<type>Screen</type> -structures. -The members should be considered read-only, -although they may change as the result of other operations on the display. -</para> -<para> -<!-- .LP --> -The following lists the C language macros, -their corresponding function equivalents that are for other language bindings, -and what data both can return. -</para> -<para>AllPlanes()</para> -<para>XAllPlanes()</para> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>AllPlanes</primary></indexterm> -<indexterm significance="preferred"><primary>XAllPlanes</primary></indexterm> -Both return a value with all bits set to 1 suitable for use in a plane argument to -a procedure. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Both -<function>BlackPixel</function> -and -<function>WhitePixel</function> -can be used in implementing a monochrome application. -These pixel values are for permanently allocated entries in the default -colormap. -The actual <acronym>RGB</acronym> (red, green, and blue) values are settable on some screens -and, in any case, may not actually be black or white. -The names are intended to convey the expected relative intensity of the colors. -<!-- .sM --> -</para> -<para> -BlackPixel(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xblackpixel'> -<funcprototype> - <funcdef>unsigned long <function>XBlackPixel</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>BlackPixel</primary></indexterm> -<indexterm significance="preferred"><primary>XBlackPixel</primary></indexterm> -Both return the black pixel value for the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -WhitePixel(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xwhitepixel'> -<funcprototype> - <funcdef>unsigned long <function>XWhitePixel</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>WhitePixel</primary></indexterm> -<indexterm significance="preferred"><primary>XWhitePixel</primary></indexterm> -Both return the white pixel value for the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ConnectionNumber(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xconnectionnumber'> -<funcprototype> - <funcdef>int <function>XConnectionNumber</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ConnectionNumber</primary></indexterm> -<indexterm significance="preferred"><primary>XConnectionNumber</primary></indexterm> -Both return a connection number for the specified display. -On a <acronym>POSIX</acronym>-conformant system, -this is the file descriptor of the connection. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultColormap(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdefaultcolormap'> -<funcprototype> - <funcdef>Colormap <function>XDefaultColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultColormap</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultColormap</primary></indexterm> -Both return the default colormap ID for allocation on the specified screen. -Most routine allocations of color should be made out of this colormap. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultDepth(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdefaultdepth'> -<funcprototype> - <funcdef>int <function>XDefaultDepth</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultDepth</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultDepth</primary></indexterm> -Both return the depth (number of planes) of the default root window for the -specified screen. -Other depths may also be supported on this screen (see -<function>XMatchVisualInfo</function>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<indexterm significance="preferred"><primary>XListDepths</primary></indexterm> -To determine the number of depths that are available on a given screen, use -<function>XListDepths</function>. -<!-- .sM --> -</para> -<para> -DefaultGC(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdefaultgc'> -<funcprototype> - <funcdef>GC <function>XDefaultGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. -<!-- .ds Cn depths --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListDepths</function> -function returns the array of depths -that are available on the specified screen. -If the specified screen_number is valid and sufficient memory for the array -can be allocated, -<function>XListDepths</function> -sets count_return to the number of available depths. -Otherwise, it does not set count_return and returns NULL. -To release the memory allocated for the array of depths, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultGC(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis> -<funcprototype> - <funcdef>GC <function>XDefaultGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultGC</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultGC</primary></indexterm> -Both return the default graphics context for the root window of the -specified screen. -This GC is created for the convenience of simple applications -and contains the default GC components with the foreground and -background pixel values initialized to the black and white -pixels for the screen, respectively. -You can modify its contents freely because it is not used in any Xlib -function. -This GC should never be freed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultRootWindow(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xdefaultrootwindow'> -<funcprototype> - <funcdef>Window <function>XDefaultRootWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultRootWindow</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultRootWindow</primary></indexterm> -Both return the root window for the default screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultScreenOfDisplay(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xdefaultscreenofdisplay'> -<funcprototype> - <funcdef>Screen *<function>XDefaultScreenOfDisplay</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultScreenOfDisplay</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultScreenOfDisplay</primary></indexterm> -Both return a pointer to the default screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ScreenOfDisplay(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xscreenofdisplay'> -<funcprototype> - <funcdef>Screen *<function>XScreenOfDisplay</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ScreenOfDisplay</primary></indexterm> -<indexterm significance="preferred"><primary>XScreenOfDisplay</primary></indexterm> -Both return a pointer to the indicated screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultScreen(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xdefaultscreen'> -<funcprototype> - <funcdef>int <function>XDefaultScreen</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultScreen</primary></indexterm> -Both return the default screen number referenced by the -<function>XOpenDisplay</function> -function. -This macro or function should be used to retrieve the screen number -in applications that will use only a single screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultVisual(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdefaultvisual'> -<funcprototype> - <funcdef>Visual *<function>XDefaultVisual</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultVisual</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultVisual</primary></indexterm> -Both return the default visual type for the specified screen. -For further information about visual types, -see <link linkend="Visual_Types">section 3.1</link>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayCells(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplaycells'> -<funcprototype> - <funcdef>int <function>XDisplayCells</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayCells</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayCells</primary></indexterm> -Both return the number of entries in the default colormap. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayPlanes(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplayplanes'> -<funcprototype> - <funcdef>int <function>XDisplayPlanes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayPlanes</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayPlanes</primary></indexterm> -Both return the depth of the root window of the specified screen. -For an explanation of depth, -see the glossary. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayString(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xdisplaystring'> -<funcprototype> - <funcdef>char *<function>XDisplayString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayString</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayString</primary></indexterm> -Both return the string that was passed to -<function>XOpenDisplay</function> -when the current display was opened. -On <acronym>POSIX</acronym>-conformant systems, -if the passed string was NULL, these return the value of -the DISPLAY environment variable when the current display was opened. -<indexterm><primary><acronym>POSIX</acronym> System Call</primary><secondary>fork</secondary></indexterm> -These are useful to applications that invoke the -<function>fork</function> -system call and want to open a new connection to the same display from the -child process as well as for printing error messages. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xlastknownrequestprocessed'> -<funcprototype> - <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XExtendedMaxRequestSize</primary></indexterm> -The -<function>XExtendedMaxRequestSize</function> -function returns zero if the specified display does not support an -extended-length protocol encoding; otherwise, -it returns the maximum request size (in 4-byte units) supported -by the server using the extended-length encoding. -The Xlib functions -<function>XDrawLines</function>, -<function>XDrawArcs</function>, -<function>XFillPolygon</function>, -<function>XChangeProperty</function>, -<function>XSetClipRectangles</function>, -and -<function>XSetRegion</function> -will use the extended-length encoding as necessary, if supported -by the server. Use of the extended-length encoding in other Xlib -functions (for example, -<function>XDrawPoints</function>, -<function>XDrawRectangles</function>, -<function>XDrawSegments</function>, -<function>XFillArcs</function>, -<function>XFillRectangles</function>, -<function>XPutImage</function>) -is permitted but not required; an Xlib implementation may choose to -split the data across multiple smaller requests instead. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis> -<funcprototype> - <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XMaxRequestSize</primary></indexterm> -The -<function>XMaxRequestSize</function> -function returns the maximum request size (in 4-byte units) supported -by the server without using an extended-length protocol encoding. -Single protocol requests to the server can be no larger than this size -unless an extended-length protocol encoding is supported by the server. -The protocol guarantees the size to be no smaller than 4096 units -(16384 bytes). -Xlib automatically breaks data up into multiple protocol requests -as necessary for the following functions: -<function>XDrawPoints</function>, -<function>XDrawRectangles</function>, -<function>XDrawSegments</function>, -<function>XFillArcs</function>, -<function>XFillRectangles</function>, -and -<function>XPutImage</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis> -<funcprototype> - <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>LastKnownRequestProcessed</primary></indexterm> -<indexterm significance="preferred"><primary>XLastKnownRequestProcessed</primary></indexterm> -Both extract the full serial number of the last request known by Xlib -to have been processed by the X server. -Xlib automatically sets this number when replies, events, and errors -are received. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -NextRequest(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xnextrequest'> -<funcprototype> - <funcdef>unsigned long <function>XNextRequest</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>NextRequest</primary></indexterm> -<indexterm significance="preferred"><primary>XNextRequest</primary></indexterm> -Both extract the full serial number that is to be used for the next -request. -Serial numbers are maintained separately for each display connection. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ProtocolVersion(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xprotocolversion'> -<funcprototype> - <funcdef>int <function>XProtocolVersion</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ProtocolVersion</primary></indexterm> -<indexterm significance="preferred"><primary>XProtocolVersion</primary></indexterm> -Both return the major version number (11) of the X protocol associated with -the connected display. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ProtocolRevision(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xprotocolrevision'> -<funcprototype> - <funcdef>int <function>XProtocolRevision</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ProtocolRevision</primary></indexterm> -<indexterm significance="preferred"><primary>XProtocolRevision</primary></indexterm> -Both return the minor protocol revision number of the X server. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -QLength(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xqlength'> -<funcprototype> - <funcdef>int <function>XQLength</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>QLength</primary></indexterm> -<indexterm significance="preferred"><primary>XQLength</primary></indexterm> -Both return the length of the event queue for the connected display. -Note that there may be more events that have not been read into -the queue yet (see -<function>XEventsQueued</function>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -RootWindow(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xrootwindow'> -<funcprototype> - <funcdef>Window <function>XRootWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm><primary>Window</primary><secondary>RootWindow</secondary></indexterm> -<indexterm significance="preferred"><primary>RootWindow</primary></indexterm> -<indexterm><primary>Window</primary><secondary>XRootWindow</secondary></indexterm> -<indexterm significance="preferred"><primary>XRootWindow</primary></indexterm> -Both return the root window. -These are useful with functions that need a drawable of a particular screen -and for creating top-level windows. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ScreenCount(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xscreencount'> -<funcprototype> - <funcdef>int <function>XScreenCount</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ScreenCount</primary></indexterm> -<indexterm significance="preferred"><primary>XScreenCount</primary></indexterm> -Both return the number of available screens. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ServerVendor(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xservervendor'> -<funcprototype> - <funcdef>char *<function>XServerVendor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ServerVendor</primary></indexterm> -<indexterm significance="preferred"><primary>XServerVendor</primary></indexterm> -Both return a pointer to a null-terminated string that provides -some identification of the owner of the X server implementation. -If the data returned by the server is in the Latin Portable Character Encoding, -then the string is in the Host Portable Character Encoding. -Otherwise, the contents of the string are implementation-dependent. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -VendorRelease(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xvendorrelease'> -<funcprototype> - <funcdef>int <function>XVendorRelease</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>VendorRelease</primary></indexterm> -<indexterm significance="preferred"><primary>XVendorRelease</primary></indexterm> -Both return a number related to a vendor's release of the X server. -</para> -</sect2> -<sect2 id="Image_Format_Functions_and_Macros"> -<title>Image Format Functions and Macros</title> -<!-- .XS --> -<!-- (SN Image Format Functions and Macros --> -<!-- .XE --> -<para> -<!-- .LP --> -Applications are required to present data to the X server -in a format that the server demands. -To help simplify applications, -most of the work required to convert the data is provided by Xlib -(see sections -<link linkend="Transferring_Images_between_Client_and_Server">8.7</link> and -<link linkend="Manipulating_Images">16.8</link>). -</para> -<para> -<!-- .LP --> -The -<structname>XPixmapFormatValues</structname> -structure provides an interface to the pixmap format information -that is returned at the time of a connection setup. -It contains: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - int depth; - int bits_per_pixel; - int scanline_pad; -} XPixmapFormatValues; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To obtain the pixmap format information for a given display, use -<function>XListPixmapFormats</function>. -<indexterm significance="preferred"><primary>XListPixmapFormats</primary></indexterm> -<!-- .sM --> -</para> -<para> -ImageByteOrder(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='ximagebyteorder'> -<funcprototype> - <funcdef>int <function>XImageByteOrder</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Cn pixmap formats that are supported by the display --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListPixmapFormats</function> -function returns an array of -<structname>XPixmapFormatValues</structname> -structures that describe the types of Z format images supported -by the specified display. -If insufficient memory is available, -<function>XListPixmapFormats</function> -returns NULL. -To free the allocated storage for the -<structname>XPixmapFormatValues</structname> -structures, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The following lists the C language macros, -their corresponding function equivalents that are for other language bindings, -and what data they both return for the specified server and screen. -These are often used by toolkits as well as by simple applications. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -ImageByteOrder(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis> -<funcprototype> - <funcdef>int <function>XImageByteOrder</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>ImageByteOrder</primary></indexterm> -<indexterm significance="preferred"><primary>XImageByteOrder</primary></indexterm> -Both specify the required byte order for images for each scanline unit in -XY format (bitmap) or for each pixel value in -Z format. -The macro or function can return either -<symbol>LSBFirst</symbol> -or -<symbol>MSBFirst</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -BitmapUnit(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xbitmapunit'> -<funcprototype> - <funcdef>int <function>XBitmapUnit</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>BitmapUnit</primary></indexterm> -<indexterm significance="preferred"><primary>XBitmapUnit</primary></indexterm> -Both return the size of a bitmap's scanline unit in bits. -The scanline is calculated in multiples of this value. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -BitmapBitOrder(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xbitmpabitorder'> -<funcprototype> - <funcdef>int <function>XBitmapBitOrder</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>BitmapBitOrder</primary></indexterm> -<indexterm significance="preferred"><primary>XBitmapBitOrder</primary></indexterm> -Within each bitmap unit, the left-most bit in the bitmap as displayed -on the screen is either the least significant or most significant bit in the -unit. -This macro or function can return -<symbol>LSBFirst</symbol> -or -<symbol>MSBFirst</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -BitmapPad(<emphasis remap='I'>display</emphasis>) -</para> -<funcsynopsis id='xbitmappad'> -<funcprototype> - <funcdef>int <function>XBitmapPad</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>BitmapPad</primary></indexterm> -<indexterm significance="preferred"><primary>XBitmapPad</primary></indexterm> -Each scanline must be padded to a multiple of bits returned -by this macro or function. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayHeight(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplayheight'> -<funcprototype> - <funcdef>int <function>XDisplayHeight</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayHeight</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayHeight</primary></indexterm> -Both return an integer that describes the height of the screen -in pixels. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayHeightMM(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplayheightmm'> -<funcprototype> - <funcdef>int <function>XDisplayHeightMM</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayHeightMM</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayHeightMM</primary></indexterm> -Both return the height of the specified screen in millimeters. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayWidth(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplaywidth'> -<funcprototype> - <funcdef>int <function>XDisplayWidth</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayWidth</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayWidth</primary></indexterm> -Both return the width of the screen in pixels. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayWidthMM(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>) -</para> -<funcsynopsis id='xdisplaywidthmm'> -<funcprototype> - <funcdef>int <function>XDisplayWidthMM</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayWidthMM</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayWidthMM</primary></indexterm> -Both return the width of the specified screen in millimeters. -</para> -</sect2> -<sect2 id="Screen_Information_Macros"> -<title>Screen Information Macros</title> -<!-- .XS --> -<!-- (SN Screen Information Macros --> -<!-- .XE --> -<para> -<!-- .LP --> -The following lists the C language macros, -their corresponding function equivalents that are for other language bindings, -and what data they both can return. -These macros or functions all take a pointer to the appropriate screen -structure. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -BlackPixelOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xblackpixelofscreen'> -<funcprototype> - <funcdef>unsigned long <function>XBlackPixelOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>BlackPixelOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XBlackPixelOfScreen</primary></indexterm> -Both return the black pixel value of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -WhitePixelOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xwhitepixelofscreen'> -<funcprototype> - <funcdef>unsigned long <function>XWhitePixelOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>WhitePixelOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XWhitePixelOfScreen</primary></indexterm> -Both return the white pixel value of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -CellsOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xcellsofscreen'> -<funcprototype> - <funcdef>int <function>XCellsOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>CellsOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XCellsOfScreen</primary></indexterm> -Both return the number of colormap cells in the default colormap -of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultColormapOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdefaultcolormapofscreen'> -<funcprototype> - <funcdef>Colormap <function>XDefaultColormapOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultColormapOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultColormapOfScreen</primary></indexterm> -Both return the default colormap of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultDepthOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdefaultdepthofscreen'> -<funcprototype> - <funcdef>int <function>XDefaultDepthOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultDepthOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultDepthOfScreen</primary></indexterm> -Both return the depth of the root window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultGCOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdefaultgcofscreen'> -<funcprototype> - <funcdef>GC <function>XDefaultGCOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultGCOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultGCOfScreen</primary></indexterm> -Both return a default graphics context (GC) of the specified screen, -which has the same depth as the root window of the screen. -The GC must never be freed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DefaultVisualOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdefaultvisualofscreen'> -<funcprototype> - <funcdef>Visual *<function>XDefaultVisualOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DefaultVisualOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDefaultVisualOfScreen</primary></indexterm> -Both return the default visual of the specified screen. -For information on visual types, -see <link linkend="Visual_Types">section 3.1</link>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DoesBackingStore(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdoesbackingstore'> -<funcprototype> - <funcdef>int <function>XDoesBackingStore</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DoesBackingStore</primary></indexterm> -<indexterm significance="preferred"><primary>XDoesBackingStore</primary></indexterm> -Both return a value indicating whether the screen supports backing -stores. -The value returned can be one of -<symbol>WhenMapped</symbol>, -<symbol>NotUseful</symbol>, -or -<symbol>Always</symbol> -(see <link linkend="Backing_Store_Attribute">section 3.2.4</link>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DoesSaveUnders(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdoessaveunders'> -<funcprototype> - <funcdef>Bool <function>XDoesSaveUnders</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DoesSaveUnders</primary></indexterm> -<indexterm significance="preferred"><primary>XDoesSaveUnders</primary></indexterm> -Both return a Boolean value indicating whether the -screen supports save unders. -If -<symbol>True</symbol>, -the screen supports save unders. -If -<symbol>False</symbol>, -the screen does not support save unders -(see <link linkend="Save_Under_Flag">section 3.2.5</link>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -DisplayOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xdisplayofscreen'> -<funcprototype> - <funcdef>Display *<function>XDisplayOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>DisplayOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XDisplayOfScreen</primary></indexterm> -Both return the display of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<indexterm significance="preferred"><primary>XScreenNumberOfScreen</primary></indexterm> -</para> -<para> -EventMaskOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xeventmaskofscreen'> -<funcprototype> - <funcdef>long <function>XEventMaskOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XScreenNumberOfScreen</function> -function returns the screen index number of the specified screen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -EventMaskOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis> -<funcprototype> - <funcdef>long <function>XEventMaskOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>EventMaskOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XEventMaskOfScreen</primary></indexterm> -Both return the event mask of the root window for the specified screen -at connection setup time. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -WidthOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xwidthofscreen'> -<funcprototype> - <funcdef>int <function>XWidthOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>WidthOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XWidthOfScreen</primary></indexterm> -Both return the width of the specified screen in pixels. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -HeightOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xheightofscreen'> -<funcprototype> - <funcdef>int <function>XHeightOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>HeightOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XHeightOfScreen</primary></indexterm> -Both return the height of the specified screen in pixels. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -WidthMMOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xwidthmmofscreen'> -<funcprototype> - <funcdef>int <function>XWidthMMOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>WidthMMOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XWidthMMOfScreen</primary></indexterm> -Both return the width of the specified screen in millimeters. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -HeightMMOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xheightmmofscreen'> -<funcprototype> - <funcdef>int <function>XHeightMMOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>HeightMMOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XHeightMMOfScreen</primary></indexterm> -Both return the height of the specified screen in millimeters. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -MaxCmapsOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xmaxcmapsofscreen'> -<funcprototype> - <funcdef>int <function>XMaxCmapsOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>MaxCmapsOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XMaxCmapsOfScreen</primary></indexterm> -Both return the maximum number of installed colormaps supported -by the specified screen -(see <link linkend="Managing_Installed_Colormaps">section 9.3</link>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -MinCmapsOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xmincmapsofscreen'> -<funcprototype> - <funcdef>int <function>XMinCmapsOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>MinCmapsOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XMinCmapsOfScreen</primary></indexterm> -Both return the minimum number of installed colormaps supported -by the specified screen -(see <link linkend="Managing_Installed_Colormaps">section 9.3</link>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -PlanesOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xplanesofscreen'> -<funcprototype> - <funcdef>int <function>XPlanesOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>PlanesOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XPlanesOfScreen</primary></indexterm> -Both return the depth of the root window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -</para> -<para> -RootWindowOfScreen(<emphasis remap='I'>screen</emphasis>) -</para> -<funcsynopsis id='xrootwindowofscreen'> -<funcprototype> - <funcdef>Window <function>XRootWindowOfScreen</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate -<type>Screen</type> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>RootWindowOfScreen</primary></indexterm> -<indexterm significance="preferred"><primary>XRootWindowOfScreen</primary></indexterm> -Both return the root window of the specified screen. -</para> -</sect2> -</sect1> -<sect1 id="Generating_a_NoOperation_Protocol_Request"> -<title>Generating a NoOperation Protocol Request</title> -<!-- .XS --> -<!-- (SN Generating a NoOperation Protocol Request --> -<!-- .XE --> -<para> -<!-- .LP --> -To execute a -<systemitem>NoOperation</systemitem> -protocol request, use -<function>XNoOp</function>. -<indexterm significance="preferred"><primary>XNoOp</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xnoop'> -<funcprototype> - <funcdef><function>XNoOp</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term><emphasis remap='I'>display</emphasis></term> - <listitem> - <para>Specifies the connection to the X server.</para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XNoOp</function> -function sends a -<systemitem>NoOperation</systemitem> -protocol request to the X server, -thereby exercising the connection. -</para> -</sect1> -<sect1 id="Freeing_Client_Created_Data"> -<title>Freeing Client-Created Data</title> -<!-- .XS --> -<!-- (SN Freeing Client-Created Data --> -<!-- .XE --> -<para> -<!-- .LP --> -To free in-memory data that was created by an Xlib function, use -<function>XFree</function>. -<indexterm significance="preferred"><primary>XFree</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xfree'> -<funcprototype> - <funcdef>XFree</funcdef> - <paramdef>void<parameter> *data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the data that is to be freed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFree</function> -function is a general-purpose Xlib routine that frees the specified data. -You must use it to free any objects that were allocated by Xlib, -unless an alternate function is explicitly specified for the object. -A NULL pointer cannot be passed to this function. -</para> -</sect1> -<sect1 id="Closing_the_Display"> -<title>Closing the Display</title> -<!-- .XS --> -<!-- (SN Closing the Display --> -<!-- .XE --> -<para> -<!-- .LP --> -To close a display or disconnect from the X server, use -<function>XCloseDisplay</function>. -<indexterm significance="preferred"><primary>XCloseDisplay</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sM --> -</para> -<funcsynopsis id='xclosedisplay'> -<funcprototype> - <funcdef>XCloseDisplay</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCloseDisplay</function> -function closes the connection to the X server for the display specified in the -<type>Display</type> -structure and destroys all windows, resource IDs -(<type>Window</type>, -<type>Font</type>, -<type>Pixmap</type>, -<type>Colormap</type>, -<type>Cursor</type>, -and -<type>GContext</type>), -or other resources that the client has created -on this display, unless the close-down mode of the resource has been changed -(see -<function>XSetCloseDownMode</function>). -Therefore, these windows, resource IDs, and other resources should never be -referenced again or an error will be generated. -Before exiting, you should call -<function>XCloseDisplay</function> -explicitly so that any pending errors are reported as -<function>XCloseDisplay</function> -performs a final -<function>XSync</function> -operation. -<indexterm><primary>Resource IDs</primary></indexterm> -<indexterm><primary>XCloseDisplay</primary></indexterm> -</para> -<para> -<!-- .LP --> -<function>XCloseDisplay</function> -can generate a -<errorname>BadGC</errorname> -error. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -Xlib provides a function to permit the resources owned by a client -to survive after the client's connection is closed. -To change a client's close-down mode, use -<function>XSetCloseDownMode</function>. -<indexterm significance="preferred"><primary>XSetCloseDownMode</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xsetclosedownmode'> -<funcprototype> - <funcdef>XSetCloseDownMode</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> close_mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>close_mode</emphasis> - </term> - <listitem> - <para> -Specifies the client close-down mode. -You can pass -<symbol>DestroyAll</symbol>, -<symbol>RetainPermanent</symbol>, -or -<symbol>RetainTemporary</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetCloseDownMode</function> -defines what will happen to the client's resources at connection close. -A connection starts in -<symbol>DestroyAll</symbol> -mode. -For information on what happens to the client's resources when the -close_mode argument is -<symbol>RetainPermanent</symbol> -or -<symbol>RetainTemporary</symbol>, -see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>. -</para> -<para> -<!-- .LP --> -<function>XSetCloseDownMode</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -</sect1> -<sect1 id="Using_X_Server_Connection_Close_Operations_"> -<title>Using X Server Connection Close Operations </title> -<!-- .XS --> -<!-- (SN Using X Server Connection Close Operations --> -<!-- .XE --> -<para> -<!-- .LP --> -When the X server's connection to a client is closed -either by an explicit call to -<function>XCloseDisplay</function> -or by a process that exits, the X server performs the following -automatic operations: -</para> -<itemizedlist> - <listitem> - <para> -It disowns all selections owned by the client -(see -<function>XSetSelectionOwner</function>). - </para> - </listitem> - <listitem> - <para> -It performs an -<function>XUngrabPointer</function> -and -<function>XUngrabKeyboard</function> -if the client has actively grabbed the pointer -or the keyboard. - </para> - </listitem> - <listitem> - <para> -It performs an -<function>XUngrabServer</function> -if the client has grabbed the server. - </para> - </listitem> - <listitem> - <para> -It releases all passive grabs made by the client. - </para> - </listitem> - <listitem> - <para> -It marks all resources (including colormap entries) allocated -by the client either as permanent or temporary, -depending on whether the close-down mode is -<symbol>RetainPermanent</symbol> -or -<symbol>RetainTemporary</symbol>. -However, this does not prevent other client applications from explicitly -destroying the resources (see -<function>XSetCloseDownMode</function>). - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -When the close-down mode is -<symbol>DestroyAll</symbol>, -the X server destroys all of a client's resources as follows: -</para> -<itemizedlist> - <listitem> - <para> -It examines each window in the client's save-set to determine if it is an inferior -(subwindow) of a window created by the client. -(The save-set is a list of other clients' windows -that are referred to as save-set windows.) -If so, the X server reparents the save-set window to the closest ancestor so -that the save-set window is not an inferior of a window created by the client. -The reparenting leaves unchanged the absolute coordinates (with respect to -the root window) of the upper-left outer corner of the save-set -window. - </para> - </listitem> - <listitem> - <para> -It performs a -<systemitem>MapWindow</systemitem> -request on the save-set window if the save-set window is unmapped. -The X server does this even if the save-set window was not an inferior of -a window created by the client. - </para> - </listitem> - <listitem> - <para> -It destroys all windows created by the client. - </para> - </listitem> - <listitem> - <para> -It performs the appropriate free request on each nonwindow resource created by -the client in the server (for example, -<type>Font</type>, -<type>Pixmap</type>, -<type>Cursor</type>, -<type>Colormap</type>, -and -<type>GContext</type>). - </para> - </listitem> - <listitem> - <para> -It frees all colors and colormap entries allocated by a client application. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Additional processing occurs when the last connection to the X server closes. -An X server goes through a cycle of having no connections and having some -connections. -When the last connection to the X server closes as a result of a connection -closing with the close_mode of -<symbol>DestroyAll</symbol>, -the X server does the following: -</para> -<itemizedlist> - <listitem> - <para> -It resets its state as if it had just been -started. -The X server begins by destroying all lingering resources from -clients that have terminated in -<symbol>RetainPermanent</symbol> -or -<symbol>RetainTemporary</symbol> -mode. - </para> - </listitem> - <listitem> - <para> -It deletes all but the predefined atom identifiers. - </para> - </listitem> - <listitem> - <para> -It deletes all properties on all root windows -(see <link linkend="Properties_and_Atoms">section 4.3</link>). - </para> - </listitem> - <listitem> - <para> -It resets all device maps and attributes -(for example, key click, bell volume, and acceleration) -as well as the access control list. - </para> - </listitem> - <listitem> - <para> -It restores the standard root tiles and cursors. - </para> - </listitem> - <listitem> - <para> -It restores the default font path. - </para> - </listitem> - <listitem> - <para> -It restores the input focus to state -<symbol>PointerRoot</symbol>. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -However, the X server does not reset if you close a connection with a close-down -mode set to -<symbol>RetainPermanent</symbol> -or -<symbol>RetainTemporary</symbol>. -</para> -</sect1> -<sect1 id="Using_Xlib_with_Threads"> -<title>Using Xlib with Threads</title> -<!-- .XS --> -<!-- (SN Using Xlib with Threads --> -<!-- .XE --> -<para> -<!-- .LP --> -On systems that have threads, support may be provided to permit -multiple threads to use Xlib concurrently. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To initialize support for concurrent threads, use -<function>XInitThreads</function>. -<indexterm significance="preferred"><primary>XInitThreads</primary></indexterm> -<!-- .sM --> -</para> -<para>Status XInitThreads();</para> -<!-- .FN --> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInitThreads</function> -function initializes Xlib support for concurrent threads. -This function must be the first Xlib function a -multi-threaded program calls, and it must complete -before any other Xlib call is made. -This function returns a nonzero status if initialization was -successful; otherwise, it returns zero. -On systems that do not support threads, this function always returns zero. -</para> -<para> -<!-- .LP --> -It is only necessary to call this function if multiple threads -might use Xlib concurrently. If all calls to Xlib functions -are protected by some other access mechanism (for example, -a mutual exclusion lock in a toolkit or through explicit client -programming), Xlib thread initialization is not required. -It is recommended that single-threaded programs not call this function. - -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To lock a display across several Xlib calls, use -<function>XLockDisplay</function>. -<indexterm significance="preferred"><primary>XLockDisplay</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xlockdisplay'> -<funcprototype> - <funcdef>XLockDisplay</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLockDisplay</function> -function locks out all other threads from using the specified display. -Other threads attempting to use the display will block until -the display is unlocked by this thread. -Nested calls to -<function>XLockDisplay</function> -work correctly; the display will not actually be unlocked until -<function>XUnlockDisplay</function> -has been called the same number of times as -<function>XLockDisplay</function>. -This function has no effect unless Xlib was successfully initialized -for threads using -<function>XInitThreads</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To unlock a display, use -<function>XUnlockDisplay</function>. -<indexterm significance="preferred"><primary>XUnlockDisplay</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xunlockdisplay'> -<funcprototype> - <funcdef>XUnlockDisplay</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnlockDisplay</function> -function allows other threads to use the specified display again. -Any threads that have blocked on the display are allowed to continue. -Nested locking works correctly; if -<function>XLockDisplay</function> -has been called multiple times by a thread, then -<function>XUnlockDisplay</function> -must be called an equal number of times before the display is -actually unlocked. -This function has no effect unless Xlib was successfully initialized -for threads using -<function>XInitThreads</function>. -</para> -</sect1> -<sect1 id="Using_Internal_Connections"> -<title>Using Internal Connections</title> -<!-- .XS --> -<!-- (SN Using Internal Connections --> -<!-- .XE --> -<para> -<!-- .LP --> -In addition to the connection to the X server, an Xlib implementation -may require connections to other kinds of servers (for example, to -input method servers as described in -<link linkend="locales_and_internationalized_text_functions">chapter 13</link>). -Toolkits and clients -that use multiple displays, or that use displays in combination with -other inputs, need to obtain these additional connections to correctly -block until input is available and need to process that input -when it is available. Simple clients that use a single display and -block for input in an Xlib event function do not need to use these -facilities. -</para> -<para> -<!-- .LP --> -To track internal connections for a display, use -<function>XAddConnectionWatch</function>. -</para> -<funcsynopsis id='xconnectionwatch'> -<funcprototype> - <funcdef>type void XConnectionWatchProc</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>int<parameter> fd</parameter></paramdef> - <paramdef>Bool<parameter> opening</parameter></paramdef> - <paramdef>XPointer<parameter> *watch_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<funcsynopsis id='xaddconnectionwatch'> -<funcprototype> - <funcdef>Status XAddConnectionWatch</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XWatchProc<parameter> procedure</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>procedure</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to be called. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAddConnectionWatch</function> -function registers a procedure to be called each time Xlib opens or closes an -internal connection for the specified display. The procedure is passed the -display, the specified client_data, the file descriptor for the connection, -a Boolean indicating whether the connection is being opened or closed, and a -pointer to a location for private watch data. If opening is -<symbol>True</symbol>, -the procedure can store a pointer to private data in the location pointed -to by watch_data; -when the procedure is later called for this same connection and opening is -<symbol>False</symbol>, -the location pointed to by watch_data will hold this same private data pointer. -</para> -<para> -<!-- .LP --> -This function can be called at any time after a display is opened. -If internal connections already exist, the registered procedure will -immediately be called for each of them, before -<function>XAddConnectionWatch</function> -returns. -<function>XAddConnectionWatch</function> -returns a nonzero status if the procedure is successfully registered; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -The registered procedure should not call any Xlib functions. -If the procedure directly or indirectly causes the state of internal -connections or watch procedures to change, the result is not defined. -If Xlib has been initialized for threads, the procedure is called with -the display locked and the result of a call by the procedure to any -Xlib function that locks the display is not defined unless the executing -thread has externally locked the display using -<function>XLockDisplay</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To stop tracking internal connections for a display, use -<function>XRemoveConnectionWatch</function>. -<indexterm significance="preferred"><primary>XRemoveConnectionWatch</primary></indexterm> -<!-- .sM --> -</para> -<para> -() -</para> -<funcsynopsis id='xremoveconnectionwatch'> -<funcprototype> - <funcdef>Status <function>XRemoveConnectionWatch</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XWatchProc<parameter> procedure</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>procedure</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to be called. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRemoveConnectionWatch</function> -function removes a previously registered connection watch procedure. -The client_data must match the client_data used when the procedure -was initially registered. - -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To process input on an internal connection, use -<function>XProcessInternalConnection</function>. -<indexterm significance="preferred"><primary>XProcessInternalConnection</primary></indexterm> -<!-- .sM --> -</para> -<para> -() -</para> -<funcsynopsis id='xprocessinternalconnection'> -<funcprototype> - <funcdef>void <function>XProcessInternalConnection</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> fd</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fd</emphasis> - </term> - <listitem> - <para> -Specifies the file descriptor. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XProcessInternalConnection</function> -function processes input available on an internal connection. -This function should be called for an internal connection only -after an operating system facility (for example, -<function>select</function> -or -<function>poll</function>) -has indicated that input is available; otherwise, -the effect is not defined. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain all of the current internal connections for a display, use -<function>XInternalConnectionNumbers</function>. -<indexterm significance="preferred"><primary>XInternalConnectionNumbers</primary></indexterm> -<!-- .sM --> -</para> -<para> -() -</para> -<funcsynopsis id='xinternalconnectionnumbers'> -<funcprototype> - <funcdef>Status <function>XInternalConnectionNumbers</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int **<parameter> fd</parameter></paramdef> - <paramdef>int *<parameter> count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fd_return</emphasis> - </term> - <listitem> - <para> -Returns the file descriptors. -<!-- .ds Cn file descriptors --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInternalConnectionNumbers</function> -function returns a list of the file descriptors for all internal -connections currently open for the specified display. -When the allocated list is no longer needed, -free it by using -<function>XFree</function>. -This functions returns a nonzero status if the list is successfully allocated; -otherwise, it returns zero. -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="display_functions">
+<title>Display Functions</title>
+<para>
+Before your program can use a display, you must establish a connection
+to the X server.
+Once you have established a connection,
+you then can use the Xlib macros and functions discussed in this chapter
+to return information about the display.
+This chapter discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Open (connect to) the display
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtain information about the display, image formats, or screens
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Generate a
+<systemitem>NoOperation</systemitem>
+protocol request
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Free client-created data
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Close (disconnect from) a display
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use X Server connection close operations
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use Xlib with threads
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use internal connections
+ </para>
+ </listitem>
+</itemizedlist>
+<sect1 id="Opening_the_Display">
+<title>Opening the Display</title>
+<!-- .XS -->
+<!-- (SN Opening the Display -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To open a connection to the X server that controls a display, use
+<function>XOpenDisplay</function>.
+<indexterm significance="preferred"><primary>XOpenDisplay</primary></indexterm>
+</para>
+<funcsynopsis id='xopendisplay'>
+<funcprototype>
+ <funcdef>Display *<function>XOpenDisplay</function></funcdef>
+ <paramdef>char *<parameter>display_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hardware display name, which determines the display
+and communications domain to be used.
+On a <acronym>POSIX</acronym>-conformant system, if the display_name is NULL,
+it defaults to the value of the DISPLAY environment variable.
+<indexterm><primary>Environment</primary><secondary>DISPLAY</secondary></indexterm>
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The encoding and interpretation of the display name are
+implementation-dependent.
+Strings in the Host Portable Character Encoding are supported;
+support for other characters is implementation-dependent.
+On <acronym>POSIX</acronym>-conformant systems,
+the display name or DISPLAY environment variable can be a string in the format:
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA 1i -->
+<!-- .ta 1i -->
+ <emphasis remap='I'>protocol</emphasis>/<emphasis remap='I'>hostname</emphasis>:<emphasis remap='I'>number</emphasis>.<emphasis remap='I'>screen_number</emphasis>
+</literallayout>
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>protocol</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a protocol family or an alias for a protocol family. Supported
+protocol families are implementation dependent. The protocol entry is
+optional. If protocol is not specified, the / separating protocol and
+hostname must also not be specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hostname</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the host machine on which the display is physically
+attached.
+You follow the hostname with either a single colon (:) or a double colon (::).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of the display server on that host machine.
+You may optionally follow this display number with a period (.).
+A single <acronym>CPU</acronym> can have more than one display.
+Multiple displays are usually numbered starting with zero.
+<indexterm><primary>Screen</primary></indexterm>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen to be used on that server.
+Multiple screens can be controlled by a single X server.
+The screen_number sets an internal variable that can be accessed by
+using the
+<function>DefaultScreen</function>
+macro or the
+<function>XDefaultScreen</function>
+function if you are using languages other than C
+(see <link linkend="Display_Macros_">section 2.2.1</link>).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+For example, the following would specify screen 1 of display 0 on the
+machine named ``dual-headed'':
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+dual-headed:0.1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XOpenDisplay</function>
+function returns a
+<type>Display</type>
+structure that serves as the
+connection to the X server and that contains all the information
+about that X server.
+<function>XOpenDisplay</function>
+connects your application to the X server through <acronym>TCP</acronym>
+or DECnet communications protocols,
+or through some local inter-process communication protocol.
+<indexterm><primary>Protocol</primary><secondary><acronym>TCP</acronym></secondary></indexterm>
+<indexterm><primary>Protocol</primary><secondary>DECnet</secondary></indexterm>
+If the protocol is specified as "tcp", "inet", or "inet6", or
+if no protocol is specified and the hostname is a host machine name and a single colon (:)
+separates the hostname and display number,
+<function>XOpenDisplay</function>
+connects using <acronym>TCP</acronym> streams. (If the protocol is specified as "inet", <acronym>TCP</acronym> over
+IPv4 is used. If the protocol is specified as "inet6", <acronym>TCP</acronym> over IPv6 is used.
+Otherwise, the implementation determines which <acronym>IP</acronym> version is used.)
+If the hostname and protocol are both not specified,
+Xlib uses whatever it believes is the fastest transport.
+If the hostname is a host machine name and a double colon (::)
+separates the hostname and display number,
+<function>XOpenDisplay</function>
+connects using DECnet.
+A single X server can support any or all of these transport mechanisms
+simultaneously.
+A particular Xlib implementation can support many more of these transport
+mechanisms.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Display</primary></indexterm>
+If successful,
+<function>XOpenDisplay</function>
+returns a pointer to a
+<type>Display</type>
+structure,
+which is defined in
+<filename class="headerfile"><X11/Xlib.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+If
+<function>XOpenDisplay</function>
+does not succeed, it returns NULL.
+After a successful call to
+<function>XOpenDisplay</function>,
+all of the screens in the display can be used by the client.
+The screen number specified in the display_name argument is returned
+by the
+<function>DefaultScreen</function>
+macro (or the
+<function>XDefaultScreen</function>
+function).
+You can access elements of the
+<type>Display</type>
+and
+<type>Screen</type>
+structures only by using the information macros or functions.
+For information about using macros and functions to obtain information from
+the
+<type>Display</type>
+structure,
+see <link linkend="Display_Macros_">section 2.2.1</link>.
+</para>
+<para>
+<!-- .LP -->
+X servers may implement various types of access control mechanisms
+(see <link linkend="Controlling_Host_Access">section 9.8</link>).
+</para>
+</sect1>
+<sect1 id="Obtaining_Information_about_the_Display_Image_Formats_or_Screens">
+<title>Obtaining Information about the Display, Image Formats, or Screens</title>
+<!-- .XS -->
+<!-- (SN Obtaining Information about the Display, Image Formats, or Screens -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The Xlib library provides a number of useful macros
+and corresponding functions that return data from the
+<type>Display</type>
+structure.
+The macros are used for C programming,
+and their corresponding function equivalents are for other language bindings.
+This section discusses the:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Display macros
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Image format functions and macros
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Screen information macros
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<indexterm ><primary>Display</primary><secondary>data structure</secondary></indexterm>
+All other members of the
+<type>Display</type>
+structure (that is, those for which no macros are defined) are private to Xlib
+and must not be used.
+Applications must never directly modify or inspect these private members of the
+<type>Display</type>
+structure.
+<!-- .NT Note -->
+The
+<function>XDisplayWidth</function>,
+<function>XDisplayHeight</function>,
+<function>XDisplayCells</function>,
+<function>XDisplayPlanes</function>,
+<function>XDisplayWidthMM</function>,
+and
+<function>XDisplayHeightMM</function>
+functions in the next sections are misnamed.
+These functions really should be named Screen<emphasis remap='I'>whatever</emphasis>
+and XScreen<emphasis remap='I'>whatever</emphasis>, not Display<emphasis remap='I'>whatever</emphasis> or XDisplay<emphasis remap='I'>whatever</emphasis>.
+Our apologies for the resulting confusion.
+<!-- .NE -->
+</para>
+<sect2 id="Display_Macros_">
+<title>Display Macros </title>
+<!-- .XS -->
+<!-- (SN Display Macros -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Applications should not directly modify any part of the
+<type>Display</type>
+and
+<type>Screen</type>
+structures.
+The members should be considered read-only,
+although they may change as the result of other operations on the display.
+</para>
+<para>
+<!-- .LP -->
+The following lists the C language macros,
+their corresponding function equivalents that are for other language bindings,
+and what data both can return.
+</para>
+<para>AllPlanes()</para>
+<para>XAllPlanes()</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>AllPlanes</primary></indexterm>
+<indexterm significance="preferred"><primary>XAllPlanes</primary></indexterm>
+Both return a value with all bits set to 1 suitable for use in a plane argument to
+a procedure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Both
+<function>BlackPixel</function>
+and
+<function>WhitePixel</function>
+can be used in implementing a monochrome application.
+These pixel values are for permanently allocated entries in the default
+colormap.
+The actual <acronym>RGB</acronym> (red, green, and blue) values are settable on some screens
+and, in any case, may not actually be black or white.
+The names are intended to convey the expected relative intensity of the colors.
+<!-- .sM -->
+</para>
+<para>
+BlackPixel(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xblackpixel'>
+<funcprototype>
+ <funcdef>unsigned long <function>XBlackPixel</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>BlackPixel</primary></indexterm>
+<indexterm significance="preferred"><primary>XBlackPixel</primary></indexterm>
+Both return the black pixel value for the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+WhitePixel(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xwhitepixel'>
+<funcprototype>
+ <funcdef>unsigned long <function>XWhitePixel</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>WhitePixel</primary></indexterm>
+<indexterm significance="preferred"><primary>XWhitePixel</primary></indexterm>
+Both return the white pixel value for the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ConnectionNumber(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xconnectionnumber'>
+<funcprototype>
+ <funcdef>int <function>XConnectionNumber</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ConnectionNumber</primary></indexterm>
+<indexterm significance="preferred"><primary>XConnectionNumber</primary></indexterm>
+Both return a connection number for the specified display.
+On a <acronym>POSIX</acronym>-conformant system,
+this is the file descriptor of the connection.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultColormap(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdefaultcolormap'>
+<funcprototype>
+ <funcdef>Colormap <function>XDefaultColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultColormap</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultColormap</primary></indexterm>
+Both return the default colormap ID for allocation on the specified screen.
+Most routine allocations of color should be made out of this colormap.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultDepth(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdefaultdepth'>
+<funcprototype>
+ <funcdef>int <function>XDefaultDepth</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultDepth</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultDepth</primary></indexterm>
+Both return the depth (number of planes) of the default root window for the
+specified screen.
+Other depths may also be supported on this screen (see
+<function>XMatchVisualInfo</function>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm significance="preferred"><primary>XListDepths</primary></indexterm>
+To determine the number of depths that are available on a given screen, use
+<function>XListDepths</function>.
+<!-- .sM -->
+</para>
+<para>
+DefaultGC(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdefaultgc'>
+<funcprototype>
+ <funcdef>GC <function>XDefaultGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+<!-- .ds Cn depths -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListDepths</function>
+function returns the array of depths
+that are available on the specified screen.
+If the specified screen_number is valid and sufficient memory for the array
+can be allocated,
+<function>XListDepths</function>
+sets count_return to the number of available depths.
+Otherwise, it does not set count_return and returns NULL.
+To release the memory allocated for the array of depths, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultGC(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>GC <function>XDefaultGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultGC</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultGC</primary></indexterm>
+Both return the default graphics context for the root window of the
+specified screen.
+This GC is created for the convenience of simple applications
+and contains the default GC components with the foreground and
+background pixel values initialized to the black and white
+pixels for the screen, respectively.
+You can modify its contents freely because it is not used in any Xlib
+function.
+This GC should never be freed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultRootWindow(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xdefaultrootwindow'>
+<funcprototype>
+ <funcdef>Window <function>XDefaultRootWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultRootWindow</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultRootWindow</primary></indexterm>
+Both return the root window for the default screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultScreenOfDisplay(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xdefaultscreenofdisplay'>
+<funcprototype>
+ <funcdef>Screen *<function>XDefaultScreenOfDisplay</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultScreenOfDisplay</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultScreenOfDisplay</primary></indexterm>
+Both return a pointer to the default screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ScreenOfDisplay(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xscreenofdisplay'>
+<funcprototype>
+ <funcdef>Screen *<function>XScreenOfDisplay</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ScreenOfDisplay</primary></indexterm>
+<indexterm significance="preferred"><primary>XScreenOfDisplay</primary></indexterm>
+Both return a pointer to the indicated screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultScreen(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xdefaultscreen'>
+<funcprototype>
+ <funcdef>int <function>XDefaultScreen</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultScreen</primary></indexterm>
+Both return the default screen number referenced by the
+<function>XOpenDisplay</function>
+function.
+This macro or function should be used to retrieve the screen number
+in applications that will use only a single screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultVisual(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdefaultvisual'>
+<funcprototype>
+ <funcdef>Visual *<function>XDefaultVisual</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultVisual</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultVisual</primary></indexterm>
+Both return the default visual type for the specified screen.
+For further information about visual types,
+see <link linkend="Visual_Types">section 3.1</link>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayCells(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplaycells'>
+<funcprototype>
+ <funcdef>int <function>XDisplayCells</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayCells</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayCells</primary></indexterm>
+Both return the number of entries in the default colormap.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayPlanes(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplayplanes'>
+<funcprototype>
+ <funcdef>int <function>XDisplayPlanes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayPlanes</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayPlanes</primary></indexterm>
+Both return the depth of the root window of the specified screen.
+For an explanation of depth,
+see the glossary.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayString(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xdisplaystring'>
+<funcprototype>
+ <funcdef>char *<function>XDisplayString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayString</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayString</primary></indexterm>
+Both return the string that was passed to
+<function>XOpenDisplay</function>
+when the current display was opened.
+On <acronym>POSIX</acronym>-conformant systems,
+if the passed string was NULL, these return the value of
+the DISPLAY environment variable when the current display was opened.
+<indexterm><primary><acronym>POSIX</acronym> System Call</primary><secondary>fork</secondary></indexterm>
+These are useful to applications that invoke the
+<function>fork</function>
+system call and want to open a new connection to the same display from the
+child process as well as for printing error messages.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xlastknownrequestprocessed'>
+<funcprototype>
+ <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XExtendedMaxRequestSize</primary></indexterm>
+The
+<function>XExtendedMaxRequestSize</function>
+function returns zero if the specified display does not support an
+extended-length protocol encoding; otherwise,
+it returns the maximum request size (in 4-byte units) supported
+by the server using the extended-length encoding.
+The Xlib functions
+<function>XDrawLines</function>,
+<function>XDrawArcs</function>,
+<function>XFillPolygon</function>,
+<function>XChangeProperty</function>,
+<function>XSetClipRectangles</function>,
+and
+<function>XSetRegion</function>
+will use the extended-length encoding as necessary, if supported
+by the server. Use of the extended-length encoding in other Xlib
+functions (for example,
+<function>XDrawPoints</function>,
+<function>XDrawRectangles</function>,
+<function>XDrawSegments</function>,
+<function>XFillArcs</function>,
+<function>XFillRectangles</function>,
+<function>XPutImage</function>)
+is permitted but not required; an Xlib implementation may choose to
+split the data across multiple smaller requests instead.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XMaxRequestSize</primary></indexterm>
+The
+<function>XMaxRequestSize</function>
+function returns the maximum request size (in 4-byte units) supported
+by the server without using an extended-length protocol encoding.
+Single protocol requests to the server can be no larger than this size
+unless an extended-length protocol encoding is supported by the server.
+The protocol guarantees the size to be no smaller than 4096 units
+(16384 bytes).
+Xlib automatically breaks data up into multiple protocol requests
+as necessary for the following functions:
+<function>XDrawPoints</function>,
+<function>XDrawRectangles</function>,
+<function>XDrawSegments</function>,
+<function>XFillArcs</function>,
+<function>XFillRectangles</function>,
+and
+<function>XPutImage</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+LastKnownRequestProcessed(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>unsigned long <function>XLastKnownRequestProcessed</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>LastKnownRequestProcessed</primary></indexterm>
+<indexterm significance="preferred"><primary>XLastKnownRequestProcessed</primary></indexterm>
+Both extract the full serial number of the last request known by Xlib
+to have been processed by the X server.
+Xlib automatically sets this number when replies, events, and errors
+are received.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+NextRequest(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xnextrequest'>
+<funcprototype>
+ <funcdef>unsigned long <function>XNextRequest</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>NextRequest</primary></indexterm>
+<indexterm significance="preferred"><primary>XNextRequest</primary></indexterm>
+Both extract the full serial number that is to be used for the next
+request.
+Serial numbers are maintained separately for each display connection.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ProtocolVersion(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xprotocolversion'>
+<funcprototype>
+ <funcdef>int <function>XProtocolVersion</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ProtocolVersion</primary></indexterm>
+<indexterm significance="preferred"><primary>XProtocolVersion</primary></indexterm>
+Both return the major version number (11) of the X protocol associated with
+the connected display.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ProtocolRevision(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xprotocolrevision'>
+<funcprototype>
+ <funcdef>int <function>XProtocolRevision</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ProtocolRevision</primary></indexterm>
+<indexterm significance="preferred"><primary>XProtocolRevision</primary></indexterm>
+Both return the minor protocol revision number of the X server.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+QLength(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xqlength'>
+<funcprototype>
+ <funcdef>int <function>XQLength</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>QLength</primary></indexterm>
+<indexterm significance="preferred"><primary>XQLength</primary></indexterm>
+Both return the length of the event queue for the connected display.
+Note that there may be more events that have not been read into
+the queue yet (see
+<function>XEventsQueued</function>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+RootWindow(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xrootwindow'>
+<funcprototype>
+ <funcdef>Window <function>XRootWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm><primary>Window</primary><secondary>RootWindow</secondary></indexterm>
+<indexterm significance="preferred"><primary>RootWindow</primary></indexterm>
+<indexterm><primary>Window</primary><secondary>XRootWindow</secondary></indexterm>
+<indexterm significance="preferred"><primary>XRootWindow</primary></indexterm>
+Both return the root window.
+These are useful with functions that need a drawable of a particular screen
+and for creating top-level windows.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ScreenCount(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xscreencount'>
+<funcprototype>
+ <funcdef>int <function>XScreenCount</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ScreenCount</primary></indexterm>
+<indexterm significance="preferred"><primary>XScreenCount</primary></indexterm>
+Both return the number of available screens.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ServerVendor(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xservervendor'>
+<funcprototype>
+ <funcdef>char *<function>XServerVendor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ServerVendor</primary></indexterm>
+<indexterm significance="preferred"><primary>XServerVendor</primary></indexterm>
+Both return a pointer to a null-terminated string that provides
+some identification of the owner of the X server implementation.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the string is in the Host Portable Character Encoding.
+Otherwise, the contents of the string are implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+VendorRelease(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xvendorrelease'>
+<funcprototype>
+ <funcdef>int <function>XVendorRelease</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>VendorRelease</primary></indexterm>
+<indexterm significance="preferred"><primary>XVendorRelease</primary></indexterm>
+Both return a number related to a vendor's release of the X server.
+</para>
+</sect2>
+<sect2 id="Image_Format_Functions_and_Macros">
+<title>Image Format Functions and Macros</title>
+<!-- .XS -->
+<!-- (SN Image Format Functions and Macros -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Applications are required to present data to the X server
+in a format that the server demands.
+To help simplify applications,
+most of the work required to convert the data is provided by Xlib
+(see sections
+<link linkend="Transferring_Images_between_Client_and_Server">8.7</link> and
+<link linkend="Manipulating_Images">16.8</link>).
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XPixmapFormatValues</structname>
+structure provides an interface to the pixmap format information
+that is returned at the time of a connection setup.
+It contains:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int depth;
+ int bits_per_pixel;
+ int scanline_pad;
+} XPixmapFormatValues;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To obtain the pixmap format information for a given display, use
+<function>XListPixmapFormats</function>.
+<indexterm significance="preferred"><primary>XListPixmapFormats</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+ImageByteOrder(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='ximagebyteorder'>
+<funcprototype>
+ <funcdef>int <function>XImageByteOrder</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Cn pixmap formats that are supported by the display -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListPixmapFormats</function>
+function returns an array of
+<structname>XPixmapFormatValues</structname>
+structures that describe the types of Z format images supported
+by the specified display.
+If insufficient memory is available,
+<function>XListPixmapFormats</function>
+returns NULL.
+To free the allocated storage for the
+<structname>XPixmapFormatValues</structname>
+structures, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The following lists the C language macros,
+their corresponding function equivalents that are for other language bindings,
+and what data they both return for the specified server and screen.
+These are often used by toolkits as well as by simple applications.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+ImageByteOrder(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>int <function>XImageByteOrder</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>ImageByteOrder</primary></indexterm>
+<indexterm significance="preferred"><primary>XImageByteOrder</primary></indexterm>
+Both specify the required byte order for images for each scanline unit in
+XY format (bitmap) or for each pixel value in
+Z format.
+The macro or function can return either
+<symbol>LSBFirst</symbol>
+or
+<symbol>MSBFirst</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+BitmapUnit(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xbitmapunit'>
+<funcprototype>
+ <funcdef>int <function>XBitmapUnit</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>BitmapUnit</primary></indexterm>
+<indexterm significance="preferred"><primary>XBitmapUnit</primary></indexterm>
+Both return the size of a bitmap's scanline unit in bits.
+The scanline is calculated in multiples of this value.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+BitmapBitOrder(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xbitmpabitorder'>
+<funcprototype>
+ <funcdef>int <function>XBitmapBitOrder</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>BitmapBitOrder</primary></indexterm>
+<indexterm significance="preferred"><primary>XBitmapBitOrder</primary></indexterm>
+Within each bitmap unit, the left-most bit in the bitmap as displayed
+on the screen is either the least significant or most significant bit in the
+unit.
+This macro or function can return
+<symbol>LSBFirst</symbol>
+or
+<symbol>MSBFirst</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+BitmapPad(<emphasis remap='I'>display</emphasis>)
+</para>
+<funcsynopsis id='xbitmappad'>
+<funcprototype>
+ <funcdef>int <function>XBitmapPad</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>BitmapPad</primary></indexterm>
+<indexterm significance="preferred"><primary>XBitmapPad</primary></indexterm>
+Each scanline must be padded to a multiple of bits returned
+by this macro or function.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayHeight(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplayheight'>
+<funcprototype>
+ <funcdef>int <function>XDisplayHeight</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayHeight</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayHeight</primary></indexterm>
+Both return an integer that describes the height of the screen
+in pixels.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayHeightMM(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplayheightmm'>
+<funcprototype>
+ <funcdef>int <function>XDisplayHeightMM</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayHeightMM</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayHeightMM</primary></indexterm>
+Both return the height of the specified screen in millimeters.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayWidth(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplaywidth'>
+<funcprototype>
+ <funcdef>int <function>XDisplayWidth</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayWidth</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayWidth</primary></indexterm>
+Both return the width of the screen in pixels.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayWidthMM(<emphasis remap='I'>display</emphasis>, <emphasis remap='I'>screen_number</emphasis>)
+</para>
+<funcsynopsis id='xdisplaywidthmm'>
+<funcprototype>
+ <funcdef>int <function>XDisplayWidthMM</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayWidthMM</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayWidthMM</primary></indexterm>
+Both return the width of the specified screen in millimeters.
+</para>
+</sect2>
+<sect2 id="Screen_Information_Macros">
+<title>Screen Information Macros</title>
+<!-- .XS -->
+<!-- (SN Screen Information Macros -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following lists the C language macros,
+their corresponding function equivalents that are for other language bindings,
+and what data they both can return.
+These macros or functions all take a pointer to the appropriate screen
+structure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+BlackPixelOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xblackpixelofscreen'>
+<funcprototype>
+ <funcdef>unsigned long <function>XBlackPixelOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>BlackPixelOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XBlackPixelOfScreen</primary></indexterm>
+Both return the black pixel value of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+WhitePixelOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xwhitepixelofscreen'>
+<funcprototype>
+ <funcdef>unsigned long <function>XWhitePixelOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>WhitePixelOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XWhitePixelOfScreen</primary></indexterm>
+Both return the white pixel value of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+CellsOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xcellsofscreen'>
+<funcprototype>
+ <funcdef>int <function>XCellsOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>CellsOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XCellsOfScreen</primary></indexterm>
+Both return the number of colormap cells in the default colormap
+of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultColormapOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdefaultcolormapofscreen'>
+<funcprototype>
+ <funcdef>Colormap <function>XDefaultColormapOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultColormapOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultColormapOfScreen</primary></indexterm>
+Both return the default colormap of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultDepthOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdefaultdepthofscreen'>
+<funcprototype>
+ <funcdef>int <function>XDefaultDepthOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultDepthOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultDepthOfScreen</primary></indexterm>
+Both return the depth of the root window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultGCOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdefaultgcofscreen'>
+<funcprototype>
+ <funcdef>GC <function>XDefaultGCOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultGCOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultGCOfScreen</primary></indexterm>
+Both return a default graphics context (GC) of the specified screen,
+which has the same depth as the root window of the screen.
+The GC must never be freed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DefaultVisualOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdefaultvisualofscreen'>
+<funcprototype>
+ <funcdef>Visual *<function>XDefaultVisualOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DefaultVisualOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDefaultVisualOfScreen</primary></indexterm>
+Both return the default visual of the specified screen.
+For information on visual types,
+see <link linkend="Visual_Types">section 3.1</link>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DoesBackingStore(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdoesbackingstore'>
+<funcprototype>
+ <funcdef>int <function>XDoesBackingStore</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DoesBackingStore</primary></indexterm>
+<indexterm significance="preferred"><primary>XDoesBackingStore</primary></indexterm>
+Both return a value indicating whether the screen supports backing
+stores.
+The value returned can be one of
+<symbol>WhenMapped</symbol>,
+<symbol>NotUseful</symbol>,
+or
+<symbol>Always</symbol>
+(see <link linkend="Backing_Store_Attribute">section 3.2.4</link>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DoesSaveUnders(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdoessaveunders'>
+<funcprototype>
+ <funcdef>Bool <function>XDoesSaveUnders</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DoesSaveUnders</primary></indexterm>
+<indexterm significance="preferred"><primary>XDoesSaveUnders</primary></indexterm>
+Both return a Boolean value indicating whether the
+screen supports save unders.
+If
+<symbol>True</symbol>,
+the screen supports save unders.
+If
+<symbol>False</symbol>,
+the screen does not support save unders
+(see <link linkend="Save_Under_Flag">section 3.2.5</link>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+DisplayOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xdisplayofscreen'>
+<funcprototype>
+ <funcdef>Display *<function>XDisplayOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>DisplayOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XDisplayOfScreen</primary></indexterm>
+Both return the display of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<indexterm significance="preferred"><primary>XScreenNumberOfScreen</primary></indexterm>
+</para>
+<para>
+EventMaskOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xeventmaskofscreen'>
+<funcprototype>
+ <funcdef>long <function>XEventMaskOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XScreenNumberOfScreen</function>
+function returns the screen index number of the specified screen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+EventMaskOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>long <function>XEventMaskOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>EventMaskOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XEventMaskOfScreen</primary></indexterm>
+Both return the event mask of the root window for the specified screen
+at connection setup time.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+WidthOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xwidthofscreen'>
+<funcprototype>
+ <funcdef>int <function>XWidthOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>WidthOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XWidthOfScreen</primary></indexterm>
+Both return the width of the specified screen in pixels.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+HeightOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xheightofscreen'>
+<funcprototype>
+ <funcdef>int <function>XHeightOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>HeightOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XHeightOfScreen</primary></indexterm>
+Both return the height of the specified screen in pixels.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+WidthMMOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xwidthmmofscreen'>
+<funcprototype>
+ <funcdef>int <function>XWidthMMOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>WidthMMOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XWidthMMOfScreen</primary></indexterm>
+Both return the width of the specified screen in millimeters.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+HeightMMOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xheightmmofscreen'>
+<funcprototype>
+ <funcdef>int <function>XHeightMMOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>HeightMMOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XHeightMMOfScreen</primary></indexterm>
+Both return the height of the specified screen in millimeters.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+MaxCmapsOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xmaxcmapsofscreen'>
+<funcprototype>
+ <funcdef>int <function>XMaxCmapsOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>MaxCmapsOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XMaxCmapsOfScreen</primary></indexterm>
+Both return the maximum number of installed colormaps supported
+by the specified screen
+(see <link linkend="Managing_Installed_Colormaps">section 9.3</link>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+MinCmapsOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xmincmapsofscreen'>
+<funcprototype>
+ <funcdef>int <function>XMinCmapsOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>MinCmapsOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XMinCmapsOfScreen</primary></indexterm>
+Both return the minimum number of installed colormaps supported
+by the specified screen
+(see <link linkend="Managing_Installed_Colormaps">section 9.3</link>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+PlanesOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xplanesofscreen'>
+<funcprototype>
+ <funcdef>int <function>XPlanesOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>PlanesOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XPlanesOfScreen</primary></indexterm>
+Both return the depth of the root window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+</para>
+<para>
+RootWindowOfScreen(<emphasis remap='I'>screen</emphasis>)
+</para>
+<funcsynopsis id='xrootwindowofscreen'>
+<funcprototype>
+ <funcdef>Window <function>XRootWindowOfScreen</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate
+<type>Screen</type>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>RootWindowOfScreen</primary></indexterm>
+<indexterm significance="preferred"><primary>XRootWindowOfScreen</primary></indexterm>
+Both return the root window of the specified screen.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Generating_a_NoOperation_Protocol_Request">
+<title>Generating a NoOperation Protocol Request</title>
+<!-- .XS -->
+<!-- (SN Generating a NoOperation Protocol Request -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To execute a
+<systemitem>NoOperation</systemitem>
+protocol request, use
+<function>XNoOp</function>.
+<indexterm significance="preferred"><primary>XNoOp</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xnoop'>
+<funcprototype>
+ <funcdef><function>XNoOp</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term><emphasis remap='I'>display</emphasis></term>
+ <listitem>
+ <para>Specifies the connection to the X server.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XNoOp</function>
+function sends a
+<systemitem>NoOperation</systemitem>
+protocol request to the X server,
+thereby exercising the connection.
+</para>
+</sect1>
+<sect1 id="Freeing_Client_Created_Data">
+<title>Freeing Client-Created Data</title>
+<!-- .XS -->
+<!-- (SN Freeing Client-Created Data -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To free in-memory data that was created by an Xlib function, use
+<function>XFree</function>.
+<indexterm significance="preferred"><primary>XFree</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xfree'>
+<funcprototype>
+ <funcdef>XFree</funcdef>
+ <paramdef>void<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data that is to be freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFree</function>
+function is a general-purpose Xlib routine that frees the specified data.
+You must use it to free any objects that were allocated by Xlib,
+unless an alternate function is explicitly specified for the object.
+A NULL pointer cannot be passed to this function.
+</para>
+</sect1>
+<sect1 id="Closing_the_Display">
+<title>Closing the Display</title>
+<!-- .XS -->
+<!-- (SN Closing the Display -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To close a display or disconnect from the X server, use
+<function>XCloseDisplay</function>.
+<indexterm significance="preferred"><primary>XCloseDisplay</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+</para>
+<funcsynopsis id='xclosedisplay'>
+<funcprototype>
+ <funcdef>XCloseDisplay</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCloseDisplay</function>
+function closes the connection to the X server for the display specified in the
+<type>Display</type>
+structure and destroys all windows, resource IDs
+(<type>Window</type>,
+<type>Font</type>,
+<type>Pixmap</type>,
+<type>Colormap</type>,
+<type>Cursor</type>,
+and
+<type>GContext</type>),
+or other resources that the client has created
+on this display, unless the close-down mode of the resource has been changed
+(see
+<function>XSetCloseDownMode</function>).
+Therefore, these windows, resource IDs, and other resources should never be
+referenced again or an error will be generated.
+Before exiting, you should call
+<function>XCloseDisplay</function>
+explicitly so that any pending errors are reported as
+<function>XCloseDisplay</function>
+performs a final
+<function>XSync</function>
+operation.
+<indexterm><primary>Resource IDs</primary></indexterm>
+<indexterm><primary>XCloseDisplay</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<function>XCloseDisplay</function>
+can generate a
+<errorname>BadGC</errorname>
+error.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+Xlib provides a function to permit the resources owned by a client
+to survive after the client's connection is closed.
+To change a client's close-down mode, use
+<function>XSetCloseDownMode</function>.
+<indexterm significance="preferred"><primary>XSetCloseDownMode</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xsetclosedownmode'>
+<funcprototype>
+ <funcdef>XSetCloseDownMode</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> close_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>close_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the client close-down mode.
+You can pass
+<symbol>DestroyAll</symbol>,
+<symbol>RetainPermanent</symbol>,
+or
+<symbol>RetainTemporary</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetCloseDownMode</function>
+defines what will happen to the client's resources at connection close.
+A connection starts in
+<symbol>DestroyAll</symbol>
+mode.
+For information on what happens to the client's resources when the
+close_mode argument is
+<symbol>RetainPermanent</symbol>
+or
+<symbol>RetainTemporary</symbol>,
+see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetCloseDownMode</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Using_X_Server_Connection_Close_Operations_">
+<title>Using X Server Connection Close Operations </title>
+<!-- .XS -->
+<!-- (SN Using X Server Connection Close Operations -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When the X server's connection to a client is closed
+either by an explicit call to
+<function>XCloseDisplay</function>
+or by a process that exits, the X server performs the following
+automatic operations:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+It disowns all selections owned by the client
+(see
+<function>XSetSelectionOwner</function>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It performs an
+<function>XUngrabPointer</function>
+and
+<function>XUngrabKeyboard</function>
+if the client has actively grabbed the pointer
+or the keyboard.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It performs an
+<function>XUngrabServer</function>
+if the client has grabbed the server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It releases all passive grabs made by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It marks all resources (including colormap entries) allocated
+by the client either as permanent or temporary,
+depending on whether the close-down mode is
+<symbol>RetainPermanent</symbol>
+or
+<symbol>RetainTemporary</symbol>.
+However, this does not prevent other client applications from explicitly
+destroying the resources (see
+<function>XSetCloseDownMode</function>).
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+When the close-down mode is
+<symbol>DestroyAll</symbol>,
+the X server destroys all of a client's resources as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+It examines each window in the client's save-set to determine if it is an inferior
+(subwindow) of a window created by the client.
+(The save-set is a list of other clients' windows
+that are referred to as save-set windows.)
+If so, the X server reparents the save-set window to the closest ancestor so
+that the save-set window is not an inferior of a window created by the client.
+The reparenting leaves unchanged the absolute coordinates (with respect to
+the root window) of the upper-left outer corner of the save-set
+window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It performs a
+<systemitem>MapWindow</systemitem>
+request on the save-set window if the save-set window is unmapped.
+The X server does this even if the save-set window was not an inferior of
+a window created by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It destroys all windows created by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It performs the appropriate free request on each nonwindow resource created by
+the client in the server (for example,
+<type>Font</type>,
+<type>Pixmap</type>,
+<type>Cursor</type>,
+<type>Colormap</type>,
+and
+<type>GContext</type>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It frees all colors and colormap entries allocated by a client application.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Additional processing occurs when the last connection to the X server closes.
+An X server goes through a cycle of having no connections and having some
+connections.
+When the last connection to the X server closes as a result of a connection
+closing with the close_mode of
+<symbol>DestroyAll</symbol>,
+the X server does the following:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+It resets its state as if it had just been
+started.
+The X server begins by destroying all lingering resources from
+clients that have terminated in
+<symbol>RetainPermanent</symbol>
+or
+<symbol>RetainTemporary</symbol>
+mode.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It deletes all but the predefined atom identifiers.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It deletes all properties on all root windows
+(see <link linkend="Properties_and_Atoms">section 4.3</link>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It resets all device maps and attributes
+(for example, key click, bell volume, and acceleration)
+as well as the access control list.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It restores the standard root tiles and cursors.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It restores the default font path.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It restores the input focus to state
+<symbol>PointerRoot</symbol>.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+However, the X server does not reset if you close a connection with a close-down
+mode set to
+<symbol>RetainPermanent</symbol>
+or
+<symbol>RetainTemporary</symbol>.
+</para>
+</sect1>
+<sect1 id="Using_Xlib_with_Threads">
+<title>Using Xlib with Threads</title>
+<!-- .XS -->
+<!-- (SN Using Xlib with Threads -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+On systems that have threads, support may be provided to permit
+multiple threads to use Xlib concurrently.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To initialize support for concurrent threads, use
+<function>XInitThreads</function>.
+<indexterm significance="preferred"><primary>XInitThreads</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>Status XInitThreads();</para>
+<!-- .FN -->
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInitThreads</function>
+function initializes Xlib support for concurrent threads.
+This function must be the first Xlib function a
+multi-threaded program calls, and it must complete
+before any other Xlib call is made.
+This function returns a nonzero status if initialization was
+successful; otherwise, it returns zero.
+On systems that do not support threads, this function always returns zero.
+</para>
+<para>
+<!-- .LP -->
+It is only necessary to call this function if multiple threads
+might use Xlib concurrently. If all calls to Xlib functions
+are protected by some other access mechanism (for example,
+a mutual exclusion lock in a toolkit or through explicit client
+programming), Xlib thread initialization is not required.
+It is recommended that single-threaded programs not call this function.
+
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To lock a display across several Xlib calls, use
+<function>XLockDisplay</function>.
+<indexterm significance="preferred"><primary>XLockDisplay</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xlockdisplay'>
+<funcprototype>
+ <funcdef>XLockDisplay</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLockDisplay</function>
+function locks out all other threads from using the specified display.
+Other threads attempting to use the display will block until
+the display is unlocked by this thread.
+Nested calls to
+<function>XLockDisplay</function>
+work correctly; the display will not actually be unlocked until
+<function>XUnlockDisplay</function>
+has been called the same number of times as
+<function>XLockDisplay</function>.
+This function has no effect unless Xlib was successfully initialized
+for threads using
+<function>XInitThreads</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To unlock a display, use
+<function>XUnlockDisplay</function>.
+<indexterm significance="preferred"><primary>XUnlockDisplay</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xunlockdisplay'>
+<funcprototype>
+ <funcdef>XUnlockDisplay</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnlockDisplay</function>
+function allows other threads to use the specified display again.
+Any threads that have blocked on the display are allowed to continue.
+Nested locking works correctly; if
+<function>XLockDisplay</function>
+has been called multiple times by a thread, then
+<function>XUnlockDisplay</function>
+must be called an equal number of times before the display is
+actually unlocked.
+This function has no effect unless Xlib was successfully initialized
+for threads using
+<function>XInitThreads</function>.
+</para>
+</sect1>
+<sect1 id="Using_Internal_Connections">
+<title>Using Internal Connections</title>
+<!-- .XS -->
+<!-- (SN Using Internal Connections -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+In addition to the connection to the X server, an Xlib implementation
+may require connections to other kinds of servers (for example, to
+input method servers as described in
+<link linkend="locales_and_internationalized_text_functions">chapter 13</link>).
+Toolkits and clients
+that use multiple displays, or that use displays in combination with
+other inputs, need to obtain these additional connections to correctly
+block until input is available and need to process that input
+when it is available. Simple clients that use a single display and
+block for input in an Xlib event function do not need to use these
+facilities.
+</para>
+<para>
+<!-- .LP -->
+To track internal connections for a display, use
+<function>XAddConnectionWatch</function>.
+</para>
+<funcsynopsis id='xconnectionwatch'>
+<funcprototype>
+ <funcdef>type void XConnectionWatchProc</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>int<parameter> fd</parameter></paramdef>
+ <paramdef>Bool<parameter> opening</parameter></paramdef>
+ <paramdef>XPointer<parameter> *watch_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis id='xaddconnectionwatch'>
+<funcprototype>
+ <funcdef>Status XAddConnectionWatch</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XWatchProc<parameter> procedure</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>procedure</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to be called.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAddConnectionWatch</function>
+function registers a procedure to be called each time Xlib opens or closes an
+internal connection for the specified display. The procedure is passed the
+display, the specified client_data, the file descriptor for the connection,
+a Boolean indicating whether the connection is being opened or closed, and a
+pointer to a location for private watch data. If opening is
+<symbol>True</symbol>,
+the procedure can store a pointer to private data in the location pointed
+to by watch_data;
+when the procedure is later called for this same connection and opening is
+<symbol>False</symbol>,
+the location pointed to by watch_data will hold this same private data pointer.
+</para>
+<para>
+<!-- .LP -->
+This function can be called at any time after a display is opened.
+If internal connections already exist, the registered procedure will
+immediately be called for each of them, before
+<function>XAddConnectionWatch</function>
+returns.
+<function>XAddConnectionWatch</function>
+returns a nonzero status if the procedure is successfully registered;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+The registered procedure should not call any Xlib functions.
+If the procedure directly or indirectly causes the state of internal
+connections or watch procedures to change, the result is not defined.
+If Xlib has been initialized for threads, the procedure is called with
+the display locked and the result of a call by the procedure to any
+Xlib function that locks the display is not defined unless the executing
+thread has externally locked the display using
+<function>XLockDisplay</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To stop tracking internal connections for a display, use
+<function>XRemoveConnectionWatch</function>.
+<indexterm significance="preferred"><primary>XRemoveConnectionWatch</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+()
+</para>
+<funcsynopsis id='xremoveconnectionwatch'>
+<funcprototype>
+ <funcdef>Status <function>XRemoveConnectionWatch</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XWatchProc<parameter> procedure</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>procedure</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to be called.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRemoveConnectionWatch</function>
+function removes a previously registered connection watch procedure.
+The client_data must match the client_data used when the procedure
+was initially registered.
+
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To process input on an internal connection, use
+<function>XProcessInternalConnection</function>.
+<indexterm significance="preferred"><primary>XProcessInternalConnection</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+()
+</para>
+<funcsynopsis id='xprocessinternalconnection'>
+<funcprototype>
+ <funcdef>void <function>XProcessInternalConnection</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> fd</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fd</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the file descriptor.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XProcessInternalConnection</function>
+function processes input available on an internal connection.
+This function should be called for an internal connection only
+after an operating system facility (for example,
+<function>select</function>
+or
+<function>poll</function>)
+has indicated that input is available; otherwise,
+the effect is not defined.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain all of the current internal connections for a display, use
+<function>XInternalConnectionNumbers</function>.
+<indexterm significance="preferred"><primary>XInternalConnectionNumbers</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+()
+</para>
+<funcsynopsis id='xinternalconnectionnumbers'>
+<funcprototype>
+ <funcdef>Status <function>XInternalConnectionNumbers</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int **<parameter> fd</parameter></paramdef>
+ <paramdef>int *<parameter> count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fd_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the file descriptors.
+<!-- .ds Cn file descriptors -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInternalConnectionNumbers</function>
+function returns a list of the file descriptors for all internal
+connections currently open for the specified display.
+When the allocated list is no longer needed,
+free it by using
+<function>XFree</function>.
+This functions returns a nonzero status if the list is successfully allocated;
+otherwise, it returns zero.
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH03.xml b/libX11/specs/libX11/CH03.xml index c2c70cbdd..dbdcd86be 100644 --- a/libX11/specs/libX11/CH03.xml +++ b/libX11/specs/libX11/CH03.xml @@ -1,4174 +1,4174 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="window_functions"><title>Window Functions</title> -<sect1 id="Visual_Types"> -<title>Visual Types</title> -<!-- .XS --> -<!-- (SN Visual Types --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>Visual Type</primary></indexterm> -On some display hardware, -it may be possible to deal with color resources in more than one way. -For example, you may be able to deal with a screen of either 12-bit depth -with arbitrary mapping of pixel to color (pseudo-color) or 24-bit depth -with 8 bits of the pixel dedicated to each of red, green, and blue. -These different ways of dealing with the visual aspects of the screen -are called visuals. -For each screen of the display, there may be a list of valid visual types -supported at different depths of the screen. -Because default windows and visual types are defined for each screen, -most simple applications need not deal with this complexity. -Xlib provides macros and functions that return the default root window, -the default depth of the default root window, and the default visual type -(see sections <link linkend="Display_Macros_">2.2.1</link> -and <link linkend="Determining_the_Appropriate_Visual_Type">16.7</link>). -</para> -<para> -<!-- .LP --> -Xlib uses an opaque -<structname>Visual</structname> -<indexterm significance="preferred"><primary>Visual</primary></indexterm> -structure that contains information about the possible color mapping. -The visual utility functions -(see <link linkend="Determining_the_Appropriate_Visual_Type">section 16.7</link>) -use an -<structname>XVisualInfo</structname> -structure to return this information to an application. -The members of this structure pertinent to this discussion are class, red_mask, -green_mask, blue_mask, bits_per_rgb, and colormap_size. -The class member specifies one of the possible visual classes of the screen -and can be -<indexterm><primary>Visual Classes</primary><secondary>StaticGray</secondary></indexterm> -<indexterm><primary>Visual Classes</primary><secondary>StaticColor</secondary></indexterm> -<indexterm><primary>Visual Classes</primary><secondary>TrueColor</secondary></indexterm> -<indexterm><primary>Visual Classes</primary><secondary>StaticColor</secondary></indexterm> -<indexterm><primary>Visual Classes</primary><secondary>GrayScale</secondary></indexterm> -<indexterm><primary>Visual Classes</primary><secondary>PseudoColor</secondary></indexterm> -<symbol>StaticGray</symbol>, -<symbol>StaticColor</symbol>, -<symbol>TrueColor</symbol>, -<symbol>GrayScale</symbol>, -<symbol>PseudoColor</symbol>, -or -<symbol>DirectColor</symbol>. -</para> -<para> -<!-- .LP --> -The following concepts may serve to make the explanation of -visual types clearer. -The screen can be color or grayscale, -can have a colormap that is writable or read-only, -and can also have a colormap whose indices are decomposed into separate -<acronym>RGB</acronym> pieces, provided one is not on a grayscale screen. -This leads to the following diagram: -</para> - -<literallayout class="monospaced"> - Color Gray-Scale - R/O R/W R/O R/W ----------------------------------------------- - Undecomposed Static Pseudo Static Gray - Colormap Color Color Gray Scale - - Decomposed True Direct - Colormap Color Color ----------------------------------------------- -</literallayout> - -<para> -<!-- .LP --> -Conceptually, -as each pixel is read out of video memory for display on the screen, -it goes through a look-up stage by indexing into a colormap. -Colormaps can be manipulated arbitrarily on some hardware, -in limited ways on other hardware, and not at all on other hardware. -The visual types affect the colormap and -the <acronym>RGB</acronym> values in the following ways: -</para> -<para> -<!-- .LP --> -</para> -<itemizedlist> - <listitem> - <para> -For -<symbol>PseudoColor</symbol>, -a pixel value indexes a colormap to produce -independent <acronym>RGB</acronym> values, and the <acronym>RGB</acronym> values can be changed dynamically. - </para> - </listitem> - <listitem> - <para> -<symbol>GrayScale</symbol> -is treated the same way as -<symbol>PseudoColor</symbol> -except that the primary that drives the screen is undefined. -Thus, the client should always store the -same value for red, green, and blue in the colormaps. - </para> - </listitem> - <listitem> - <para> -For -<symbol>DirectColor</symbol>, -a pixel value is decomposed into separate <acronym>RGB</acronym> subfields, and each -subfield separately indexes the colormap for the corresponding value. -The <acronym>RGB</acronym> values can be changed dynamically. - </para> - </listitem> - <listitem> - <para> -<symbol>TrueColor</symbol> -is treated the same way as -<symbol>DirectColor</symbol> -except that the colormap has predefined, read-only <acronym>RGB</acronym> values. -These <acronym>RGB</acronym> values are server dependent but provide linear or near-linear -ramps in each primary. - </para> - </listitem> - <listitem> - <para> -<symbol>StaticColor</symbol> -is treated the same way as -<symbol>PseudoColor</symbol> -except that the colormap has predefined, -read-only, server-dependent <acronym>RGB</acronym> values. - </para> - </listitem> - <listitem> - <para> -<symbol>StaticGray</symbol> -is treated the same way as -<symbol>StaticColor</symbol> -except that the <acronym>RGB</acronym> values are equal for any single pixel -value, thus resulting in shades of gray. -<symbol>StaticGray</symbol> -with a two-entry -colormap can be thought of as monochrome. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The red_mask, green_mask, and blue_mask members are only defined for -<symbol>DirectColor</symbol> -and -<symbol>TrueColor</symbol>. -Each has one contiguous set of bits with no -intersections. -The bits_per_rgb member specifies the log base 2 of the -number of distinct color values (individually) of red, green, and blue. -Actual <acronym>RGB</acronym> values are unsigned 16-bit numbers. -The colormap_size member defines the number of available colormap entries -in a newly created colormap. -For -<symbol>DirectColor</symbol> -and -<symbol>TrueColor</symbol>, -this is the size of an individual pixel subfield. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the visual ID from a -<structname>Visual</structname>, -use -<function>XVisualIDFromVisual</function>. -<indexterm significance="preferred"><primary>XVisualIDFromVisual</primary></indexterm> -</para> -<!-- .sM --> -<funcsynopsis id='xvisualidfromvisual'> -<funcprototype> - <funcdef>VisualID <function>XVisualIDFromVisual</function></funcdef> - <paramdef>Visual *<parameter>visual</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>visual</emphasis> - </term> - <listitem> - <para> -Specifies the visual type. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XVisualIDFromVisual</function> -function returns the visual ID for the specified visual type. -</para> -</sect1> -<sect1 id="Window_Attributes"> -<title>Window Attributes</title> -<!-- .XS --> -<!-- (SN Window Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Window</primary></indexterm> -<indexterm><primary>Window</primary><secondary>attributes</secondary></indexterm> -All -<symbol>InputOutput</symbol> -windows have a border width of zero or more pixels, an optional background, -an event suppression mask (which suppresses propagation of events from -children), and a property list -(see <link linkend="Properties_and_Atoms">section 4.3</link>). -The window border and background can be a solid color or a pattern, called -a tile. -All windows except the root have a parent and are clipped by their parent. -If a window is stacked on top of another window, it obscures that other -window for the purpose of input. -If a window has a background (almost all do), it obscures the other -window for purposes of output. -Attempts to output to the obscured area do nothing, -and no input events (for example, pointer motion) are generated for the -obscured area. -</para> -<para> -<!-- .LP --> -Windows also have associated property lists -(see <link linkend="Properties_and_Atoms">section 4.3</link>). -</para> -<para> -<!-- .LP --> -Both -<symbol>InputOutput</symbol> -and -<symbol>InputOnly</symbol> -windows have the following common attributes, -which are the only attributes of an -<symbol>InputOnly</symbol> -window: -</para> -<itemizedlist> - <listitem> - <para> -win-gravity - </para> - </listitem> - <listitem> - <para> -event-mask - </para> - </listitem> - <listitem> - <para> -do-not-propagate-mask - </para> - </listitem> - <listitem> - <para> -override-redirect - </para> - </listitem> - <listitem> - <para> -cursor - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -If you specify any other attributes for an -<symbol>InputOnly</symbol> -window, -a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<symbol>InputOnly</symbol> -windows are used for controlling input events in situations where -<symbol>InputOutput</symbol> -windows are unnecessary. -<symbol>InputOnly</symbol> -windows are invisible; can only be used to control such things as -cursors, input event generation, and grabbing; -and cannot be used in any graphics requests. -Note that -<symbol>InputOnly</symbol> -windows cannot have -<symbol>InputOutput</symbol> -windows as inferiors. -</para> -<para> -<!-- .LP --> -Windows have borders of a programmable width and pattern -as well as a background pattern or tile. -<indexterm><primary>Tile</primary><secondary>pixmaps</secondary></indexterm> -Pixel values can be used for solid colors. -<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm> -<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm> -The background and border pixmaps can be destroyed immediately after -creating the window if no further explicit references to them -are to be made. -<indexterm ><primary>Tile</primary><secondary>mode</secondary></indexterm> -The pattern can either be relative to the parent -or absolute. -If -<symbol>ParentRelative</symbol>, -the parent's background is used. -</para> -<para> -<!-- .LP --> -When windows are first created, -they are not visible (not mapped) on the screen. -Any output to a window that is not visible on the screen -and that does not have backing store will be discarded. -<indexterm><primary>Window</primary><secondary>mapping</secondary></indexterm> -An application may wish to create a window long before it is -mapped to the screen. -When a window is eventually mapped to the screen -(using -<function>XMapWindow</function>), -<indexterm><primary>XMapWindow</primary></indexterm> -the X server generates an -<symbol>Expose</symbol> -event for the window if backing store has not been maintained. -</para> -<para> -<!-- .LP --> -A window manager can override your choice of size, -border width, and position for a top-level window. -Your program must be prepared to use the actual size and position -of the top window. -It is not acceptable for a client application to resize itself -unless in direct response to a human command to do so. -Instead, either your program should use the space given to it, -or if the space is too small for any useful work, your program -might ask the user to resize the window. -The border of your top-level window is considered fair game -for window managers. -</para> -<para> -<!-- .LP --> -To set an attribute of a window, -set the appropriate member of the -<structname>XSetWindowAttributes</structname> -structure and OR in the corresponding value bitmask in your subsequent calls to -<function>XCreateWindow</function> -and -<function>XChangeWindowAttributes</function>, -or use one of the other convenience functions that set the appropriate -attribute. -The symbols for the value mask bits and the -<structname>XSetWindowAttributes</structname> -structure are: -<!-- .sM --> -</para> -<para> -<!-- .LP --> -/* Window attribute value mask bits */ - - -<literallayout class="monospaced"> -/* Window attribute value mask bits */ -#define CWBackPixmap (1L<<0) -#define CWBackPixel (1L<<1) -#define CWBorderPixmap (1L<<2) -#define CWBorderPixel (1L<<3) -#define CWBitGravity (1L<<4) -#define CWWinGravity (1L<<5) -#define CWBackingStore (1L<<6) -#define CWBackingPlanes (1L<<7) -#define CWBackingPixel (1L<<8) -#define CWOverrideRedirect (1L<<9) -#define CWSaveUnder (1L<<10) -#define CWEventMask (1L<<11) -#define CWDontPropagate (1L<<12) -#define CWColormap (1L<<13) -#define CWCursor (1L<<14) -</literallayout> - -<indexterm significance="preferred"><primary>XSetWindowAttributes</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -/* Values */ - -typedef struct { - Pixmap background_pixmap; /* background, None, or ParentRelative */ - unsigned long background_pixel; /* background pixel */ - Pixmap border_pixmap; /* border of the window or CopyFromParent */ - unsigned long border_pixel; /* border pixel value */ - int bit_gravity; /* one of bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes; /* planes to be preserved if possible */ - unsigned long backing_pixel; /* value to use in restoring planes */ - Bool save_under; /* should bits under be saved? (popups) */ - long event_mask; /* set of events that should be saved */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override_redirect */ - Colormap colormap; /* color map to be associated with window */ - Cursor cursor; /* cursor to be displayed (or None) */ -} XSetWindowAttributes; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The following lists the defaults for each window attribute and indicates -whether the attribute is applicable to -<symbol>InputOutput</symbol> -and -<symbol>InputOnly</symbol> -windows: -</para> -<informaltable> - <tgroup cols='4'> - <colspec colname='c1' align='left'/> - <colspec colname='c2' align='left'/> - <colspec colname='c3' align='center'/> - <colspec colname='c4' align='center'/> - <thead> - <row> - <entry>Attribute</entry> - <entry>Default</entry> - <entry>InputOutput</entry> - <entry>InputOnly</entry> - </row> - </thead> - <tbody> - <row> - <entry>background-pixmap</entry> - <entry><symbol>None</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>background-pixel</entry> - <entry>Undefined</entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>border-pixmap</entry> - <entry><symbol>CopyFromParent</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>border-pixel</entry> - <entry>Undefined</entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>bit-gravity</entry> - <entry><symbol>ForgetGravity</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>win-gravity</entry> - <entry><symbol>NorthWestGravity</symbol></entry> - <entry>Yes</entry> - <entry>Yes</entry> - </row> - <row> - <entry>backing-store</entry> - <entry><symbol>NotUseful</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>backing-planes</entry> - <entry>All ones</entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>backing-pixel</entry> - <entry>zero</entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>save-under</entry> - <entry><symbol>False</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>event-mask</entry> - <entry>empty set</entry> - <entry>Yes</entry> - <entry>Yes</entry> - </row> - <row> - <entry>do-not-propagate-mask</entry> - <entry>empty set</entry> - <entry>Yes</entry> - <entry>Yes</entry> - </row> - <row> - <entry>override-redirect</entry> - <entry><symbol>False</symbol></entry> - <entry>Yes</entry> - <entry>Yes</entry> - </row> - <row> - <entry>colormap</entry> - <entry><symbol>CopyFromParent</symbol></entry> - <entry>Yes</entry> - <entry>No</entry> - </row> - <row> - <entry>cursor</entry> - <entry><symbol>None</symbol></entry> - <entry>Yes</entry> - <entry>Yes</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<sect2 id="Background_Attribute"> -<title>Background Attribute</title> -<!-- .XS --> -<!-- (SN Background Attribute --> -<!-- .XE --> -<para> -<!-- .LP --> -Only -<symbol>InputOutput</symbol> -windows can have a background. -You can set the background of an -<symbol>InputOutput</symbol> -window by using a pixel or a pixmap. -</para> -<para> -<!-- .LP --> -The background-pixmap attribute of a window specifies the pixmap to be used for -a window's background. -This pixmap can be of any size, although some sizes may be faster than others. -The background-pixel attribute of a window specifies a pixel value used to paint -a window's background in a single color. -</para> -<para> -<!-- .LP --> -You can set the background-pixmap to a pixmap, -<symbol>None</symbol> -(default), or -<symbol>ParentRelative</symbol>. -You can set the background-pixel of a window to any pixel value (no default). -If you specify a background-pixel, -it overrides either the default background-pixmap -or any value you may have set in the background-pixmap. -A pixmap of an undefined size that is filled with the background-pixel is used -for the background. -Range checking is not performed on the background pixel; -it simply is truncated to the appropriate number of bits. -</para> -<para> -<!-- .LP --> -If you set the background-pixmap, -it overrides the default. -The background-pixmap and the window must have the same depth, -or a -<errorname>BadMatch</errorname> -error results. -If you set background-pixmap to -<symbol>None</symbol>, -the window has no defined background. -If you set the background-pixmap to -<symbol>ParentRelative</symbol>: -</para> -<itemizedlist> - <listitem> - <para> -The parent window's background-pixmap is used. -The child window, however, must have the same depth as -its parent, -or a -<errorname>BadMatch</errorname> -error results. - </para> - </listitem> - <listitem> - <para> -If the parent window has a background-pixmap of -<symbol>None</symbol>, -the window also has a background-pixmap of -<symbol>None</symbol>. - </para> - </listitem> - <listitem> - <para> -A copy of the parent window's background-pixmap is not made. -The parent's background-pixmap is examined each time the child window's -background-pixmap is required. - </para> - </listitem> - <listitem> - <para> -The background tile origin always aligns with the parent window's -background tile origin. -If the background-pixmap is not -<symbol>ParentRelative</symbol>, -the background tile origin is the child window's origin. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Setting a new background, whether by setting background-pixmap or -background-pixel, overrides any previous background. -The background-pixmap can be freed immediately if no further explicit reference -is made to it (the X server will keep a copy to use when needed). -If you later draw into the pixmap used for the background, -what happens is undefined because the -X implementation is free to make a copy of the pixmap or -to use the same pixmap. -</para> -<para> -<!-- .LP --> -When no valid contents are available for regions of a window -and either the regions are visible or the server is maintaining backing store, -the server automatically tiles the regions with the window's background -unless the window has a background of -<symbol>None</symbol>. -If the background is -<symbol>None</symbol>, -the previous screen contents from other windows of the same depth as the window -are simply left in place as long as the contents come from the parent of the -window or an inferior of the parent. -Otherwise, the initial contents of the exposed regions are undefined. -<symbol>Expose</symbol> -events are then generated for the regions, even if the background-pixmap -is -<symbol>None</symbol> -(see <link linkend="Exposure_Events">section 10.9</link>). -</para> -</sect2> -<sect2 id="Border_Attribute"> -<title>Border Attribute</title> -<!-- .XS --> -<!-- (SN Border Attribute --> -<!-- .XE --> -<para> -<!-- .LP --> -Only -<symbol>InputOutput</symbol> -windows can have a border. -You can set the border of an -<symbol>InputOutput</symbol> -window by using a pixel or a pixmap. -</para> -<para> -<!-- .LP --> -The border-pixmap attribute of a window specifies the pixmap to be used -for a window's border. -The border-pixel attribute of a window specifies a pixmap of undefined size -filled with that pixel be used for a window's border. -Range checking is not performed on the background pixel; -it simply is truncated to the appropriate number of bits. -The border tile origin is always the same as the background tile origin. -</para> -<para> -<!-- .LP --> -You can also set the border-pixmap to a pixmap of any size (some may be faster -than others) or to -<symbol>CopyFromParent</symbol> -(default). -You can set the border-pixel to any pixel value (no default). -</para> -<para> -<!-- .LP --> -If you set a border-pixmap, -it overrides the default. -The border-pixmap and the window must have the same depth, -or a -<errorname>BadMatch</errorname> -error results. -If you set the border-pixmap to -<symbol>CopyFromParent</symbol>, -the parent window's border-pixmap is copied. -Subsequent changes to the parent window's border attribute do not affect -the child window. -However, the child window must have the same depth as the parent window, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -The border-pixmap can be freed immediately if no further explicit reference -is made to it. -If you later draw into the pixmap used for the border, -what happens is undefined because the -X implementation is free either to make a copy of the pixmap or -to use the same pixmap. -If you specify a border-pixel, -it overrides either the default border-pixmap -or any value you may have set in the border-pixmap. -All pixels in the window's border will be set to the border-pixel. -Setting a new border, whether by setting border-pixel or by setting -border-pixmap, overrides any previous border. -</para> -<para> -<!-- .LP --> -Output to a window is always clipped to the inside of the window. -Therefore, graphics operations never affect the window border. -</para> -</sect2> -<sect2 id="Gravity_Attributes"> -<title>Gravity Attributes</title> -<!-- .XS --> -<!-- (SN Gravity Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -The bit gravity of a window defines which region of the window should be -retained when an -<symbol>InputOutput</symbol> -window is resized. -The default value for the bit-gravity attribute is -<symbol>ForgetGravity</symbol>. -The window gravity of a window allows you to define how the -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window should be repositioned if its parent is resized. -The default value for the win-gravity attribute is -<symbol>NorthWestGravity</symbol>. -</para> -<para> -<!-- .LP --> -If the inside width or height of a window is not changed -and if the window is moved or its border is changed, -then the contents of the window are not lost but move with the window. -Changing the inside width or height of the window causes its contents to be -moved or lost (depending on the bit-gravity of the window) and causes -children to be reconfigured (depending on their win-gravity). -For a -change of width and height, the (x, y) pairs are defined: -</para> -<para> -<!-- .LP --> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1' align='left'/> - <colspec colname='c2' align='left'/> - <thead> - <row> - <entry>Gravity Direction</entry> - <entry>Coordinates</entry> - </row> - </thead> - <tbody> - <row> - <entry><symbol>NorthWestGravity</symbol></entry> - <entry>(0, 0)</entry> - </row> - <row> - <entry><symbol>NorthGravity</symbol></entry> - <entry>(Width/2, 0)</entry> - </row> - <row> - <entry><symbol>NorthEastGravity</symbol></entry> - <entry>(Width, 0)</entry> - </row> - <row> - <entry><symbol>WestGravity</symbol></entry> - <entry>(0, Height/2)</entry> - </row> - <row> - <entry><symbol>CenterGravity</symbol></entry> - <entry>(Width/2, Height/2)</entry> - </row> - <row> - <entry><symbol>EastGravity</symbol></entry> - <entry>(Width, Height/2)</entry> - </row> - <row> - <entry><symbol>SouthWestGravity</symbol></entry> - <entry>(0, Height)</entry> - </row> - <row> - <entry><symbol>SouthGravity</symbol></entry> - <entry>(Width/2, Height)</entry> - </row> - <row> - <entry><symbol>SouthEastGravity</symbol></entry> - <entry>(Width, Height)</entry> - </row> - </tbody> - </tgroup> -</informaltable> -</para> -<para> -<!-- .LP --> -When a window with one of these bit-gravity values is resized, -the corresponding pair -defines the change in position of each pixel in the window. -When a window with one of these win-gravities has its parent window resized, -the corresponding pair defines the change in position of the window -within the parent. -When a window is so repositioned, a -<symbol>GravityNotify</symbol> -event is generated -(see <link linkend="GravityNotify_Events">section 10.10.5</link>). -</para> -<para> -<!-- .LP --> -A bit-gravity of -<symbol>StaticGravity</symbol> -indicates that the contents or origin should not move relative to the -origin of the root window. -If the change in size of the window is coupled with a change in position (x, y), -then for bit-gravity the change in position of each pixel is (−x, −y), and for -win-gravity the change in position of a child when its parent is so resized is -(−x, −y). -Note that -<symbol>StaticGravity</symbol> -still only takes effect when the width or height of the window is changed, -not when the window is moved. -</para> -<para> -<!-- .LP --> -A bit-gravity of -<symbol>ForgetGravity</symbol> -indicates that the window's contents are always discarded after a size change, -even if a backing store or save under has been requested. -The window is tiled with its background -and zero or more -<symbol>Expose</symbol> -events are generated. -If no background is defined, the existing screen contents are not -altered. -Some X servers may also ignore the specified bit-gravity and -always generate -<symbol>Expose</symbol> -events. -</para> -<para> -<!-- .LP --> -The contents and borders of inferiors are not affected by their parent's -bit-gravity. -A server is permitted to ignore the specified bit-gravity and use -<symbol>Forget</symbol> -instead. -</para> -<para> -<!-- .LP --> -A win-gravity of -<symbol>UnmapGravity</symbol> -is like -<symbol>NorthWestGravity</symbol> -(the window is not moved), -except the child is also -unmapped when the parent is resized, -and an -<symbol>UnmapNotify</symbol> -event is -generated. -</para> -</sect2> -<sect2 id="Backing_Store_Attribute"> -<title>Backing Store Attribute</title> -<!-- .XS --> -<!-- (SN Backing Store Attribute --> -<!-- .XE --> -<para> -<!-- .LP --> -Some implementations of the X server may choose to maintain the contents of -<symbol>InputOutput</symbol> -windows. -If the X server maintains the contents of a window, -the off-screen saved pixels -are known as backing store. -The backing store advises the X server on what to do -with the contents of a window. -The backing-store attribute can be set to -<symbol>NotUseful</symbol> -(default), -<symbol>WhenMapped</symbol>, -or -<symbol>Always</symbol>. -</para> -<para> -<!-- .LP --> -A backing-store attribute of -<symbol>NotUseful</symbol> -advises the X server that -maintaining contents is unnecessary, -although some X implementations may -still choose to maintain contents and, therefore, not generate -<symbol>Expose</symbol> -events. -A backing-store attribute of -<symbol>WhenMapped</symbol> -advises the X server that maintaining contents of -obscured regions when the window is mapped would be beneficial. -In this case, -the server may generate an -<symbol>Expose</symbol> -event when the window is created. -A backing-store attribute of -<symbol>Always</symbol> -advises the X server that maintaining contents even when -the window is unmapped would be beneficial. -Even if the window is larger than its parent, -this is a request to the X server to maintain complete contents, -not just the region within the parent window boundaries. -While the X server maintains the window's contents, -<symbol>Expose</symbol> -events normally are not generated, -but the X server may stop maintaining -contents at any time. -</para> -<para> -<!-- .LP --> -When the contents of obscured regions of a window are being maintained, -regions obscured by noninferior windows are included in the destination -of graphics requests (and source, when the window is the source). -However, regions obscured by inferior windows are not included. -</para> -</sect2> -<sect2 id="Save_Under_Flag"> -<title>Save Under Flag</title> -<!-- .XS --> -<!-- (SN Save Under Flag --> -<!-- .XE --> -<indexterm><primary>Save Unders</primary></indexterm> -<para> -<!-- .LP --> -Some server implementations may preserve contents of -<symbol>InputOutput</symbol> -windows under other -<symbol>InputOutput</symbol> -windows. -This is not the same as preserving the contents of a window for you. -You may get better visual -appeal if transient windows (for example, pop-up menus) request that the system -preserve the screen contents under them, -so the temporarily obscured applications do not have to repaint. -</para> -<para> -<!-- .LP --> -You can set the save-under flag to -<symbol>True</symbol> -or -<symbol>False</symbol> -(default). -If save-under is -<symbol>True</symbol>, -the X server is advised that, when this window is mapped, -saving the contents of windows it obscures would be beneficial. -</para> -</sect2> -<sect2 id="Backing_Planes_and_Backing_Pixel_Attributes"> -<title>Backing Planes and Backing Pixel Attributes</title> -<!-- .XS --> -<!-- (SN Backing Planes and Backing Pixel Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -You can set backing planes to indicate (with bits set to 1) -which bit planes of an -<symbol>InputOutput</symbol> -window hold dynamic data that must be preserved in backing store -and during save unders. -The default value for the backing-planes attribute is all bits set to 1. -You can set backing pixel to specify what bits to use in planes not -covered by backing planes. -The default value for the backing-pixel attribute is all bits set to 0. -The X server is free to save only the specified bit planes in the backing store -or the save under and is free to regenerate the remaining planes with -the specified pixel value. -Any extraneous bits in these values (that is, those bits beyond -the specified depth of the window) may be simply ignored. -If you request backing store or save unders, -you should use these members to minimize the amount of off-screen memory -required to store your window. -</para> -</sect2> -<sect2 id="Event_Mask_and_Do_Not_Propagate_Mask_Attributes"> -<title>Event Mask and Do Not Propagate Mask Attributes</title> -<!-- .XS --> -<!-- (SN Event Mask and Do Not Propagate Mask Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -The event mask defines which events the client is interested in for this -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window (or, for some event types, inferiors of this window). -The event mask is the bitwise inclusive OR of zero or more of the -valid event mask bits. -You can specify that no maskable events are reported by setting -<symbol>NoEventMask</symbol> -(default). -</para> -<para> -<!-- .LP --> -The do-not-propagate-mask attribute -defines which events should not be propagated to -ancestor windows when no client has the event type selected in this -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window. -The do-not-propagate-mask is the bitwise inclusive OR of zero or more -of the following masks: -<symbol>KeyPress</symbol>, -<symbol>KeyRelease</symbol>, -<symbol>ButtonPress</symbol>, -<symbol>ButtonRelease</symbol>, -<symbol>PointerMotion</symbol>, -<symbol>Button1Motion</symbol>, -<symbol>Button2Motion</symbol>, -<symbol>Button3Motion</symbol>, -<symbol>Button4Motion</symbol>, -<symbol>Button5Motion</symbol>, -and -<symbol>ButtonMotion</symbol>. -You can specify that all events are propagated by setting -<symbol>NoEventMask</symbol> -(default). -</para> -</sect2> -<sect2 id="Override_Redirect_Flag"> -<title>Override Redirect Flag</title> -<!-- .XS --> -<!-- (SN Override Redirect Flag --> -<!-- .XE --> -<para> -<!-- .LP --> -To control window placement or to add decoration, -a window manager often needs to intercept (redirect) any map or configure -request. -Pop-up windows, however, often need to be mapped without a window manager -getting in the way. -To control whether an -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window is to ignore these structure control facilities, -use the override-redirect flag. -</para> -<para> -<!-- .LP --> -The override-redirect flag specifies whether map and configure requests -on this window should override a -<symbol>SubstructureRedirectMask</symbol> -on the parent. -You can set the override-redirect flag to -<symbol>True</symbol> -or -<symbol>False</symbol> -(default). -Window managers use this information to avoid tampering with pop-up windows -(see also <link linkend="inter_client_communication_functions">chapter 14</link>). -</para> -</sect2> -<sect2 id="Colormap_Attribute"> -<title>Colormap Attribute</title> -<!-- .XS --> -<!-- (SN Colormap Attribute --> -<!-- .XE --> -<para> -<!-- .LP --> -The colormap attribute specifies which colormap best reflects the true -colors of the -<symbol>InputOutput</symbol> -window. -The colormap must have the same visual type as the window, -or a -<errorname>BadMatch</errorname> -error results. -X servers capable of supporting multiple -hardware colormaps can use this information, -and window managers can use it for calls to -<function>XInstallColormap</function>. -You can set the colormap attribute to a colormap or to -<symbol>CopyFromParent</symbol> -(default). -</para> -<para> -<!-- .LP --> -If you set the colormap to -<symbol>CopyFromParent</symbol>, -the parent window's colormap is copied and used by its child. -However, the child window must have the same visual type as the parent, -or a -<errorname>BadMatch</errorname> -error results. -The parent window must not have a colormap of -<symbol>None</symbol>, -or a -<errorname>BadMatch</errorname> -error results. -The colormap is copied by sharing the colormap object between the child -and parent, not by making a complete copy of the colormap contents. -Subsequent changes to the parent window's colormap attribute do -not affect the child window. -</para> -</sect2> -<sect2 id="Cursor_Attribute"> -<title>Cursor Attribute</title> -<!-- .XS --> -<!-- (SN Cursor Attribute --> -<!-- .XE --> -<para> -<!-- .LP --> -The cursor attribute specifies which cursor is to be used when the pointer is -in the -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window. -You can set the cursor to a cursor or -<symbol>None</symbol> -(default). -</para> -<para> -<!-- .LP --> -If you set the cursor to -<symbol>None</symbol>, -the parent's cursor is used when the -pointer is in the -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol> -window, and any change in the parent's cursor will cause an -immediate change in the displayed cursor. -By calling -<function>XFreeCursor</function>, -the cursor can be freed immediately as long as no further explicit reference -to it is made. -</para> -</sect2> -</sect1> -<sect1 id="Creating_Windows"> -<title>Creating Windows</title> -<!-- .XS --> -<!-- (SN Creating Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides basic ways for creating windows, -and toolkits often supply higher-level functions specifically for -creating and placing top-level windows, -which are discussed in the appropriate toolkit documentation. -If you do not use a toolkit, however, -you must provide some standard information or hints for the window -manager by using the Xlib inter-client communication functions -(see <link linkend="inter_client_communication_functions">chapter 14</link>). -</para> -<para> -<!-- .LP --> -If you use Xlib to create your own top-level windows -(direct children of the root window), -you must observe the following rules so that all applications interact -reasonably across the different styles of window management: -</para> -<itemizedlist> - <listitem> - <para> -You must never fight with the window manager for the size or -placement of your top-level window. - </para> - </listitem> - <listitem> - <para> -You must be able to deal with whatever size window you get, -even if this means that your application just prints a message -like ``Please make me bigger'' in its window. - </para> - </listitem> - <listitem> - <para> -You should only attempt to resize or move top-level windows in -direct response to a user request. -If a request to change the size of a top-level window fails, -you must be prepared to live with what you get. -You are free to resize or move the children of top-level -windows as necessary. -(Toolkits often have facilities for automatic relayout.) - </para> - </listitem> - <listitem> - <para> -If you do not use a toolkit that automatically sets standard window properties, -you should set these properties for top-level windows before mapping them. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -For further information, -see <link linkend="inter_client_communication_functions">chapter 14</link> and -the <emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>. -</para> -<para> -<!-- .LP --> -<function>XCreateWindow</function> -is the more general function that allows you to set specific window attributes -when you create a window. -<function>XCreateSimpleWindow</function> -creates a window that inherits its attributes from its parent window. -</para> -<para> -<!-- .LP --> -<indexterm><primary>Window</primary><secondary>InputOnly</secondary></indexterm> -The X server acts as if -<symbol>InputOnly</symbol> -windows do not exist for -the purposes of graphics requests, exposure processing, and -<symbol>VisibilityNotify</symbol> -events. -An -<symbol>InputOnly</symbol> -window cannot be used as a -drawable (that is, as a source or destination for graphics requests). -<symbol>InputOnly</symbol> -and -<symbol>InputOutput</symbol> -windows act identically in other respects (properties, -grabs, input control, and so on). -Extension packages can define other classes of windows. -</para> -<para> -<!-- .LP --> -To create an unmapped window and set its window attributes, use -<function>XCreateWindow</function>. -</para> -<indexterm significance="preferred"><primary>XCreateWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatewindow'> -<funcprototype> - <funcdef>Window <function>XCreateWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> parent</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint<parameter> border_width</parameter></paramdef> - <paramdef>int<parameter> depth</parameter></paramdef> - <paramdef>unsignedint<parameter> class</parameter></paramdef> - <paramdef>Visual<parameter> *visual</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> - <paramdef>XSetWindowAttributes<parameter> *attributes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>parent</emphasis> - </term> - <listitem> - <para> -Specifies the parent window. -<!-- .ds Xy , which are the top-left outside corner of the created window's \ --> -borders and are relative to the inside of the parent window's borders - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the created window's inside dimensions \ --> -and do not include the created window's borders - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. -The dimensions must be nonzero, -or a -<errorname>BadValue</errorname> -error results. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border_width</emphasis> - </term> - <listitem> - <para> -Specifies the width of the created window's border in pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth</emphasis> - </term> - <listitem> - <para> -Specifies the window's depth. -A depth of -<symbol>CopyFromParent</symbol> -means the depth is taken from the parent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class</emphasis> - </term> - <listitem> - <para> -Specifies the created window's class. -You can pass -<symbol>InputOutput</symbol>, -<symbol>InputOnly</symbol>, -or -<symbol>CopyFromParent</symbol>. -A class of -<symbol>CopyFromParent</symbol> -means the class -is taken from the parent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>visual</emphasis> - </term> - <listitem> - <para> -Specifies the visual type. -A visual of -<symbol>CopyFromParent</symbol> -means the visual type is taken from the -parent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which window attributes are defined in the attributes -argument. -This mask is the bitwise inclusive OR of the valid attribute mask bits. -If valuemask is zero, -the attributes are ignored and are not referenced. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>attributes</emphasis> - </term> - <listitem> - <para> -Specifies the structure from which the values (as specified by the value mask) -are to be taken. -The value mask should have the appropriate bits -set to indicate which attributes have been set in the structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateWindow</function> -function creates an unmapped subwindow for a specified parent window, -returns the window ID of the created window, -and causes the X server to generate a -<symbol>CreateNotify</symbol> -event. -The created window is placed on top in the stacking order -with respect to siblings. -</para> -<para> -<!-- .LP --> -The coordinate system has the X axis horizontal and the Y axis vertical -with the origin [0, 0] at the upper-left corner. -Coordinates are integral, -in terms of pixels, -and coincide with pixel centers. -Each window and pixmap has its own coordinate system. -For a window, -the origin is inside the border at the inside, upper-left corner. -</para> -<para> -<!-- .LP --> -The border_width for an -<symbol>InputOnly</symbol> -window must be zero, or a -<errorname>BadMatch</errorname> -error results. -For class -<symbol>InputOutput</symbol>, -the visual type and depth must be a combination supported for the screen, -or a -<errorname>BadMatch</errorname> -error results. -The depth need not be the same as the parent, -but the parent must not be a window of class -<symbol>InputOnly</symbol>, -or a -<errorname>BadMatch</errorname> -error results. -For an -<symbol>InputOnly</symbol> -window, -the depth must be zero, and the visual must be one supported by the screen. -If either condition is not met, -a -<errorname>BadMatch</errorname> -error results. -The parent window, however, may have any depth and class. -If you specify any invalid window attribute for a window, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -The created window is not yet displayed (mapped) on the user's display. -To display the window, call -<function>XMapWindow</function>. -The new window initially uses the same cursor as -its parent. -A new cursor can be defined for the new window by calling -<function>XDefineCursor</function>. -<indexterm><primary>Cursor</primary><secondary>Initial State</secondary></indexterm> -<indexterm><primary>XDefineCursor</primary></indexterm> -The window will not be visible on the screen unless it and all of its -ancestors are mapped and it is not obscured by any of its ancestors. -</para> -<para> -<!-- .LP --> -<function>XCreateWindow</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadCursor</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create an unmapped -<symbol>InputOutput</symbol> -subwindow of a given parent window, use -<function>XCreateSimpleWindow</function>. -</para> -<indexterm significance="preferred"><primary>XCreateSimpleWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatesimplewindow'> -<funcprototype> - <funcdef>Window <function>XCreateSimpleWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> parent</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint<parameter> border_width</parameter></paramdef> - <paramdef>unsignedlong<parameter> border</parameter></paramdef> - <paramdef>unsignedlong<parameter> background</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>parent</emphasis> - </term> - <listitem> - <para> -Specifies the parent window. -<!-- .ds Xy , which are the top-left outside corner of the new window's borders \ --> -and are relative to the inside of the parent window's borders - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the created window's inside dimensions \ --> -and do not include the created window's borders - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. -The dimensions must be nonzero, -or a -<errorname>BadValue</errorname> -error results. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border_width</emphasis> - </term> - <listitem> - <para> -Specifies the width of the created window's border in pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border</emphasis> - </term> - <listitem> - <para> -Specifies the border pixel value of the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background</emphasis> - </term> - <listitem> - <para> -Specifies the background pixel value of the window. - - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateSimpleWindow</function> -function creates an unmapped -<symbol>InputOutput</symbol> -subwindow for a specified parent window, returns the -window ID of the created window, and causes the X server to generate a -<symbol>CreateNotify</symbol> -event. -The created window is placed on top in the stacking order with respect to -siblings. -Any part of the window that extends outside its parent window is clipped. -The border_width for an -<symbol>InputOnly</symbol> -window must be zero, or a -<errorname>BadMatch</errorname> -error results. -<function>XCreateSimpleWindow</function> -inherits its depth, class, and visual from its parent. -All other window attributes, except background and border, -have their default values. -</para> -<para> -<!-- .LP --> -<function>XCreateSimpleWindow</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Destroying_Windows"> -<title>Destroying Windows</title> -<!-- .XS --> -<!-- (SN Destroying Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to destroy a window or destroy all -subwindows of a window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy a window and all of its subwindows, use -<function>XDestroyWindow</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroywindow'> -<funcprototype> - <funcdef><function>XDestroyWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDestroyWindow</function> -function destroys the specified window as well as all of its subwindows and causes -the X server to generate a -<symbol>DestroyNotify</symbol> -event for each window. -The window should never be referenced again. -If the window specified by the w argument is mapped, -it is unmapped automatically. -The ordering of the -<symbol>DestroyNotify</symbol> -events is such that for any given window being destroyed, -<symbol>DestroyNotify</symbol> -is generated on any inferiors of the window before being generated on -the window itself. -The ordering among siblings and across subhierarchies is not otherwise -constrained. -If the window you specified is a root window, no windows are destroyed. -Destroying a mapped window will generate -<symbol>Expose</symbol> -events on other windows that were obscured by the window being destroyed. -</para> -<para> -<!-- .LP --> -<function>XDestroyWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy all subwindows of a specified window, use -<function>XDestroySubwindows</function>. -</para> -<indexterm significance="preferred"><primary>XDestroySubwindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroysubwindows'> -<funcprototype> - <funcdef><function>XDestroySubwindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDestroySubwindows</function> -function destroys all inferior windows of the specified window, -in bottom-to-top stacking order. -It causes the X server to generate a -<symbol>DestroyNotify</symbol> -event for each window. -If any mapped -subwindows were actually destroyed, -<function>XDestroySubwindows</function> -causes the X server to generate -<symbol>Expose</symbol> -events on the specified window. -This is much more efficient than deleting many windows -one at a time because much of the work need be performed only once for all -of the windows, rather than for each window. -The subwindows should never be referenced again. -</para> -<para> -<!-- .LP --> -<function>XDestroySubwindows</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Mapping_Windows_"> -<title>Mapping Windows </title> -<!-- .XS --> -<!-- (SN Mapping Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -A window is considered mapped if an -<function>XMapWindow</function> -call has been made on it. -It may not be visible on the screen for one of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -It is obscured by another opaque window. - </para> - </listitem> - <listitem> - <para> -One of its ancestors is not mapped. - </para> - </listitem> - <listitem> - <para> -It is entirely clipped by an ancestor. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<symbol>Expose</symbol> -events are generated for the window when part or all of -it becomes visible on the screen. -A client receives the -<symbol>Expose</symbol> -events only if it has asked for them. -Windows retain their position in the stacking order when they are unmapped. -</para> -<para> -<!-- .LP --> -A window manager may want to control the placement of subwindows. -If -<symbol>SubstructureRedirectMask</symbol> -has been selected by a window manager -on a parent window (usually a root window), -a map request initiated by other clients on a child window is not performed, -and the window manager is sent a -<symbol>MapRequest</symbol> -event. -However, if the override-redirect flag on the child had been set to -<symbol>True</symbol> -(usually only on pop-up menus), -the map request is performed. -</para> -<para> -<!-- .LP --> -A tiling window manager might decide to reposition and resize other clients' -windows and then decide to map the window to its final location. -A window manager that wants to provide decoration might -reparent the child into a frame first. -For further information, -see <link linkend="Override_Redirect_Flag">sections 3.2.8</link> -and <link linkend="Window_State_Change_Events_">10.10</link>. -Only a single client at a time can select for -<symbol>SubstructureRedirectMask</symbol>. -</para> -<para> -<!-- .LP --> -Similarly, a single client can select for -<symbol>ResizeRedirectMask</symbol> -on a parent window. -Then, any attempt to resize the window by another client is suppressed, and -the client receives a -<symbol>ResizeRequest</symbol> -event. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map a given window, use -<function>XMapWindow</function>. -</para> -<indexterm significance="preferred"><primary>XMapWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmapwindow'> -<funcprototype> - <funcdef><function>XMapWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMapWindow</function> -function -maps the window and all of its -subwindows that have had map requests. -Mapping a window that has an unmapped ancestor does not display the -window but marks it as eligible for display when the ancestor becomes -mapped. -Such a window is called unviewable. -When all its ancestors are mapped, -the window becomes viewable -and will be visible on the screen if it is not obscured by another window. -This function has no effect if the window is already mapped. -</para> -<para> -<!-- .LP --> -If the override-redirect of the window is -<symbol>False</symbol> -and if some other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent window, then the X server generates a -<symbol>MapRequest</symbol> -event, and the -<function>XMapWindow</function> -function does not map the window. -Otherwise, the window is mapped, and the X server generates a -<symbol>MapNotify</symbol> -event. -</para> -<para> -<!-- .LP --> -If the window becomes viewable and no earlier contents for it are remembered, -the X server tiles the window with its background. -If the window's background is undefined, -the existing screen contents are not -altered, and the X server generates zero or more -<symbol>Expose</symbol> -events. -If backing-store was maintained while the window was unmapped, no -<symbol>Expose</symbol> -events -are generated. -If backing-store will now be maintained, -a full-window exposure is always generated. -Otherwise, only visible regions may be reported. -Similar tiling and exposure take place for any newly viewable inferiors. -</para> -<para> -<!-- .LP --> -<indexterm><primary>XMapWindow</primary></indexterm> -If the window is an -<symbol>InputOutput</symbol> -window, -<function>XMapWindow</function> -generates -<symbol>Expose</symbol> -events on each -<symbol>InputOutput</symbol> -window that it causes to be displayed. -If the client maps and paints the window -and if the client begins processing events, -the window is painted twice. -To avoid this, -first ask for -<symbol>Expose</symbol> -events and then map the window, -so the client processes input events as usual. -The event list will include -<symbol>Expose</symbol> -for each -window that has appeared on the screen. -The client's normal response to -an -<symbol>Expose</symbol> -event should be to repaint the window. -This method usually leads to simpler programs and to proper interaction -with window managers. -</para> -<para> -<!-- .LP --> -<function>XMapWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map and raise a window, use -<function>XMapRaised</function>. -</para> -<indexterm significance="preferred"><primary>XMapRaised</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmapraised'> -<funcprototype> - <funcdef><function>XMapRaised</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMapRaised</function> -function -essentially is similar to -<function>XMapWindow</function> -in that it maps the window and all of its -subwindows that have had map requests. -However, it also raises the specified window to the top of the stack. -For additional information, -see -<function>XMapWindow</function>. -</para> -<para> -<!-- .LP --> -<function>XMapRaised</function> -can generate multiple -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map all subwindows for a specified window, use -<function>XMapSubwindows</function>. -</para> -<indexterm significance="preferred"><primary>XMapSubwindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmapsubwindows'> -<funcprototype> - <funcdef><function>XMapSubwindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMapSubwindows</function> -<indexterm><primary>XMapSubwindows</primary></indexterm> -function maps all subwindows for a specified window in top-to-bottom stacking -order. -The X server generates -<symbol>Expose</symbol> -events on each newly displayed window. -This may be much more efficient than mapping many windows -one at a time because the server needs to perform much of the work -only once, for all of the windows, rather than for each window. -</para> -<para> -<!-- .LP --> -<function>XMapSubwindows</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Unmapping_Windows"> -<title>Unmapping Windows</title> -<!-- .XS --> -<!-- (SN Unmapping Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to unmap a window or all subwindows. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To unmap a window, use -<function>XUnmapWindow</function>. -</para> -<indexterm significance="preferred"><primary>XUnmapWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunmapwindow'> -<funcprototype> - <funcdef><function>XUnmapWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnmapWindow</function> -function unmaps the specified window and causes the X server to generate an -<symbol>UnmapNotify</symbol> -<indexterm><primary>UnmapNotify Event</primary></indexterm> -<indexterm><primary>XUnmapWindow</primary></indexterm> -event. -If the specified window is already unmapped, -<function>XUnmapWindow</function> -has no effect. -Normal exposure processing on formerly obscured windows is performed. -Any child window will no longer be visible until another map call is -made on the parent. -In other words, the subwindows are still mapped but are not visible -until the parent is mapped. -Unmapping a window will generate -<symbol>Expose</symbol> -events on windows that were formerly obscured by it. -</para> -<para> -<!-- .LP --> -<function>XUnmapWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To unmap all subwindows for a specified window, use -<function>XUnmapSubwindows</function>. -</para> -<indexterm significance="preferred"><primary>XUnmapSubwindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunmapsubwindows'> -<funcprototype> - <funcdef><function>XUnmapSubwindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnmapSubwindows</function> -function unmaps all subwindows for the specified window in bottom-to-top -stacking order. -It causes the X server to generate an -<symbol>UnmapNotify</symbol> -event on each subwindow and -<symbol>Expose</symbol> -events on formerly obscured windows. -<indexterm><primary>UnmapNotify Event</primary></indexterm> -Using this function is much more efficient than unmapping multiple windows -one at a time because the server needs to perform much of the work -only once, for all of the windows, rather than for each window. -</para> -<para> -<!-- .LP --> -<function>XUnmapSubwindows</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Configuring_Windows"> -<title>Configuring Windows</title> -<!-- .XS --> -<!-- (SN Configuring Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -Xlib provides functions that you can use to -move a window, resize a window, move and resize a window, or -change a window's border width. -To change one of these parameters, -set the appropriate member of the -<structname>XWindowChanges</structname> -structure and OR in the corresponding value mask in subsequent calls to -<function>XConfigureWindow</function>. -The symbols for the value mask bits and the -<structname>XWindowChanges</structname> -structure are: -<!-- .sM --> -</para> -<para> -<!-- .LP --> - -<literallayout class="monospaced"> -/* Configure window value mask bits */ -#define CWX (1<<0) -#define CWY (1<<1) -#define CWWidth (1<<2) -#define CWHeight (1<<3) -#define CWBorderWidth (1<<4) -#define CWSibling (1<<5) -#define CWStackMode (1<<6) -</literallayout> - -<indexterm significance="preferred"><primary>XWindowChanges</primary></indexterm> -<literallayout class="monospaced"> -/* Values */ - -typedef struct { - int x, y; - int width, height; - int border_width; - Window sibling; - int stack_mode; -} XWindowChanges; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The x and y members are used to set the window's x and y coordinates, -which are relative to the parent's origin -and indicate the position of the upper-left outer corner of the window. -The width and height members are used to set the inside size of the window, -not including the border, and must be nonzero, or a -<errorname>BadValue</errorname> -error results. -Attempts to configure a root window have no effect. -</para> -<para> -<!-- .LP --> -The border_width member is used to set the width of the border in pixels. -Note that setting just the border width leaves the outer-left corner of the window -in a fixed position but moves the absolute position of the window's origin. -If you attempt to set the border-width attribute of an -<symbol>InputOnly</symbol> -window nonzero, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -The sibling member is used to set the sibling window for stacking operations. -The stack_mode member is used to set how the window is to be restacked -and can be set to -<symbol>Above</symbol>, -<symbol>Below</symbol>, -<symbol>TopIf</symbol>, -<symbol>BottomIf</symbol>, -or -<symbol>Opposite</symbol>. -</para> -<para> -<!-- .LP --> -If the override-redirect flag of the window is -<symbol>False</symbol> -and if some other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no further processing is performed. -Otherwise, -if some other client has selected -<symbol>ResizeRedirectMask</symbol> -on the window and the inside -width or height of the window is being changed, -a -<symbol>ResizeRequest</symbol> -event is generated, and the current inside width and height are -used instead. -Note that the override-redirect flag of the window has no effect -on -<symbol>ResizeRedirectMask</symbol> -and that -<symbol>SubstructureRedirectMask</symbol> -on the parent has precedence over -<symbol>ResizeRedirectMask</symbol> -on the window. -</para> -<para> -<!-- .LP --> -When the geometry of the window is changed as specified, -the window is restacked among siblings, and a -<symbol>ConfigureNotify</symbol> -event is generated if the state of the window actually changes. -<symbol>GravityNotify</symbol> -events are generated after -<symbol>ConfigureNotify</symbol> -events. -If the inside width or height of the window has actually changed, -children of the window are affected as specified. -</para> -<para> -<!-- .LP --> -If a window's size actually changes, -the window's subwindows move according to their window gravity. -Depending on the window's bit gravity, -the contents of the window also may be moved -(see <link linkend="Gravity_Attributes">section 3.2.3</link>). -</para> -<para> -<!-- .LP --> -If regions of the window were obscured but now are not, -exposure processing is performed on these formerly obscured windows, -including the window itself and its inferiors. -As a result of increasing the width or height, -exposure processing is also performed on any new regions of the window -and any regions where window contents are lost. -</para> -<para> -<!-- .LP --> -The restack check (specifically, the computation for -<symbol>BottomIf</symbol>, -<symbol>TopIf</symbol>, -and -<symbol>Opposite</symbol>) -is performed with respect to the window's final size and position (as -controlled by the other arguments of the request), not its initial position. -If a sibling is specified without a stack_mode, -a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -If a sibling and a stack_mode are specified, -the window is restacked as follows: -</para> -<informaltable frame="none"> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>Above</symbol></entry> - <entry>The window is placed just above the sibling.</entry> - </row> - <row> - <entry><symbol>Below</symbol></entry> - <entry>The window is placed just below the sibling.</entry> - </row> - <row> - <entry><symbol>TopIf</symbol></entry> - <entry>If the sibling occludes the window, the window is placed at the top of the stack.</entry> - </row> - <row> - <entry><symbol>BottomIf</symbol></entry> - <entry>If the window occludes the sibling, the window is placed at the bottom of the stack.</entry> - </row> - <row> - <entry><symbol>Opposite</symbol></entry> - <entry> -If the sibling occludes the window, the window is placed at the top of the stack. -If the window occludes the sibling, -the window is placed at the bottom of the stack. - </entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -If a stack_mode is specified but no sibling is specified, -the window is restacked as follows: -</para> - -<informaltable frame="none"> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>Above</symbol></entry> - <entry>The window is placed at the top of the stack.</entry> - </row> - <row> - <entry><symbol>Below</symbol></entry> - <entry>The window is placed at the bottom of the stack.</entry> - </row> - <row> - <entry><symbol>TopIf</symbol></entry> - <entry> -If any sibling occludes the window, the window is placed at -the top of the stack. - </entry> - </row> - <row> - <entry><symbol>BottomIf</symbol></entry> - <entry> -If the window occludes any sibling, the window is placed at -the bottom of the stack. - </entry> - </row> - <row> - <entry><symbol>Opposite</symbol></entry> - <entry> -If any sibling occludes the window, the window -is placed at the top of the stack. -If the window occludes any sibling, -the window is placed at the bottom of the stack. - </entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Attempts to configure a root window have no effect. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To configure a window's size, location, stacking, or border, use -<function>XConfigureWindow</function>. -</para> -<indexterm significance="preferred"><primary>XConfigureWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xconfigurewindow'> -<funcprototype> - <funcdef><function>XConfigureWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedint<parameter> value_mask</parameter></paramdef> - <paramdef>XWindowChanges<parameter> *values</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi to be reconfigured --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_mask</emphasis> - </term> - <listitem> - <para> -Specifies which values are to be set using information in -the values structure. -This mask is the bitwise inclusive OR of the valid configure window values bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XWindowChanges</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XConfigureWindow</function> -function uses the values specified in the -<structname>XWindowChanges</structname> -structure to reconfigure a window's size, position, border, and stacking order. -Values not specified are taken from the existing geometry of the window. -</para> -<para> -<!-- .LP --> -If a sibling is specified without a stack_mode or if the window -is not actually a sibling, -a -<errorname>BadMatch</errorname> -error results. -Note that the computations for -<symbol>BottomIf</symbol>, -<symbol>TopIf</symbol>, -and -<symbol>Opposite</symbol> -are performed with respect to the window's final geometry (as controlled by the -other arguments passed to -<function>XConfigureWindow</function>), -not its initial geometry. -Any backing store contents of the window, its -inferiors, and other newly visible windows are either discarded or -changed to reflect the current screen contents -(depending on the implementation). -</para> -<para> -<!-- .LP --> -<function>XConfigureWindow</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To move a window without changing its size, use -<function>XMoveWindow</function>. -</para> -<indexterm significance="preferred"><primary>XMoveWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmovewindow'> -<funcprototype> - <funcdef><function>XMoveWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi to be moved --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. -<!-- .ds Xy , which define the new location of the top-left pixel \ --> -of the window's border or the window itself if it has no border - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMoveWindow</function> -function moves the specified window to the specified x and y coordinates, -but it does not change the window's size, raise the window, or -change the mapping state of the window. -Moving a mapped window may or may not lose the window's contents -depending on if the window is obscured by nonchildren -and if no backing store exists. -If the contents of the window are lost, -the X server generates -<symbol>Expose</symbol> -events. -Moving a mapped window generates -<symbol>Expose</symbol> -events on any formerly obscured windows. -</para> -<para> -<!-- .LP --> -If the override-redirect flag of the window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no further processing is -performed. -Otherwise, the window is moved. -</para> -<para> -<!-- .LP --> -<function>XMoveWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change a window's size without changing the upper-left coordinate, use -<function>XResizeWindow</function>. -</para> -<indexterm significance="preferred"><primary>XResizeWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xresizewindow'> -<funcprototype> - <funcdef><function>XResizeWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. -<!-- .ds Wh , which are the interior dimensions of the window \ --> -after the call completes - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XResizeWindow</function> -function changes the inside dimensions of the specified window, not including -its borders. -This function does not change the window's upper-left coordinate or -the origin and does not restack the window. -Changing the size of a mapped window may lose its contents and generate -<symbol>Expose</symbol> -events. -If a mapped window is made smaller, -changing its size generates -<symbol>Expose</symbol> -events on windows that the mapped window formerly obscured. -</para> -<para> -<!-- .LP --> -If the override-redirect flag of the window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no further processing is performed. -If either width or height is zero, -a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XResizeWindow</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change the size and location of a window, use -<function>XMoveResizeWindow</function>. -</para> -<indexterm significance="preferred"><primary>XMoveResizeWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmoveresizewindow'> -<funcprototype> - <funcdef><function>XMoveResizeWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi to be reconfigured --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. -<!-- .ds Xy , which define the new position of the window relative to its parent --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which define the interior size of the window --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMoveResizeWindow</function> -function changes the size and location of the specified window -without raising it. -Moving and resizing a mapped window may generate an -<symbol>Expose</symbol> -event on the window. -Depending on the new size and location parameters, -moving and resizing a window may generate -<symbol>Expose</symbol> -events on windows that the window formerly obscured. -</para> -<para> -<!-- .LP --> -If the override-redirect flag of the window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no further processing is performed. -Otherwise, the window size and location are changed. -</para> -<para> -<!-- .LP --> -<function>XMoveResizeWindow</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change the border width of a given window, use -<function>XSetWindowBorderWidth</function>. -</para> -<indexterm significance="preferred"><primary>XSetWindowBorderWidth</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowborderwidth'> -<funcprototype> - <funcdef><function>XSetWindowBorderWidth</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedint<parameter> width</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -Specifies the width of the window border. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWindowBorderWidth</function> -function sets the specified window's border width to the specified width. -</para> -<para> -<!-- .LP --> -<function>XSetWindowBorderWidth</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Changing_Window_Stacking_Order"> -<title>Changing Window Stacking Order</title> -<!-- .XS --> -<!-- (SN Changing Window Stacking Order --> -<!-- .XE --> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -Xlib provides functions that you can use to raise, lower, circulate, -or restack windows. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To raise a window so that no sibling window obscures it, use -<function>XRaiseWindow</function>. -</para> -<indexterm significance="preferred"><primary>XRaiseWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xraisewindow'> -<funcprototype> - <funcdef><function>XRaiseWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRaiseWindow</function> -function -raises the specified window to the top of the stack so that no sibling window -obscures it. -If the windows are regarded as overlapping sheets of paper stacked -on a desk, -then raising a window is analogous to moving the sheet to the top of -the stack but leaving its x and y location on the desk constant. -Raising a mapped window may generate -<symbol>Expose</symbol> -events for the window and any mapped subwindows that were formerly obscured. -</para> -<para> -<!-- .LP --> -If the override-redirect attribute of the window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no processing is performed. -Otherwise, the window is raised. -</para> -<para> -<!-- .LP --> -<function>XRaiseWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To lower a window so that it does not obscure any sibling windows, use -<function>XLowerWindow</function>. -</para> -<indexterm significance="preferred"><primary>XLowerWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlowerwindow'> -<funcprototype> - <funcdef><function>XLowerWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLowerWindow</function> -function lowers the specified window to the bottom of the stack -so that it does not obscure any sibling -windows. -If the windows are regarded as overlapping sheets of paper -stacked on a desk, then lowering a window is analogous to moving the -sheet to the bottom of the stack but leaving its x and y location on -the desk constant. -Lowering a mapped window will generate -<symbol>Expose</symbol> -events on any windows it formerly obscured. -</para> -<para> -<!-- .LP --> -If the override-redirect attribute of the window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates a -<symbol>ConfigureRequest</symbol> -event, and no processing is performed. -Otherwise, the window is lowered to the bottom of the -stack. -</para> -<para> -<!-- .LP --> -<function>XLowerWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To circulate a subwindow up or down, use -<function>XCirculateSubwindows</function>. -</para> -<indexterm significance="preferred"><primary>XCirculateSubwindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcirculatesubwindows'> -<funcprototype> - <funcdef><function>XCirculateSubwindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> direction</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>direction</emphasis> - </term> - <listitem> - <para> -Specifies the direction (up or down) that you want to circulate -the window. -You can pass -<symbol>RaiseLowest</symbol> -or -<symbol>LowerHighest</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCirculateSubwindows</function> -function circulates children of the specified window in the specified -direction. -If you specify -<symbol>RaiseLowest</symbol>, -<function>XCirculateSubwindows</function> -raises the lowest mapped child (if any) that is occluded -by another child to the top of the stack. -If you specify -<symbol>LowerHighest</symbol>, -<function>XCirculateSubwindows</function> -lowers the highest mapped child (if any) that occludes another child -to the bottom of the stack. -Exposure processing is then performed on formerly obscured windows. -If some other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the window, the X server generates a -<symbol>CirculateRequest</symbol> -event, and no further processing is performed. -If a child is actually restacked, -the X server generates a -<symbol>CirculateNotify</symbol> -event. -</para> -<para> -<!-- .LP --> -<function>XCirculateSubwindows</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To raise the lowest mapped child of a window that is partially or completely -occluded by another child, use -<function>XCirculateSubwindowsUp</function>. -</para> -<indexterm significance="preferred"><primary>XCirculateSubwindowsUp</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcirculatesubwindowsup'> -<funcprototype> - <funcdef><function>XCirculateSubwindowsUp</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCirculateSubwindowsUp</function> -function raises the lowest mapped child of the specified window that -is partially -or completely -occluded by another child. -Completely unobscured children are not affected. -This is a convenience function equivalent to -<function>XCirculateSubwindows</function> -with -<symbol>RaiseLowest</symbol> -specified. -</para> -<para> -<!-- .LP --> -<function>XCirculateSubwindowsUp</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To lower the highest mapped child of a window that partially or -completely occludes another child, use -<function>XCirculateSubwindowsDown</function>. -</para> -<indexterm significance="preferred"><primary>XCirculateSubwindowsDown</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcirculatesubwindowsdown'> -<funcprototype> - <funcdef><function>XCirculateSubwindowsDown</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCirculateSubwindowsDown</function> -function lowers the highest mapped child of the specified window that partially -or completely occludes another child. -Completely unobscured children are not affected. -This is a convenience function equivalent to -<function>XCirculateSubwindows</function> -with -<symbol>LowerHighest</symbol> -specified. -</para> -<para> -<!-- .LP --> -<function>XCirculateSubwindowsDown</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To restack a set of windows from top to bottom, use -<function>XRestackWindows</function>. -</para> -<indexterm significance="preferred"><primary>XRestackWindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrestackwindows'> -<funcprototype> - <funcdef><function>XRestackWindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> windows[]</parameter></paramdef> - <paramdef>int<parameter> nwindows</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>windows</emphasis> - </term> - <listitem> - <para> -Specifies an array containing the windows to be restacked. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nwindows</emphasis> - </term> - <listitem> - <para> -Specifies the number of windows to be restacked. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRestackWindows</function> -function restacks the windows in the order specified, -from top to bottom. -The stacking order of the first window in the windows array is unaffected, -but the other windows in the array are stacked underneath the first window, -in the order of the array. -The stacking order of the other windows is not affected. -For each window in the window array that is not a child of the specified window, -a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -If the override-redirect attribute of a window is -<symbol>False</symbol> -and some -other client has selected -<symbol>SubstructureRedirectMask</symbol> -on the parent, the X server generates -<symbol>ConfigureRequest</symbol> -events for each window whose override-redirect flag is not set, -and no further processing is performed. -Otherwise, the windows will be restacked in top-to-bottom order. -</para> -<para> -<!-- .LP --> -<function>XRestackWindows</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Changing_Window_Attributes"> -<title>Changing Window Attributes</title> -<!-- .XS --> -<!-- (SN Changing Window Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set window attributes. -<function>XChangeWindowAttributes</function> -is the more general function that allows you to set one or more window -attributes provided by the -<structname>XSetWindowAttributes</structname> -structure. -The other functions described in this section allow you to set one specific -window attribute, such as a window's background. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change one or more attributes for a given window, use -<function>XChangeWindowAttributes</function>. -</para> -<indexterm significance="preferred"><primary>XChangeWindowAttributes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangewindowattributes'> -<funcprototype> - <funcdef><function>XChangeWindowAttributes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> - <paramdef>XSetWindowAttributes<parameter> *attributes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which window attributes are defined in the attributes -argument. -This mask is the bitwise inclusive OR of the valid attribute mask bits. -If valuemask is zero, -the attributes are ignored and are not referenced. -The values and restrictions are -the same as for -<function>XCreateWindow</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - - </term> - <listitem> - <para> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>attributes</emphasis> - </term> - <listitem> - <para> -Specifies the structure from which the values (as specified by the value mask) -are to be taken. -The value mask should have the appropriate bits -set to indicate which attributes have been set in the structure -(see <link linkend="Window_Attributes">section 3.2</link>). - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Depending on the valuemask, -the -<function>XChangeWindowAttributes</function> -function uses the window attributes in the -<structname>XSetWindowAttributes</structname> -structure to change the specified window attributes. -Changing the background does not cause the window contents to be -changed. -To repaint the window and its background, use -<function>XClearWindow</function>. -Setting the border or changing the background such that the -border tile origin changes causes the border to be repainted. -Changing the background of a root window to -<symbol>None</symbol> -or -<symbol>ParentRelative</symbol> -restores the default background pixmap. -Changing the border of a root window to -<symbol>CopyFromParent</symbol> -restores the default border pixmap. -Changing the win-gravity does not affect the current position of the -window. -Changing the backing-store of an obscured window to -<symbol>WhenMapped</symbol> -or -<symbol>Always</symbol>, -or changing the backing-planes, backing-pixel, or -save-under of a mapped window may have no immediate effect. -Changing the colormap of a window (that is, defining a new map, not -changing the contents of the existing map) generates a -<symbol>ColormapNotify</symbol> -event. -Changing the colormap of a visible window may have no -immediate effect on the screen because the map may not be installed -(see -<function>XInstallColormap</function>). -Changing the cursor of a root window to -<symbol>None</symbol> -restores the default -cursor. -Whenever possible, you are encouraged to share colormaps. -</para> -<para> -<!-- .LP --> -Multiple clients can select input on the same window. -Their event masks are maintained separately. -When an event is generated, -it is reported to all interested clients. -However, only one client at a time can select for -<symbol>SubstructureRedirectMask</symbol>, -<symbol>ResizeRedirectMask</symbol>, -and -<symbol>ButtonPressMask</symbol>. -If a client attempts to select any of these event masks -and some other client has already selected one, -a -<errorname>BadAccess</errorname> -error results. -There is only one do-not-propagate-mask for a window, -not one per client. -</para> -<para> -<!-- .LP --> -<function>XChangeWindowAttributes</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadCursor</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the background of a window to a given pixel, use -<function>XSetWindowBackground</function>. -</para> -<indexterm significance="preferred"><primary>XSetWindowBackground</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowbackground'> -<funcprototype> - <funcdef><function>XSetWindowBackground</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedlong<parameter> background_pixel</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background_pixel</emphasis> - </term> - <listitem> - <para> -Specifies the pixel that is to be used for the background. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWindowBackground</function> -function sets the background of the window to the specified pixel value. -Changing the background does not cause the window contents to be changed. -<function>XSetWindowBackground</function> -uses a pixmap of undefined size filled with the pixel value you passed. -If you try to change the background of an -<symbol>InputOnly</symbol> -window, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XSetWindowBackground</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set the background of a window to a given pixmap, use -<function>XSetWindowBackgroundPixmap</function>. -</para> -<indexterm><primary>Window</primary><secondary>background</secondary></indexterm> -<indexterm significance="preferred"><primary>XSetWindowBackgroundPixmap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowbackgroundpixmap'> -<funcprototype> - <funcdef><function>XSetWindowBackgroundPixmap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Pixmap<parameter> background_pixmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background_pixmap</emphasis> - </term> - <listitem> - <para> -Specifies the background pixmap, -<symbol>ParentRelative</symbol>, -or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm> -<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm> -The -<function>XSetWindowBackgroundPixmap</function> -function sets the background pixmap of the window to the specified pixmap. -The background pixmap can immediately be freed if no further explicit -references to it are to be made. -If -<symbol>ParentRelative</symbol> -is specified, -the background pixmap of the window's parent is used, -or on the root window, the default background is restored. -If you try to change the background of an -<symbol>InputOnly</symbol> -window, a -<errorname>BadMatch</errorname> -error results. -If the background is set to -<symbol>None</symbol>, -the window has no defined background. -</para> -<para> -<!-- .LP --> -<function>XSetWindowBackgroundPixmap</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadWindow</errorname> -errors. -<!-- .NT Note --> -<function>XSetWindowBackground</function> -and -<function>XSetWindowBackgroundPixmap</function> -do not change the current contents of the window. -<!-- .NE --> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change and repaint a window's border to a given pixel, use -<function>XSetWindowBorder</function>. -</para> -<indexterm significance="preferred"><primary>XSetWindowBorder</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowborder'> -<funcprototype> - <funcdef><function>XSetWindowBorder</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>unsignedlong<parameter> border_pixel</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border_pixel</emphasis> - </term> - <listitem> - <para> -Specifies the entry in the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWindowBorder</function> -function sets the border of the window to the pixel value you specify. -If you attempt to perform this on an -<symbol>InputOnly</symbol> -window, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XSetWindowBorder</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change and repaint the border tile of a given window, use -<function>XSetWindowBorderPixmap</function>. -</para> -<indexterm significance="preferred"><primary>XSetWindowBorderPixmap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowborderpixmap'> -<funcprototype> - <funcdef><function>XSetWindowBorderPixmap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Pixmap<parameter> border_pixmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border_pixmap</emphasis> - </term> - <listitem> - <para> -Specifies the border pixmap or -<symbol>CopyFromParent</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWindowBorderPixmap</function> -function sets the border pixmap of the window to the pixmap you specify. -The border pixmap can be freed immediately if no further explicit -references to it are to be made. -If you specify -<symbol>CopyFromParent</symbol>, -a copy of the parent window's border pixmap is used. -If you attempt to perform this on an -<symbol>InputOnly</symbol> -window, a -<errorname>BadMatch</errorname> -error results. -<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm> -<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm> -</para> -<para> -<!-- .LP --> -<function>XSetWindowBorderPixmap</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the colormap of a given window, use -<function>XSetWindowColormap</function>. -</para> -<indexterm significance="preferred"><primary>XSetWindowColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwindowcolormap'> -<funcprototype> - <funcdef><function>XSetWindowColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWindowColormap</function> -function sets the specified colormap of the specified window. -The colormap must have the same visual type as the window, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XSetWindowColormap</function> -can generate -<errorname>BadColor</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To define which cursor will be used in a window, use -<function>XDefineCursor</function>. -</para> -<indexterm><primary>Window</primary><secondary>defining the cursor</secondary></indexterm> -<indexterm significance="preferred"><primary>XDefineCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdefinecursor'> -<funcprototype> - <funcdef><function>XDefineCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor that is to be displayed or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If a cursor is set, it will be used when the pointer is in the window. -If the cursor is -<symbol>None</symbol>, -it is equivalent to -<function>XUndefineCursor</function>. -</para> -<para> -<!-- .LP --> -<function>XDefineCursor</function> -can generate -<errorname>BadCursor</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To undefine the cursor in a given window, use -<function>XUndefineCursor</function>. -</para> -<indexterm><primary>Window</primary><secondary>undefining the cursor</secondary></indexterm> -<indexterm significance="preferred"><primary>XUndefineCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xundefinecursor'> -<funcprototype> - <funcdef><function>XUndefineCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUndefineCursor</function> -function undoes the effect of a previous -<function>XDefineCursor</function> -for this window. -When the pointer is in the window, -the parent's cursor will now be used. -On the root window, -the default cursor is restored. -</para> -<para> -<!-- .LP --> -<function>XUndefineCursor</function> -can generate a -<errorname>BadWindow</errorname> -error. -<!-- .bp --> - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="window_functions"><title>Window Functions</title>
+<sect1 id="Visual_Types">
+<title>Visual Types</title>
+<!-- .XS -->
+<!-- (SN Visual Types -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>Visual Type</primary></indexterm>
+On some display hardware,
+it may be possible to deal with color resources in more than one way.
+For example, you may be able to deal with a screen of either 12-bit depth
+with arbitrary mapping of pixel to color (pseudo-color) or 24-bit depth
+with 8 bits of the pixel dedicated to each of red, green, and blue.
+These different ways of dealing with the visual aspects of the screen
+are called visuals.
+For each screen of the display, there may be a list of valid visual types
+supported at different depths of the screen.
+Because default windows and visual types are defined for each screen,
+most simple applications need not deal with this complexity.
+Xlib provides macros and functions that return the default root window,
+the default depth of the default root window, and the default visual type
+(see sections <link linkend="Display_Macros_">2.2.1</link>
+and <link linkend="Determining_the_Appropriate_Visual_Type">16.7</link>).
+</para>
+<para>
+<!-- .LP -->
+Xlib uses an opaque
+<structname>Visual</structname>
+<indexterm significance="preferred"><primary>Visual</primary></indexterm>
+structure that contains information about the possible color mapping.
+The visual utility functions
+(see <link linkend="Determining_the_Appropriate_Visual_Type">section 16.7</link>)
+use an
+<structname>XVisualInfo</structname>
+structure to return this information to an application.
+The members of this structure pertinent to this discussion are class, red_mask,
+green_mask, blue_mask, bits_per_rgb, and colormap_size.
+The class member specifies one of the possible visual classes of the screen
+and can be
+<indexterm><primary>Visual Classes</primary><secondary>StaticGray</secondary></indexterm>
+<indexterm><primary>Visual Classes</primary><secondary>StaticColor</secondary></indexterm>
+<indexterm><primary>Visual Classes</primary><secondary>TrueColor</secondary></indexterm>
+<indexterm><primary>Visual Classes</primary><secondary>StaticColor</secondary></indexterm>
+<indexterm><primary>Visual Classes</primary><secondary>GrayScale</secondary></indexterm>
+<indexterm><primary>Visual Classes</primary><secondary>PseudoColor</secondary></indexterm>
+<symbol>StaticGray</symbol>,
+<symbol>StaticColor</symbol>,
+<symbol>TrueColor</symbol>,
+<symbol>GrayScale</symbol>,
+<symbol>PseudoColor</symbol>,
+or
+<symbol>DirectColor</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The following concepts may serve to make the explanation of
+visual types clearer.
+The screen can be color or grayscale,
+can have a colormap that is writable or read-only,
+and can also have a colormap whose indices are decomposed into separate
+<acronym>RGB</acronym> pieces, provided one is not on a grayscale screen.
+This leads to the following diagram:
+</para>
+
+<literallayout class="monospaced">
+ Color Gray-Scale
+ R/O R/W R/O R/W
+----------------------------------------------
+ Undecomposed Static Pseudo Static Gray
+ Colormap Color Color Gray Scale
+
+ Decomposed True Direct
+ Colormap Color Color
+----------------------------------------------
+</literallayout>
+
+<para>
+<!-- .LP -->
+Conceptually,
+as each pixel is read out of video memory for display on the screen,
+it goes through a look-up stage by indexing into a colormap.
+Colormaps can be manipulated arbitrarily on some hardware,
+in limited ways on other hardware, and not at all on other hardware.
+The visual types affect the colormap and
+the <acronym>RGB</acronym> values in the following ways:
+</para>
+<para>
+<!-- .LP -->
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+For
+<symbol>PseudoColor</symbol>,
+a pixel value indexes a colormap to produce
+independent <acronym>RGB</acronym> values, and the <acronym>RGB</acronym> values can be changed dynamically.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>GrayScale</symbol>
+is treated the same way as
+<symbol>PseudoColor</symbol>
+except that the primary that drives the screen is undefined.
+Thus, the client should always store the
+same value for red, green, and blue in the colormaps.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+For
+<symbol>DirectColor</symbol>,
+a pixel value is decomposed into separate <acronym>RGB</acronym> subfields, and each
+subfield separately indexes the colormap for the corresponding value.
+The <acronym>RGB</acronym> values can be changed dynamically.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>TrueColor</symbol>
+is treated the same way as
+<symbol>DirectColor</symbol>
+except that the colormap has predefined, read-only <acronym>RGB</acronym> values.
+These <acronym>RGB</acronym> values are server dependent but provide linear or near-linear
+ramps in each primary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>StaticColor</symbol>
+is treated the same way as
+<symbol>PseudoColor</symbol>
+except that the colormap has predefined,
+read-only, server-dependent <acronym>RGB</acronym> values.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>StaticGray</symbol>
+is treated the same way as
+<symbol>StaticColor</symbol>
+except that the <acronym>RGB</acronym> values are equal for any single pixel
+value, thus resulting in shades of gray.
+<symbol>StaticGray</symbol>
+with a two-entry
+colormap can be thought of as monochrome.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The red_mask, green_mask, and blue_mask members are only defined for
+<symbol>DirectColor</symbol>
+and
+<symbol>TrueColor</symbol>.
+Each has one contiguous set of bits with no
+intersections.
+The bits_per_rgb member specifies the log base 2 of the
+number of distinct color values (individually) of red, green, and blue.
+Actual <acronym>RGB</acronym> values are unsigned 16-bit numbers.
+The colormap_size member defines the number of available colormap entries
+in a newly created colormap.
+For
+<symbol>DirectColor</symbol>
+and
+<symbol>TrueColor</symbol>,
+this is the size of an individual pixel subfield.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the visual ID from a
+<structname>Visual</structname>,
+use
+<function>XVisualIDFromVisual</function>.
+<indexterm significance="preferred"><primary>XVisualIDFromVisual</primary></indexterm>
+</para>
+<!-- .sM -->
+<funcsynopsis id='xvisualidfromvisual'>
+<funcprototype>
+ <funcdef>VisualID <function>XVisualIDFromVisual</function></funcdef>
+ <paramdef>Visual *<parameter>visual</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>visual</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the visual type.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XVisualIDFromVisual</function>
+function returns the visual ID for the specified visual type.
+</para>
+</sect1>
+<sect1 id="Window_Attributes">
+<title>Window Attributes</title>
+<!-- .XS -->
+<!-- (SN Window Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Window</primary></indexterm>
+<indexterm><primary>Window</primary><secondary>attributes</secondary></indexterm>
+All
+<symbol>InputOutput</symbol>
+windows have a border width of zero or more pixels, an optional background,
+an event suppression mask (which suppresses propagation of events from
+children), and a property list
+(see <link linkend="Properties_and_Atoms">section 4.3</link>).
+The window border and background can be a solid color or a pattern, called
+a tile.
+All windows except the root have a parent and are clipped by their parent.
+If a window is stacked on top of another window, it obscures that other
+window for the purpose of input.
+If a window has a background (almost all do), it obscures the other
+window for purposes of output.
+Attempts to output to the obscured area do nothing,
+and no input events (for example, pointer motion) are generated for the
+obscured area.
+</para>
+<para>
+<!-- .LP -->
+Windows also have associated property lists
+(see <link linkend="Properties_and_Atoms">section 4.3</link>).
+</para>
+<para>
+<!-- .LP -->
+Both
+<symbol>InputOutput</symbol>
+and
+<symbol>InputOnly</symbol>
+windows have the following common attributes,
+which are the only attributes of an
+<symbol>InputOnly</symbol>
+window:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+win-gravity
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+event-mask
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+do-not-propagate-mask
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+override-redirect
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+cursor
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+If you specify any other attributes for an
+<symbol>InputOnly</symbol>
+window,
+a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<symbol>InputOnly</symbol>
+windows are used for controlling input events in situations where
+<symbol>InputOutput</symbol>
+windows are unnecessary.
+<symbol>InputOnly</symbol>
+windows are invisible; can only be used to control such things as
+cursors, input event generation, and grabbing;
+and cannot be used in any graphics requests.
+Note that
+<symbol>InputOnly</symbol>
+windows cannot have
+<symbol>InputOutput</symbol>
+windows as inferiors.
+</para>
+<para>
+<!-- .LP -->
+Windows have borders of a programmable width and pattern
+as well as a background pattern or tile.
+<indexterm><primary>Tile</primary><secondary>pixmaps</secondary></indexterm>
+Pixel values can be used for solid colors.
+<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm>
+<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm>
+The background and border pixmaps can be destroyed immediately after
+creating the window if no further explicit references to them
+are to be made.
+<indexterm ><primary>Tile</primary><secondary>mode</secondary></indexterm>
+The pattern can either be relative to the parent
+or absolute.
+If
+<symbol>ParentRelative</symbol>,
+the parent's background is used.
+</para>
+<para>
+<!-- .LP -->
+When windows are first created,
+they are not visible (not mapped) on the screen.
+Any output to a window that is not visible on the screen
+and that does not have backing store will be discarded.
+<indexterm><primary>Window</primary><secondary>mapping</secondary></indexterm>
+An application may wish to create a window long before it is
+mapped to the screen.
+When a window is eventually mapped to the screen
+(using
+<function>XMapWindow</function>),
+<indexterm><primary>XMapWindow</primary></indexterm>
+the X server generates an
+<symbol>Expose</symbol>
+event for the window if backing store has not been maintained.
+</para>
+<para>
+<!-- .LP -->
+A window manager can override your choice of size,
+border width, and position for a top-level window.
+Your program must be prepared to use the actual size and position
+of the top window.
+It is not acceptable for a client application to resize itself
+unless in direct response to a human command to do so.
+Instead, either your program should use the space given to it,
+or if the space is too small for any useful work, your program
+might ask the user to resize the window.
+The border of your top-level window is considered fair game
+for window managers.
+</para>
+<para>
+<!-- .LP -->
+To set an attribute of a window,
+set the appropriate member of the
+<structname>XSetWindowAttributes</structname>
+structure and OR in the corresponding value bitmask in your subsequent calls to
+<function>XCreateWindow</function>
+and
+<function>XChangeWindowAttributes</function>,
+or use one of the other convenience functions that set the appropriate
+attribute.
+The symbols for the value mask bits and the
+<structname>XSetWindowAttributes</structname>
+structure are:
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+/* Window attribute value mask bits */
+
+
+<literallayout class="monospaced">
+/* Window attribute value mask bits */
+#define CWBackPixmap (1L<<0)
+#define CWBackPixel (1L<<1)
+#define CWBorderPixmap (1L<<2)
+#define CWBorderPixel (1L<<3)
+#define CWBitGravity (1L<<4)
+#define CWWinGravity (1L<<5)
+#define CWBackingStore (1L<<6)
+#define CWBackingPlanes (1L<<7)
+#define CWBackingPixel (1L<<8)
+#define CWOverrideRedirect (1L<<9)
+#define CWSaveUnder (1L<<10)
+#define CWEventMask (1L<<11)
+#define CWDontPropagate (1L<<12)
+#define CWColormap (1L<<13)
+#define CWCursor (1L<<14)
+</literallayout>
+
+<indexterm significance="preferred"><primary>XSetWindowAttributes</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+/* Values */
+
+typedef struct {
+ Pixmap background_pixmap; /* background, None, or ParentRelative */
+ unsigned long background_pixel; /* background pixel */
+ Pixmap border_pixmap; /* border of the window or CopyFromParent */
+ unsigned long border_pixel; /* border pixel value */
+ int bit_gravity; /* one of bit gravity values */
+ int win_gravity; /* one of the window gravity values */
+ int backing_store; /* NotUseful, WhenMapped, Always */
+ unsigned long backing_planes; /* planes to be preserved if possible */
+ unsigned long backing_pixel; /* value to use in restoring planes */
+ Bool save_under; /* should bits under be saved? (popups) */
+ long event_mask; /* set of events that should be saved */
+ long do_not_propagate_mask; /* set of events that should not propagate */
+ Bool override_redirect; /* boolean value for override_redirect */
+ Colormap colormap; /* color map to be associated with window */
+ Cursor cursor; /* cursor to be displayed (or None) */
+} XSetWindowAttributes;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The following lists the defaults for each window attribute and indicates
+whether the attribute is applicable to
+<symbol>InputOutput</symbol>
+and
+<symbol>InputOnly</symbol>
+windows:
+</para>
+<informaltable>
+ <tgroup cols='4'>
+ <colspec colname='c1' align='left'/>
+ <colspec colname='c2' align='left'/>
+ <colspec colname='c3' align='center'/>
+ <colspec colname='c4' align='center'/>
+ <thead>
+ <row>
+ <entry>Attribute</entry>
+ <entry>Default</entry>
+ <entry>InputOutput</entry>
+ <entry>InputOnly</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>background-pixmap</entry>
+ <entry><symbol>None</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>background-pixel</entry>
+ <entry>Undefined</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>border-pixmap</entry>
+ <entry><symbol>CopyFromParent</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>border-pixel</entry>
+ <entry>Undefined</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>bit-gravity</entry>
+ <entry><symbol>ForgetGravity</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>win-gravity</entry>
+ <entry><symbol>NorthWestGravity</symbol></entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry>backing-store</entry>
+ <entry><symbol>NotUseful</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>backing-planes</entry>
+ <entry>All ones</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>backing-pixel</entry>
+ <entry>zero</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>save-under</entry>
+ <entry><symbol>False</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>event-mask</entry>
+ <entry>empty set</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry>do-not-propagate-mask</entry>
+ <entry>empty set</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry>override-redirect</entry>
+ <entry><symbol>False</symbol></entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry>colormap</entry>
+ <entry><symbol>CopyFromParent</symbol></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ </row>
+ <row>
+ <entry>cursor</entry>
+ <entry><symbol>None</symbol></entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<sect2 id="Background_Attribute">
+<title>Background Attribute</title>
+<!-- .XS -->
+<!-- (SN Background Attribute -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Only
+<symbol>InputOutput</symbol>
+windows can have a background.
+You can set the background of an
+<symbol>InputOutput</symbol>
+window by using a pixel or a pixmap.
+</para>
+<para>
+<!-- .LP -->
+The background-pixmap attribute of a window specifies the pixmap to be used for
+a window's background.
+This pixmap can be of any size, although some sizes may be faster than others.
+The background-pixel attribute of a window specifies a pixel value used to paint
+a window's background in a single color.
+</para>
+<para>
+<!-- .LP -->
+You can set the background-pixmap to a pixmap,
+<symbol>None</symbol>
+(default), or
+<symbol>ParentRelative</symbol>.
+You can set the background-pixel of a window to any pixel value (no default).
+If you specify a background-pixel,
+it overrides either the default background-pixmap
+or any value you may have set in the background-pixmap.
+A pixmap of an undefined size that is filled with the background-pixel is used
+for the background.
+Range checking is not performed on the background pixel;
+it simply is truncated to the appropriate number of bits.
+</para>
+<para>
+<!-- .LP -->
+If you set the background-pixmap,
+it overrides the default.
+The background-pixmap and the window must have the same depth,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If you set background-pixmap to
+<symbol>None</symbol>,
+the window has no defined background.
+If you set the background-pixmap to
+<symbol>ParentRelative</symbol>:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The parent window's background-pixmap is used.
+The child window, however, must have the same depth as
+its parent,
+or a
+<errorname>BadMatch</errorname>
+error results.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the parent window has a background-pixmap of
+<symbol>None</symbol>,
+the window also has a background-pixmap of
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A copy of the parent window's background-pixmap is not made.
+The parent's background-pixmap is examined each time the child window's
+background-pixmap is required.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The background tile origin always aligns with the parent window's
+background tile origin.
+If the background-pixmap is not
+<symbol>ParentRelative</symbol>,
+the background tile origin is the child window's origin.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Setting a new background, whether by setting background-pixmap or
+background-pixel, overrides any previous background.
+The background-pixmap can be freed immediately if no further explicit reference
+is made to it (the X server will keep a copy to use when needed).
+If you later draw into the pixmap used for the background,
+what happens is undefined because the
+X implementation is free to make a copy of the pixmap or
+to use the same pixmap.
+</para>
+<para>
+<!-- .LP -->
+When no valid contents are available for regions of a window
+and either the regions are visible or the server is maintaining backing store,
+the server automatically tiles the regions with the window's background
+unless the window has a background of
+<symbol>None</symbol>.
+If the background is
+<symbol>None</symbol>,
+the previous screen contents from other windows of the same depth as the window
+are simply left in place as long as the contents come from the parent of the
+window or an inferior of the parent.
+Otherwise, the initial contents of the exposed regions are undefined.
+<symbol>Expose</symbol>
+events are then generated for the regions, even if the background-pixmap
+is
+<symbol>None</symbol>
+(see <link linkend="Exposure_Events">section 10.9</link>).
+</para>
+</sect2>
+<sect2 id="Border_Attribute">
+<title>Border Attribute</title>
+<!-- .XS -->
+<!-- (SN Border Attribute -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Only
+<symbol>InputOutput</symbol>
+windows can have a border.
+You can set the border of an
+<symbol>InputOutput</symbol>
+window by using a pixel or a pixmap.
+</para>
+<para>
+<!-- .LP -->
+The border-pixmap attribute of a window specifies the pixmap to be used
+for a window's border.
+The border-pixel attribute of a window specifies a pixmap of undefined size
+filled with that pixel be used for a window's border.
+Range checking is not performed on the background pixel;
+it simply is truncated to the appropriate number of bits.
+The border tile origin is always the same as the background tile origin.
+</para>
+<para>
+<!-- .LP -->
+You can also set the border-pixmap to a pixmap of any size (some may be faster
+than others) or to
+<symbol>CopyFromParent</symbol>
+(default).
+You can set the border-pixel to any pixel value (no default).
+</para>
+<para>
+<!-- .LP -->
+If you set a border-pixmap,
+it overrides the default.
+The border-pixmap and the window must have the same depth,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If you set the border-pixmap to
+<symbol>CopyFromParent</symbol>,
+the parent window's border-pixmap is copied.
+Subsequent changes to the parent window's border attribute do not affect
+the child window.
+However, the child window must have the same depth as the parent window,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The border-pixmap can be freed immediately if no further explicit reference
+is made to it.
+If you later draw into the pixmap used for the border,
+what happens is undefined because the
+X implementation is free either to make a copy of the pixmap or
+to use the same pixmap.
+If you specify a border-pixel,
+it overrides either the default border-pixmap
+or any value you may have set in the border-pixmap.
+All pixels in the window's border will be set to the border-pixel.
+Setting a new border, whether by setting border-pixel or by setting
+border-pixmap, overrides any previous border.
+</para>
+<para>
+<!-- .LP -->
+Output to a window is always clipped to the inside of the window.
+Therefore, graphics operations never affect the window border.
+</para>
+</sect2>
+<sect2 id="Gravity_Attributes">
+<title>Gravity Attributes</title>
+<!-- .XS -->
+<!-- (SN Gravity Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The bit gravity of a window defines which region of the window should be
+retained when an
+<symbol>InputOutput</symbol>
+window is resized.
+The default value for the bit-gravity attribute is
+<symbol>ForgetGravity</symbol>.
+The window gravity of a window allows you to define how the
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window should be repositioned if its parent is resized.
+The default value for the win-gravity attribute is
+<symbol>NorthWestGravity</symbol>.
+</para>
+<para>
+<!-- .LP -->
+If the inside width or height of a window is not changed
+and if the window is moved or its border is changed,
+then the contents of the window are not lost but move with the window.
+Changing the inside width or height of the window causes its contents to be
+moved or lost (depending on the bit-gravity of the window) and causes
+children to be reconfigured (depending on their win-gravity).
+For a
+change of width and height, the (x, y) pairs are defined:
+</para>
+<para>
+<!-- .LP -->
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1' align='left'/>
+ <colspec colname='c2' align='left'/>
+ <thead>
+ <row>
+ <entry>Gravity Direction</entry>
+ <entry>Coordinates</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><symbol>NorthWestGravity</symbol></entry>
+ <entry>(0, 0)</entry>
+ </row>
+ <row>
+ <entry><symbol>NorthGravity</symbol></entry>
+ <entry>(Width/2, 0)</entry>
+ </row>
+ <row>
+ <entry><symbol>NorthEastGravity</symbol></entry>
+ <entry>(Width, 0)</entry>
+ </row>
+ <row>
+ <entry><symbol>WestGravity</symbol></entry>
+ <entry>(0, Height/2)</entry>
+ </row>
+ <row>
+ <entry><symbol>CenterGravity</symbol></entry>
+ <entry>(Width/2, Height/2)</entry>
+ </row>
+ <row>
+ <entry><symbol>EastGravity</symbol></entry>
+ <entry>(Width, Height/2)</entry>
+ </row>
+ <row>
+ <entry><symbol>SouthWestGravity</symbol></entry>
+ <entry>(0, Height)</entry>
+ </row>
+ <row>
+ <entry><symbol>SouthGravity</symbol></entry>
+ <entry>(Width/2, Height)</entry>
+ </row>
+ <row>
+ <entry><symbol>SouthEastGravity</symbol></entry>
+ <entry>(Width, Height)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+</para>
+<para>
+<!-- .LP -->
+When a window with one of these bit-gravity values is resized,
+the corresponding pair
+defines the change in position of each pixel in the window.
+When a window with one of these win-gravities has its parent window resized,
+the corresponding pair defines the change in position of the window
+within the parent.
+When a window is so repositioned, a
+<symbol>GravityNotify</symbol>
+event is generated
+(see <link linkend="GravityNotify_Events">section 10.10.5</link>).
+</para>
+<para>
+<!-- .LP -->
+A bit-gravity of
+<symbol>StaticGravity</symbol>
+indicates that the contents or origin should not move relative to the
+origin of the root window.
+If the change in size of the window is coupled with a change in position (x, y),
+then for bit-gravity the change in position of each pixel is (−x, −y), and for
+win-gravity the change in position of a child when its parent is so resized is
+(−x, −y).
+Note that
+<symbol>StaticGravity</symbol>
+still only takes effect when the width or height of the window is changed,
+not when the window is moved.
+</para>
+<para>
+<!-- .LP -->
+A bit-gravity of
+<symbol>ForgetGravity</symbol>
+indicates that the window's contents are always discarded after a size change,
+even if a backing store or save under has been requested.
+The window is tiled with its background
+and zero or more
+<symbol>Expose</symbol>
+events are generated.
+If no background is defined, the existing screen contents are not
+altered.
+Some X servers may also ignore the specified bit-gravity and
+always generate
+<symbol>Expose</symbol>
+events.
+</para>
+<para>
+<!-- .LP -->
+The contents and borders of inferiors are not affected by their parent's
+bit-gravity.
+A server is permitted to ignore the specified bit-gravity and use
+<symbol>Forget</symbol>
+instead.
+</para>
+<para>
+<!-- .LP -->
+A win-gravity of
+<symbol>UnmapGravity</symbol>
+is like
+<symbol>NorthWestGravity</symbol>
+(the window is not moved),
+except the child is also
+unmapped when the parent is resized,
+and an
+<symbol>UnmapNotify</symbol>
+event is
+generated.
+</para>
+</sect2>
+<sect2 id="Backing_Store_Attribute">
+<title>Backing Store Attribute</title>
+<!-- .XS -->
+<!-- (SN Backing Store Attribute -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some implementations of the X server may choose to maintain the contents of
+<symbol>InputOutput</symbol>
+windows.
+If the X server maintains the contents of a window,
+the off-screen saved pixels
+are known as backing store.
+The backing store advises the X server on what to do
+with the contents of a window.
+The backing-store attribute can be set to
+<symbol>NotUseful</symbol>
+(default),
+<symbol>WhenMapped</symbol>,
+or
+<symbol>Always</symbol>.
+</para>
+<para>
+<!-- .LP -->
+A backing-store attribute of
+<symbol>NotUseful</symbol>
+advises the X server that
+maintaining contents is unnecessary,
+although some X implementations may
+still choose to maintain contents and, therefore, not generate
+<symbol>Expose</symbol>
+events.
+A backing-store attribute of
+<symbol>WhenMapped</symbol>
+advises the X server that maintaining contents of
+obscured regions when the window is mapped would be beneficial.
+In this case,
+the server may generate an
+<symbol>Expose</symbol>
+event when the window is created.
+A backing-store attribute of
+<symbol>Always</symbol>
+advises the X server that maintaining contents even when
+the window is unmapped would be beneficial.
+Even if the window is larger than its parent,
+this is a request to the X server to maintain complete contents,
+not just the region within the parent window boundaries.
+While the X server maintains the window's contents,
+<symbol>Expose</symbol>
+events normally are not generated,
+but the X server may stop maintaining
+contents at any time.
+</para>
+<para>
+<!-- .LP -->
+When the contents of obscured regions of a window are being maintained,
+regions obscured by noninferior windows are included in the destination
+of graphics requests (and source, when the window is the source).
+However, regions obscured by inferior windows are not included.
+</para>
+</sect2>
+<sect2 id="Save_Under_Flag">
+<title>Save Under Flag</title>
+<!-- .XS -->
+<!-- (SN Save Under Flag -->
+<!-- .XE -->
+<indexterm><primary>Save Unders</primary></indexterm>
+<para>
+<!-- .LP -->
+Some server implementations may preserve contents of
+<symbol>InputOutput</symbol>
+windows under other
+<symbol>InputOutput</symbol>
+windows.
+This is not the same as preserving the contents of a window for you.
+You may get better visual
+appeal if transient windows (for example, pop-up menus) request that the system
+preserve the screen contents under them,
+so the temporarily obscured applications do not have to repaint.
+</para>
+<para>
+<!-- .LP -->
+You can set the save-under flag to
+<symbol>True</symbol>
+or
+<symbol>False</symbol>
+(default).
+If save-under is
+<symbol>True</symbol>,
+the X server is advised that, when this window is mapped,
+saving the contents of windows it obscures would be beneficial.
+</para>
+</sect2>
+<sect2 id="Backing_Planes_and_Backing_Pixel_Attributes">
+<title>Backing Planes and Backing Pixel Attributes</title>
+<!-- .XS -->
+<!-- (SN Backing Planes and Backing Pixel Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You can set backing planes to indicate (with bits set to 1)
+which bit planes of an
+<symbol>InputOutput</symbol>
+window hold dynamic data that must be preserved in backing store
+and during save unders.
+The default value for the backing-planes attribute is all bits set to 1.
+You can set backing pixel to specify what bits to use in planes not
+covered by backing planes.
+The default value for the backing-pixel attribute is all bits set to 0.
+The X server is free to save only the specified bit planes in the backing store
+or the save under and is free to regenerate the remaining planes with
+the specified pixel value.
+Any extraneous bits in these values (that is, those bits beyond
+the specified depth of the window) may be simply ignored.
+If you request backing store or save unders,
+you should use these members to minimize the amount of off-screen memory
+required to store your window.
+</para>
+</sect2>
+<sect2 id="Event_Mask_and_Do_Not_Propagate_Mask_Attributes">
+<title>Event Mask and Do Not Propagate Mask Attributes</title>
+<!-- .XS -->
+<!-- (SN Event Mask and Do Not Propagate Mask Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The event mask defines which events the client is interested in for this
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window (or, for some event types, inferiors of this window).
+The event mask is the bitwise inclusive OR of zero or more of the
+valid event mask bits.
+You can specify that no maskable events are reported by setting
+<symbol>NoEventMask</symbol>
+(default).
+</para>
+<para>
+<!-- .LP -->
+The do-not-propagate-mask attribute
+defines which events should not be propagated to
+ancestor windows when no client has the event type selected in this
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window.
+The do-not-propagate-mask is the bitwise inclusive OR of zero or more
+of the following masks:
+<symbol>KeyPress</symbol>,
+<symbol>KeyRelease</symbol>,
+<symbol>ButtonPress</symbol>,
+<symbol>ButtonRelease</symbol>,
+<symbol>PointerMotion</symbol>,
+<symbol>Button1Motion</symbol>,
+<symbol>Button2Motion</symbol>,
+<symbol>Button3Motion</symbol>,
+<symbol>Button4Motion</symbol>,
+<symbol>Button5Motion</symbol>,
+and
+<symbol>ButtonMotion</symbol>.
+You can specify that all events are propagated by setting
+<symbol>NoEventMask</symbol>
+(default).
+</para>
+</sect2>
+<sect2 id="Override_Redirect_Flag">
+<title>Override Redirect Flag</title>
+<!-- .XS -->
+<!-- (SN Override Redirect Flag -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To control window placement or to add decoration,
+a window manager often needs to intercept (redirect) any map or configure
+request.
+Pop-up windows, however, often need to be mapped without a window manager
+getting in the way.
+To control whether an
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window is to ignore these structure control facilities,
+use the override-redirect flag.
+</para>
+<para>
+<!-- .LP -->
+The override-redirect flag specifies whether map and configure requests
+on this window should override a
+<symbol>SubstructureRedirectMask</symbol>
+on the parent.
+You can set the override-redirect flag to
+<symbol>True</symbol>
+or
+<symbol>False</symbol>
+(default).
+Window managers use this information to avoid tampering with pop-up windows
+(see also <link linkend="inter_client_communication_functions">chapter 14</link>).
+</para>
+</sect2>
+<sect2 id="Colormap_Attribute">
+<title>Colormap Attribute</title>
+<!-- .XS -->
+<!-- (SN Colormap Attribute -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The colormap attribute specifies which colormap best reflects the true
+colors of the
+<symbol>InputOutput</symbol>
+window.
+The colormap must have the same visual type as the window,
+or a
+<errorname>BadMatch</errorname>
+error results.
+X servers capable of supporting multiple
+hardware colormaps can use this information,
+and window managers can use it for calls to
+<function>XInstallColormap</function>.
+You can set the colormap attribute to a colormap or to
+<symbol>CopyFromParent</symbol>
+(default).
+</para>
+<para>
+<!-- .LP -->
+If you set the colormap to
+<symbol>CopyFromParent</symbol>,
+the parent window's colormap is copied and used by its child.
+However, the child window must have the same visual type as the parent,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The parent window must not have a colormap of
+<symbol>None</symbol>,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The colormap is copied by sharing the colormap object between the child
+and parent, not by making a complete copy of the colormap contents.
+Subsequent changes to the parent window's colormap attribute do
+not affect the child window.
+</para>
+</sect2>
+<sect2 id="Cursor_Attribute">
+<title>Cursor Attribute</title>
+<!-- .XS -->
+<!-- (SN Cursor Attribute -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The cursor attribute specifies which cursor is to be used when the pointer is
+in the
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window.
+You can set the cursor to a cursor or
+<symbol>None</symbol>
+(default).
+</para>
+<para>
+<!-- .LP -->
+If you set the cursor to
+<symbol>None</symbol>,
+the parent's cursor is used when the
+pointer is in the
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>
+window, and any change in the parent's cursor will cause an
+immediate change in the displayed cursor.
+By calling
+<function>XFreeCursor</function>,
+the cursor can be freed immediately as long as no further explicit reference
+to it is made.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Creating_Windows">
+<title>Creating Windows</title>
+<!-- .XS -->
+<!-- (SN Creating Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides basic ways for creating windows,
+and toolkits often supply higher-level functions specifically for
+creating and placing top-level windows,
+which are discussed in the appropriate toolkit documentation.
+If you do not use a toolkit, however,
+you must provide some standard information or hints for the window
+manager by using the Xlib inter-client communication functions
+(see <link linkend="inter_client_communication_functions">chapter 14</link>).
+</para>
+<para>
+<!-- .LP -->
+If you use Xlib to create your own top-level windows
+(direct children of the root window),
+you must observe the following rules so that all applications interact
+reasonably across the different styles of window management:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+You must never fight with the window manager for the size or
+placement of your top-level window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+You must be able to deal with whatever size window you get,
+even if this means that your application just prints a message
+like ``Please make me bigger'' in its window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+You should only attempt to resize or move top-level windows in
+direct response to a user request.
+If a request to change the size of a top-level window fails,
+you must be prepared to live with what you get.
+You are free to resize or move the children of top-level
+windows as necessary.
+(Toolkits often have facilities for automatic relayout.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If you do not use a toolkit that automatically sets standard window properties,
+you should set these properties for top-level windows before mapping them.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+For further information,
+see <link linkend="inter_client_communication_functions">chapter 14</link> and
+the <emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateWindow</function>
+is the more general function that allows you to set specific window attributes
+when you create a window.
+<function>XCreateSimpleWindow</function>
+creates a window that inherits its attributes from its parent window.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Window</primary><secondary>InputOnly</secondary></indexterm>
+The X server acts as if
+<symbol>InputOnly</symbol>
+windows do not exist for
+the purposes of graphics requests, exposure processing, and
+<symbol>VisibilityNotify</symbol>
+events.
+An
+<symbol>InputOnly</symbol>
+window cannot be used as a
+drawable (that is, as a source or destination for graphics requests).
+<symbol>InputOnly</symbol>
+and
+<symbol>InputOutput</symbol>
+windows act identically in other respects (properties,
+grabs, input control, and so on).
+Extension packages can define other classes of windows.
+</para>
+<para>
+<!-- .LP -->
+To create an unmapped window and set its window attributes, use
+<function>XCreateWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatewindow'>
+<funcprototype>
+ <funcdef>Window <function>XCreateWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> parent</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint<parameter> border_width</parameter></paramdef>
+ <paramdef>int<parameter> depth</parameter></paramdef>
+ <paramdef>unsignedint<parameter> class</parameter></paramdef>
+ <paramdef>Visual<parameter> *visual</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XSetWindowAttributes<parameter> *attributes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>parent</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the parent window.
+<!-- .ds Xy , which are the top-left outside corner of the created window's \ -->
+borders and are relative to the inside of the parent window's borders
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the created window's inside dimensions \ -->
+and do not include the created window's borders
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+The dimensions must be nonzero,
+or a
+<errorname>BadValue</errorname>
+error results.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border_width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the width of the created window's border in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window's depth.
+A depth of
+<symbol>CopyFromParent</symbol>
+means the depth is taken from the parent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the created window's class.
+You can pass
+<symbol>InputOutput</symbol>,
+<symbol>InputOnly</symbol>,
+or
+<symbol>CopyFromParent</symbol>.
+A class of
+<symbol>CopyFromParent</symbol>
+means the class
+is taken from the parent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>visual</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the visual type.
+A visual of
+<symbol>CopyFromParent</symbol>
+means the visual type is taken from the
+parent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which window attributes are defined in the attributes
+argument.
+This mask is the bitwise inclusive OR of the valid attribute mask bits.
+If valuemask is zero,
+the attributes are ignored and are not referenced.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>attributes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the structure from which the values (as specified by the value mask)
+are to be taken.
+The value mask should have the appropriate bits
+set to indicate which attributes have been set in the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateWindow</function>
+function creates an unmapped subwindow for a specified parent window,
+returns the window ID of the created window,
+and causes the X server to generate a
+<symbol>CreateNotify</symbol>
+event.
+The created window is placed on top in the stacking order
+with respect to siblings.
+</para>
+<para>
+<!-- .LP -->
+The coordinate system has the X axis horizontal and the Y axis vertical
+with the origin [0, 0] at the upper-left corner.
+Coordinates are integral,
+in terms of pixels,
+and coincide with pixel centers.
+Each window and pixmap has its own coordinate system.
+For a window,
+the origin is inside the border at the inside, upper-left corner.
+</para>
+<para>
+<!-- .LP -->
+The border_width for an
+<symbol>InputOnly</symbol>
+window must be zero, or a
+<errorname>BadMatch</errorname>
+error results.
+For class
+<symbol>InputOutput</symbol>,
+the visual type and depth must be a combination supported for the screen,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The depth need not be the same as the parent,
+but the parent must not be a window of class
+<symbol>InputOnly</symbol>,
+or a
+<errorname>BadMatch</errorname>
+error results.
+For an
+<symbol>InputOnly</symbol>
+window,
+the depth must be zero, and the visual must be one supported by the screen.
+If either condition is not met,
+a
+<errorname>BadMatch</errorname>
+error results.
+The parent window, however, may have any depth and class.
+If you specify any invalid window attribute for a window, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The created window is not yet displayed (mapped) on the user's display.
+To display the window, call
+<function>XMapWindow</function>.
+The new window initially uses the same cursor as
+its parent.
+A new cursor can be defined for the new window by calling
+<function>XDefineCursor</function>.
+<indexterm><primary>Cursor</primary><secondary>Initial State</secondary></indexterm>
+<indexterm><primary>XDefineCursor</primary></indexterm>
+The window will not be visible on the screen unless it and all of its
+ancestors are mapped and it is not obscured by any of its ancestors.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateWindow</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadCursor</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create an unmapped
+<symbol>InputOutput</symbol>
+subwindow of a given parent window, use
+<function>XCreateSimpleWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateSimpleWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatesimplewindow'>
+<funcprototype>
+ <funcdef>Window <function>XCreateSimpleWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> parent</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint<parameter> border_width</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> border</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> background</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>parent</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the parent window.
+<!-- .ds Xy , which are the top-left outside corner of the new window's borders \ -->
+and are relative to the inside of the parent window's borders
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the created window's inside dimensions \ -->
+and do not include the created window's borders
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+The dimensions must be nonzero,
+or a
+<errorname>BadValue</errorname>
+error results.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border_width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the width of the created window's border in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the border pixel value of the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the background pixel value of the window.
+
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateSimpleWindow</function>
+function creates an unmapped
+<symbol>InputOutput</symbol>
+subwindow for a specified parent window, returns the
+window ID of the created window, and causes the X server to generate a
+<symbol>CreateNotify</symbol>
+event.
+The created window is placed on top in the stacking order with respect to
+siblings.
+Any part of the window that extends outside its parent window is clipped.
+The border_width for an
+<symbol>InputOnly</symbol>
+window must be zero, or a
+<errorname>BadMatch</errorname>
+error results.
+<function>XCreateSimpleWindow</function>
+inherits its depth, class, and visual from its parent.
+All other window attributes, except background and border,
+have their default values.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateSimpleWindow</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Destroying_Windows">
+<title>Destroying Windows</title>
+<!-- .XS -->
+<!-- (SN Destroying Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to destroy a window or destroy all
+subwindows of a window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy a window and all of its subwindows, use
+<function>XDestroyWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroywindow'>
+<funcprototype>
+ <funcdef><function>XDestroyWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDestroyWindow</function>
+function destroys the specified window as well as all of its subwindows and causes
+the X server to generate a
+<symbol>DestroyNotify</symbol>
+event for each window.
+The window should never be referenced again.
+If the window specified by the w argument is mapped,
+it is unmapped automatically.
+The ordering of the
+<symbol>DestroyNotify</symbol>
+events is such that for any given window being destroyed,
+<symbol>DestroyNotify</symbol>
+is generated on any inferiors of the window before being generated on
+the window itself.
+The ordering among siblings and across subhierarchies is not otherwise
+constrained.
+If the window you specified is a root window, no windows are destroyed.
+Destroying a mapped window will generate
+<symbol>Expose</symbol>
+events on other windows that were obscured by the window being destroyed.
+</para>
+<para>
+<!-- .LP -->
+<function>XDestroyWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy all subwindows of a specified window, use
+<function>XDestroySubwindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroySubwindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroysubwindows'>
+<funcprototype>
+ <funcdef><function>XDestroySubwindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDestroySubwindows</function>
+function destroys all inferior windows of the specified window,
+in bottom-to-top stacking order.
+It causes the X server to generate a
+<symbol>DestroyNotify</symbol>
+event for each window.
+If any mapped
+subwindows were actually destroyed,
+<function>XDestroySubwindows</function>
+causes the X server to generate
+<symbol>Expose</symbol>
+events on the specified window.
+This is much more efficient than deleting many windows
+one at a time because much of the work need be performed only once for all
+of the windows, rather than for each window.
+The subwindows should never be referenced again.
+</para>
+<para>
+<!-- .LP -->
+<function>XDestroySubwindows</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Mapping_Windows_">
+<title>Mapping Windows </title>
+<!-- .XS -->
+<!-- (SN Mapping Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A window is considered mapped if an
+<function>XMapWindow</function>
+call has been made on it.
+It may not be visible on the screen for one of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+It is obscured by another opaque window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+One of its ancestors is not mapped.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It is entirely clipped by an ancestor.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<symbol>Expose</symbol>
+events are generated for the window when part or all of
+it becomes visible on the screen.
+A client receives the
+<symbol>Expose</symbol>
+events only if it has asked for them.
+Windows retain their position in the stacking order when they are unmapped.
+</para>
+<para>
+<!-- .LP -->
+A window manager may want to control the placement of subwindows.
+If
+<symbol>SubstructureRedirectMask</symbol>
+has been selected by a window manager
+on a parent window (usually a root window),
+a map request initiated by other clients on a child window is not performed,
+and the window manager is sent a
+<symbol>MapRequest</symbol>
+event.
+However, if the override-redirect flag on the child had been set to
+<symbol>True</symbol>
+(usually only on pop-up menus),
+the map request is performed.
+</para>
+<para>
+<!-- .LP -->
+A tiling window manager might decide to reposition and resize other clients'
+windows and then decide to map the window to its final location.
+A window manager that wants to provide decoration might
+reparent the child into a frame first.
+For further information,
+see <link linkend="Override_Redirect_Flag">sections 3.2.8</link>
+and <link linkend="Window_State_Change_Events_">10.10</link>.
+Only a single client at a time can select for
+<symbol>SubstructureRedirectMask</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Similarly, a single client can select for
+<symbol>ResizeRedirectMask</symbol>
+on a parent window.
+Then, any attempt to resize the window by another client is suppressed, and
+the client receives a
+<symbol>ResizeRequest</symbol>
+event.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map a given window, use
+<function>XMapWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XMapWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmapwindow'>
+<funcprototype>
+ <funcdef><function>XMapWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMapWindow</function>
+function
+maps the window and all of its
+subwindows that have had map requests.
+Mapping a window that has an unmapped ancestor does not display the
+window but marks it as eligible for display when the ancestor becomes
+mapped.
+Such a window is called unviewable.
+When all its ancestors are mapped,
+the window becomes viewable
+and will be visible on the screen if it is not obscured by another window.
+This function has no effect if the window is already mapped.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect of the window is
+<symbol>False</symbol>
+and if some other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent window, then the X server generates a
+<symbol>MapRequest</symbol>
+event, and the
+<function>XMapWindow</function>
+function does not map the window.
+Otherwise, the window is mapped, and the X server generates a
+<symbol>MapNotify</symbol>
+event.
+</para>
+<para>
+<!-- .LP -->
+If the window becomes viewable and no earlier contents for it are remembered,
+the X server tiles the window with its background.
+If the window's background is undefined,
+the existing screen contents are not
+altered, and the X server generates zero or more
+<symbol>Expose</symbol>
+events.
+If backing-store was maintained while the window was unmapped, no
+<symbol>Expose</symbol>
+events
+are generated.
+If backing-store will now be maintained,
+a full-window exposure is always generated.
+Otherwise, only visible regions may be reported.
+Similar tiling and exposure take place for any newly viewable inferiors.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>XMapWindow</primary></indexterm>
+If the window is an
+<symbol>InputOutput</symbol>
+window,
+<function>XMapWindow</function>
+generates
+<symbol>Expose</symbol>
+events on each
+<symbol>InputOutput</symbol>
+window that it causes to be displayed.
+If the client maps and paints the window
+and if the client begins processing events,
+the window is painted twice.
+To avoid this,
+first ask for
+<symbol>Expose</symbol>
+events and then map the window,
+so the client processes input events as usual.
+The event list will include
+<symbol>Expose</symbol>
+for each
+window that has appeared on the screen.
+The client's normal response to
+an
+<symbol>Expose</symbol>
+event should be to repaint the window.
+This method usually leads to simpler programs and to proper interaction
+with window managers.
+</para>
+<para>
+<!-- .LP -->
+<function>XMapWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map and raise a window, use
+<function>XMapRaised</function>.
+</para>
+<indexterm significance="preferred"><primary>XMapRaised</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmapraised'>
+<funcprototype>
+ <funcdef><function>XMapRaised</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMapRaised</function>
+function
+essentially is similar to
+<function>XMapWindow</function>
+in that it maps the window and all of its
+subwindows that have had map requests.
+However, it also raises the specified window to the top of the stack.
+For additional information,
+see
+<function>XMapWindow</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XMapRaised</function>
+can generate multiple
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map all subwindows for a specified window, use
+<function>XMapSubwindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XMapSubwindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmapsubwindows'>
+<funcprototype>
+ <funcdef><function>XMapSubwindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMapSubwindows</function>
+<indexterm><primary>XMapSubwindows</primary></indexterm>
+function maps all subwindows for a specified window in top-to-bottom stacking
+order.
+The X server generates
+<symbol>Expose</symbol>
+events on each newly displayed window.
+This may be much more efficient than mapping many windows
+one at a time because the server needs to perform much of the work
+only once, for all of the windows, rather than for each window.
+</para>
+<para>
+<!-- .LP -->
+<function>XMapSubwindows</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Unmapping_Windows">
+<title>Unmapping Windows</title>
+<!-- .XS -->
+<!-- (SN Unmapping Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to unmap a window or all subwindows.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To unmap a window, use
+<function>XUnmapWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnmapWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunmapwindow'>
+<funcprototype>
+ <funcdef><function>XUnmapWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnmapWindow</function>
+function unmaps the specified window and causes the X server to generate an
+<symbol>UnmapNotify</symbol>
+<indexterm><primary>UnmapNotify Event</primary></indexterm>
+<indexterm><primary>XUnmapWindow</primary></indexterm>
+event.
+If the specified window is already unmapped,
+<function>XUnmapWindow</function>
+has no effect.
+Normal exposure processing on formerly obscured windows is performed.
+Any child window will no longer be visible until another map call is
+made on the parent.
+In other words, the subwindows are still mapped but are not visible
+until the parent is mapped.
+Unmapping a window will generate
+<symbol>Expose</symbol>
+events on windows that were formerly obscured by it.
+</para>
+<para>
+<!-- .LP -->
+<function>XUnmapWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To unmap all subwindows for a specified window, use
+<function>XUnmapSubwindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnmapSubwindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunmapsubwindows'>
+<funcprototype>
+ <funcdef><function>XUnmapSubwindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnmapSubwindows</function>
+function unmaps all subwindows for the specified window in bottom-to-top
+stacking order.
+It causes the X server to generate an
+<symbol>UnmapNotify</symbol>
+event on each subwindow and
+<symbol>Expose</symbol>
+events on formerly obscured windows.
+<indexterm><primary>UnmapNotify Event</primary></indexterm>
+Using this function is much more efficient than unmapping multiple windows
+one at a time because the server needs to perform much of the work
+only once, for all of the windows, rather than for each window.
+</para>
+<para>
+<!-- .LP -->
+<function>XUnmapSubwindows</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Configuring_Windows">
+<title>Configuring Windows</title>
+<!-- .XS -->
+<!-- (SN Configuring Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to
+move a window, resize a window, move and resize a window, or
+change a window's border width.
+To change one of these parameters,
+set the appropriate member of the
+<structname>XWindowChanges</structname>
+structure and OR in the corresponding value mask in subsequent calls to
+<function>XConfigureWindow</function>.
+The symbols for the value mask bits and the
+<structname>XWindowChanges</structname>
+structure are:
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+
+<literallayout class="monospaced">
+/* Configure window value mask bits */
+#define CWX (1<<0)
+#define CWY (1<<1)
+#define CWWidth (1<<2)
+#define CWHeight (1<<3)
+#define CWBorderWidth (1<<4)
+#define CWSibling (1<<5)
+#define CWStackMode (1<<6)
+</literallayout>
+
+<indexterm significance="preferred"><primary>XWindowChanges</primary></indexterm>
+<literallayout class="monospaced">
+/* Values */
+
+typedef struct {
+ int x, y;
+ int width, height;
+ int border_width;
+ Window sibling;
+ int stack_mode;
+} XWindowChanges;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The x and y members are used to set the window's x and y coordinates,
+which are relative to the parent's origin
+and indicate the position of the upper-left outer corner of the window.
+The width and height members are used to set the inside size of the window,
+not including the border, and must be nonzero, or a
+<errorname>BadValue</errorname>
+error results.
+Attempts to configure a root window have no effect.
+</para>
+<para>
+<!-- .LP -->
+The border_width member is used to set the width of the border in pixels.
+Note that setting just the border width leaves the outer-left corner of the window
+in a fixed position but moves the absolute position of the window's origin.
+If you attempt to set the border-width attribute of an
+<symbol>InputOnly</symbol>
+window nonzero, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The sibling member is used to set the sibling window for stacking operations.
+The stack_mode member is used to set how the window is to be restacked
+and can be set to
+<symbol>Above</symbol>,
+<symbol>Below</symbol>,
+<symbol>TopIf</symbol>,
+<symbol>BottomIf</symbol>,
+or
+<symbol>Opposite</symbol>.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect flag of the window is
+<symbol>False</symbol>
+and if some other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no further processing is performed.
+Otherwise,
+if some other client has selected
+<symbol>ResizeRedirectMask</symbol>
+on the window and the inside
+width or height of the window is being changed,
+a
+<symbol>ResizeRequest</symbol>
+event is generated, and the current inside width and height are
+used instead.
+Note that the override-redirect flag of the window has no effect
+on
+<symbol>ResizeRedirectMask</symbol>
+and that
+<symbol>SubstructureRedirectMask</symbol>
+on the parent has precedence over
+<symbol>ResizeRedirectMask</symbol>
+on the window.
+</para>
+<para>
+<!-- .LP -->
+When the geometry of the window is changed as specified,
+the window is restacked among siblings, and a
+<symbol>ConfigureNotify</symbol>
+event is generated if the state of the window actually changes.
+<symbol>GravityNotify</symbol>
+events are generated after
+<symbol>ConfigureNotify</symbol>
+events.
+If the inside width or height of the window has actually changed,
+children of the window are affected as specified.
+</para>
+<para>
+<!-- .LP -->
+If a window's size actually changes,
+the window's subwindows move according to their window gravity.
+Depending on the window's bit gravity,
+the contents of the window also may be moved
+(see <link linkend="Gravity_Attributes">section 3.2.3</link>).
+</para>
+<para>
+<!-- .LP -->
+If regions of the window were obscured but now are not,
+exposure processing is performed on these formerly obscured windows,
+including the window itself and its inferiors.
+As a result of increasing the width or height,
+exposure processing is also performed on any new regions of the window
+and any regions where window contents are lost.
+</para>
+<para>
+<!-- .LP -->
+The restack check (specifically, the computation for
+<symbol>BottomIf</symbol>,
+<symbol>TopIf</symbol>,
+and
+<symbol>Opposite</symbol>)
+is performed with respect to the window's final size and position (as
+controlled by the other arguments of the request), not its initial position.
+If a sibling is specified without a stack_mode,
+a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If a sibling and a stack_mode are specified,
+the window is restacked as follows:
+</para>
+<informaltable frame="none">
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>Above</symbol></entry>
+ <entry>The window is placed just above the sibling.</entry>
+ </row>
+ <row>
+ <entry><symbol>Below</symbol></entry>
+ <entry>The window is placed just below the sibling.</entry>
+ </row>
+ <row>
+ <entry><symbol>TopIf</symbol></entry>
+ <entry>If the sibling occludes the window, the window is placed at the top of the stack.</entry>
+ </row>
+ <row>
+ <entry><symbol>BottomIf</symbol></entry>
+ <entry>If the window occludes the sibling, the window is placed at the bottom of the stack.</entry>
+ </row>
+ <row>
+ <entry><symbol>Opposite</symbol></entry>
+ <entry>
+If the sibling occludes the window, the window is placed at the top of the stack.
+If the window occludes the sibling,
+the window is placed at the bottom of the stack.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+If a stack_mode is specified but no sibling is specified,
+the window is restacked as follows:
+</para>
+
+<informaltable frame="none">
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>Above</symbol></entry>
+ <entry>The window is placed at the top of the stack.</entry>
+ </row>
+ <row>
+ <entry><symbol>Below</symbol></entry>
+ <entry>The window is placed at the bottom of the stack.</entry>
+ </row>
+ <row>
+ <entry><symbol>TopIf</symbol></entry>
+ <entry>
+If any sibling occludes the window, the window is placed at
+the top of the stack.
+ </entry>
+ </row>
+ <row>
+ <entry><symbol>BottomIf</symbol></entry>
+ <entry>
+If the window occludes any sibling, the window is placed at
+the bottom of the stack.
+ </entry>
+ </row>
+ <row>
+ <entry><symbol>Opposite</symbol></entry>
+ <entry>
+If any sibling occludes the window, the window
+is placed at the top of the stack.
+If the window occludes any sibling,
+the window is placed at the bottom of the stack.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Attempts to configure a root window have no effect.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To configure a window's size, location, stacking, or border, use
+<function>XConfigureWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XConfigureWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xconfigurewindow'>
+<funcprototype>
+ <funcdef><function>XConfigureWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedint<parameter> value_mask</parameter></paramdef>
+ <paramdef>XWindowChanges<parameter> *values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi to be reconfigured -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which values are to be set using information in
+the values structure.
+This mask is the bitwise inclusive OR of the valid configure window values bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XWindowChanges</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XConfigureWindow</function>
+function uses the values specified in the
+<structname>XWindowChanges</structname>
+structure to reconfigure a window's size, position, border, and stacking order.
+Values not specified are taken from the existing geometry of the window.
+</para>
+<para>
+<!-- .LP -->
+If a sibling is specified without a stack_mode or if the window
+is not actually a sibling,
+a
+<errorname>BadMatch</errorname>
+error results.
+Note that the computations for
+<symbol>BottomIf</symbol>,
+<symbol>TopIf</symbol>,
+and
+<symbol>Opposite</symbol>
+are performed with respect to the window's final geometry (as controlled by the
+other arguments passed to
+<function>XConfigureWindow</function>),
+not its initial geometry.
+Any backing store contents of the window, its
+inferiors, and other newly visible windows are either discarded or
+changed to reflect the current screen contents
+(depending on the implementation).
+</para>
+<para>
+<!-- .LP -->
+<function>XConfigureWindow</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To move a window without changing its size, use
+<function>XMoveWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XMoveWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmovewindow'>
+<funcprototype>
+ <funcdef><function>XMoveWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi to be moved -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+<!-- .ds Xy , which define the new location of the top-left pixel \ -->
+of the window's border or the window itself if it has no border
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMoveWindow</function>
+function moves the specified window to the specified x and y coordinates,
+but it does not change the window's size, raise the window, or
+change the mapping state of the window.
+Moving a mapped window may or may not lose the window's contents
+depending on if the window is obscured by nonchildren
+and if no backing store exists.
+If the contents of the window are lost,
+the X server generates
+<symbol>Expose</symbol>
+events.
+Moving a mapped window generates
+<symbol>Expose</symbol>
+events on any formerly obscured windows.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect flag of the window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no further processing is
+performed.
+Otherwise, the window is moved.
+</para>
+<para>
+<!-- .LP -->
+<function>XMoveWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change a window's size without changing the upper-left coordinate, use
+<function>XResizeWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XResizeWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xresizewindow'>
+<funcprototype>
+ <funcdef><function>XResizeWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+<!-- .ds Wh , which are the interior dimensions of the window \ -->
+after the call completes
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XResizeWindow</function>
+function changes the inside dimensions of the specified window, not including
+its borders.
+This function does not change the window's upper-left coordinate or
+the origin and does not restack the window.
+Changing the size of a mapped window may lose its contents and generate
+<symbol>Expose</symbol>
+events.
+If a mapped window is made smaller,
+changing its size generates
+<symbol>Expose</symbol>
+events on windows that the mapped window formerly obscured.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect flag of the window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no further processing is performed.
+If either width or height is zero,
+a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XResizeWindow</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change the size and location of a window, use
+<function>XMoveResizeWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XMoveResizeWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmoveresizewindow'>
+<funcprototype>
+ <funcdef><function>XMoveResizeWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi to be reconfigured -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+<!-- .ds Xy , which define the new position of the window relative to its parent -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which define the interior size of the window -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMoveResizeWindow</function>
+function changes the size and location of the specified window
+without raising it.
+Moving and resizing a mapped window may generate an
+<symbol>Expose</symbol>
+event on the window.
+Depending on the new size and location parameters,
+moving and resizing a window may generate
+<symbol>Expose</symbol>
+events on windows that the window formerly obscured.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect flag of the window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no further processing is performed.
+Otherwise, the window size and location are changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XMoveResizeWindow</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change the border width of a given window, use
+<function>XSetWindowBorderWidth</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWindowBorderWidth</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowborderwidth'>
+<funcprototype>
+ <funcdef><function>XSetWindowBorderWidth</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedint<parameter> width</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the width of the window border.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWindowBorderWidth</function>
+function sets the specified window's border width to the specified width.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowBorderWidth</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Changing_Window_Stacking_Order">
+<title>Changing Window Stacking Order</title>
+<!-- .XS -->
+<!-- (SN Changing Window Stacking Order -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to raise, lower, circulate,
+or restack windows.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To raise a window so that no sibling window obscures it, use
+<function>XRaiseWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XRaiseWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xraisewindow'>
+<funcprototype>
+ <funcdef><function>XRaiseWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRaiseWindow</function>
+function
+raises the specified window to the top of the stack so that no sibling window
+obscures it.
+If the windows are regarded as overlapping sheets of paper stacked
+on a desk,
+then raising a window is analogous to moving the sheet to the top of
+the stack but leaving its x and y location on the desk constant.
+Raising a mapped window may generate
+<symbol>Expose</symbol>
+events for the window and any mapped subwindows that were formerly obscured.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect attribute of the window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no processing is performed.
+Otherwise, the window is raised.
+</para>
+<para>
+<!-- .LP -->
+<function>XRaiseWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To lower a window so that it does not obscure any sibling windows, use
+<function>XLowerWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XLowerWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlowerwindow'>
+<funcprototype>
+ <funcdef><function>XLowerWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLowerWindow</function>
+function lowers the specified window to the bottom of the stack
+so that it does not obscure any sibling
+windows.
+If the windows are regarded as overlapping sheets of paper
+stacked on a desk, then lowering a window is analogous to moving the
+sheet to the bottom of the stack but leaving its x and y location on
+the desk constant.
+Lowering a mapped window will generate
+<symbol>Expose</symbol>
+events on any windows it formerly obscured.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect attribute of the window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates a
+<symbol>ConfigureRequest</symbol>
+event, and no processing is performed.
+Otherwise, the window is lowered to the bottom of the
+stack.
+</para>
+<para>
+<!-- .LP -->
+<function>XLowerWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To circulate a subwindow up or down, use
+<function>XCirculateSubwindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XCirculateSubwindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcirculatesubwindows'>
+<funcprototype>
+ <funcdef><function>XCirculateSubwindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> direction</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>direction</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the direction (up or down) that you want to circulate
+the window.
+You can pass
+<symbol>RaiseLowest</symbol>
+or
+<symbol>LowerHighest</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCirculateSubwindows</function>
+function circulates children of the specified window in the specified
+direction.
+If you specify
+<symbol>RaiseLowest</symbol>,
+<function>XCirculateSubwindows</function>
+raises the lowest mapped child (if any) that is occluded
+by another child to the top of the stack.
+If you specify
+<symbol>LowerHighest</symbol>,
+<function>XCirculateSubwindows</function>
+lowers the highest mapped child (if any) that occludes another child
+to the bottom of the stack.
+Exposure processing is then performed on formerly obscured windows.
+If some other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the window, the X server generates a
+<symbol>CirculateRequest</symbol>
+event, and no further processing is performed.
+If a child is actually restacked,
+the X server generates a
+<symbol>CirculateNotify</symbol>
+event.
+</para>
+<para>
+<!-- .LP -->
+<function>XCirculateSubwindows</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To raise the lowest mapped child of a window that is partially or completely
+occluded by another child, use
+<function>XCirculateSubwindowsUp</function>.
+</para>
+<indexterm significance="preferred"><primary>XCirculateSubwindowsUp</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcirculatesubwindowsup'>
+<funcprototype>
+ <funcdef><function>XCirculateSubwindowsUp</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCirculateSubwindowsUp</function>
+function raises the lowest mapped child of the specified window that
+is partially
+or completely
+occluded by another child.
+Completely unobscured children are not affected.
+This is a convenience function equivalent to
+<function>XCirculateSubwindows</function>
+with
+<symbol>RaiseLowest</symbol>
+specified.
+</para>
+<para>
+<!-- .LP -->
+<function>XCirculateSubwindowsUp</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To lower the highest mapped child of a window that partially or
+completely occludes another child, use
+<function>XCirculateSubwindowsDown</function>.
+</para>
+<indexterm significance="preferred"><primary>XCirculateSubwindowsDown</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcirculatesubwindowsdown'>
+<funcprototype>
+ <funcdef><function>XCirculateSubwindowsDown</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCirculateSubwindowsDown</function>
+function lowers the highest mapped child of the specified window that partially
+or completely occludes another child.
+Completely unobscured children are not affected.
+This is a convenience function equivalent to
+<function>XCirculateSubwindows</function>
+with
+<symbol>LowerHighest</symbol>
+specified.
+</para>
+<para>
+<!-- .LP -->
+<function>XCirculateSubwindowsDown</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To restack a set of windows from top to bottom, use
+<function>XRestackWindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XRestackWindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrestackwindows'>
+<funcprototype>
+ <funcdef><function>XRestackWindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> windows[]</parameter></paramdef>
+ <paramdef>int<parameter> nwindows</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>windows</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array containing the windows to be restacked.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nwindows</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of windows to be restacked.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRestackWindows</function>
+function restacks the windows in the order specified,
+from top to bottom.
+The stacking order of the first window in the windows array is unaffected,
+but the other windows in the array are stacked underneath the first window,
+in the order of the array.
+The stacking order of the other windows is not affected.
+For each window in the window array that is not a child of the specified window,
+a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If the override-redirect attribute of a window is
+<symbol>False</symbol>
+and some
+other client has selected
+<symbol>SubstructureRedirectMask</symbol>
+on the parent, the X server generates
+<symbol>ConfigureRequest</symbol>
+events for each window whose override-redirect flag is not set,
+and no further processing is performed.
+Otherwise, the windows will be restacked in top-to-bottom order.
+</para>
+<para>
+<!-- .LP -->
+<function>XRestackWindows</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Changing_Window_Attributes">
+<title>Changing Window Attributes</title>
+<!-- .XS -->
+<!-- (SN Changing Window Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set window attributes.
+<function>XChangeWindowAttributes</function>
+is the more general function that allows you to set one or more window
+attributes provided by the
+<structname>XSetWindowAttributes</structname>
+structure.
+The other functions described in this section allow you to set one specific
+window attribute, such as a window's background.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change one or more attributes for a given window, use
+<function>XChangeWindowAttributes</function>.
+</para>
+<indexterm significance="preferred"><primary>XChangeWindowAttributes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangewindowattributes'>
+<funcprototype>
+ <funcdef><function>XChangeWindowAttributes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XSetWindowAttributes<parameter> *attributes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which window attributes are defined in the attributes
+argument.
+This mask is the bitwise inclusive OR of the valid attribute mask bits.
+If valuemask is zero,
+the attributes are ignored and are not referenced.
+The values and restrictions are
+the same as for
+<function>XCreateWindow</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+
+ </term>
+ <listitem>
+ <para>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>attributes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the structure from which the values (as specified by the value mask)
+are to be taken.
+The value mask should have the appropriate bits
+set to indicate which attributes have been set in the structure
+(see <link linkend="Window_Attributes">section 3.2</link>).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Depending on the valuemask,
+the
+<function>XChangeWindowAttributes</function>
+function uses the window attributes in the
+<structname>XSetWindowAttributes</structname>
+structure to change the specified window attributes.
+Changing the background does not cause the window contents to be
+changed.
+To repaint the window and its background, use
+<function>XClearWindow</function>.
+Setting the border or changing the background such that the
+border tile origin changes causes the border to be repainted.
+Changing the background of a root window to
+<symbol>None</symbol>
+or
+<symbol>ParentRelative</symbol>
+restores the default background pixmap.
+Changing the border of a root window to
+<symbol>CopyFromParent</symbol>
+restores the default border pixmap.
+Changing the win-gravity does not affect the current position of the
+window.
+Changing the backing-store of an obscured window to
+<symbol>WhenMapped</symbol>
+or
+<symbol>Always</symbol>,
+or changing the backing-planes, backing-pixel, or
+save-under of a mapped window may have no immediate effect.
+Changing the colormap of a window (that is, defining a new map, not
+changing the contents of the existing map) generates a
+<symbol>ColormapNotify</symbol>
+event.
+Changing the colormap of a visible window may have no
+immediate effect on the screen because the map may not be installed
+(see
+<function>XInstallColormap</function>).
+Changing the cursor of a root window to
+<symbol>None</symbol>
+restores the default
+cursor.
+Whenever possible, you are encouraged to share colormaps.
+</para>
+<para>
+<!-- .LP -->
+Multiple clients can select input on the same window.
+Their event masks are maintained separately.
+When an event is generated,
+it is reported to all interested clients.
+However, only one client at a time can select for
+<symbol>SubstructureRedirectMask</symbol>,
+<symbol>ResizeRedirectMask</symbol>,
+and
+<symbol>ButtonPressMask</symbol>.
+If a client attempts to select any of these event masks
+and some other client has already selected one,
+a
+<errorname>BadAccess</errorname>
+error results.
+There is only one do-not-propagate-mask for a window,
+not one per client.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeWindowAttributes</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadCursor</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the background of a window to a given pixel, use
+<function>XSetWindowBackground</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWindowBackground</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowbackground'>
+<funcprototype>
+ <funcdef><function>XSetWindowBackground</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> background_pixel</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background_pixel</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pixel that is to be used for the background.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWindowBackground</function>
+function sets the background of the window to the specified pixel value.
+Changing the background does not cause the window contents to be changed.
+<function>XSetWindowBackground</function>
+uses a pixmap of undefined size filled with the pixel value you passed.
+If you try to change the background of an
+<symbol>InputOnly</symbol>
+window, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowBackground</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set the background of a window to a given pixmap, use
+<function>XSetWindowBackgroundPixmap</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>background</secondary></indexterm>
+<indexterm significance="preferred"><primary>XSetWindowBackgroundPixmap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowbackgroundpixmap'>
+<funcprototype>
+ <funcdef><function>XSetWindowBackgroundPixmap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Pixmap<parameter> background_pixmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background_pixmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the background pixmap,
+<symbol>ParentRelative</symbol>,
+or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm>
+<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm>
+The
+<function>XSetWindowBackgroundPixmap</function>
+function sets the background pixmap of the window to the specified pixmap.
+The background pixmap can immediately be freed if no further explicit
+references to it are to be made.
+If
+<symbol>ParentRelative</symbol>
+is specified,
+the background pixmap of the window's parent is used,
+or on the root window, the default background is restored.
+If you try to change the background of an
+<symbol>InputOnly</symbol>
+window, a
+<errorname>BadMatch</errorname>
+error results.
+If the background is set to
+<symbol>None</symbol>,
+the window has no defined background.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowBackgroundPixmap</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .NT Note -->
+<function>XSetWindowBackground</function>
+and
+<function>XSetWindowBackgroundPixmap</function>
+do not change the current contents of the window.
+<!-- .NE -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change and repaint a window's border to a given pixel, use
+<function>XSetWindowBorder</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWindowBorder</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowborder'>
+<funcprototype>
+ <funcdef><function>XSetWindowBorder</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> border_pixel</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border_pixel</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the entry in the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWindowBorder</function>
+function sets the border of the window to the pixel value you specify.
+If you attempt to perform this on an
+<symbol>InputOnly</symbol>
+window, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowBorder</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change and repaint the border tile of a given window, use
+<function>XSetWindowBorderPixmap</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWindowBorderPixmap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowborderpixmap'>
+<funcprototype>
+ <funcdef><function>XSetWindowBorderPixmap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Pixmap<parameter> border_pixmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border_pixmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the border pixmap or
+<symbol>CopyFromParent</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWindowBorderPixmap</function>
+function sets the border pixmap of the window to the pixmap you specify.
+The border pixmap can be freed immediately if no further explicit
+references to it are to be made.
+If you specify
+<symbol>CopyFromParent</symbol>,
+a copy of the parent window's border pixmap is used.
+If you attempt to perform this on an
+<symbol>InputOnly</symbol>
+window, a
+<errorname>BadMatch</errorname>
+error results.
+<indexterm><primary>Resource IDs</primary><secondary>freeing</secondary></indexterm>
+<indexterm><primary>Freeing</primary><secondary>resources</secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowBorderPixmap</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the colormap of a given window, use
+<function>XSetWindowColormap</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWindowColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwindowcolormap'>
+<funcprototype>
+ <funcdef><function>XSetWindowColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWindowColormap</function>
+function sets the specified colormap of the specified window.
+The colormap must have the same visual type as the window,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWindowColormap</function>
+can generate
+<errorname>BadColor</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To define which cursor will be used in a window, use
+<function>XDefineCursor</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>defining the cursor</secondary></indexterm>
+<indexterm significance="preferred"><primary>XDefineCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdefinecursor'>
+<funcprototype>
+ <funcdef><function>XDefineCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor that is to be displayed or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If a cursor is set, it will be used when the pointer is in the window.
+If the cursor is
+<symbol>None</symbol>,
+it is equivalent to
+<function>XUndefineCursor</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XDefineCursor</function>
+can generate
+<errorname>BadCursor</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To undefine the cursor in a given window, use
+<function>XUndefineCursor</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>undefining the cursor</secondary></indexterm>
+<indexterm significance="preferred"><primary>XUndefineCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xundefinecursor'>
+<funcprototype>
+ <funcdef><function>XUndefineCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUndefineCursor</function>
+function undoes the effect of a previous
+<function>XDefineCursor</function>
+for this window.
+When the pointer is in the window,
+the parent's cursor will now be used.
+On the root window,
+the default cursor is restored.
+</para>
+<para>
+<!-- .LP -->
+<function>XUndefineCursor</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+<!-- .bp -->
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH04.xml b/libX11/specs/libX11/CH04.xml index 5ace5e1a3..3bd5d04aa 100644 --- a/libX11/specs/libX11/CH04.xml +++ b/libX11/specs/libX11/CH04.xml @@ -1,2508 +1,2508 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="window_information_functions"> -<title>Window Information Functions</title> - -<para> -After you connect the display to the X server and create a window, you can use the Xlib window -information functions to: -</para> -<itemizedlist> - <listitem><para>Obtain information about a window</para></listitem> - <listitem><para>Translate screen coordinates</para></listitem> - <listitem><para>Manipulate property lists</para></listitem> - <listitem><para>Obtain and change window properties</para></listitem> - <listitem><para>Manipulate selections</para></listitem> -</itemizedlist> - -<sect1 id="Obtaining_Window_Information"> -<title>Obtaining Window Information</title> -<!-- .XS --> -<!-- (SN Obtaining Window Information --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to obtain information about -the window tree, the window's current attributes, -the window's current geometry, or the current pointer coordinates. -Because they are most frequently used by window managers, -these functions all return a status to indicate whether the window still -exists. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the parent, a list of children, and number of children for -a given window, use -<function>XQueryTree</function>. -</para> -<indexterm><primary>Child Window</primary></indexterm> -<indexterm><primary>Parent Window</primary></indexterm> -<indexterm significance="preferred"><primary>XQueryTree</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerytree'> -<funcprototype> - <funcdef>Status <function>XQueryTree</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> *root_return</parameter></paramdef> - <paramdef>Window<parameter> *parent_return</parameter></paramdef> - <paramdef>Window<parameter> **children_return</parameter></paramdef> - <paramdef>unsignedint<parameter> *nchildren_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose list of children, root, parent, and number of children \ --> -you want to obtain - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>root_return</emphasis> - </term> - <listitem> - <para> -Returns the root window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>parent_return</emphasis> - </term> - <listitem> - <para> -Returns the parent window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>children_return</emphasis> - </term> - <listitem> - <para> -Returns the list of children. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nchildren_return</emphasis> - </term> - <listitem> - <para> -Returns the number of children. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryTree</function> -function returns the root ID, the parent window ID, -a pointer to the list of children windows -(NULL when there are no children), -and the number of children in the list for the specified window. -The children are listed in current stacking order, from bottom-most -(first) to top-most (last). -<function>XQueryTree</function> -returns zero if it fails and nonzero if it succeeds. -To free a non-NULL children list when it is no longer needed, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XQueryTree</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the current attributes of a given window, use -<function>XGetWindowAttributes</function>. -</para> -<indexterm significance="preferred"><primary>XGetWindowAttributes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwindowattributes'> -<funcprototype> - <funcdef>Status <function>XGetWindowAttributes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XWindowAttributes<parameter> *window_attributes_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose current attributes you want to obtain --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_attributes_return</emphasis> - </term> - <listitem> - <para> -Returns the specified window's attributes in the -<structname>XWindowAttributes</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWindowAttributes</function> -function returns the current attributes for the specified window to an -<structname>XWindowAttributes</structname> -structure. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XWindowAttributes</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - int x, y; /* location of window */ - int width, height; /* width and height of window */ - int border_width; /* border width of window */ - int depth; /* depth of window */ - Visual *visual; /* the associated visual structure */ - Window root; /* root of screen containing window */ - int class; /* InputOutput, InputOnly*/ - int bit_gravity; /* one of the bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes; /* planes to be preserved if possible */ - unsigned long backing_pixel; /* value to be used when restoring planes */ - Bool save_under; /* boolean, should bits under be saved? */ - Colormap colormap; /* color map to be associated with window */ - Bool map_installed; /* boolean, is color map currently installed*/ - int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ - long all_event_masks; /* set of events all people have interest in*/ - long your_event_mask; /* my event mask */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override-redirect */ - Screen *screen; /* back pointer to correct screen */ -} XWindowAttributes; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The x and y members are set to the upper-left outer -corner relative to the parent window's origin. -The width and height members are set to the inside size of the window, -not including the border. -The border_width member is set to the window's border width in pixels. -The depth member is set to the depth of the window -(that is, bits per pixel for the object). -The visual member is a pointer to the screen's associated -<structname>Visual</structname> -structure. -The root member is set to the root window of the screen containing the window. -The class member is set to the window's class and can be either -<symbol>InputOutput</symbol> -or -<symbol>InputOnly</symbol>. -</para> -<para> -<!-- .LP --> -The bit_gravity member is set to the window's bit gravity -and can be one of the following: - <simplelist type="vert" columns="2"> - <member><symbol>ForgetGravity</symbol></member> - <member><symbol>NorthWestGravity</symbol></member> - <member><symbol>NorthGravity</symbol></member> - <member><symbol>NorthEastGravity</symbol></member> - <member><symbol>WestGravity</symbol></member> - - <member><symbol>EastGravity</symbol></member> - <member><symbol>SouthWestGravity</symbol></member> - <member><symbol>SouthGravity</symbol></member> - <member><symbol>SouthEastGravity</symbol></member> - <member><symbol>StaticGravity</symbol></member> - </simplelist> -</para> -<para> -The win_gravity member is set to the window's window gravity -and can be one of the following: - <simplelist type="vert" columns="2"> - <member><symbol>UnmapGravity</symbol></member> - <member><symbol>NorthWestGravity</symbol></member> - <member><symbol>NorthGravity</symbol></member> - <member><symbol>NorthEastGravity</symbol></member> - <member><symbol>WestGravity</symbol></member> - - <member><symbol>EastGravity</symbol></member> - <member><symbol>SouthWestGravity</symbol></member> - <member><symbol>SouthGravity</symbol></member> - <member><symbol>SouthEastGravity</symbol></member> - <member><symbol>StaticGravity</symbol></member> - <member><symbol>CenterGravity</symbol></member> - </simplelist> -</para> -<para> -<!-- .LP --> -For additional information on gravity, -see <link linkend="Gravity_Attributes">section 3.2.3</link>. -</para> -<para> -<!-- .LP --> -The backing_store member is set to indicate how the X server should maintain -the contents of a window -and can be -<symbol>WhenMapped</symbol>, -<symbol>Always</symbol>, -or -<symbol>NotUseful</symbol>. -The backing_planes member is set to indicate (with bits set to 1) which bit -planes of the window hold dynamic data that must be preserved in backing_stores -and during save_unders. -The backing_pixel member is set to indicate what values to use -for planes not set in backing_planes. -</para> -<para> -<!-- .LP --> -The save_under member is set to -<symbol>True</symbol> -or -<symbol>False</symbol>. -The colormap member is set to the colormap for the specified window and can be -a colormap ID or -<symbol>None</symbol>. -The map_installed member is set to indicate whether the colormap is -currently installed and can be -<symbol>True</symbol> -or -<symbol>False</symbol>. -The map_state member is set to indicate the state of the window and can be -<symbol>IsUnmapped</symbol>, -<symbol>IsUnviewable</symbol>, -or -<symbol>IsViewable</symbol>. -<symbol>IsUnviewable</symbol> -is used if the window is mapped but some ancestor is unmapped. -</para> -<para> -<!-- .LP --> -The all_event_masks member is set to the bitwise inclusive OR of all event -masks selected on the window by all clients. -The your_event_mask member is set to the bitwise inclusive OR of all event -masks selected by the querying client. -The do_not_propagate_mask member is set to the bitwise inclusive OR of the -set of events that should not propagate. -</para> -<para> -<!-- .LP --> -The override_redirect member is set to indicate whether this window overrides -structure control facilities and can be -<symbol>True</symbol> -or -<symbol>False</symbol>. -Window manager clients should ignore the window if this member is -<symbol>True</symbol>. -</para> -<para> -<!-- .LP --> -The screen member is set to a screen pointer that gives you a back pointer -to the correct screen. -This makes it easier to obtain the screen information without -having to loop over the root window fields to see which field matches. -</para> -<para> -<!-- .LP --> -<function>XGetWindowAttributes</function> -can generate -<errorname>BadDrawable</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the current geometry of a given drawable, use -<function>XGetGeometry</function>. -</para> -<indexterm significance="preferred"><primary>XGetGeometry</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetgeometry'> -<funcprototype> - <funcdef>Status <function>XGetGeometry</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>Window<parameter> *root_return</parameter></paramdef> - <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> - <paramdef>unsignedint<parameter> *border_width_return</parameter></paramdef> - <paramdef>unsignedint<parameter> *depth_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Dr , which can be a window or a pixmap --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable(Dr. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>root_return</emphasis> - </term> - <listitem> - <para> -Returns the root window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_return</emphasis> - </term> - <listitem> - <para> -Return the x and y coordinates that define the location of the drawable. -For a window, -these coordinates specify the upper-left outer corner relative to -its parent's origin. -For pixmaps, these coordinates are always zero. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the drawable's dimensions (width and height). -For a window, -these dimensions specify the inside size, not including the border. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>border_width_return</emphasis> - </term> - <listitem> - <para> -Returns the border width in pixels. -If the drawable is a pixmap, it returns zero. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth_return</emphasis> - </term> - <listitem> - <para> -Returns the depth of the drawable (bits per pixel for the object). - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetGeometry</function> -function returns the root window and the current geometry of the drawable. -The geometry of the drawable includes the x and y coordinates, width and height, -border width, and depth. -These are described in the argument list. -It is legal to pass to this function a window whose class is -<symbol>InputOnly</symbol>. -</para> -<para> -<!-- .LP --> -<function>XGetGeometry</function> -can generate a -<errorname>BadDrawable</errorname> -error. -</para> -</sect1> -<sect1 id="Translating_Screen_Coordinates"> -<title>Translating Screen Coordinates</title> -<!-- .XS --> -<!-- (SN Translating Screen Coordinates --> -<!-- .XE --> -<para> -<!-- .LP --> -Applications sometimes -need to perform a coordinate transformation from the coordinate -space of one window to another window or need to determine which -window the pointing device is in. -<function>XTranslateCoordinates</function> -and -<function>XQueryPointer</function> -fulfill these needs (and avoid any race conditions) by -asking the X server to perform these operations. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To translate a coordinate in one window to the coordinate -space of another window, use -<function>XTranslateCoordinates</function>. -</para> -<indexterm significance="preferred"><primary>XTranslateCoordinates</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtranslatecoordinates'> -<funcprototype> - <funcdef>Bool <function>XTranslateCoordinates</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Windowsrc_w,<parameter> dest_w</parameter></paramdef> - <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef> - <paramdef>int*dest_x_return,<parameter> *dest_y_return</parameter></paramdef> - <paramdef>Window<parameter> *child_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_w</emphasis> - </term> - <listitem> - <para> -Specifies the source window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_w</emphasis> - </term> - <listitem> - <para> -Specifies the destination window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates within the source window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y_return</emphasis> - </term> - <listitem> - <para> -Return the x and y coordinates within the destination window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>child_return</emphasis> - </term> - <listitem> - <para> -Returns the child if the coordinates are contained in a mapped child of the -destination window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If -<function>XTranslateCoordinates</function> -returns -<symbol>True</symbol>, -it takes the src_x and src_y coordinates relative -to the source window's origin and returns these coordinates to -dest_x_return and dest_y_return -relative to the destination window's origin. -If -<function>XTranslateCoordinates</function> -returns -<symbol>False</symbol>, -src_w and dest_w are on different screens, -and dest_x_return and dest_y_return are zero. -If the coordinates are contained in a mapped child of dest_w, -that child is returned to child_return. -Otherwise, child_return is set to -<symbol>None</symbol>. -</para> -<para> -<!-- .LP --> -<function>XTranslateCoordinates</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the screen coordinates of the pointer -or to determine the pointer coordinates relative to a specified window, use -<function>XQueryPointer</function>. -</para> -<indexterm significance="preferred"><primary>XQueryPointer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerypointer'> -<funcprototype> - <funcdef>Bool <function>XQueryPointer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window*root_return,<parameter> *child_return</parameter></paramdef> - <paramdef>int*root_x_return,<parameter> *root_y_return</parameter></paramdef> - <paramdef>int*win_x_return,<parameter> *win_y_return</parameter></paramdef> - <paramdef>unsignedint<parameter> *mask_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. -<!-- .ds Ro that the pointer is in --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>root_return</emphasis> - </term> - <listitem> - <para> -Returns the root window (Ro. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>child_return</emphasis> - </term> - <listitem> - <para> -Returns the child window that the pointer is located in, if any. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>root_x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>root_y_return</emphasis> - </term> - <listitem> - <para> -Return the pointer coordinates relative to the root window's origin. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>win_x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>win_y_return</emphasis> - </term> - <listitem> - <para> -Return the pointer coordinates relative to the specified window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mask_return</emphasis> - </term> - <listitem> - <para> -Returns the current state of the modifier keys and pointer buttons. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryPointer</function> -function returns the root window the pointer is logically on and the pointer -coordinates relative to the root window's origin. -If -<function>XQueryPointer</function> -returns -<symbol>False</symbol>, -the pointer is not on the same screen as the specified window, and -<function>XQueryPointer</function> -returns -<symbol>None</symbol> -to child_return and zero to win_x_return and win_y_return. -If -<function>XQueryPointer</function> -returns -<symbol>True</symbol>, -the pointer coordinates returned to win_x_return and win_y_return -are relative to the origin of the specified window. -In this case, -<function>XQueryPointer</function> -returns the child that contains the pointer, if any, -or else -<symbol>None</symbol> -to child_return. -</para> -<para> -<!-- .LP --> -<function>XQueryPointer</function> -returns the current logical state of the keyboard buttons -and the modifier keys in mask_return. -It sets mask_return to the bitwise inclusive OR of one or more -of the button or modifier key bitmasks to match -the current state of the mouse buttons and the modifier keys. -</para> -<para> -<!-- .LP --> -Note that the logical state of a device (as seen through Xlib) -may lag the physical state if device event processing is frozen -(see <link linkend="Pointer_Grabbing_">section 12.1</link>). -</para> -<para> -<!-- .LP --> -<function>XQueryPointer</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Properties_and_Atoms"> -<title>Properties and Atoms</title> -<!-- .XS --> -<!-- (SN Properties and Atoms --> -<!-- .XE --> -<para> -<!-- .LP --> -A property is a collection of named, typed data. -The window system has a set of predefined properties -<indexterm><primary>Atom</primary><secondary>predefined</secondary></indexterm> -(for example, the name of a window, size hints, and so on), and users can -define any other arbitrary information and associate it with windows. -Each property has a name, -which is an ISO Latin-1 string. -For each named property, -a unique identifier (atom) is associated with it. -A property also has a type, for example, string or integer. -These types are also indicated using atoms, so arbitrary new -types can be defined. -Data of only one type may be associated with a single -property name. -Clients can store and retrieve properties associated with windows. -For efficiency reasons, -an atom is used rather than a character string. -<function>XInternAtom</function> -can be used to obtain the atom for property names. -<indexterm><primary>Atom</primary></indexterm> -</para> -<para> -<!-- .LP --> -A property is also stored in one of several possible formats. -The X server can store the information as 8-bit quantities, 16-bit -quantities, or 32-bit quantities. -This permits the X server to present the data in the byte order that the -client expects. -<!-- .NT Note --> -If you define further properties of complex type, -you must encode and decode them yourself. -These functions must be carefully written if they are to be portable. -For further information about how to write a library extension, -see <link linkend="extensions">appendix C</link>. -<!-- .NE --> -The type of a property is defined by an atom, which allows for -arbitrary extension in this type scheme. -<indexterm><primary>Atom</primary></indexterm> -</para> -<para> -<!-- .LP --> -Certain property names are -predefined in the server for commonly used functions. -The atoms for these properties are defined in -<filename class="headerfile"><X11/Xatom.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -To avoid name clashes with user symbols, the -<code>#define</code> -name for each atom has the XA_ prefix. -For an explanation of the functions that let you get and set -much of the information stored in these predefined properties, -see <link linkend="inter_client_communication_functions">chapter 14</link>. -</para> -<para> -<!-- .LP --> -The core protocol imposes no semantics on these property names, -but semantics are specified in other X Consortium standards, -such as the <emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis> -and the <emphasis remap='I'>X Logical Font Description Conventions</emphasis>. -</para> -<para> -<!-- .LP --> -You can use properties to communicate other information between -applications. -The functions described in this section let you define new properties -and get the unique atom IDs in your applications. -</para> -<para> -<!-- .LP --> -Although any particular atom can have some client interpretation -within each of the name spaces, -atoms occur in five distinct name spaces within the protocol: -</para> -<itemizedlist> - <listitem> - <para> -Selections - </para> - </listitem> - <listitem> - <para> -Property names - </para> - </listitem> - <listitem> - <para> -Property types - </para> - </listitem> - <listitem> - <para> -Font properties - </para> - </listitem> - <listitem> - <para> -Type of a -<symbol>ClientMessage</symbol> -event (none are built into the X server) - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -The built-in selection property names are: -<simplelist type="vert" columns="2"> - <member><property>PRIMARY</property></member> - <member><property>SECONDARY</property></member> -</simplelist> -</para> -<para> -<!-- .LP --> -The built-in property names are: - <simplelist type="vert" columns="2"> - <member><property>CUT_BUFFER0</property></member> - <member><property>CUT_BUFFER1</property></member> - <member><property>CUT_BUFFER2</property></member> - <member><property>CUT_BUFFER3</property></member> - <member><property>CUT_BUFFER4</property></member> - <member><property>CUT_BUFFER5</property></member> - <member><property>CUT_BUFFER6</property></member> - <member><property>CUT_BUFFER7</property></member> - <member><property>RGB_BEST_MAP</property></member> - <member><property>RGB_BLUE_MAP</property></member> - <member><property>RGB_DEFAULT_MAP</property></member> - <member><property>RGB_GRAY_MAP</property></member> - <member><property>RGB_GREEN_MAP</property></member> - <member><property>RGB_RED_MAP</property></member> - - <member><property>RESOURCE_MANAGER</property></member> - <member><property>WM_CLASS</property></member> - <member><property>WM_CLIENT_MACHINE</property></member> - <member><property>WM_COLORMAP_WINDOWS</property></member> - <member><property>WM_COMMAND</property></member> - <member><property>WM_HINTS</property></member> - <member><property>WM_ICON_NAME</property></member> - <member><property>WM_ICON_SIZE</property></member> - <member><property>WM_NAME</property></member> - <member><property>WM_NORMAL_HINTS</property></member> - <member><property>WM_PROTOCOLS</property></member> - <member><property>WM_STATE</property></member> - <member><property>WM_TRANSIENT_FOR</property></member> - <member><property>WM_ZOOM_HINTS</property></member> - </simplelist> -</para> -<para> -The built-in property types are: - <simplelist type="vert" columns="2"> - <member><property>ARC</property></member> - <member><property>ATOM</property></member> - <member><property>BITMAP</property></member> - <member><property>CARDINAL</property></member> - <member><property>COLORMAP</property></member> - <member><property>CURSOR</property></member> - <member><property>DRAWABLE</property></member> - <member><property>FONT</property></member> - <member><property>INTEGER</property></member> - <member><property>PIXMAP</property></member> - <member><property>POINT</property></member> - <member><property>RGB_COLOR_MAP</property></member> - <member><property>RECTANGLE</property></member> - <member><property>STRING</property></member> - <member><property>VISUALID</property></member> - <member><property>WINDOW</property></member> - <member><property>WM_HINTS</property></member> - <member><property>WM_SIZE_HINTS</property></member> - </simplelist> -</para> -<para> -The built-in font property names are: - <simplelist type="vert" columns="2"> - <member><property>MIN_SPACE</property></member> - <member><property>NORM_SPACE</property></member> - <member><property>MAX_SPACE</property></member> - <member><property>END_SPACE</property></member> - <member><property>SUPERSCRIPT_X</property></member> - <member><property>SUPERSCRIPT_Y</property></member> - <member><property>SUBSCRIPT_X</property></member> - <member><property>SUBSCRIPT_Y</property></member> - <member><property>UNDERLINE_POSITION</property></member> - <member><property>UNDERLINE_THICKNESS</property></member> - <member><property>FONT_NAME</property></member> - <member><property>FULL_NAME</property></member> - - <member><property>STRIKEOUT_DESCENT</property></member> - <member><property>STRIKEOUT_ASCENT</property></member> - <member><property>ITALIC_ANGLE</property></member> - <member><property>X_HEIGHT</property></member> - <member><property>QUAD_WIDTH</property></member> - <member><property>WEIGHT</property></member> - <member><property>POINT_SIZE</property></member> - <member><property>RESOLUTION</property></member> - <member><property>COPYRIGHT</property></member> - <member><property>NOTICE</property></member> - <member><property>FAMILY_NAME</property></member> - <member><property>CAP_HEIGHT</property></member> - </simplelist> -</para> -<para> -<!-- .LP --> -For further information about font properties, -see <link linkend="Font_Metrics">section 8.5</link>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return an atom for a given name, use -<function>XInternAtom</function>. -</para> -<indexterm><primary>Atom</primary><secondary>interning</secondary></indexterm> -<indexterm significance="preferred"><primary>XInternAtom</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinternatom'> -<funcprototype> - <funcdef>Atom <function>XInternAtom</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *atom_name</parameter></paramdef> - <paramdef>Bool<parameter> only_if_exists</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>atom_name</emphasis> - </term> - <listitem> - <para> -Specifies the name associated with the atom you want returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>only_if_exists</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the atom must be created. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInternAtom</function> -function returns the atom identifier associated with the specified atom_name -string. -If only_if_exists is -<symbol>False</symbol>, -the atom is created if it does not exist. -Therefore, -<function>XInternAtom</function> -can return -<symbol>None</symbol>. -If the atom name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Uppercase and lowercase matter; -the strings ``thing'', ``Thing'', and ``thinG'' -all designate different atoms. -The atom will remain defined even after the client's connection closes. -It will become undefined only when the last connection to -the X server closes. -</para> -<para> -<!-- .LP --> -<function>XInternAtom</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return atoms for an array of names, use -<function>XInternAtoms</function>. -</para> -<indexterm><primary>Atom</primary><secondary>interning</secondary></indexterm> -<indexterm significance="preferred"><primary>XInternAtoms</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinternatoms'> -<funcprototype> - <funcdef>Status <function>XInternAtoms</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> **names</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>Bool<parameter> only_if_exists</parameter></paramdef> - <paramdef>Atom<parameter> *atoms_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>names</emphasis> - </term> - <listitem> - <para> -Specifies the array of atom names. -<!-- .ds Cn atom names in the array --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>only_if_exists</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the atom must be created. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>atoms_return</emphasis> - </term> - <listitem> - <para> -Returns the atoms. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInternAtoms</function> -function returns the atom identifiers associated with the specified names. -The atoms are stored in the atoms_return array supplied by the caller. -Calling this function is equivalent to calling -<function>XInternAtom</function> -for each of the names in turn with the specified value of only_if_exists, -but this function minimizes the number of round-trip protocol exchanges -between the client and the X server. -</para> -<para> -<!-- .LP --> -This function returns a nonzero status if atoms are returned for -all of the names; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -<function>XInternAtoms</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return a name for a given atom identifier, use -<function>XGetAtomName</function>. -</para> -<indexterm><primary>Atom</primary><secondary>getting name</secondary></indexterm> -<indexterm significance="preferred"><primary>XGetAtomName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetatomname'> -<funcprototype> - <funcdef>char *<function>XGetAtomName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Atom<parameter> atom</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>atom</emphasis> - </term> - <listitem> - <para> -Specifies the atom for the property name you want returned. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetAtomName</function> -function returns the name associated with the specified atom. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned string is in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -To free the resulting string, -call -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetAtomName</function> -can generate a -<errorname>BadAtom</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return the names for an array of atom identifiers, use -<function>XGetAtomNames</function>. -</para> -<indexterm><primary>Atom</primary><secondary>getting name</secondary></indexterm> -<indexterm significance="preferred"><primary>XGetAtomNames</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetatomnames'> -<funcprototype> - <funcdef>Status <function>XGetAtomNames</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Atom<parameter> *atoms</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>char<parameter> **names_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>atoms</emphasis> - </term> - <listitem> - <para> -Specifies the array of atoms. -<!-- .ds Cn atoms in the array --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>names_return</emphasis> - </term> - <listitem> - <para> -Returns the atom names. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetAtomNames</function> -function returns the names associated with the specified atoms. -The names are stored in the names_return array supplied by the caller. -Calling this function is equivalent to calling -<function>XGetAtomName</function> -for each of the atoms in turn, -but this function minimizes the number of round-trip protocol exchanges -between the client and the X server. -</para> -<para> -<!-- .LP --> -This function returns a nonzero status if names are returned for -all of the atoms; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -<function>XGetAtomNames</function> -can generate a -<errorname>BadAtom</errorname> -error. -</para> -</sect1> -<sect1 id="Obtaining_and_Changing_Window_Properties"> -<title>Obtaining and Changing Window Properties</title> -<!-- .XS --> -<!-- (SN Obtaining and Changing Window Properties --> -<!-- .XE --> -<para> -<!-- .LP --> -You can attach a property list to every window. -Each property has a name, a type, and a value -(see <link linkend="Properties_and_Atoms">section 4.3</link>). -The value is an array of 8-bit, 16-bit, or 32-bit quantities, -whose interpretation is left to the clients. The type -<type>char</type> -is used to represent 8-bit quantities, the type -<type>short</type> -is used to represent 16-bit quantities, and the type -<type>long</type> -is used to represent 32-bit quantities. -</para> -<para> -<!-- .LP --> -Xlib provides functions that you can use to obtain, -change, update, or interchange window properties. -In addition, Xlib provides other utility functions for inter-client -communication -(see <link linkend="inter_client_communication_functions">chapter 14</link>). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the type, format, and value of a property of a given window, use -<function>XGetWindowProperty</function>. -<indexterm><primary>Property</primary><secondary>getting</secondary></indexterm> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XGetWindowProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwindowproperty'> -<funcprototype> - <funcdef>int <function>XGetWindowProperty</function></funcdef> - <paramdef><parameter> display</parameter></paramdef> - <paramdef><parameter> w</parameter></paramdef> - <paramdef><parameter> property</parameter></paramdef> - <paramdef><parameter> long_offset</parameter></paramdef> - <paramdef><parameter> long_length</parameter></paramdef> - <paramdef><parameter> delete</parameter></paramdef> - <paramdef><parameter> req_type</parameter></paramdef> - <paramdef><parameter> actual_type_return</parameter></paramdef> - <paramdef><parameter> actual_format_return</parameter></paramdef> - <paramdef><parameter> nitems_return</parameter></paramdef> - <paramdef><parameter> bytes_after_return</parameter></paramdef> - <paramdef>.br<parameter> prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose property you want to obtain --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>long_offset</emphasis> - </term> - <listitem> - <para> -Specifies the offset in the specified property (in 32-bit quantities) -where the data is to be retrieved. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>long_length</emphasis> - </term> - <listitem> - <para> -Specifies the length in 32-bit multiples of the data to be retrieved. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>delete</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that determines whether the property is deleted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>req_type</emphasis> - </term> - <listitem> - <para> -Specifies the atom identifier associated with the property type or -<symbol>AnyPropertyType</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>actual_type_return</emphasis> - </term> - <listitem> - <para> -Returns the atom identifier that defines the actual type of the property. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>actual_format_return</emphasis> - </term> - <listitem> - <para> -Returns the actual format of the property. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nitems_return</emphasis> - </term> - <listitem> - <para> -Returns the actual number of 8-bit, 16-bit, or 32-bit items -stored in the prop_return data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes_after_return</emphasis> - </term> - <listitem> - <para> -Returns the number of bytes remaining to be read in the property if -a partial read was performed. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>prop_return</emphasis> - </term> - <listitem> - <para> -Returns the data in the specified format. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWindowProperty</function> -function returns the actual type of the property; the actual format of the property; -the number of 8-bit, 16-bit, or 32-bit items transferred; the number of bytes remaining -to be read in the property; and a pointer to the data actually returned. -<function>XGetWindowProperty</function> -sets the return arguments as follows: -</para> -<itemizedlist> - <listitem> - <para> -If the specified property does not exist for the specified window, -<function>XGetWindowProperty</function> -returns -<symbol>None</symbol> -to actual_type_return and the value zero to -actual_format_return and bytes_after_return. -The nitems_return argument is empty. -In this case, the delete argument is ignored. - </para> - </listitem> - <listitem> - <para> -If the specified property exists -but its type does not match the specified type, -<function>XGetWindowProperty</function> -returns the actual property type to actual_type_return, -the actual property format (never zero) to actual_format_return, -and the property length in bytes -(even if the actual_format_return is 16 or 32) -to bytes_after_return. -It also ignores the delete argument. -The nitems_return argument is empty. - </para> - </listitem> - <listitem> - <para> -If the specified property exists and either you assign -<symbol>AnyPropertyType</symbol> -to the req_type argument or the specified type matches the actual property type, -<function>XGetWindowProperty</function> -returns the actual property type to actual_type_return and the actual -property format (never zero) to actual_format_return. -It also returns a value to bytes_after_return and nitems_return, by -defining the following -values: - </para> - </listitem> - <listitem> - <para> -<!-- .nf --> - N = actual length of the stored property in bytes - (even if the format is 16 or 32) - I = 4 * long_offset - T = N - I - L = MINIMUM(T, 4 * long_length) - A = N - (I + L) -<!-- .fi --> - </para> - </listitem> - <listitem> - <para> -The returned value starts at byte index I in the property (indexing -from zero), and its length in bytes is L. -If the value for long_offset causes L to be negative, -a -<errorname>BadValue</errorname> -error results. -The value of bytes_after_return is A, -giving the number of trailing unread bytes in the stored property. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -If the returned format is 8, the returned data is represented as a -<type>char</type> -array. -If the returned format is 16, the returned data is represented as a -<type>short</type> -array and should be cast to that type to obtain the elements. -If the returned format is 32, the returned data is represented as a -<type>long</type> -array and should be cast to that type to obtain the elements. -</para> -<para> -<!-- .LP --> -<function>XGetWindowProperty</function> -always allocates one extra byte in prop_return -(even if the property is zero length) -and sets it to zero so that simple properties consisting of characters -do not have to be copied into yet another string before use. -</para> -<para> -<!-- .LP --> -If delete is -<symbol>True</symbol> -and bytes_after_return is zero, -<function>XGetWindowProperty</function> -deletes the property -from the window and generates a -<symbol>PropertyNotify</symbol> -event on the window. -</para> -<para> -<!-- .LP --> -The function returns -<symbol>Success</symbol> -if it executes successfully. -To free the resulting data, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetWindowProperty</function> -can generate -<errorname>BadAtom</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a given window's property list, use -<function>XListProperties</function>. -</para> -<indexterm><primary>Property</primary><secondary>listing</secondary></indexterm> -<indexterm significance="preferred"><primary>XListProperties</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlistproperties'> -<funcprototype> - <funcdef>Atom *<function>XListProperties</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> *num_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose property list you want to obtain --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the length of the properties array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListProperties</function> -function returns a pointer to an array of atom properties that are defined for -the specified window or returns NULL if no properties were found. -To free the memory allocated by this function, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XListProperties</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change a property of a given window, use -<function>XChangeProperty</function>. -</para> -<indexterm><primary>Property</primary><secondary>changing</secondary></indexterm> -<indexterm><primary>Property</primary><secondary>appending</secondary></indexterm> -<indexterm><primary>Property</primary><secondary>prepending</secondary></indexterm> -<indexterm><primary>Property</primary><secondary>replacing</secondary></indexterm> -<indexterm><primary>Property</primary><secondary>format</secondary></indexterm> -<indexterm><primary>Property</primary><secondary>type</secondary></indexterm> -<indexterm significance="preferred"><primary>XChangeProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangeproperty'> -<funcprototype> - <funcdef><function>XChangeProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Atomproperty,<parameter> type</parameter></paramdef> - <paramdef>int<parameter> format</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> - <paramdef>unsignedchar<parameter> *data</parameter></paramdef> - <paramdef>int<parameter> nelements</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose property you want to change --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>type</emphasis> - </term> - <listitem> - <para> -Specifies the type of the property. -The X server does not interpret the type but simply -passes it back to an application that later calls -<function>XGetWindowProperty</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>format</emphasis> - </term> - <listitem> - <para> -Specifies whether the data should be viewed as a list -of 8-bit, 16-bit, or 32-bit quantities. -Possible values are 8, 16, and 32. -This information allows the X server to correctly perform -byte-swap operations as necessary. -If the format is 16-bit or 32-bit, -you must explicitly cast your data pointer to an (unsigned char *) in the call -to -<function>XChangeProperty</function>. -<!-- .\" Changed name of this file to prop_mode.a on 1/13/87 --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the mode of the operation. -You can pass -<symbol>PropModeReplace</symbol>, -<symbol>PropModePrepend</symbol>, -or -<symbol>PropModeAppend</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the property data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nelements</emphasis> - </term> - <listitem> - <para> -Specifies the number of elements of the specified data format. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangeProperty</function> -function alters the property for the specified window and -causes the X server to generate a -<symbol>PropertyNotify</symbol> -event on that window. -<function>XChangeProperty</function> -performs the following: -</para> -<itemizedlist> - <listitem> - <para> -If mode is -<symbol>PropModeReplace</symbol>, -<function>XChangeProperty</function> -discards the previous property value and stores the new data. - </para> - </listitem> - <listitem> - <para> -If mode is -<symbol>PropModePrepend</symbol> -or -<symbol>PropModeAppend</symbol>, -<function>XChangeProperty</function> -inserts the specified data before the beginning of the existing data -or onto the end of the existing data, respectively. -The type and format must match the existing property value, -or a -<errorname>BadMatch</errorname> -error results. -If the property is undefined, -it is treated as defined with the correct type and -format with zero-length data. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -If the specified format is 8, the property data must be a -<type>char</type> -array. -If the specified format is 16, the property data must be a -<type>short</type> -array. -If the specified format is 32, the property data must be a -<type>long</type> -array. -</para> -<para> -<!-- .LP --> -The lifetime of a property is not tied to the storing client. -Properties remain until explicitly deleted, until the window is destroyed, -or until the server resets. -For a discussion of what happens when the connection to the X server is closed, -see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>. -The maximum size of a property is server dependent and can vary dynamically -depending on the amount of memory the server has available. -(If there is insufficient space, a -<errorname>BadAlloc</errorname> -error results.) -</para> -<para> -<!-- .LP --> -<function>XChangeProperty</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To rotate a window's property list, use -<function>XRotateWindowProperties</function>. -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XRotateWindowProperties</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrotatewindowproperties'> -<funcprototype> - <funcdef><function>XRotateWindowProperties</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Atom<parameter> properties[]</parameter></paramdef> - <paramdef>int<parameter> num_prop</parameter></paramdef> - <paramdef>int<parameter> npositions</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>properties</emphasis> - </term> - <listitem> - <para> -Specifies the array of properties that are to be rotated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_prop</emphasis> - </term> - <listitem> - <para> -Specifies the length of the properties array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npositions</emphasis> - </term> - <listitem> - <para> -Specifies the rotation amount. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRotateWindowProperties</function> -function allows you to rotate properties on a window and causes -the X server to generate -<symbol>PropertyNotify</symbol> -events. -If the property names in the properties array are viewed as being numbered -starting from zero and if there are num_prop property names in the list, -then the value associated with property name I becomes the value associated -with property name (I + npositions) mod N for all I from zero to N − 1. -The effect is to rotate the states by npositions places around the virtual ring -of property names (right for positive npositions, -left for negative npositions). -If npositions mod N is nonzero, -the X server generates a -<symbol>PropertyNotify</symbol> -event for each property in the order that they are listed in the array. -If an atom occurs more than once in the list or no property with that -name is defined for the window, -a -<errorname>BadMatch</errorname> -error results. -If a -<errorname>BadAtom</errorname> -or -<errorname>BadMatch</errorname> -error results, -no properties are changed. -</para> -<para> -<!-- .LP --> -<function>XRotateWindowProperties</function> -can generate -<errorname>BadAtom</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To delete a property on a given window, use -<function>XDeleteProperty</function>. -</para> -<indexterm><primary>Property</primary><secondary>deleting</secondary></indexterm> -<indexterm significance="preferred"><primary>XDeleteProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdeleteproperty'> -<funcprototype> - <funcdef><function>XDeleteProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose property you want to delete --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDeleteProperty</function> -function deletes the specified property only if the -property was defined on the specified window -and causes the X server to generate a -<symbol>PropertyNotify</symbol> -event on the window unless the property does not exist. -</para> -<para> -<!-- .LP --> -<function>XDeleteProperty</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Selections"> -<title>Selections</title> -<!-- .XS --> -<!-- (SN Selections --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Selection</primary></indexterm> -Selections are one method used by applications to exchange data. -By using the property mechanism, -applications can exchange data of arbitrary types and can negotiate -the type of the data. -A selection can be thought of as an indirect property with a dynamic type. -That is, rather than having the property stored in the X server, -the property is maintained by some client (the owner). -A selection is global in nature (considered to belong to the user -but be maintained by clients) rather than being private to a particular -window subhierarchy or a particular set of clients. -</para> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set, get, or request conversion -of selections. -This allows applications to implement the notion of current selection, -which requires that notification be sent to applications when they no -longer own the selection. -Applications that support selection often highlight the current selection -and so must be informed when another application has -acquired the selection so that they can unhighlight the selection. -</para> -<para> -<!-- .LP --> -When a client asks for the contents of -a selection, it specifies a selection target type. -This target type -can be used to control the transmitted representation of the contents. -For example, if the selection is ``the last thing the user clicked on'' -and that is currently an image, then the target type might specify -whether the contents of the image should be sent in XY format or Z format. -</para> -<para> -<!-- .LP --> -The target type can also be used to control the class of -contents transmitted, for example, -asking for the ``looks'' (fonts, line -spacing, indentation, and so forth) of a paragraph selection, not the -text of the paragraph. -The target type can also be used for other -purposes. -The protocol does not constrain the semantics. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the selection owner, use -<function>XSetSelectionOwner</function>. -</para> -<indexterm><primary>Selection</primary><secondary>setting the owner</secondary></indexterm> -<indexterm significance="preferred"><primary>XSetSelectionOwner</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetselectionowner'> -<funcprototype> - <funcdef><function>XSetSelectionOwner</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Atom<parameter> selection</parameter></paramdef> - <paramdef>Window<parameter> owner</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>selection</emphasis> - </term> - <listitem> - <para> -Specifies the selection atom. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>owner</emphasis> - </term> - <listitem> - <para> -Specifies the owner of the specified selection atom. -You can pass a window or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetSelectionOwner</function> -function changes the owner and last-change time for the specified selection -and has no effect if the specified time is earlier than the current -last-change time of the specified selection -or is later than the current X server time. -Otherwise, the last-change time is set to the specified time, -with -<symbol>CurrentTime</symbol> -replaced by the current server time. -If the owner window is specified as -<symbol>None</symbol>, -then the owner of the selection becomes -<symbol>None</symbol> -(that is, no owner). -Otherwise, the owner of the selection becomes the client executing -the request. -</para> -<para> -<!-- .LP --> -If the new owner (whether a client or -<symbol>None</symbol>) -is not -the same as the current owner of the selection and the current -owner is not -<symbol>None</symbol>, -the current owner is sent a -<symbol>SelectionClear</symbol> -event. -If the client that is the owner of a selection is later -terminated (that is, its connection is closed) -or if the owner window it has specified in the request is later -destroyed, -the owner of the selection automatically -reverts to -<symbol>None</symbol>, -but the last-change time is not affected. -The selection atom is uninterpreted by the X server. -<function>XGetSelectionOwner</function> -returns the owner window, which is reported in -<symbol>SelectionRequest</symbol> -and -<symbol>SelectionClear</symbol> -events. -Selections are global to the X server. -</para> -<para> -<!-- .LP --> -<function>XSetSelectionOwner</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return the selection owner, use -<function>XGetSelectionOwner</function>. -</para> -<indexterm><primary>Selection</primary><secondary>getting the owner</secondary></indexterm> -<indexterm significance="preferred"><primary>XGetSelectionOwner</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetselectionowner'> -<funcprototype> - <funcdef>Window <function>XGetSelectionOwner</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Atom<parameter> selection</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Se whose owner you want returned --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>selection</emphasis> - </term> - <listitem> - <para> -Specifies the selection atom (Se. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetSelectionOwner</function> -function -returns the window ID associated with the window that currently owns the -specified selection. -If no selection was specified, the function returns the constant -<symbol>None</symbol>. -If -<symbol>None</symbol> -is returned, -there is no owner for the selection. -</para> -<para> -<!-- .LP --> -<function>XGetSelectionOwner</function> -can generate a -<errorname>BadAtom</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To request conversion of a selection, use -<function>XConvertSelection</function>. -</para> -<indexterm><primary>Selection</primary><secondary>converting</secondary></indexterm> -<indexterm significance="preferred"><primary>XConvertSelection</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xconvertselection'> -<funcprototype> - <funcdef><function>XConvertSelection</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Atomselection,<parameter> target</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> - <paramdef>Window<parameter> requestor</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>selection</emphasis> - </term> - <listitem> - <para> -Specifies the selection atom. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target</emphasis> - </term> - <listitem> - <para> -Specifies the target atom. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. -You also can pass -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>requestor</emphasis> - </term> - <listitem> - <para> -Specifies the requestor. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XConvertSelection</function> -requests that the specified selection be converted to the specified target -type: -</para> -<itemizedlist> - <listitem> - <para> -If the specified selection has an owner, the X server sends a -<symbol>SelectionRequest</symbol> -event to that owner. - </para> - </listitem> - <listitem> - <para> -If no owner for the specified -selection exists, the X server generates a -<symbol>SelectionNotify</symbol> -event to the -requestor with property -<symbol>None</symbol>. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The arguments are passed on unchanged in either of the events. -There are two predefined selection atoms: PRIMARY and SECONDARY. -</para> -<para> -<!-- .LP --> -<function>XConvertSelection</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .bp --> - - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="window_information_functions">
+<title>Window Information Functions</title>
+
+<para>
+After you connect the display to the X server and create a window, you can use the Xlib window
+information functions to:
+</para>
+<itemizedlist>
+ <listitem><para>Obtain information about a window</para></listitem>
+ <listitem><para>Translate screen coordinates</para></listitem>
+ <listitem><para>Manipulate property lists</para></listitem>
+ <listitem><para>Obtain and change window properties</para></listitem>
+ <listitem><para>Manipulate selections</para></listitem>
+</itemizedlist>
+
+<sect1 id="Obtaining_Window_Information">
+<title>Obtaining Window Information</title>
+<!-- .XS -->
+<!-- (SN Obtaining Window Information -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to obtain information about
+the window tree, the window's current attributes,
+the window's current geometry, or the current pointer coordinates.
+Because they are most frequently used by window managers,
+these functions all return a status to indicate whether the window still
+exists.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the parent, a list of children, and number of children for
+a given window, use
+<function>XQueryTree</function>.
+</para>
+<indexterm><primary>Child Window</primary></indexterm>
+<indexterm><primary>Parent Window</primary></indexterm>
+<indexterm significance="preferred"><primary>XQueryTree</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerytree'>
+<funcprototype>
+ <funcdef>Status <function>XQueryTree</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> *root_return</parameter></paramdef>
+ <paramdef>Window<parameter> *parent_return</parameter></paramdef>
+ <paramdef>Window<parameter> **children_return</parameter></paramdef>
+ <paramdef>unsignedint<parameter> *nchildren_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose list of children, root, parent, and number of children \ -->
+you want to obtain
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>root_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the root window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>parent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the parent window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>children_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of children.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nchildren_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of children.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryTree</function>
+function returns the root ID, the parent window ID,
+a pointer to the list of children windows
+(NULL when there are no children),
+and the number of children in the list for the specified window.
+The children are listed in current stacking order, from bottom-most
+(first) to top-most (last).
+<function>XQueryTree</function>
+returns zero if it fails and nonzero if it succeeds.
+To free a non-NULL children list when it is no longer needed, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryTree</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the current attributes of a given window, use
+<function>XGetWindowAttributes</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWindowAttributes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwindowattributes'>
+<funcprototype>
+ <funcdef>Status <function>XGetWindowAttributes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XWindowAttributes<parameter> *window_attributes_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose current attributes you want to obtain -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_attributes_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the specified window's attributes in the
+<structname>XWindowAttributes</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWindowAttributes</function>
+function returns the current attributes for the specified window to an
+<structname>XWindowAttributes</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XWindowAttributes</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int x, y; /* location of window */
+ int width, height; /* width and height of window */
+ int border_width; /* border width of window */
+ int depth; /* depth of window */
+ Visual *visual; /* the associated visual structure */
+ Window root; /* root of screen containing window */
+ int class; /* InputOutput, InputOnly*/
+ int bit_gravity; /* one of the bit gravity values */
+ int win_gravity; /* one of the window gravity values */
+ int backing_store; /* NotUseful, WhenMapped, Always */
+ unsigned long backing_planes; /* planes to be preserved if possible */
+ unsigned long backing_pixel; /* value to be used when restoring planes */
+ Bool save_under; /* boolean, should bits under be saved? */
+ Colormap colormap; /* color map to be associated with window */
+ Bool map_installed; /* boolean, is color map currently installed*/
+ int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
+ long all_event_masks; /* set of events all people have interest in*/
+ long your_event_mask; /* my event mask */
+ long do_not_propagate_mask; /* set of events that should not propagate */
+ Bool override_redirect; /* boolean value for override-redirect */
+ Screen *screen; /* back pointer to correct screen */
+} XWindowAttributes;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The x and y members are set to the upper-left outer
+corner relative to the parent window's origin.
+The width and height members are set to the inside size of the window,
+not including the border.
+The border_width member is set to the window's border width in pixels.
+The depth member is set to the depth of the window
+(that is, bits per pixel for the object).
+The visual member is a pointer to the screen's associated
+<structname>Visual</structname>
+structure.
+The root member is set to the root window of the screen containing the window.
+The class member is set to the window's class and can be either
+<symbol>InputOutput</symbol>
+or
+<symbol>InputOnly</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The bit_gravity member is set to the window's bit gravity
+and can be one of the following:
+ <simplelist type="vert" columns="2">
+ <member><symbol>ForgetGravity</symbol></member>
+ <member><symbol>NorthWestGravity</symbol></member>
+ <member><symbol>NorthGravity</symbol></member>
+ <member><symbol>NorthEastGravity</symbol></member>
+ <member><symbol>WestGravity</symbol></member>
+
+ <member><symbol>EastGravity</symbol></member>
+ <member><symbol>SouthWestGravity</symbol></member>
+ <member><symbol>SouthGravity</symbol></member>
+ <member><symbol>SouthEastGravity</symbol></member>
+ <member><symbol>StaticGravity</symbol></member>
+ </simplelist>
+</para>
+<para>
+The win_gravity member is set to the window's window gravity
+and can be one of the following:
+ <simplelist type="vert" columns="2">
+ <member><symbol>UnmapGravity</symbol></member>
+ <member><symbol>NorthWestGravity</symbol></member>
+ <member><symbol>NorthGravity</symbol></member>
+ <member><symbol>NorthEastGravity</symbol></member>
+ <member><symbol>WestGravity</symbol></member>
+
+ <member><symbol>EastGravity</symbol></member>
+ <member><symbol>SouthWestGravity</symbol></member>
+ <member><symbol>SouthGravity</symbol></member>
+ <member><symbol>SouthEastGravity</symbol></member>
+ <member><symbol>StaticGravity</symbol></member>
+ <member><symbol>CenterGravity</symbol></member>
+ </simplelist>
+</para>
+<para>
+<!-- .LP -->
+For additional information on gravity,
+see <link linkend="Gravity_Attributes">section 3.2.3</link>.
+</para>
+<para>
+<!-- .LP -->
+The backing_store member is set to indicate how the X server should maintain
+the contents of a window
+and can be
+<symbol>WhenMapped</symbol>,
+<symbol>Always</symbol>,
+or
+<symbol>NotUseful</symbol>.
+The backing_planes member is set to indicate (with bits set to 1) which bit
+planes of the window hold dynamic data that must be preserved in backing_stores
+and during save_unders.
+The backing_pixel member is set to indicate what values to use
+for planes not set in backing_planes.
+</para>
+<para>
+<!-- .LP -->
+The save_under member is set to
+<symbol>True</symbol>
+or
+<symbol>False</symbol>.
+The colormap member is set to the colormap for the specified window and can be
+a colormap ID or
+<symbol>None</symbol>.
+The map_installed member is set to indicate whether the colormap is
+currently installed and can be
+<symbol>True</symbol>
+or
+<symbol>False</symbol>.
+The map_state member is set to indicate the state of the window and can be
+<symbol>IsUnmapped</symbol>,
+<symbol>IsUnviewable</symbol>,
+or
+<symbol>IsViewable</symbol>.
+<symbol>IsUnviewable</symbol>
+is used if the window is mapped but some ancestor is unmapped.
+</para>
+<para>
+<!-- .LP -->
+The all_event_masks member is set to the bitwise inclusive OR of all event
+masks selected on the window by all clients.
+The your_event_mask member is set to the bitwise inclusive OR of all event
+masks selected by the querying client.
+The do_not_propagate_mask member is set to the bitwise inclusive OR of the
+set of events that should not propagate.
+</para>
+<para>
+<!-- .LP -->
+The override_redirect member is set to indicate whether this window overrides
+structure control facilities and can be
+<symbol>True</symbol>
+or
+<symbol>False</symbol>.
+Window manager clients should ignore the window if this member is
+<symbol>True</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The screen member is set to a screen pointer that gives you a back pointer
+to the correct screen.
+This makes it easier to obtain the screen information without
+having to loop over the root window fields to see which field matches.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWindowAttributes</function>
+can generate
+<errorname>BadDrawable</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the current geometry of a given drawable, use
+<function>XGetGeometry</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetGeometry</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetgeometry'>
+<funcprototype>
+ <funcdef>Status <function>XGetGeometry</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>Window<parameter> *root_return</parameter></paramdef>
+ <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+ <paramdef>unsignedint<parameter> *border_width_return</parameter></paramdef>
+ <paramdef>unsignedint<parameter> *depth_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Dr , which can be a window or a pixmap -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable(Dr.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>root_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the root window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the x and y coordinates that define the location of the drawable.
+For a window,
+these coordinates specify the upper-left outer corner relative to
+its parent's origin.
+For pixmaps, these coordinates are always zero.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the drawable's dimensions (width and height).
+For a window,
+these dimensions specify the inside size, not including the border.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>border_width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the border width in pixels.
+If the drawable is a pixmap, it returns zero.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the depth of the drawable (bits per pixel for the object).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetGeometry</function>
+function returns the root window and the current geometry of the drawable.
+The geometry of the drawable includes the x and y coordinates, width and height,
+border width, and depth.
+These are described in the argument list.
+It is legal to pass to this function a window whose class is
+<symbol>InputOnly</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetGeometry</function>
+can generate a
+<errorname>BadDrawable</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Translating_Screen_Coordinates">
+<title>Translating Screen Coordinates</title>
+<!-- .XS -->
+<!-- (SN Translating Screen Coordinates -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Applications sometimes
+need to perform a coordinate transformation from the coordinate
+space of one window to another window or need to determine which
+window the pointing device is in.
+<function>XTranslateCoordinates</function>
+and
+<function>XQueryPointer</function>
+fulfill these needs (and avoid any race conditions) by
+asking the X server to perform these operations.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To translate a coordinate in one window to the coordinate
+space of another window, use
+<function>XTranslateCoordinates</function>.
+</para>
+<indexterm significance="preferred"><primary>XTranslateCoordinates</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtranslatecoordinates'>
+<funcprototype>
+ <funcdef>Bool <function>XTranslateCoordinates</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Windowsrc_w,<parameter> dest_w</parameter></paramdef>
+ <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef>
+ <paramdef>int*dest_x_return,<parameter> *dest_y_return</parameter></paramdef>
+ <paramdef>Window<parameter> *child_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the source window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the destination window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates within the source window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the x and y coordinates within the destination window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>child_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the child if the coordinates are contained in a mapped child of the
+destination window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If
+<function>XTranslateCoordinates</function>
+returns
+<symbol>True</symbol>,
+it takes the src_x and src_y coordinates relative
+to the source window's origin and returns these coordinates to
+dest_x_return and dest_y_return
+relative to the destination window's origin.
+If
+<function>XTranslateCoordinates</function>
+returns
+<symbol>False</symbol>,
+src_w and dest_w are on different screens,
+and dest_x_return and dest_y_return are zero.
+If the coordinates are contained in a mapped child of dest_w,
+that child is returned to child_return.
+Otherwise, child_return is set to
+<symbol>None</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<function>XTranslateCoordinates</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the screen coordinates of the pointer
+or to determine the pointer coordinates relative to a specified window, use
+<function>XQueryPointer</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryPointer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerypointer'>
+<funcprototype>
+ <funcdef>Bool <function>XQueryPointer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window*root_return,<parameter> *child_return</parameter></paramdef>
+ <paramdef>int*root_x_return,<parameter> *root_y_return</parameter></paramdef>
+ <paramdef>int*win_x_return,<parameter> *win_y_return</parameter></paramdef>
+ <paramdef>unsignedint<parameter> *mask_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+<!-- .ds Ro that the pointer is in -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>root_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the root window (Ro.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>child_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the child window that the pointer is located in, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>root_x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>root_y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the pointer coordinates relative to the root window's origin.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>win_x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>win_y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the pointer coordinates relative to the specified window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mask_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the current state of the modifier keys and pointer buttons.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryPointer</function>
+function returns the root window the pointer is logically on and the pointer
+coordinates relative to the root window's origin.
+If
+<function>XQueryPointer</function>
+returns
+<symbol>False</symbol>,
+the pointer is not on the same screen as the specified window, and
+<function>XQueryPointer</function>
+returns
+<symbol>None</symbol>
+to child_return and zero to win_x_return and win_y_return.
+If
+<function>XQueryPointer</function>
+returns
+<symbol>True</symbol>,
+the pointer coordinates returned to win_x_return and win_y_return
+are relative to the origin of the specified window.
+In this case,
+<function>XQueryPointer</function>
+returns the child that contains the pointer, if any,
+or else
+<symbol>None</symbol>
+to child_return.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryPointer</function>
+returns the current logical state of the keyboard buttons
+and the modifier keys in mask_return.
+It sets mask_return to the bitwise inclusive OR of one or more
+of the button or modifier key bitmasks to match
+the current state of the mouse buttons and the modifier keys.
+</para>
+<para>
+<!-- .LP -->
+Note that the logical state of a device (as seen through Xlib)
+may lag the physical state if device event processing is frozen
+(see <link linkend="Pointer_Grabbing_">section 12.1</link>).
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryPointer</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Properties_and_Atoms">
+<title>Properties and Atoms</title>
+<!-- .XS -->
+<!-- (SN Properties and Atoms -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A property is a collection of named, typed data.
+The window system has a set of predefined properties
+<indexterm><primary>Atom</primary><secondary>predefined</secondary></indexterm>
+(for example, the name of a window, size hints, and so on), and users can
+define any other arbitrary information and associate it with windows.
+Each property has a name,
+which is an ISO Latin-1 string.
+For each named property,
+a unique identifier (atom) is associated with it.
+A property also has a type, for example, string or integer.
+These types are also indicated using atoms, so arbitrary new
+types can be defined.
+Data of only one type may be associated with a single
+property name.
+Clients can store and retrieve properties associated with windows.
+For efficiency reasons,
+an atom is used rather than a character string.
+<function>XInternAtom</function>
+can be used to obtain the atom for property names.
+<indexterm><primary>Atom</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+A property is also stored in one of several possible formats.
+The X server can store the information as 8-bit quantities, 16-bit
+quantities, or 32-bit quantities.
+This permits the X server to present the data in the byte order that the
+client expects.
+<!-- .NT Note -->
+If you define further properties of complex type,
+you must encode and decode them yourself.
+These functions must be carefully written if they are to be portable.
+For further information about how to write a library extension,
+see <link linkend="extensions">appendix C</link>.
+<!-- .NE -->
+The type of a property is defined by an atom, which allows for
+arbitrary extension in this type scheme.
+<indexterm><primary>Atom</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+Certain property names are
+predefined in the server for commonly used functions.
+The atoms for these properties are defined in
+<filename class="headerfile"><X11/Xatom.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+To avoid name clashes with user symbols, the
+<code>#define</code>
+name for each atom has the XA_ prefix.
+For an explanation of the functions that let you get and set
+much of the information stored in these predefined properties,
+see <link linkend="inter_client_communication_functions">chapter 14</link>.
+</para>
+<para>
+<!-- .LP -->
+The core protocol imposes no semantics on these property names,
+but semantics are specified in other X Consortium standards,
+such as the <emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>
+and the <emphasis remap='I'>X Logical Font Description Conventions</emphasis>.
+</para>
+<para>
+<!-- .LP -->
+You can use properties to communicate other information between
+applications.
+The functions described in this section let you define new properties
+and get the unique atom IDs in your applications.
+</para>
+<para>
+<!-- .LP -->
+Although any particular atom can have some client interpretation
+within each of the name spaces,
+atoms occur in five distinct name spaces within the protocol:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Selections
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Property names
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Property types
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Font properties
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Type of a
+<symbol>ClientMessage</symbol>
+event (none are built into the X server)
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+The built-in selection property names are:
+<simplelist type="vert" columns="2">
+ <member><property>PRIMARY</property></member>
+ <member><property>SECONDARY</property></member>
+</simplelist>
+</para>
+<para>
+<!-- .LP -->
+The built-in property names are:
+ <simplelist type="vert" columns="2">
+ <member><property>CUT_BUFFER0</property></member>
+ <member><property>CUT_BUFFER1</property></member>
+ <member><property>CUT_BUFFER2</property></member>
+ <member><property>CUT_BUFFER3</property></member>
+ <member><property>CUT_BUFFER4</property></member>
+ <member><property>CUT_BUFFER5</property></member>
+ <member><property>CUT_BUFFER6</property></member>
+ <member><property>CUT_BUFFER7</property></member>
+ <member><property>RGB_BEST_MAP</property></member>
+ <member><property>RGB_BLUE_MAP</property></member>
+ <member><property>RGB_DEFAULT_MAP</property></member>
+ <member><property>RGB_GRAY_MAP</property></member>
+ <member><property>RGB_GREEN_MAP</property></member>
+ <member><property>RGB_RED_MAP</property></member>
+
+ <member><property>RESOURCE_MANAGER</property></member>
+ <member><property>WM_CLASS</property></member>
+ <member><property>WM_CLIENT_MACHINE</property></member>
+ <member><property>WM_COLORMAP_WINDOWS</property></member>
+ <member><property>WM_COMMAND</property></member>
+ <member><property>WM_HINTS</property></member>
+ <member><property>WM_ICON_NAME</property></member>
+ <member><property>WM_ICON_SIZE</property></member>
+ <member><property>WM_NAME</property></member>
+ <member><property>WM_NORMAL_HINTS</property></member>
+ <member><property>WM_PROTOCOLS</property></member>
+ <member><property>WM_STATE</property></member>
+ <member><property>WM_TRANSIENT_FOR</property></member>
+ <member><property>WM_ZOOM_HINTS</property></member>
+ </simplelist>
+</para>
+<para>
+The built-in property types are:
+ <simplelist type="vert" columns="2">
+ <member><property>ARC</property></member>
+ <member><property>ATOM</property></member>
+ <member><property>BITMAP</property></member>
+ <member><property>CARDINAL</property></member>
+ <member><property>COLORMAP</property></member>
+ <member><property>CURSOR</property></member>
+ <member><property>DRAWABLE</property></member>
+ <member><property>FONT</property></member>
+ <member><property>INTEGER</property></member>
+ <member><property>PIXMAP</property></member>
+ <member><property>POINT</property></member>
+ <member><property>RGB_COLOR_MAP</property></member>
+ <member><property>RECTANGLE</property></member>
+ <member><property>STRING</property></member>
+ <member><property>VISUALID</property></member>
+ <member><property>WINDOW</property></member>
+ <member><property>WM_HINTS</property></member>
+ <member><property>WM_SIZE_HINTS</property></member>
+ </simplelist>
+</para>
+<para>
+The built-in font property names are:
+ <simplelist type="vert" columns="2">
+ <member><property>MIN_SPACE</property></member>
+ <member><property>NORM_SPACE</property></member>
+ <member><property>MAX_SPACE</property></member>
+ <member><property>END_SPACE</property></member>
+ <member><property>SUPERSCRIPT_X</property></member>
+ <member><property>SUPERSCRIPT_Y</property></member>
+ <member><property>SUBSCRIPT_X</property></member>
+ <member><property>SUBSCRIPT_Y</property></member>
+ <member><property>UNDERLINE_POSITION</property></member>
+ <member><property>UNDERLINE_THICKNESS</property></member>
+ <member><property>FONT_NAME</property></member>
+ <member><property>FULL_NAME</property></member>
+
+ <member><property>STRIKEOUT_DESCENT</property></member>
+ <member><property>STRIKEOUT_ASCENT</property></member>
+ <member><property>ITALIC_ANGLE</property></member>
+ <member><property>X_HEIGHT</property></member>
+ <member><property>QUAD_WIDTH</property></member>
+ <member><property>WEIGHT</property></member>
+ <member><property>POINT_SIZE</property></member>
+ <member><property>RESOLUTION</property></member>
+ <member><property>COPYRIGHT</property></member>
+ <member><property>NOTICE</property></member>
+ <member><property>FAMILY_NAME</property></member>
+ <member><property>CAP_HEIGHT</property></member>
+ </simplelist>
+</para>
+<para>
+<!-- .LP -->
+For further information about font properties,
+see <link linkend="Font_Metrics">section 8.5</link>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return an atom for a given name, use
+<function>XInternAtom</function>.
+</para>
+<indexterm><primary>Atom</primary><secondary>interning</secondary></indexterm>
+<indexterm significance="preferred"><primary>XInternAtom</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinternatom'>
+<funcprototype>
+ <funcdef>Atom <function>XInternAtom</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *atom_name</parameter></paramdef>
+ <paramdef>Bool<parameter> only_if_exists</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>atom_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name associated with the atom you want returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>only_if_exists</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the atom must be created.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInternAtom</function>
+function returns the atom identifier associated with the specified atom_name
+string.
+If only_if_exists is
+<symbol>False</symbol>,
+the atom is created if it does not exist.
+Therefore,
+<function>XInternAtom</function>
+can return
+<symbol>None</symbol>.
+If the atom name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Uppercase and lowercase matter;
+the strings ``thing'', ``Thing'', and ``thinG''
+all designate different atoms.
+The atom will remain defined even after the client's connection closes.
+It will become undefined only when the last connection to
+the X server closes.
+</para>
+<para>
+<!-- .LP -->
+<function>XInternAtom</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return atoms for an array of names, use
+<function>XInternAtoms</function>.
+</para>
+<indexterm><primary>Atom</primary><secondary>interning</secondary></indexterm>
+<indexterm significance="preferred"><primary>XInternAtoms</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinternatoms'>
+<funcprototype>
+ <funcdef>Status <function>XInternAtoms</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> **names</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>Bool<parameter> only_if_exists</parameter></paramdef>
+ <paramdef>Atom<parameter> *atoms_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>names</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the array of atom names.
+<!-- .ds Cn atom names in the array -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>only_if_exists</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the atom must be created.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>atoms_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the atoms.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInternAtoms</function>
+function returns the atom identifiers associated with the specified names.
+The atoms are stored in the atoms_return array supplied by the caller.
+Calling this function is equivalent to calling
+<function>XInternAtom</function>
+for each of the names in turn with the specified value of only_if_exists,
+but this function minimizes the number of round-trip protocol exchanges
+between the client and the X server.
+</para>
+<para>
+<!-- .LP -->
+This function returns a nonzero status if atoms are returned for
+all of the names;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+<function>XInternAtoms</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return a name for a given atom identifier, use
+<function>XGetAtomName</function>.
+</para>
+<indexterm><primary>Atom</primary><secondary>getting name</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGetAtomName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetatomname'>
+<funcprototype>
+ <funcdef>char *<function>XGetAtomName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Atom<parameter> atom</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>atom</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the atom for the property name you want returned.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetAtomName</function>
+function returns the name associated with the specified atom.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned string is in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+To free the resulting string,
+call
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetAtomName</function>
+can generate a
+<errorname>BadAtom</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return the names for an array of atom identifiers, use
+<function>XGetAtomNames</function>.
+</para>
+<indexterm><primary>Atom</primary><secondary>getting name</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGetAtomNames</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetatomnames'>
+<funcprototype>
+ <funcdef>Status <function>XGetAtomNames</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Atom<parameter> *atoms</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>char<parameter> **names_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>atoms</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the array of atoms.
+<!-- .ds Cn atoms in the array -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>names_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the atom names.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetAtomNames</function>
+function returns the names associated with the specified atoms.
+The names are stored in the names_return array supplied by the caller.
+Calling this function is equivalent to calling
+<function>XGetAtomName</function>
+for each of the atoms in turn,
+but this function minimizes the number of round-trip protocol exchanges
+between the client and the X server.
+</para>
+<para>
+<!-- .LP -->
+This function returns a nonzero status if names are returned for
+all of the atoms;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetAtomNames</function>
+can generate a
+<errorname>BadAtom</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Obtaining_and_Changing_Window_Properties">
+<title>Obtaining and Changing Window Properties</title>
+<!-- .XS -->
+<!-- (SN Obtaining and Changing Window Properties -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You can attach a property list to every window.
+Each property has a name, a type, and a value
+(see <link linkend="Properties_and_Atoms">section 4.3</link>).
+The value is an array of 8-bit, 16-bit, or 32-bit quantities,
+whose interpretation is left to the clients. The type
+<type>char</type>
+is used to represent 8-bit quantities, the type
+<type>short</type>
+is used to represent 16-bit quantities, and the type
+<type>long</type>
+is used to represent 32-bit quantities.
+</para>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to obtain,
+change, update, or interchange window properties.
+In addition, Xlib provides other utility functions for inter-client
+communication
+(see <link linkend="inter_client_communication_functions">chapter 14</link>).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the type, format, and value of a property of a given window, use
+<function>XGetWindowProperty</function>.
+<indexterm><primary>Property</primary><secondary>getting</secondary></indexterm>
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XGetWindowProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwindowproperty'>
+<funcprototype>
+ <funcdef>int <function>XGetWindowProperty</function></funcdef>
+ <paramdef><parameter> display</parameter></paramdef>
+ <paramdef><parameter> w</parameter></paramdef>
+ <paramdef><parameter> property</parameter></paramdef>
+ <paramdef><parameter> long_offset</parameter></paramdef>
+ <paramdef><parameter> long_length</parameter></paramdef>
+ <paramdef><parameter> delete</parameter></paramdef>
+ <paramdef><parameter> req_type</parameter></paramdef>
+ <paramdef><parameter> actual_type_return</parameter></paramdef>
+ <paramdef><parameter> actual_format_return</parameter></paramdef>
+ <paramdef><parameter> nitems_return</parameter></paramdef>
+ <paramdef><parameter> bytes_after_return</parameter></paramdef>
+ <paramdef>.br<parameter> prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose property you want to obtain -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>long_offset</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the offset in the specified property (in 32-bit quantities)
+where the data is to be retrieved.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>long_length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length in 32-bit multiples of the data to be retrieved.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>delete</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that determines whether the property is deleted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>req_type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the atom identifier associated with the property type or
+<symbol>AnyPropertyType</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>actual_type_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the atom identifier that defines the actual type of the property.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>actual_format_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the actual format of the property.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nitems_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the actual number of 8-bit, 16-bit, or 32-bit items
+stored in the prop_return data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes_after_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of bytes remaining to be read in the property if
+a partial read was performed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the data in the specified format.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWindowProperty</function>
+function returns the actual type of the property; the actual format of the property;
+the number of 8-bit, 16-bit, or 32-bit items transferred; the number of bytes remaining
+to be read in the property; and a pointer to the data actually returned.
+<function>XGetWindowProperty</function>
+sets the return arguments as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the specified property does not exist for the specified window,
+<function>XGetWindowProperty</function>
+returns
+<symbol>None</symbol>
+to actual_type_return and the value zero to
+actual_format_return and bytes_after_return.
+The nitems_return argument is empty.
+In this case, the delete argument is ignored.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the specified property exists
+but its type does not match the specified type,
+<function>XGetWindowProperty</function>
+returns the actual property type to actual_type_return,
+the actual property format (never zero) to actual_format_return,
+and the property length in bytes
+(even if the actual_format_return is 16 or 32)
+to bytes_after_return.
+It also ignores the delete argument.
+The nitems_return argument is empty.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the specified property exists and either you assign
+<symbol>AnyPropertyType</symbol>
+to the req_type argument or the specified type matches the actual property type,
+<function>XGetWindowProperty</function>
+returns the actual property type to actual_type_return and the actual
+property format (never zero) to actual_format_return.
+It also returns a value to bytes_after_return and nitems_return, by
+defining the following
+values:
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<!-- .nf -->
+ N = actual length of the stored property in bytes
+ (even if the format is 16 or 32)
+ I = 4 * long_offset
+ T = N - I
+ L = MINIMUM(T, 4 * long_length)
+ A = N - (I + L)
+<!-- .fi -->
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The returned value starts at byte index I in the property (indexing
+from zero), and its length in bytes is L.
+If the value for long_offset causes L to be negative,
+a
+<errorname>BadValue</errorname>
+error results.
+The value of bytes_after_return is A,
+giving the number of trailing unread bytes in the stored property.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+If the returned format is 8, the returned data is represented as a
+<type>char</type>
+array.
+If the returned format is 16, the returned data is represented as a
+<type>short</type>
+array and should be cast to that type to obtain the elements.
+If the returned format is 32, the returned data is represented as a
+<type>long</type>
+array and should be cast to that type to obtain the elements.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWindowProperty</function>
+always allocates one extra byte in prop_return
+(even if the property is zero length)
+and sets it to zero so that simple properties consisting of characters
+do not have to be copied into yet another string before use.
+</para>
+<para>
+<!-- .LP -->
+If delete is
+<symbol>True</symbol>
+and bytes_after_return is zero,
+<function>XGetWindowProperty</function>
+deletes the property
+from the window and generates a
+<symbol>PropertyNotify</symbol>
+event on the window.
+</para>
+<para>
+<!-- .LP -->
+The function returns
+<symbol>Success</symbol>
+if it executes successfully.
+To free the resulting data,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWindowProperty</function>
+can generate
+<errorname>BadAtom</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a given window's property list, use
+<function>XListProperties</function>.
+</para>
+<indexterm><primary>Property</primary><secondary>listing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XListProperties</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlistproperties'>
+<funcprototype>
+ <funcdef>Atom *<function>XListProperties</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> *num_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose property list you want to obtain -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the length of the properties array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListProperties</function>
+function returns a pointer to an array of atom properties that are defined for
+the specified window or returns NULL if no properties were found.
+To free the memory allocated by this function, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XListProperties</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change a property of a given window, use
+<function>XChangeProperty</function>.
+</para>
+<indexterm><primary>Property</primary><secondary>changing</secondary></indexterm>
+<indexterm><primary>Property</primary><secondary>appending</secondary></indexterm>
+<indexterm><primary>Property</primary><secondary>prepending</secondary></indexterm>
+<indexterm><primary>Property</primary><secondary>replacing</secondary></indexterm>
+<indexterm><primary>Property</primary><secondary>format</secondary></indexterm>
+<indexterm><primary>Property</primary><secondary>type</secondary></indexterm>
+<indexterm significance="preferred"><primary>XChangeProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangeproperty'>
+<funcprototype>
+ <funcdef><function>XChangeProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Atomproperty,<parameter> type</parameter></paramdef>
+ <paramdef>int<parameter> format</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> *data</parameter></paramdef>
+ <paramdef>int<parameter> nelements</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose property you want to change -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the type of the property.
+The X server does not interpret the type but simply
+passes it back to an application that later calls
+<function>XGetWindowProperty</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies whether the data should be viewed as a list
+of 8-bit, 16-bit, or 32-bit quantities.
+Possible values are 8, 16, and 32.
+This information allows the X server to correctly perform
+byte-swap operations as necessary.
+If the format is 16-bit or 32-bit,
+you must explicitly cast your data pointer to an (unsigned char *) in the call
+to
+<function>XChangeProperty</function>.
+<!-- .\" Changed name of this file to prop_mode.a on 1/13/87 -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode of the operation.
+You can pass
+<symbol>PropModeReplace</symbol>,
+<symbol>PropModePrepend</symbol>,
+or
+<symbol>PropModeAppend</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nelements</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements of the specified data format.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangeProperty</function>
+function alters the property for the specified window and
+causes the X server to generate a
+<symbol>PropertyNotify</symbol>
+event on that window.
+<function>XChangeProperty</function>
+performs the following:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If mode is
+<symbol>PropModeReplace</symbol>,
+<function>XChangeProperty</function>
+discards the previous property value and stores the new data.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If mode is
+<symbol>PropModePrepend</symbol>
+or
+<symbol>PropModeAppend</symbol>,
+<function>XChangeProperty</function>
+inserts the specified data before the beginning of the existing data
+or onto the end of the existing data, respectively.
+The type and format must match the existing property value,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If the property is undefined,
+it is treated as defined with the correct type and
+format with zero-length data.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+If the specified format is 8, the property data must be a
+<type>char</type>
+array.
+If the specified format is 16, the property data must be a
+<type>short</type>
+array.
+If the specified format is 32, the property data must be a
+<type>long</type>
+array.
+</para>
+<para>
+<!-- .LP -->
+The lifetime of a property is not tied to the storing client.
+Properties remain until explicitly deleted, until the window is destroyed,
+or until the server resets.
+For a discussion of what happens when the connection to the X server is closed,
+see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>.
+The maximum size of a property is server dependent and can vary dynamically
+depending on the amount of memory the server has available.
+(If there is insufficient space, a
+<errorname>BadAlloc</errorname>
+error results.)
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeProperty</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To rotate a window's property list, use
+<function>XRotateWindowProperties</function>.
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XRotateWindowProperties</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrotatewindowproperties'>
+<funcprototype>
+ <funcdef><function>XRotateWindowProperties</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Atom<parameter> properties[]</parameter></paramdef>
+ <paramdef>int<parameter> num_prop</parameter></paramdef>
+ <paramdef>int<parameter> npositions</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>properties</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the array of properties that are to be rotated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of the properties array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npositions</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the rotation amount.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRotateWindowProperties</function>
+function allows you to rotate properties on a window and causes
+the X server to generate
+<symbol>PropertyNotify</symbol>
+events.
+If the property names in the properties array are viewed as being numbered
+starting from zero and if there are num_prop property names in the list,
+then the value associated with property name I becomes the value associated
+with property name (I + npositions) mod N for all I from zero to N − 1.
+The effect is to rotate the states by npositions places around the virtual ring
+of property names (right for positive npositions,
+left for negative npositions).
+If npositions mod N is nonzero,
+the X server generates a
+<symbol>PropertyNotify</symbol>
+event for each property in the order that they are listed in the array.
+If an atom occurs more than once in the list or no property with that
+name is defined for the window,
+a
+<errorname>BadMatch</errorname>
+error results.
+If a
+<errorname>BadAtom</errorname>
+or
+<errorname>BadMatch</errorname>
+error results,
+no properties are changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XRotateWindowProperties</function>
+can generate
+<errorname>BadAtom</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To delete a property on a given window, use
+<function>XDeleteProperty</function>.
+</para>
+<indexterm><primary>Property</primary><secondary>deleting</secondary></indexterm>
+<indexterm significance="preferred"><primary>XDeleteProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdeleteproperty'>
+<funcprototype>
+ <funcdef><function>XDeleteProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose property you want to delete -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDeleteProperty</function>
+function deletes the specified property only if the
+property was defined on the specified window
+and causes the X server to generate a
+<symbol>PropertyNotify</symbol>
+event on the window unless the property does not exist.
+</para>
+<para>
+<!-- .LP -->
+<function>XDeleteProperty</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Selections">
+<title>Selections</title>
+<!-- .XS -->
+<!-- (SN Selections -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Selection</primary></indexterm>
+Selections are one method used by applications to exchange data.
+By using the property mechanism,
+applications can exchange data of arbitrary types and can negotiate
+the type of the data.
+A selection can be thought of as an indirect property with a dynamic type.
+That is, rather than having the property stored in the X server,
+the property is maintained by some client (the owner).
+A selection is global in nature (considered to belong to the user
+but be maintained by clients) rather than being private to a particular
+window subhierarchy or a particular set of clients.
+</para>
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set, get, or request conversion
+of selections.
+This allows applications to implement the notion of current selection,
+which requires that notification be sent to applications when they no
+longer own the selection.
+Applications that support selection often highlight the current selection
+and so must be informed when another application has
+acquired the selection so that they can unhighlight the selection.
+</para>
+<para>
+<!-- .LP -->
+When a client asks for the contents of
+a selection, it specifies a selection target type.
+This target type
+can be used to control the transmitted representation of the contents.
+For example, if the selection is ``the last thing the user clicked on''
+and that is currently an image, then the target type might specify
+whether the contents of the image should be sent in XY format or Z format.
+</para>
+<para>
+<!-- .LP -->
+The target type can also be used to control the class of
+contents transmitted, for example,
+asking for the ``looks'' (fonts, line
+spacing, indentation, and so forth) of a paragraph selection, not the
+text of the paragraph.
+The target type can also be used for other
+purposes.
+The protocol does not constrain the semantics.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the selection owner, use
+<function>XSetSelectionOwner</function>.
+</para>
+<indexterm><primary>Selection</primary><secondary>setting the owner</secondary></indexterm>
+<indexterm significance="preferred"><primary>XSetSelectionOwner</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetselectionowner'>
+<funcprototype>
+ <funcdef><function>XSetSelectionOwner</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Atom<parameter> selection</parameter></paramdef>
+ <paramdef>Window<parameter> owner</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>selection</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the selection atom.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the owner of the specified selection atom.
+You can pass a window or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetSelectionOwner</function>
+function changes the owner and last-change time for the specified selection
+and has no effect if the specified time is earlier than the current
+last-change time of the specified selection
+or is later than the current X server time.
+Otherwise, the last-change time is set to the specified time,
+with
+<symbol>CurrentTime</symbol>
+replaced by the current server time.
+If the owner window is specified as
+<symbol>None</symbol>,
+then the owner of the selection becomes
+<symbol>None</symbol>
+(that is, no owner).
+Otherwise, the owner of the selection becomes the client executing
+the request.
+</para>
+<para>
+<!-- .LP -->
+If the new owner (whether a client or
+<symbol>None</symbol>)
+is not
+the same as the current owner of the selection and the current
+owner is not
+<symbol>None</symbol>,
+the current owner is sent a
+<symbol>SelectionClear</symbol>
+event.
+If the client that is the owner of a selection is later
+terminated (that is, its connection is closed)
+or if the owner window it has specified in the request is later
+destroyed,
+the owner of the selection automatically
+reverts to
+<symbol>None</symbol>,
+but the last-change time is not affected.
+The selection atom is uninterpreted by the X server.
+<function>XGetSelectionOwner</function>
+returns the owner window, which is reported in
+<symbol>SelectionRequest</symbol>
+and
+<symbol>SelectionClear</symbol>
+events.
+Selections are global to the X server.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetSelectionOwner</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return the selection owner, use
+<function>XGetSelectionOwner</function>.
+</para>
+<indexterm><primary>Selection</primary><secondary>getting the owner</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGetSelectionOwner</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetselectionowner'>
+<funcprototype>
+ <funcdef>Window <function>XGetSelectionOwner</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Atom<parameter> selection</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Se whose owner you want returned -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>selection</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the selection atom (Se.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetSelectionOwner</function>
+function
+returns the window ID associated with the window that currently owns the
+specified selection.
+If no selection was specified, the function returns the constant
+<symbol>None</symbol>.
+If
+<symbol>None</symbol>
+is returned,
+there is no owner for the selection.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetSelectionOwner</function>
+can generate a
+<errorname>BadAtom</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To request conversion of a selection, use
+<function>XConvertSelection</function>.
+</para>
+<indexterm><primary>Selection</primary><secondary>converting</secondary></indexterm>
+<indexterm significance="preferred"><primary>XConvertSelection</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xconvertselection'>
+<funcprototype>
+ <funcdef><function>XConvertSelection</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Atomselection,<parameter> target</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+ <paramdef>Window<parameter> requestor</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>selection</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the selection atom.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target atom.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+You also can pass
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>requestor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the requestor.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XConvertSelection</function>
+requests that the specified selection be converted to the specified target
+type:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If the specified selection has an owner, the X server sends a
+<symbol>SelectionRequest</symbol>
+event to that owner.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If no owner for the specified
+selection exists, the X server generates a
+<symbol>SelectionNotify</symbol>
+event to the
+requestor with property
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The arguments are passed on unchanged in either of the events.
+There are two predefined selection atoms: PRIMARY and SECONDARY.
+</para>
+<para>
+<!-- .LP -->
+<function>XConvertSelection</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .bp -->
+
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH05.xml b/libX11/specs/libX11/CH05.xml index 134831e60..1dd8e675a 100644 --- a/libX11/specs/libX11/CH05.xml +++ b/libX11/specs/libX11/CH05.xml @@ -1,818 +1,818 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="pixmap_and_cursor_functions"> -<title>Pixmap and Cursor Functions</title> -<sect1 id="Creating_and_Freeing_Pixmaps"> -<title>Creating and Freeing Pixmaps</title> -<!-- .XS --> -<!-- (SN Creating and Freeing Pixmaps --> -<!-- .XE --> -<para> -<!-- .LP --> -Pixmaps can only be used on the screen on which they were created. -Pixmaps are off-screen resources that are used for various operations, -such as defining cursors as tiling patterns -or as the source for certain raster operations. -Most graphics requests can operate either on a window or on a pixmap. -A bitmap is a single bit-plane pixmap. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a pixmap of a given size, use -<function>XCreatePixmap</function>. -</para> -<indexterm significance="preferred"><primary>XCreatePixmap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatepixmap'> -<funcprototype> - <funcdef>Pixmap <function>XCreatePixmap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint<parameter> depth</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies which screen the pixmap is created on. -<!-- .ds Wh , which define the dimensions of the pixmap --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth</emphasis> - </term> - <listitem> - <para> -Specifies the depth of the pixmap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreatePixmap</function> -function creates a pixmap of the width, height, and depth you specified -and returns a pixmap ID that identifies it. -It is valid to pass an -<symbol>InputOnly</symbol> -window to the drawable argument. -The width and height arguments must be nonzero, -or a -<errorname>BadValue</errorname> -error results. -The depth argument must be one of the depths supported by the screen -of the specified drawable, -or a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -The server uses the specified drawable to determine on which screen -to create the pixmap. -The pixmap can be used only on this screen -and only with other drawables of the same depth (see -<function>XCopyPlane</function> -for an exception to this rule). -The initial contents of the pixmap are undefined. -</para> -<para> -<!-- .LP --> -<function>XCreatePixmap</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadDrawable</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free all storage associated with a specified pixmap, use -<function>XFreePixmap</function>. -</para> -<indexterm significance="preferred"><primary>XFreePixmap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreepixmap'> -<funcprototype> - <funcdef><function>XFreePixmap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Pixmap<parameter> pixmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixmap</emphasis> - </term> - <listitem> - <para> -Specifies the pixmap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreePixmap</function> -function first deletes the association between the pixmap ID and the pixmap. -Then, the X server frees the pixmap storage when there are no references to it. -The pixmap should never be referenced again. -</para> -<para> -<!-- .LP --> -<function>XFreePixmap</function> -can generate a -<errorname>BadPixmap</errorname> -error. -</para> -</sect1> -<sect1 id="Creating_Recoloring_and_Freeing_Cursors"> -<title>Creating, Recoloring, and Freeing Cursors</title> -<!-- .XS --> -<!-- (SN Creating, Recoloring, and Freeing Cursors --> -<!-- .XE --> -<para> -<!-- .LP --> -Each window can have a different cursor defined for it. -Whenever the pointer is in a visible window, -it is set to the cursor defined for that window. -If no cursor was defined for that window, -the cursor is the one defined for the parent window. -</para> -<para> -<!-- .LP --> -From X's perspective, -a cursor consists of a cursor source, mask, colors, and a hotspot. -The mask pixmap determines the shape of the cursor and must be a depth -of one. -The source pixmap must have a depth of one, -and the colors determine the colors of the source. -The hotspot defines the point on the cursor that is reported -when a pointer event occurs. -There may be limitations imposed by the hardware on -cursors as to size and whether a mask is implemented. -<indexterm><primary>XQueryBestCursor</primary></indexterm> -<function>XQueryBestCursor</function> -can be used to find out what sizes are possible. -There is a standard font for creating cursors, but -Xlib provides functions that you can use to create cursors -from an arbitrary font or from bitmaps. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a cursor from the standard cursor font, use -<function>XCreateFontCursor</function>. -</para> -<para> -#include <X11/cursorfont.h> -</para> - -<indexterm significance="preferred"><primary>XCreateFontCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatefontcursor'> -<funcprototype> - <funcdef>Cursor <function>XCreateFontCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedint<parameter> shape</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>shape</emphasis> - </term> - <listitem> - <para> -Specifies the shape of the cursor. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -X provides a set of standard cursor shapes in a special font named -cursor. -Applications are encouraged to use this interface for their cursors -because the font can be customized for the individual display type. -The shape argument specifies which glyph of the standard fonts -to use. -</para> -<para> -<!-- .LP --> -The hotspot comes from the information stored in the cursor font. -The initial colors of a cursor are a black foreground and a white -background (see -<function>XRecolorCursor</function>). -For further information about cursor shapes, -see <link linkend="x_font_cursors">appendix B</link>. -</para> -<para> -<!-- .LP --> -<function>XCreateFontCursor</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a cursor from font glyphs, use -<function>XCreateGlyphCursor</function>. -</para> -<indexterm significance="preferred"><primary>XCreateGlyphCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreateglyphcursor'> -<funcprototype> - <funcdef>Cursor <function>XCreateGlyphCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Fontsource_font,<parameter> mask_font</parameter></paramdef> - <paramdef>unsignedintsource_char,<parameter> mask_char</parameter></paramdef> - <paramdef>XColor<parameter> *foreground_color</parameter></paramdef> - <paramdef>XColor<parameter> *background_color</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>source_font</emphasis> - </term> - <listitem> - <para> -Specifies the font for the source glyph. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mask_font</emphasis> - </term> - <listitem> - <para> -Specifies the font for the mask glyph or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>source_char</emphasis> - </term> - <listitem> - <para> -Specifies the character glyph for the source. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mask_char</emphasis> - </term> - <listitem> - <para> -Specifies the glyph character for the mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>foreground_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the foreground of the source. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the background of the source. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateGlyphCursor</function> -function is similar to -<function>XCreatePixmapCursor</function> -except that the source and mask bitmaps are obtained from the specified -font glyphs. -The source_char must be a defined glyph in source_font, -or a -<errorname>BadValue</errorname> -error results. -If mask_font is given, -mask_char must be a defined glyph in mask_font, -or a -<errorname>BadValue</errorname> -error results. -The mask_font and character are optional. -The origins of the source_char and mask_char (if defined) glyphs are -positioned coincidently and define the hotspot. -The source_char and mask_char need not have the same bounding box metrics, -and there is no restriction on the placement of the hotspot relative to the bounding -boxes. -If no mask_char is given, all pixels of the source are displayed. -You can free the fonts immediately by calling -<function>XFreeFont</function> -if no further explicit references to them are to be made. -</para> -<para> -<!-- .LP --> -For 2-byte matrix fonts, -the 16-bit value should be formed with the byte1 -member in the most significant byte and the byte2 member in the -least significant byte. -</para> -<para> -<!-- .LP --> -<function>XCreateGlyphCursor</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadFont</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a cursor from two bitmaps, -use -<function>XCreatePixmapCursor</function>. -</para> -<indexterm significance="preferred"><primary>XCreatePixmapCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatepixmapcursor'> -<funcprototype> - <funcdef>Cursor <function>XCreatePixmapCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Pixmap<parameter> source</parameter></paramdef> - <paramdef>Pixmap<parameter> mask</parameter></paramdef> - <paramdef>XColor<parameter> *foreground_color</parameter></paramdef> - <paramdef>XColor<parameter> *background_color</parameter></paramdef> - <paramdef>unsignedintx,<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>source</emphasis> - </term> - <listitem> - <para> -Specifies the shape of the source cursor. -<!-- .\" *** JIM: NEED TO CHECK THIS. *** --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mask</emphasis> - </term> - <listitem> - <para> -Specifies the cursor's source bits to be displayed or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>foreground_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the foreground of the source. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the background of the source. -<!-- .ds Xy , which indicate the hotspot relative to the source's origin --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreatePixmapCursor</function> -function creates a cursor and returns the cursor ID associated with it. -The foreground and background <acronym>RGB</acronym> values must be specified using -foreground_color and background_color, -even if the X server only has a -<symbol>StaticGray</symbol> -or -<symbol>GrayScale</symbol> -screen. -The foreground color is used for the pixels set to 1 in the -source, and the background color is used for the pixels set to 0. -Both source and mask, if specified, must have depth one (or a -<errorname>BadMatch</errorname> -error results) but can have any root. -The mask argument defines the shape of the cursor. -The pixels set to 1 in the mask define which source pixels are displayed, -and the pixels set to 0 define which pixels are ignored. -If no mask is given, -all pixels of the source are displayed. -The mask, if present, must be the same size as the pixmap defined by the -source argument, or a -<errorname>BadMatch</errorname> -error results. -The hotspot must be a point within the source, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -The components of the cursor can be transformed arbitrarily to meet -display limitations. -The pixmaps can be freed immediately if no further explicit references -to them are to be made. -Subsequent drawing in the source or mask pixmap has an undefined effect on the -cursor. -The X server might or might not make a copy of the pixmap. -</para> -<para> -<!-- .LP --> -<function>XCreatePixmapCursor</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadPixmap</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To determine useful cursor sizes, use -<function>XQueryBestCursor</function>. -</para> -<indexterm significance="preferred"><primary>XQueryBestCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerybestcursor'> -<funcprototype> - <funcdef>Status <function>XQueryBestCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Dr , which indicates the screen --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable(Dr. -<!-- .ds Wh \ of the cursor that you want the size information for --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the best width and height that is closest to the specified width -and height. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Some displays allow larger cursors than other displays. -The -<function>XQueryBestCursor</function> -function provides a way to find out what size cursors are actually -possible on the display. -<indexterm ><primary>Cursor</primary><secondary>limitations</secondary></indexterm> -It returns the largest size that can be displayed. -Applications should be prepared to use smaller cursors on displays that -cannot support large ones. -</para> -<para> -<!-- .LP --> -<function>XQueryBestCursor</function> -can generate a -<errorname>BadDrawable</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change the color of a given cursor, use -<function>XRecolorCursor</function>. -</para> -<indexterm significance="preferred"><primary>XRecolorCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrecolorcursor'> -<funcprototype> - <funcdef><function>XRecolorCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> - <paramdef>XColor*foreground_color,<parameter> *background_color</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>foreground_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the foreground of the source. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background_color</emphasis> - </term> - <listitem> - <para> -Specifies the <acronym>RGB</acronym> values for the background of the source. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRecolorCursor</function> -function changes the color of the specified cursor, and -if the cursor is being displayed on a screen, -the change is visible immediately. -The pixel members of the -<structname>XColor</structname> -structures are ignored; only the <acronym>RGB</acronym> values are used. -</para> -<para> -<!-- .LP --> -<function>XRecolorCursor</function> -can generate a -<errorname>BadCursor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free (destroy) a given cursor, use -<function>XFreeCursor</function>. -</para> -<indexterm significance="preferred"><primary>XFreeCursor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreecursor'> -<funcprototype> - <funcdef><function>XFreeCursor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeCursor</function> -function deletes the association between the cursor resource ID -and the specified cursor. -The cursor storage is freed when no other resource references it. -The specified cursor ID should not be referred to again. -</para> -<para> -<!-- .LP --> -<function>XFreeCursor</function> -can generate a -<errorname>BadCursor</errorname> -error. -<!-- .bp --> - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="pixmap_and_cursor_functions">
+<title>Pixmap and Cursor Functions</title>
+<sect1 id="Creating_and_Freeing_Pixmaps">
+<title>Creating and Freeing Pixmaps</title>
+<!-- .XS -->
+<!-- (SN Creating and Freeing Pixmaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Pixmaps can only be used on the screen on which they were created.
+Pixmaps are off-screen resources that are used for various operations,
+such as defining cursors as tiling patterns
+or as the source for certain raster operations.
+Most graphics requests can operate either on a window or on a pixmap.
+A bitmap is a single bit-plane pixmap.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a pixmap of a given size, use
+<function>XCreatePixmap</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreatePixmap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatepixmap'>
+<funcprototype>
+ <funcdef>Pixmap <function>XCreatePixmap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint<parameter> depth</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which screen the pixmap is created on.
+<!-- .ds Wh , which define the dimensions of the pixmap -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the depth of the pixmap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreatePixmap</function>
+function creates a pixmap of the width, height, and depth you specified
+and returns a pixmap ID that identifies it.
+It is valid to pass an
+<symbol>InputOnly</symbol>
+window to the drawable argument.
+The width and height arguments must be nonzero,
+or a
+<errorname>BadValue</errorname>
+error results.
+The depth argument must be one of the depths supported by the screen
+of the specified drawable,
+or a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The server uses the specified drawable to determine on which screen
+to create the pixmap.
+The pixmap can be used only on this screen
+and only with other drawables of the same depth (see
+<function>XCopyPlane</function>
+for an exception to this rule).
+The initial contents of the pixmap are undefined.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreatePixmap</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadDrawable</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free all storage associated with a specified pixmap, use
+<function>XFreePixmap</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreePixmap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreepixmap'>
+<funcprototype>
+ <funcdef><function>XFreePixmap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Pixmap<parameter> pixmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pixmap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreePixmap</function>
+function first deletes the association between the pixmap ID and the pixmap.
+Then, the X server frees the pixmap storage when there are no references to it.
+The pixmap should never be referenced again.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreePixmap</function>
+can generate a
+<errorname>BadPixmap</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Creating_Recoloring_and_Freeing_Cursors">
+<title>Creating, Recoloring, and Freeing Cursors</title>
+<!-- .XS -->
+<!-- (SN Creating, Recoloring, and Freeing Cursors -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Each window can have a different cursor defined for it.
+Whenever the pointer is in a visible window,
+it is set to the cursor defined for that window.
+If no cursor was defined for that window,
+the cursor is the one defined for the parent window.
+</para>
+<para>
+<!-- .LP -->
+From X's perspective,
+a cursor consists of a cursor source, mask, colors, and a hotspot.
+The mask pixmap determines the shape of the cursor and must be a depth
+of one.
+The source pixmap must have a depth of one,
+and the colors determine the colors of the source.
+The hotspot defines the point on the cursor that is reported
+when a pointer event occurs.
+There may be limitations imposed by the hardware on
+cursors as to size and whether a mask is implemented.
+<indexterm><primary>XQueryBestCursor</primary></indexterm>
+<function>XQueryBestCursor</function>
+can be used to find out what sizes are possible.
+There is a standard font for creating cursors, but
+Xlib provides functions that you can use to create cursors
+from an arbitrary font or from bitmaps.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a cursor from the standard cursor font, use
+<function>XCreateFontCursor</function>.
+</para>
+<para>
+#include <X11/cursorfont.h>
+</para>
+
+<indexterm significance="preferred"><primary>XCreateFontCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatefontcursor'>
+<funcprototype>
+ <funcdef>Cursor <function>XCreateFontCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedint<parameter> shape</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>shape</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the shape of the cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+X provides a set of standard cursor shapes in a special font named
+cursor.
+Applications are encouraged to use this interface for their cursors
+because the font can be customized for the individual display type.
+The shape argument specifies which glyph of the standard fonts
+to use.
+</para>
+<para>
+<!-- .LP -->
+The hotspot comes from the information stored in the cursor font.
+The initial colors of a cursor are a black foreground and a white
+background (see
+<function>XRecolorCursor</function>).
+For further information about cursor shapes,
+see <link linkend="x_font_cursors">appendix B</link>.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateFontCursor</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a cursor from font glyphs, use
+<function>XCreateGlyphCursor</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateGlyphCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreateglyphcursor'>
+<funcprototype>
+ <funcdef>Cursor <function>XCreateGlyphCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Fontsource_font,<parameter> mask_font</parameter></paramdef>
+ <paramdef>unsignedintsource_char,<parameter> mask_char</parameter></paramdef>
+ <paramdef>XColor<parameter> *foreground_color</parameter></paramdef>
+ <paramdef>XColor<parameter> *background_color</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>source_font</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font for the source glyph.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mask_font</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font for the mask glyph or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>source_char</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character glyph for the source.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mask_char</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the glyph character for the mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>foreground_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the foreground of the source.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the background of the source.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateGlyphCursor</function>
+function is similar to
+<function>XCreatePixmapCursor</function>
+except that the source and mask bitmaps are obtained from the specified
+font glyphs.
+The source_char must be a defined glyph in source_font,
+or a
+<errorname>BadValue</errorname>
+error results.
+If mask_font is given,
+mask_char must be a defined glyph in mask_font,
+or a
+<errorname>BadValue</errorname>
+error results.
+The mask_font and character are optional.
+The origins of the source_char and mask_char (if defined) glyphs are
+positioned coincidently and define the hotspot.
+The source_char and mask_char need not have the same bounding box metrics,
+and there is no restriction on the placement of the hotspot relative to the bounding
+boxes.
+If no mask_char is given, all pixels of the source are displayed.
+You can free the fonts immediately by calling
+<function>XFreeFont</function>
+if no further explicit references to them are to be made.
+</para>
+<para>
+<!-- .LP -->
+For 2-byte matrix fonts,
+the 16-bit value should be formed with the byte1
+member in the most significant byte and the byte2 member in the
+least significant byte.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateGlyphCursor</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadFont</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a cursor from two bitmaps,
+use
+<function>XCreatePixmapCursor</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreatePixmapCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatepixmapcursor'>
+<funcprototype>
+ <funcdef>Cursor <function>XCreatePixmapCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Pixmap<parameter> source</parameter></paramdef>
+ <paramdef>Pixmap<parameter> mask</parameter></paramdef>
+ <paramdef>XColor<parameter> *foreground_color</parameter></paramdef>
+ <paramdef>XColor<parameter> *background_color</parameter></paramdef>
+ <paramdef>unsignedintx,<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>source</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the shape of the source cursor.
+<!-- .\" *** JIM: NEED TO CHECK THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor's source bits to be displayed or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>foreground_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the foreground of the source.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the background of the source.
+<!-- .ds Xy , which indicate the hotspot relative to the source's origin -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreatePixmapCursor</function>
+function creates a cursor and returns the cursor ID associated with it.
+The foreground and background <acronym>RGB</acronym> values must be specified using
+foreground_color and background_color,
+even if the X server only has a
+<symbol>StaticGray</symbol>
+or
+<symbol>GrayScale</symbol>
+screen.
+The foreground color is used for the pixels set to 1 in the
+source, and the background color is used for the pixels set to 0.
+Both source and mask, if specified, must have depth one (or a
+<errorname>BadMatch</errorname>
+error results) but can have any root.
+The mask argument defines the shape of the cursor.
+The pixels set to 1 in the mask define which source pixels are displayed,
+and the pixels set to 0 define which pixels are ignored.
+If no mask is given,
+all pixels of the source are displayed.
+The mask, if present, must be the same size as the pixmap defined by the
+source argument, or a
+<errorname>BadMatch</errorname>
+error results.
+The hotspot must be a point within the source,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The components of the cursor can be transformed arbitrarily to meet
+display limitations.
+The pixmaps can be freed immediately if no further explicit references
+to them are to be made.
+Subsequent drawing in the source or mask pixmap has an undefined effect on the
+cursor.
+The X server might or might not make a copy of the pixmap.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreatePixmapCursor</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadPixmap</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To determine useful cursor sizes, use
+<function>XQueryBestCursor</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryBestCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerybestcursor'>
+<funcprototype>
+ <funcdef>Status <function>XQueryBestCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Dr , which indicates the screen -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable(Dr.
+<!-- .ds Wh \ of the cursor that you want the size information for -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the best width and height that is closest to the specified width
+and height.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Some displays allow larger cursors than other displays.
+The
+<function>XQueryBestCursor</function>
+function provides a way to find out what size cursors are actually
+possible on the display.
+<indexterm ><primary>Cursor</primary><secondary>limitations</secondary></indexterm>
+It returns the largest size that can be displayed.
+Applications should be prepared to use smaller cursors on displays that
+cannot support large ones.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryBestCursor</function>
+can generate a
+<errorname>BadDrawable</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change the color of a given cursor, use
+<function>XRecolorCursor</function>.
+</para>
+<indexterm significance="preferred"><primary>XRecolorCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrecolorcursor'>
+<funcprototype>
+ <funcdef><function>XRecolorCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+ <paramdef>XColor*foreground_color,<parameter> *background_color</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>foreground_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the foreground of the source.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background_color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the <acronym>RGB</acronym> values for the background of the source.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRecolorCursor</function>
+function changes the color of the specified cursor, and
+if the cursor is being displayed on a screen,
+the change is visible immediately.
+The pixel members of the
+<structname>XColor</structname>
+structures are ignored; only the <acronym>RGB</acronym> values are used.
+</para>
+<para>
+<!-- .LP -->
+<function>XRecolorCursor</function>
+can generate a
+<errorname>BadCursor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free (destroy) a given cursor, use
+<function>XFreeCursor</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeCursor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreecursor'>
+<funcprototype>
+ <funcdef><function>XFreeCursor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeCursor</function>
+function deletes the association between the cursor resource ID
+and the specified cursor.
+The cursor storage is freed when no other resource references it.
+The specified cursor ID should not be referred to again.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreeCursor</function>
+can generate a
+<errorname>BadCursor</errorname>
+error.
+<!-- .bp -->
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH06.xml b/libX11/specs/libX11/CH06.xml index e4c54fd74..87379fff7 100644 --- a/libX11/specs/libX11/CH06.xml +++ b/libX11/specs/libX11/CH06.xml @@ -1,7448 +1,7448 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="color_management_functions"> -<title>Color Management Functions</title> -<!-- .sp 2 --> -<!-- .nr H1 6 --> -<!-- .nr H2 0 --> -<!-- .nr H3 0 --> -<!-- .nr H4 0 --> -<!-- .nr H5 0 --> -<!-- .na --> -<para> -<!-- .LP --> -<!-- .XS --> -<!-- Chapter 6: Color Management Functions --> -<!-- .XE --> -Each X window always has an associated colormap that -provides a level of indirection between pixel values and colors displayed -on the screen. -Xlib provides functions that you can use to manipulate a colormap. -The X protocol defines colors using values in the <acronym>RGB</acronym> color space. -The <acronym>RGB</acronym> color space is device dependent; -rendering an <acronym>RGB</acronym> value on differing output devices typically results -in different colors. -Xlib also provides a means for clients to specify color using -device-independent color spaces for consistent results across devices. -Xlib supports device-independent color spaces derivable from the <acronym>CIE</acronym> XYZ -color space. -This includes the <acronym>CIE</acronym> XYZ, xyY, L*u*v*, and L*a*b* color spaces as well as -the TekHVC color space. -</para> -<para> -<!-- .LP --> -This chapter discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Create, copy, and destroy a colormap - </para> - </listitem> - <listitem> - <para> -Specify colors by name or value - </para> - </listitem> - <listitem> - <para> -Allocate, modify, and free color cells - </para> - </listitem> - <listitem> - <para> -Read entries in a colormap - </para> - </listitem> - <listitem> - <para> -Convert between color spaces - </para> - </listitem> - <listitem> - <para> -Control aspects of color conversion - </para> - </listitem> - <listitem> - <para> -Query the color gamut of a screen - </para> - </listitem> - <listitem> - <para> -Add new color spaces - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -All functions, types, and symbols in this chapter with the prefix ``Xcms'' -are defined in -<filename class="headerfile"><X11/Xcms.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xcms.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xcms.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xcms.h></filename></secondary></indexterm> -The remaining functions and types are defined in -<filename class="headerfile"><X11/Xlib.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -</para> -<para> -<!-- .LP --> -Functions in this chapter manipulate the representation of color on the -screen. -For each possible value that a pixel can take in a window, -there is a color cell in the colormap. -For example, -if a window is 4 bits deep, pixel values 0 through 15 are defined. -A colormap is a collection of color cells. -A color cell consists of a triple of red, green, and blue (<acronym>RGB</acronym>) values. -The hardware imposes limits on the number of significant -bits in these values. -As each pixel is read out of display memory, the pixel -is looked up in a colormap. -The <acronym>RGB</acronym> value of the cell determines what color is displayed on the screen. -On a grayscale display with a black-and-white monitor, -the values are combined to determine the brightness on the screen. -</para> -<para> -<!-- .LP --> -Typically, an application allocates color cells or sets of color cells -to obtain the desired colors. -The client can allocate read-only cells. -In which case, -the pixel values for these colors can be shared among multiple applications, -and the <acronym>RGB</acronym> value of the cell cannot be changed. -If the client allocates read/write cells, -they are exclusively owned by the client, -and the color associated with the pixel value can be changed at will. -Cells must be allocated (and, if read/write, initialized with an <acronym>RGB</acronym> value) -by a client to obtain desired colors. -The use of pixel value for an -unallocated cell results in an undefined color. -</para> -<para> -<!-- .LP --> -Because colormaps are associated with windows, X supports displays -with multiple colormaps and, indeed, different types of colormaps. -If there are insufficient colormap resources in the display, -some windows will display in their true colors, and others -will display with incorrect colors. -A window manager usually controls which windows are displayed -in their true colors if more than one colormap is required for -the color resources the applications are using. -At any time, there is a set of installed colormaps for a screen. -Windows using one of the installed colormaps display with true colors, and -windows using other colormaps generally display with incorrect colors. -You can control the set of installed colormaps by using -<function>XInstallColormap</function> -and -<function>XUninstallColormap</function>. -</para> -<para> -<!-- .LP --> -Colormaps are local to a particular screen. -Screens always have a default colormap, -and programs typically allocate cells out of this colormap. -Generally, you should not write applications that monopolize -color resources. -Although some hardware supports multiple colormaps installed at one time, -many of the hardware displays -built today support only a single installed colormap, so the primitives -are written to encourage sharing of colormap entries between applications. -</para> -<para> -<!-- .LP --> -The -<function>DefaultColormap</function> -macro returns the default colormap. -The -<function>DefaultVisual</function> -macro -returns the default visual type for the specified screen. -<indexterm><primary>Color map</primary></indexterm> -Possible visual types are -<symbol>StaticGray</symbol>, -<symbol>GrayScale</symbol>, -<symbol>StaticColor</symbol>, -<symbol>PseudoColor</symbol>, -<symbol>TrueColor</symbol>, -or -<symbol>DirectColor</symbol> -(see <link linkend="Visual_Types">section 3.1</link>). -</para> -<sect1 id="Color_Structures"> -<title>Color Structures</title> -<!-- .XS --> -<!-- (SN Color Structures --> -<!-- .XE --> -<para> -<!-- .LP --> -Functions that operate only on <acronym>RGB</acronym> color space values use an -<structname>XColor</structname> -structure, which contains: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XColor</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - unsigned long pixel; /* pixel value */ - unsigned short red, green, blue; /* rgb values */ - char flags; /* DoRed, DoGreen, DoBlue */ - char pad; -} XColor; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The red, green, and blue values are always in the range 0 to 65535 -inclusive, independent of the number of bits actually used in the -display hardware. -The server scales these values down to the range used by the hardware. -Black is represented by (0,0,0), -and white is represented by (65535,65535,65535). -<indexterm><primary>Color</primary></indexterm> -In some functions, -the flags member controls which of the red, green, and blue members is used -and can be the inclusive OR of zero or more of -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Functions that operate on all color space values use an -<structname>XcmsColor</structname> -structure. -This structure contains a union of substructures, -each supporting color specification encoding for a particular color space. -Like the -<structname>XColor</structname> -structure, the -<structname>XcmsColor</structname> -structure contains pixel -and color specification information (the spec member in the -<structname>XcmsColor</structname> -structure). -<indexterm significance="preferred"><primary>XcmsColor</primary></indexterm> -<!-- .sM --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 1i 2.5i --> -<!-- .ta .5i 1i 2.5i --> -typedef unsigned long XcmsColorFormat; /* Color Specification Format */ - -typedef struct { - union { - XcmsRGB RGB; - XcmsRGBi RGBi; - XcmsCIEXYZ CIEXYZ; - XcmsCIEuvY CIEuvY; - XcmsCIExyY CIExyY; - XcmsCIELab CIELab; - XcmsCIELuv CIELuv; - XcmsTekHVC TekHVC; - XcmsPad Pad; - } spec; - unsigned long pixel; - XcmsColorFormat format; -} XcmsColor; /* Xcms Color Structure */ -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Because the color specification can be encoded for the various color spaces, -encoding for the spec member is identified by the format member, -which is of type -<type>XcmsColorFormat</type>. -The following macros define standard formats. -<!-- .sM --> -</para> - -<literallayout class="monospaced"> -#define XcmsUndefinedFormat 0x00000000 -#define XcmsCIEXYZFormat 0x00000001 /* CIE XYZ */ -#define XcmsCIEuvYFormat 0x00000002 /* CIE u'v'Y */ -#define XcmsCIExyYFormat 0x00000003 /* CIE xyY */ -#define XcmsCIELabFormat 0x00000004 /* CIE L*a*b* */ -#define XcmsCIELuvFormat 0x00000005 /* CIE L*u*v* */ -#define XcmsTekHVCFormat 0x00000006 /* TekHVC */ -#define XcmsRGBFormat 0x80000000 /* RGB Device */ -#define XcmsRGBiFormat 0x80000001 /* RGB Intensity */ -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -Formats for device-independent color spaces are -distinguishable from those for device-dependent spaces by the 32nd bit. -If this bit is set, -it indicates that the color specification is in a device-dependent form; -otherwise, it is in a device-independent form. -If the 31st bit is set, -this indicates that the color space has been added to Xlib at run time -(see <link linkend="Creating_Additional_Color_Spaces">section 6.12.4</link>). -The format value for a color space added at run time may be different each -time the program is executed. -If references to such a color space must be made outside the client -(for example, storing a color specification in a file), -then reference should be made by color space string prefix -(see -<function>XcmsFormatOfPrefix</function> -and -<function>XcmsPrefixOfFormat</function>). -</para> -<para> -<!-- .LP --> -Data types that describe the color specification encoding for the various -color spaces are defined as follows: -<!-- .sM --> -<indexterm significance="preferred"><primary>XcmsRGB</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef double XcmsFloat; - -typedef struct { - unsigned short red; /* 0x0000 to 0xffff */ - unsigned short green; /* 0x0000 to 0xffff */ - unsigned short blue; /* 0x0000 to 0xffff */ -} XcmsRGB; /* RGB Device */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsRGBi</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat red; /* 0.0 to 1.0 */ - XcmsFloat green; /* 0.0 to 1.0 */ - XcmsFloat blue; /* 0.0 to 1.0 */ -} XcmsRGBi; /* RGB Intensity */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsCIEXYZ</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat X; - XcmsFloat Y; /* 0.0 to 1.0 */ - XcmsFloat Z; -} XcmsCIEXYZ; /* CIE XYZ */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsCIEuvY</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat u_prime; /* 0.0 to ~0.6 */ - XcmsFloat v_prime; /* 0.0 to ~0.6 */ - XcmsFloat Y; /* 0.0 to 1.0 */ -} XcmsCIEuvY; /* CIE u'v'Y */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsCIExyY</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat x; /* 0.0 to ~.75 */ - XcmsFloat y; /* 0.0 to ~.85 */ - XcmsFloat Y; /* 0.0 to 1.0 */ -} XcmsCIExyY; /* CIE xyY */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsCIELab</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat L_star; /* 0.0 to 100.0 */ - XcmsFloat a_star; - XcmsFloat b_star; -} XcmsCIELab; /* CIE L*a*b* */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsCIELuv</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat L_star; /* 0.0 to 100.0 */ - XcmsFloat u_star; - XcmsFloat v_star; -} XcmsCIELuv; /* CIE L*u*v* */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsTekHVC</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat H; /* 0.0 to 360.0 */ - XcmsFloat V; /* 0.0 to 100.0 */ - XcmsFloat C; /* 0.0 to 100.0 */ -} XcmsTekHVC; /* TekHVC */ -</literallayout> -<indexterm significance="preferred"><primary>XcmsPad</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - XcmsFloat pad0; - XcmsFloat pad1; - XcmsFloat pad2; - XcmsFloat pad3; -} XcmsPad; /* four doubles */ -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The device-dependent formats provided allow color specification in: -</para> -<itemizedlist> - <listitem> - <para> -<acronym>RGB</acronym> Intensity -(<structname>XcmsRGBi</structname>) - </para> - </listitem> - <listitem> - <para> -Red, green, and blue linear intensity values, -floating-point values from 0.0 to 1.0, -where 1.0 indicates full intensity, 0.5 half intensity, and so on. - </para> - </listitem> - <listitem> - <para> -<acronym>RGB</acronym> Device -(<structname>XcmsRGB</structname>) - </para> - </listitem> - <listitem> - <para> -Red, green, and blue values appropriate for the specified output device. -<structname>XcmsRGB</structname> -values are of type unsigned short, -scaled from 0 to 65535 inclusive, -and are interchangeable with the red, green, and blue values in an -<structname>XColor</structname> -structure. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -It is important to note that <acronym>RGB</acronym> Intensity values are not gamma corrected -values. -In contrast, -<acronym>RGB</acronym> Device values generated as a result of converting color specifications -are always gamma corrected, and -<acronym>RGB</acronym> Device values acquired as a result of querying a colormap -or passed in by the client are assumed by Xlib to be gamma corrected. -The term <emphasis remap='I'><acronym>RGB</acronym> value</emphasis> in this manual always refers to an <acronym>RGB</acronym> Device value. -</para> -</sect1> -<sect1 id="Color_Strings"> -<title>Color Strings</title> -<!-- .XS --> -<!-- (SN Color Strings --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides a mechanism for using string names for colors. -A color string may either contain an abstract color name -or a numerical color specification. -Color strings are case-insensitive. -</para> -<para> -<!-- .LP --> -Color strings are used in the following functions: -</para> -<itemizedlist> - <listitem> - <para> -<function>XAllocNamedColor</function> - </para> - </listitem> - <listitem> - <para> -<function>XcmsAllocNamedColor</function> - </para> - </listitem> - <listitem> - <para> -<function>XLookupColor</function> - </para> - </listitem> - <listitem> - <para> -<function>XcmsLookupColor</function> - </para> - </listitem> - <listitem> - <para> -<function>XParseColor</function> - </para> - </listitem> - <listitem> - <para> -<function>XStoreNamedColor</function> - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Xlib supports the use of abstract color names, for example, red or blue. -A value for this abstract name is obtained by searching one or more color -name databases. -Xlib first searches zero or more client-side databases; -the number, location, and content of these databases is -implementation-dependent and might depend on the current locale. -If the name is not found, Xlib then looks for the color in the -X server's database. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -A numerical color specification -consists of a color space name and a set of values in the following syntax: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<emphasis remap='I'><color_space_name></emphasis>:<emphasis remap='I'><value>/.../<value></emphasis> -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The following are examples of valid color strings. -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -"CIEXYZ:0.3227/0.28133/0.2493" -"RGBi:1.0/0.0/0.0" -"rgb:00/ff/00" -"CIELuv:50.0/0.0/0.0" -</literallayout> -The syntax and semantics of numerical specifications are given -for each standard color space in the following sections. -</para> -<sect2 id="RGB_Device_String_Specification"> -<title><acronym>RGB</acronym> Device String Specification</title> -<!-- .XS --> -<!-- (SN <acronym>RGB</acronym> Device String Specification --> -<!-- .XE --> -<para> -<!-- .LP --> -An <acronym>RGB</acronym> Device specification is identified by -the prefix ``rgb:'' and conforms to the following syntax: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -rgb:<emphasis remap='I'><red>/<green>/<blue></emphasis> - - <emphasis remap='I'><red></emphasis>, <emphasis remap='I'><green></emphasis>, <emphasis remap='I'><blue></emphasis> := <emphasis remap='I'>h</emphasis> | <emphasis remap='I'>hh</emphasis> | <emphasis remap='I'>hhh</emphasis> | <emphasis remap='I'>hhhh</emphasis> - <emphasis remap='I'>h</emphasis> := single hexadecimal digits (case insignificant) -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -Note that <emphasis remap='I'>h</emphasis> indicates the value scaled in 4 bits, -<emphasis remap='I'>hh</emphasis> the value scaled in 8 bits, -<emphasis remap='I'>hhh</emphasis> the value scaled in 12 bits, -and <emphasis remap='I'>hhhh</emphasis> the value scaled in 16 bits, respectively. -</para> -<para> -<!-- .LP --> -Typical examples are the strings ``rgb:ea/75/52'' and ``rgb:ccc/320/320'', -but mixed numbers of hexadecimal digit strings -(``rgb:ff/a5/0'' and ``rgb:ccc/32/0'') -are also allowed. -</para> -<para> -<!-- .LP --> -For backward compatibility, an older syntax for <acronym>RGB</acronym> Device is -supported, but its continued use is not encouraged. -The syntax is an initial sharp sign character followed by -a numeric specification, in one of the following formats: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -<!-- .TA 2i --> -<!-- .ta 2i --> -#RGB (4 bits each) -#RRGGBB (8 bits each) -#RRRGGGBBB (12 bits each) -#RRRRGGGGBBBB (16 bits each) -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -The R, G, and B represent single hexadecimal digits. -When fewer than 16 bits each are specified, -they represent the most significant bits of the value -(unlike the ``rgb:'' syntax, in which values are scaled). -For example, the string ``#3a7'' is the same as ``#3000a0007000''. -</para> -</sect2> -<sect2 id="RGB_Intensity_String_Specification"> -<title><acronym>RGB</acronym> Intensity String Specification</title> -<!-- .XS --> -<!-- (SN RGB Intensity String Specification --> -<!-- .XE --> -<para> -<!-- .LP --> -An <acronym>RGB</acronym> intensity specification is identified -by the prefix ``rgbi:'' and conforms to the following syntax: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -rgbi:<emphasis remap='I'><red>/<green>/<blue></emphasis> -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -Note that red, green, and blue are floating-point values -between 0.0 and 1.0, inclusive. -The input format for these values is an optional sign, -a string of numbers possibly containing a decimal point, -and an optional exponent field containing an E or e -followed by a possibly signed integer string. -</para> -</sect2> -<sect2 id="Device_Independent_String_Specifications"> -<title>Device-Independent String Specifications</title> -<!-- .XS --> -<!-- (SN Device-Independent String Specifications --> -<!-- .XE --> -<para> -<!-- .LP --> -The standard device-independent string specifications have -the following syntax: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -CIEXYZ:<emphasis remap='I'><X>/<Y>/<Z></emphasis> -CIEuvY:<emphasis remap='I'><u>/<v>/<Y></emphasis> -CIExyY:<emphasis remap='I'><x>/<y>/<Y></emphasis> -CIELab:<emphasis remap='I'><L>/<a>/<b></emphasis> -CIELuv:<emphasis remap='I'><L>/<u>/<v></emphasis> -TekHVC:<emphasis remap='I'><H>/<V>/<C></emphasis> -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -All of the values (C, H, V, X, Y, Z, a, b, u, v, y, x) are -floating-point values. -The syntax for these values is an optional plus or minus sign, -a string of digits possibly containing a decimal point, -and an optional exponent field consisting of an ``E'' or ``e'' -followed by an optional plus or minus followed by a string of digits. -</para> -</sect2> -</sect1> -<sect1 id="Color_Conversion_Contexts_and_Gamut_Mapping"> -<title>Color Conversion Contexts and Gamut Mapping</title> -<!-- .XS --> -<!-- (SN Color Conversion Contexts and Gamut Mapping --> -<!-- .XE --> -<para> -<!-- .LP --> -When Xlib converts device-independent color specifications -into device-dependent specifications and vice versa, -it uses knowledge about the color limitations of the screen hardware. -This information, typically called the device profile, -<indexterm><primary>Device profile</primary></indexterm> -is available in a Color Conversion Context (CCC). -<indexterm><primary>Color Conversion Context</primary></indexterm> -<indexterm><primary>CCC</primary></indexterm> -</para> -<para> -<!-- .LP --> -Because a specified color may be outside the color gamut of the target screen -and the white point associated with the color specification may differ -from the white point inherent to the screen, -Xlib applies gamut mapping when it encounters certain conditions: -<indexterm><primary>White point</primary></indexterm> -</para> -<itemizedlist> - <listitem> - <para> -Gamut compression occurs when conversion of device-independent -color specifications to device-dependent color specifications -results in a color out of the target screen's gamut. - </para> - </listitem> - <listitem> - <para> -White adjustment occurs when the inherent white point of the screen -differs from the white point assumed by the client. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Gamut handling methods are stored as callbacks in the CCC, -which in turn are used by the color space conversion routines. -Client data is also stored in the CCC for each callback. -The CCC also contains the white point the client assumes to be -associated with color specifications (that is, the Client White Point). -<indexterm><primary>Client White Point</primary></indexterm> -<indexterm><primary>Gamut compression</primary></indexterm> -<indexterm><primary>Gamut handling</primary></indexterm> -<indexterm><primary>White point adjustment</primary></indexterm> -The client can specify the gamut handling callbacks and client data -as well as the Client White Point. -Xlib does not preclude the X client from performing other -forms of gamut handling (for example, gamut expansion); -however, Xlib does not provide direct support for gamut handling -other than white adjustment and gamut compression. -</para> -<para> -<!-- .LP --> -Associated with each colormap is an initial CCC transparently generated by -Xlib. -<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm> -Therefore, -when you specify a colormap as an argument to an Xlib function, -you are indirectly specifying a CCC. -<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm> -There is a default CCC associated with each screen. -Newly created CCCs inherit attributes from the default CCC, -so the default CCC attributes can be modified to affect new CCCs. -<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm> -</para> -<para> -<!-- .LP --> -Xcms functions in which gamut mapping can occur return -<type>Status</type> -and have specific status values defined for them, -as follows: -</para> -<itemizedlist> - <listitem> - <para> -<symbol>XcmsFailure</symbol> -indicates that the function failed. - </para> - </listitem> - <listitem> - <para> -<symbol>XcmsSuccess</symbol> -indicates that the function succeeded. -In addition, -if the function performed any color conversion, -the colors did not need to be compressed. - </para> - </listitem> - <listitem> - <para> -<symbol>XcmsSuccessWithCompression</symbol> -indicates the function performed color conversion -and at least one of the colors needed to be compressed. -The gamut compression method is determined by the gamut compression -procedure in the CCC that is specified directly as a function argument -or in the CCC indirectly specified by means of the colormap argument. - </para> - </listitem> -</itemizedlist> -</sect1> -<sect1 id="Creating_Copying_and_Destroying_Colormaps"> -<title>Creating, Copying, and Destroying Colormaps</title> -<!-- .XS --> -<!-- (SN Creating, Copying, and Destroying Colormaps --> -<!-- .XE --> -<para> -<!-- .LP --> -To create a colormap for a screen, use -<function>XCreateColormap</function>.</para> -<indexterm significance="preferred"><primary>XCreateColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatecolormap'> -<funcprototype> - <funcdef>Colormap <function>XCreateColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Visual<parameter> *visual</parameter></paramdef> - <paramdef>int<parameter> alloc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi on whose screen you want to create a colormap --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>visual</emphasis> - </term> - <listitem> - <para> -Specifies a visual type supported on the screen. -If the visual type is not one supported by the screen, -a -<errorname>BadMatch</errorname> -error results. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>alloc</emphasis> - </term> - <listitem> - <para> -Specifies the colormap entries to be allocated. -You can pass -<symbol>AllocNone</symbol> -or -<symbol>AllocAll</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateColormap</function> -function creates a colormap of the specified visual type for the screen -on which the specified window resides and returns the colormap ID -associated with it. -Note that the specified window is only used to determine the screen. -</para> -<para> -<!-- .LP --> -The initial values of the colormap entries are undefined for the -visual classes -<symbol>GrayScale</symbol>, -<symbol>PseudoColor</symbol>, -and -<symbol>DirectColor</symbol>. -For -<symbol>StaticGray</symbol>, -<symbol>StaticColor</symbol>, -and -<symbol>TrueColor</symbol>, -the entries have defined values, -but those values are specific to the visual and are not defined by X. -For -<symbol>StaticGray</symbol>, -<symbol>StaticColor</symbol>, -and -<symbol>TrueColor</symbol>, -alloc must be -<symbol>AllocNone</symbol>, -or a -<errorname>BadMatch</errorname> -error results. -For the other visual classes, -if alloc is -<symbol>AllocNone</symbol>, -the colormap initially has no allocated entries, -and clients can allocate them. -For information about the visual types, -see <link linkend="Visual_Types">section 3.1</link>. -</para> -<para> -<!-- .LP --> -If alloc is -<symbol>AllocAll</symbol>, -the entire colormap is allocated writable. -The initial values of all allocated entries are undefined. -For -<symbol>GrayScale</symbol> -and -<symbol>PseudoColor</symbol>, -the effect is as if an -<function>XAllocColorCells</function> -call returned all pixel values from zero to N - 1, -where N is the colormap entries value in the specified visual. -For -<symbol>DirectColor</symbol>, -the effect is as if an -<function>XAllocColorPlanes</function> -call returned a pixel value of zero and red_mask, green_mask, -and blue_mask values containing the same bits as the corresponding -masks in the specified visual. -However, in all cases, -none of these entries can be freed by using -<function>XFreeColors</function>. -</para> -<para> -<!-- .LP --> -<function>XCreateColormap</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a new colormap when the allocation out of a previously -shared colormap has failed because of resource exhaustion, use -<function>XCopyColormapAndFree</function>. -</para> -<indexterm significance="preferred"><primary>XCopyColormapAndFree</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcopycolormapandfree'> -<funcprototype> - <funcdef>Colormap <function>XCopyColormapAndFree</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCopyColormapAndFree</function> -function creates a colormap of the same visual type and for the same screen -as the specified colormap and returns the new colormap ID. -It also moves all of the client's existing allocation from the specified -colormap to the new colormap with their color values intact -and their read-only or writable characteristics intact and frees those entries -in the specified colormap. -Color values in other entries in the new colormap are undefined. -If the specified colormap was created by the client with alloc set to -<symbol>AllocAll</symbol>, -the new colormap is also created with -<symbol>AllocAll</symbol>, -all color values for all entries are copied from the specified colormap, -and then all entries in the specified colormap are freed. -If the specified colormap was not created by the client with -<symbol>AllocAll</symbol>, -the allocations to be moved are all those pixels and planes -that have been allocated by the client using -<function>XAllocColor</function>, -<function>XAllocNamedColor</function>, -<function>XAllocColorCells</function>, -or -<function>XAllocColorPlanes</function> -and that have not been freed since they were allocated. -</para> -<para> -<!-- .LP --> -<function>XCopyColormapAndFree</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadColor</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy a colormap, use -<function>XFreeColormap</function>. -<indexterm significance="preferred"><primary>XFreeColormap</primary></indexterm> -</para> -<!-- .sM --> -<funcsynopsis id='xfreecolormap'> -<funcprototype> - <funcdef><function>XFreeColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Cm that you want to destroy --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap (Cm. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeColormap</function> -function deletes the association between the colormap resource ID -and the colormap and frees the colormap storage. -However, this function has no effect on the default colormap for a screen. -If the specified colormap is an installed map for a screen, -it is uninstalled (see -<function>XUninstallColormap</function>). -If the specified colormap is defined as the colormap for a window (by -<function>XCreateWindow</function>, -<function>XSetWindowColormap</function>, -or -<function>XChangeWindowAttributes</function>), -<function>XFreeColormap</function> -changes the colormap associated with the window to -<symbol>None</symbol> -and generates a -<symbol>ColormapNotify</symbol> -event. -X does not define the colors displayed for a window with a colormap of -<symbol>None</symbol>. -</para> -<para> -<!-- .LP --> -<function>XFreeColormap</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -</sect1> -<sect1 id="Mapping_Color_Names_to_Values"> -<title>Mapping Color Names to Values</title> -<!-- .XS --> -<!-- (SN Mapping Color Names to Values --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To map a color name to an <acronym>RGB</acronym> value, use -<function>XLookupColor</function>. -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm significance="preferred"><primary>XLookupColor</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xlookupcolor'> -<funcprototype> - <funcdef>Status <function>XLookupColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *color_name</parameter></paramdef> - <paramdef>XColor*exact_def_return,<parameter> *screen_def_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_name</emphasis> - </term> - <listitem> - <para> -Specifies the color name string (for example, red) whose color -definition structure you want returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>exact_def_return</emphasis> - </term> - <listitem> - <para> -Returns the exact <acronym>RGB</acronym> values. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_def_return</emphasis> - </term> - <listitem> - <para> -Returns the closest <acronym>RGB</acronym> values provided by the hardware. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLookupColor</function> -function looks up the string name of a color with respect to the screen -associated with the specified colormap. -It returns both the exact color values and -the closest values provided by the screen -with respect to the visual type of the specified colormap. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -<function>XLookupColor</function> -returns nonzero if the name is resolved; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -<function>XLookupColor</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map a color name to the exact <acronym>RGB</acronym> value, use -<function>XParseColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm significance="preferred"><primary>XParseColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xparsecolor'> -<funcprototype> - <funcdef>Status <function>XParseColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *spec</parameter></paramdef> - <paramdef>XColor<parameter> *exact_def_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>spec</emphasis> - </term> - <listitem> - <para> -Specifies the color name string; -case is ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>exact_def_return</emphasis> - </term> - <listitem> - <para> -Returns the exact color value for later use and sets the -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol> -flags. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XParseColor</function> -function looks up the string name of a color with respect to the screen -associated with the specified colormap. -It returns the exact color value. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -<function>XParseColor</function> -returns nonzero if the name is resolved; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -<function>XParseColor</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map a color name to a value in an arbitrary color space, use -<function>XcmsLookupColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsLookupColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmslookupcolor'> -<funcprototype> - <funcdef>Status <function>XcmsLookupColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *color_string</parameter></paramdef> - <paramdef>XcmsColor*color_exact_return,<parameter> *color_screen_return</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. -<!-- .ds St --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_string</emphasis> - </term> - <listitem> - <para> -Specifies the color string(St. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_exact_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification parsed from the color string -or parsed from the corresponding string found in a color-name database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_screen_return</emphasis> - </term> - <listitem> - <para> -Returns the color that can be reproduced on the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>result_format</emphasis> - </term> - <listitem> - <para> -Specifies the color format for the returned color -specifications (color_screen_return and color_exact_return arguments). -If the format is -<symbol>XcmsUndefinedFormat</symbol> -and the color string contains a -numerical color specification, -the specification is returned in the format used in that numerical -color specification. -If the format is -<symbol>XcmsUndefinedFormat</symbol> -and the color string contains a color name, -the specification is returned in the format used -to store the color in the database. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsLookupColor</function> -function looks up the string name of a color with respect to the screen -associated with the specified colormap. -It returns both the exact color values and -the closest values provided by the screen -with respect to the visual type of the specified colormap. -The values are returned in the format specified by result_format. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -<function>XcmsLookupColor</function> -returns -<symbol>XcmsSuccess</symbol> -or -<symbol>XcmsSuccessWithCompression</symbol> -if the name is resolved; otherwise, it returns -<symbol>XcmsFailure</symbol>. -If -<symbol>XcmsSuccessWithCompression</symbol> -is returned, the color specification returned in -color_screen_return is the result of gamut compression. -</para> -</sect1> - -<sect1 id="Allocating_and_Freeing_Color_Cells"> -<title>Allocating and Freeing Color Cells</title> -<!-- .XS --> -<!-- (SN Allocating and Freeing Color Cells --> -<!-- .XE --> -<para> -<!-- .LP --> -There are two ways of allocating color cells: -explicitly as read-only entries, one pixel value at a time, -or read/write, -where you can allocate a number of color cells and planes simultaneously. -<indexterm><primary>Read-only colormap cells</primary></indexterm> -A read-only cell has its <acronym>RGB</acronym> value set by the server. -<indexterm><primary>Read/write colormap cells</primary></indexterm> -Read/write cells do not have defined colors initially; -functions described in the next section must be used to store values into them. -Although it is possible for any client to store values into a read/write -cell allocated by another client, -read/write cells normally should be considered private to the client -that allocated them. -</para> -<para> -<!-- .LP --> -Read-only colormap cells are shared among clients. -The server counts each allocation and freeing of the cell by clients. -When the last client frees a shared cell, the cell is finally deallocated. -If a single client allocates the same read-only cell multiple -times, the server counts each such allocation, not just the first one. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a read-only color cell with an <acronym>RGB</acronym> value, use -<function>XAllocColor</function>. -</para> -<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm> -<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XAllocColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xalloccolor'> -<funcprototype> - <funcdef>Status <function>XAllocColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XColor<parameter> *screen_in_out</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_in_out</emphasis> - </term> - <listitem> - <para> -Specifies and returns the values actually used in the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocColor</function> -function allocates a read-only colormap entry corresponding to the closest -<acronym>RGB</acronym> value supported by the hardware. -<function>XAllocColor</function> -returns the pixel value of the color closest to the specified -<acronym>RGB</acronym> elements supported by the hardware -and returns the <acronym>RGB</acronym> value actually used. -The corresponding colormap cell is read-only. -In addition, -<function>XAllocColor</function> -returns nonzero if it succeeded or zero if it failed. -<indexterm><primary>Color map</primary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm><primary>Allocation</primary><secondary>colormap</secondary></indexterm> -<indexterm><primary>read-only colormap cells</primary></indexterm> -Multiple clients that request the same effective <acronym>RGB</acronym> value can be assigned -the same read-only entry, thus allowing entries to be shared. -When the last client deallocates a shared cell, it is deallocated. -<function>XAllocColor</function> -does not use or affect the flags in the -<structname>XColor</structname> -structure. -</para> -<para> -<!-- .LP --> -<function>XAllocColor</function> -can generate a -<errorname>BadColor</errorname> -error. -<!-- .EQ --> -delim %% -<!-- .EN --> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a read-only color cell with a color in arbitrary format, use -<function>XcmsAllocColor</function>. -</para> -<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm> -<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsAllocColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsalloccolor'> -<funcprototype> - <funcdef>Status <function>XcmsAllocColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_in_out</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_in_out</emphasis> - </term> - <listitem> - <para> -Specifies the color to allocate and returns the pixel and color -that is actually used in the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>result_format</emphasis> - </term> - <listitem> - <para> -Specifies the color format for the returned color specification. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsAllocColor</function> -function is similar to -<function>XAllocColor</function> -except the color can be specified in any format. -The -<function>XcmsAllocColor</function> -function ultimately calls -<function>XAllocColor</function> -to allocate a read-only color cell (colormap entry) with the specified color. -<function>XcmsAllocColor</function> -first converts the color specified -to an <acronym>RGB</acronym> value and then passes this to -<function>XAllocColor</function>. -<function>XcmsAllocColor</function> -returns the pixel value of the color cell and the color specification -actually allocated. -This returned color specification is the result of converting the <acronym>RGB</acronym> value -returned by -<function>XAllocColor</function> -into the format specified with the result_format argument. -If there is no interest in a returned color specification, -unnecessary computation can be bypassed if result_format is set to -<symbol>XcmsRGBFormat</symbol>. -The corresponding colormap cell is read-only. -If this routine returns -<symbol>XcmsFailure</symbol>, -the color_in_out color specification is left unchanged. -</para> -<para> -<!-- .LP --> -<function>XcmsAllocColor</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a read-only color cell using a color name and return the closest -color supported by the hardware in <acronym>RGB</acronym> format, use -<function>XAllocNamedColor</function>. -</para> -<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm> -<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XAllocNamedColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xallocnamedcolor'> -<funcprototype> - <funcdef>Status <function>XAllocNamedColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *color_name</parameter></paramdef> - <paramdef>XColor*screen_def_return,<parameter> *exact_def_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_name</emphasis> - </term> - <listitem> - <para> -Specifies the color name string (for example, red) whose color -definition structure you want returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_def_return</emphasis> - </term> - <listitem> - <para> -Returns the closest <acronym>RGB</acronym> values provided by the hardware. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>exact_def_return</emphasis> - </term> - <listitem> - <para> -Returns the exact <acronym>RGB</acronym> values. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocNamedColor</function> -function looks up the named color with respect to the screen that is -associated with the specified colormap. -It returns both the exact database definition and -the closest color supported by the screen. -The allocated color cell is read-only. -The pixel value is returned in screen_def_return. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -If screen_def_return and exact_def_return -point to the same structure, the pixel field will be set correctly, -but the color values are undefined. -<function>XAllocNamedColor</function> -returns nonzero if a cell is allocated; -otherwise, it returns zero. -</para> -<para> -<!-- .LP --> -<function>XAllocNamedColor</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a read-only color cell using a color name and return the closest -color supported by the hardware in an arbitrary format, use -<function>XcmsAllocNamedColor</function>. -</para> -<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm> -<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsAllocNamedColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsallocnamedcolor'> -<funcprototype> - <funcdef>Status <function>XcmsAllocNamedColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *color_string</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_screen_return</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_exact_return</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. -<!-- .ds St \ whose color definition structure is to be returned --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_string</emphasis> - </term> - <listitem> - <para> -Specifies the color string(St. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_screen_return</emphasis> - </term> - <listitem> - <para> -Returns the pixel value of the color cell and color specification -that actually is stored for that cell. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_exact_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification parsed from the color string -or parsed from the corresponding string found in a color-name database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>result_format</emphasis> - </term> - <listitem> - <para> -Specifies the color format for the returned color -specifications (color_screen_return and color_exact_return arguments). -If the format is -<symbol>XcmsUndefinedFormat</symbol> -and the color string contains a -numerical color specification, -the specification is returned in the format used in that numerical -color specification. -If the format is -<symbol>XcmsUndefinedFormat</symbol> -and the color string contains a color name, -the specification is returned in the format used -to store the color in the database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsAllocNamedColor</function> -function is similar to -<function>XAllocNamedColor</function> -except that the color returned can be in any format specified. -This function -ultimately calls -<function>XAllocColor</function> -to allocate a read-only color cell with -the color specified by a color string. -The color string is parsed into an -<structname>XcmsColor</structname> -structure (see -<function>XcmsLookupColor</function>), -converted -to an <acronym>RGB</acronym> value, and finally passed to -<function>XAllocColor</function>. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -</para> -<para> -<!-- .LP --> -This function returns both the color specification as a result -of parsing (exact specification) and the actual color specification -stored (screen specification). -This screen specification is the result of converting the <acronym>RGB</acronym> value -returned by -<function>XAllocColor</function> -into the format specified in result_format. -If there is no interest in a returned color specification, -unnecessary computation can be bypassed if result_format is set to -<symbol>XcmsRGBFormat</symbol>. -If color_screen_return and color_exact_return -point to the same structure, the pixel field will be set correctly, -but the color values are undefined. -</para> -<para> -<!-- .LP --> -<function>XcmsAllocNamedColor</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate read/write color cell and color plane combinations for a -<symbol>PseudoColor</symbol> -model, use -<function>XAllocColorCells</function>. -</para> -<indexterm><primary>Read/write colormap cells</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Allocation</primary><secondary>read/write colormap cells</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XAllocColorCells</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xalloccolorcells'> -<funcprototype> - <funcdef>Status <function>XAllocColorCells</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>Bool<parameter> contig</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane_masks_return[]</parameter></paramdef> - <paramdef>unsignedint<parameter> nplanes</parameter></paramdef> - <paramdef>unsignedlong<parameter> pixels_return[]</parameter></paramdef> - <paramdef>unsignedint<parameter> npixels</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>contig</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the planes must be contiguous. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane_mask_return</emphasis> - </term> - <listitem> - <para> -Returns an array of plane masks. -<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nplanes</emphasis> - </term> - <listitem> - <para> -Specifies the number of plane masks that are to be returned in the plane masks -array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixels_return</emphasis> - </term> - <listitem> - <para> -Returns an array of pixel values. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npixels</emphasis> - </term> - <listitem> - <para> -Specifies the number of pixel values that are to be returned in the -pixels_return array. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocColorCells</function> -function allocates read/write color cells. -The number of colors must be positive and the number of planes nonnegative, -or a -<errorname>BadValue</errorname> -error results. -If ncolors and nplanes are requested, -then ncolors pixels -and nplane plane masks are returned. -No mask will have any bits set to 1 in common with -any other mask or with any of the pixels. -By ORing together each pixel with zero or more masks, -ncolors × 2<superscript><emphasis>nplanes</emphasis></superscript> -distinct pixels can be produced. -All of these are -allocated writable by the request. -For -<symbol>GrayScale</symbol> -or -<symbol>PseudoColor</symbol>, -each mask has exactly one bit set to 1. -For -<symbol>DirectColor</symbol>, -each has exactly three bits set to 1. -If contig is -<symbol>True</symbol> -and if all masks are ORed -together, a single contiguous set of bits set to 1 will be formed for -<symbol>GrayScale</symbol> -or -<symbol>PseudoColor</symbol> -and three contiguous sets of bits set to 1 (one within each -pixel subfield) for -<symbol>DirectColor</symbol>. -The <acronym>RGB</acronym> values of the allocated -entries are undefined. -<function>XAllocColorCells</function> -returns nonzero if it succeeded or zero if it failed. -</para> -<para> -<!-- .LP --> -<function>XAllocColorCells</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate read/write color resources for a -<symbol>DirectColor</symbol> -model, use -<function>XAllocColorPlanes</function>. -</para> -<indexterm><primary>Read/write colormap planes</primary><secondary>allocating</secondary></indexterm> -<indexterm><primary>Allocation</primary><secondary>read/write colormap planes</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm> -<indexterm significance="preferred"><primary>XAllocColorPlanes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xalloccolorplanes'> -<funcprototype> - <funcdef>Status <function>XAllocColorPlanes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>Bool<parameter> contig</parameter></paramdef> - <paramdef>unsignedlong<parameter> pixels_return[]</parameter></paramdef> - <paramdef>int<parameter> ncolors</parameter></paramdef> - <paramdef>intnreds,ngreens,<parameter> nblues</parameter></paramdef> - <paramdef>unsignedlong*rmask_return,*gmask_return,<parameter> *bmask_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>contig</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the planes must be contiguous. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixels_return</emphasis> - </term> - <listitem> - <para> -Returns an array of pixel values. -<function>XAllocColorPlanes</function> -returns the pixel values in this array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of pixel values that are to be returned in the -pixels_return array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nreds</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ngreens</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nblues</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> -Specify the number of red, green, and blue planes. -The value you pass must be nonnegative. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rmask_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gmask_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bmask_return</emphasis> - </term> - <listitem> - <para> -Return bit masks for the red, green, and blue planes. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The specified ncolors must be positive; -and nreds, ngreens, and nblues must be nonnegative, -or a -<errorname>BadValue</errorname> -error results. -If ncolors colors, nreds reds, ngreens greens, and nblues blues are requested, -ncolors pixels are returned; and the masks have nreds, ngreens, and -nblues bits set to 1, respectively. -If contig is -<symbol>True</symbol>, -each mask will have -a contiguous set of bits set to 1. -No mask will have any bits set to 1 in common with -any other mask or with any of the pixels. -For -<symbol>DirectColor</symbol>, -each mask -will lie within the corresponding pixel subfield. -By ORing together -subsets of masks with each pixel value, -ncolors × 2<superscript><emphasis>(nreds+ngreens+nblues)</emphasis></superscript> -distinct pixel values can be produced. -All of these are allocated by the request. -However, in the -colormap, there are only -ncolors × 2<superscript><emphasis>nreds</emphasis></superscript> -independent red entries, -ncolors × 2<superscript><emphasis>ngreens</emphasis></superscript> -independent green entries, and -ncolors × 2<superscript><emphasis>nblues</emphasis></superscript> -independent blue entries. -This is true even for -<symbol>PseudoColor</symbol>. -When the colormap entry of a pixel -value is changed (using -<function>XStoreColors</function>, -<function>XStoreColor</function>, -or -<function>XStoreNamedColor</function>), -the pixel is decomposed according to the masks, -and the corresponding independent entries are updated. -<function>XAllocColorPlanes</function> -returns nonzero if it succeeded or zero if it failed. -</para> -<para> -<!-- .LP --> -<function>XAllocColorPlanes</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -<indexterm><primary>Freeing</primary><secondary>colors</secondary></indexterm> -To free colormap cells, use -<function>XFreeColors</function>. -<indexterm significance="preferred"><primary>XFreeColors</primary></indexterm> -<indexterm><primary>Color</primary><secondary>deallocation</secondary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis id='xfreecolors'> -<funcprototype> - <funcdef><function>XFreeColors</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>unsignedlong<parameter> pixels[]</parameter></paramdef> - <paramdef>int<parameter> npixels</parameter></paramdef> - <paramdef>unsignedlong<parameter> planes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. -<!-- .ds Pi that map to the cells in the specified colormap --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixels</emphasis> - </term> - <listitem> - <para> -Specifies an array of pixel values (Pi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npixels</emphasis> - </term> - <listitem> - <para> -Specifies the number of pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>planes</emphasis> - </term> - <listitem> - <para> -Specifies the planes you want to free. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeColors</function> -function frees the cells represented by pixels whose values are in the -pixels array. -The planes argument should not have any bits set to 1 in common with any of the -pixels. -The set of all pixels is produced by ORing together subsets of -the planes argument with the pixels. -The request frees all of these pixels that -were allocated by the client (using -<indexterm><primary>XAllocColor</primary></indexterm> -<indexterm><primary>XAllocNamedColor</primary></indexterm> -<indexterm><primary>XAllocColorCells</primary></indexterm> -<indexterm><primary>XAllocColorPlanes</primary></indexterm> -<function>XAllocColor</function>, -<function>XAllocNamedColor</function>, -<function>XAllocColorCells</function>, -and -<function>XAllocColorPlanes</function>). -Note that freeing an -individual pixel obtained from -<function>XAllocColorPlanes</function> -may not actually allow -it to be reused until all of its related pixels are also freed. -Similarly, -a read-only entry is not actually freed until it has been freed by all clients, -and if a client allocates the same read-only entry multiple times, -it must free the entry that many times before the entry is actually freed. -</para> -<para> -<!-- .LP --> -All specified pixels that are allocated by the client in the colormap are -freed, even if one or more pixels produce an error. -If a specified pixel is not a valid index into the colormap, a -<errorname>BadValue</errorname> -error results. -If a specified pixel is not allocated by the -client (that is, is unallocated or is only allocated by another client) -or if the colormap was created with all entries writable (by passing -<symbol>AllocAll</symbol> -to -<function>XCreateColormap</function>), -a -<errorname>BadAccess</errorname> -error results. -If more than one pixel is in error, -the one that gets reported is arbitrary. -</para> -<para> -<!-- .LP --> -<function>XFreeColors</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect1> -<sect1 id="Modifying_and_Querying_Colormap_Cells"> -<title>Modifying and Querying Colormap Cells</title> -<!-- .XS --> -<!-- (SN Modifying and Querying Colormap Cells --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To store an <acronym>RGB</acronym> value in a single colormap cell, use -<function>XStoreColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm> -<indexterm significance="preferred"><primary>XStoreColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorecolor'> -<funcprototype> - <funcdef><function>XStoreColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XColor<parameter> *color</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color</emphasis> - </term> - <listitem> - <para> -Specifies the pixel and <acronym>RGB</acronym> values. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XStoreColor</function> -function changes the colormap entry of the pixel value specified in the -pixel member of the -<structname>XColor</structname> -structure. -You specified this value in the -pixel member of the -<structname>XColor</structname> -structure. -This pixel value must be a read/write cell and a valid index into the colormap. -If a specified pixel is not a valid index into the colormap, -a -<errorname>BadValue</errorname> -error results. -<function>XStoreColor</function> -also changes the red, green, and/or blue color components. -You specify which color components are to be changed by setting -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and/or -<symbol>DoBlue</symbol> -in the flags member of the -<structname>XColor</structname> -structure. -If the colormap is an installed map for its screen, -the changes are visible immediately. -</para> -<para> -<!-- .LP --> -<function>XStoreColor</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store multiple <acronym>RGB</acronym> values in multiple colormap cells, use -<function>XStoreColors</function>. -</para> -<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm> -<indexterm significance="preferred"><primary>XStoreColors</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorecolors'> -<funcprototype> - <funcdef><function>XStoreColors</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XColor<parameter> color[]</parameter></paramdef> - <paramdef>int<parameter> ncolors</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color</emphasis> - </term> - <listitem> - <para> -Specifies an array of color definition structures to be stored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -<!-- .\"Specifies the number of color definition structures. --> -Specifies the number of -<structname>XColor</structname> -structures in the color definition array. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XStoreColors</function> -function changes the colormap entries of the pixel values -specified in the pixel members of the -<structname>XColor</structname> -structures. -You specify which color components are to be changed by setting -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and/or -<symbol>DoBlue</symbol> -in the flags member of the -<structname>XColor</structname> -structures. -If the colormap is an installed map for its screen, the -changes are visible immediately. -<function>XStoreColors</function> -changes the specified pixels if they are allocated writable in the colormap -by any client, even if one or more pixels generates an error. -If a specified pixel is not a valid index into the colormap, a -<errorname>BadValue</errorname> -error results. -If a specified pixel either is unallocated or is allocated read-only, a -<errorname>BadAccess</errorname> -error results. -If more than one pixel is in error, -the one that gets reported is arbitrary. -</para> -<para> -<!-- .LP --> -<function>XStoreColors</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store a color of arbitrary format in a single colormap cell, use -<function>XcmsStoreColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsStoreColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsstorecolor'> -<funcprototype> - <funcdef>Status <function>XcmsStoreColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color</emphasis> - </term> - <listitem> - <para> -Specifies the color cell and the color to store. -Values specified in this -<structname>XcmsColor</structname> -structure remain unchanged on return. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsStoreColor</function> -function converts the color specified in the -<structname>XcmsColor</structname> -structure into <acronym>RGB</acronym> values. -It then uses this <acronym>RGB</acronym> specification in an -<structname>XColor</structname> -structure, whose three flags -(<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol>) -are set, in a call to -<function>XStoreColor</function> -to change the color cell specified by the pixel member of the -<structname>XcmsColor</structname> -structure. -This pixel value must be a valid index for the specified colormap, -and the color cell specified by the pixel value must be a read/write cell. -If the pixel value is not a valid index, a -<errorname>BadValue</errorname> -error results. -If the color cell is unallocated or is allocated read-only, a -<errorname>BadAccess</errorname> -error results. -If the colormap is an installed map for its screen, -the changes are visible immediately. -</para> -<para> -<!-- .LP --> -Note that -<function>XStoreColor</function> -has no return value; therefore, an -<symbol>XcmsSuccess</symbol> -return value from this function indicates that the conversion -to <acronym>RGB</acronym> succeeded and the call to -<function>XStoreColor</function> -was made. -To obtain the actual color stored, use -<function>XcmsQueryColor</function>. -Because of the screen's hardware limitations or gamut compression, -the color stored in the colormap may not be identical -to the color specified. -</para> -<para> -<!-- .LP --> -<function>XcmsStoreColor</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store multiple colors of arbitrary format in multiple colormap cells, use -<function>XcmsStoreColors</function>. -</para> -<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsStoreColors</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsstorecolors'> -<funcprototype> - <funcdef>Status <function>XcmsStoreColors</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors[]</parameter></paramdef> - <paramdef>int<parameter> ncolors</parameter></paramdef> - <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors</emphasis> - </term> - <listitem> - <para> -Specifies the color specification array of -<structname>XcmsColor</structname> -structures, each specifying a color cell and the color to store in that -cell. -Values specified in the array remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_flags_return</emphasis> - </term> - <listitem> - <para> -Returns an array of Boolean values indicating compression status. -If a non-NULL pointer is supplied, -each element of the array is set to -<symbol>True</symbol> -if the corresponding color was compressed and -<symbol>False</symbol> -otherwise. -Pass NULL if the compression status is not useful. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsStoreColors</function> -function converts the colors specified in the array of -<structname>XcmsColor</structname> -structures into <acronym>RGB</acronym> values and then uses these <acronym>RGB</acronym> specifications in -<structname>XColor</structname> -structures, whose three flags -(<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol>) -are set, in a call to -<function>XStoreColors</function> -to change the color cells specified by the pixel member of the corresponding -<structname>XcmsColor</structname> -structure. -Each pixel value must be a valid index for the specified colormap, -and the color cell specified by each pixel value must be a read/write cell. -If a pixel value is not a valid index, a -<errorname>BadValue</errorname> -error results. -If a color cell is unallocated or is allocated read-only, a -<errorname>BadAccess</errorname> -error results. -If more than one pixel is in error, -the one that gets reported is arbitrary. -If the colormap is an installed map for its screen, -the changes are visible immediately. -</para> -<para> -<!-- .LP --> -Note that -<function>XStoreColors</function> -has no return value; therefore, an -<symbol>XcmsSuccess</symbol> -return value from this function indicates that conversions -to <acronym>RGB</acronym> succeeded and the call to -<function>XStoreColors</function> -was made. -To obtain the actual colors stored, use -<function>XcmsQueryColors</function>. -Because of the screen's hardware limitations or gamut compression, -the colors stored in the colormap may not be identical -to the colors specified. -</para> -<para> -<!-- .LP --> -<function>XcmsStoreColors</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store a color specified by name in a single colormap cell, use -<function>XStoreNamedColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm> -<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm> -<indexterm significance="preferred"><primary>XStoreNamedColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorenamedcolor'> -<funcprototype> - <funcdef><function>XStoreNamedColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>char<parameter> *color</parameter></paramdef> - <paramdef>unsignedlong<parameter> pixel</parameter></paramdef> - <paramdef>int<parameter> flags</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color</emphasis> - </term> - <listitem> - <para> -Specifies the color name string (for example, red). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixel</emphasis> - </term> - <listitem> - <para> -Specifies the entry in the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>flags</emphasis> - </term> - <listitem> - <para> -Specifies which red, green, and blue components are set. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XStoreNamedColor</function> -function looks up the named color with respect to the screen associated with -the colormap and stores the result in the specified colormap. -The pixel argument determines the entry in the colormap. -The flags argument determines which of the red, green, and blue components -are set. -You can set this member to the -bitwise inclusive OR of the bits -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol>. -If the color name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -If the specified pixel is not a valid index into the colormap, a -<errorname>BadValue</errorname> -error results. -If the specified pixel either is unallocated or is allocated read-only, a -<errorname>BadAccess</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XStoreNamedColor</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadName</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -The -<function>XQueryColor</function> -and -<function>XQueryColors</function> -functions take pixel values in the pixel member of -<structname>XColor</structname> -structures and store in the structures the <acronym>RGB</acronym> values for those -pixels from the specified colormap. -The values returned for an unallocated entry are undefined. -These functions also set the flags member in the -<structname>XColor</structname> -structure to all three colors. -If a pixel is not a valid index into the specified colormap, a -<errorname>BadValue</errorname> -error results. -If more than one pixel is in error, -the one that gets reported is arbitrary. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To query the <acronym>RGB</acronym> value of a single colormap cell, use -<function>XQueryColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm> -<indexterm significance="preferred"><primary>XQueryColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerycolor'> -<funcprototype> - <funcdef><function>XQueryColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XColor<parameter> *def_in_out</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>def_in_out</emphasis> - </term> - <listitem> - <para> -Specifies and returns the <acronym>RGB</acronym> values for the pixel specified in the structure. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryColor</function> -function returns the current <acronym>RGB</acronym> value for the pixel in the -<structname>XColor</structname> -structure and sets the -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol> -flags. -</para> -<para> -<!-- .LP --> -<function>XQueryColor</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To query the <acronym>RGB</acronym> values of multiple colormap cells, use -<function>XQueryColors</function>. -</para> -<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm> -<indexterm significance="preferred"><primary>XQueryColors</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerycolors'> -<funcprototype> - <funcdef><function>XQueryColors</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XColor<parameter> defs_in_out[]</parameter></paramdef> - <paramdef>int<parameter> ncolors</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>defs_in_out</emphasis> - </term> - <listitem> - <para> -Specifies and returns an array of color definition structures for the pixel -specified in the structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -<!-- .\"Specifies the number of color definition structures. --> -Specifies the number of -<structname>XColor</structname> -structures in the color definition array. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryColors</function> -function returns the <acronym>RGB</acronym> value for each pixel in each -<structname>XColor</structname> -structure and sets the -<symbol>DoRed</symbol>, -<symbol>DoGreen</symbol>, -and -<symbol>DoBlue</symbol> -flags in each structure. - -</para> -<para> -<!-- .LP --> -<function>XQueryColors</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To query the color of a single colormap cell in an arbitrary format, use -<function>XcmsQueryColor</function>. -</para> -<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsQueryColor</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsquerycolor'> -<funcprototype> - <funcdef>Status <function>XcmsQueryColor</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_in_out</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_in_out</emphasis> - </term> - <listitem> - <para> -Specifies the pixel member that indicates the color cell to query. -The color specification stored for the color cell is returned in this -<structname>XcmsColor</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>result_format</emphasis> - </term> - <listitem> - <para> -Specifies the color format for the returned color specification. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryColor</function> -function obtains the <acronym>RGB</acronym> value -for the pixel value in the pixel member of the specified -<structname>XcmsColor</structname> -structure and then -converts the value to the target format as -specified by the result_format argument. -If the pixel is not a valid index in the specified colormap, a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XcmsQueryColor</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To query the color of multiple colormap cells in an arbitrary format, use -<function>XcmsQueryColors</function>. -</para> -<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsQueryColors</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsquerycolors'> -<funcprototype> - <funcdef>Status <function>XcmsQueryColors</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of -<structname>XcmsColor</structname> -structures, each pixel member indicating the color cell to query. -The color specifications for the color cells are returned in these structures. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>result_format</emphasis> - </term> - <listitem> - <para> -Specifies the color format for the returned color specification. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryColors</function> -function obtains the <acronym>RGB</acronym> values -for pixel values in the pixel members of -<structname>XcmsColor</structname> -structures and then -converts the values to the target format as -specified by the result_format argument. -If a pixel is not a valid index into the specified colormap, a -<errorname>BadValue</errorname> -error results. -If more than one pixel is in error, -the one that gets reported is arbitrary. -</para> -<para> -<!-- .LP --> -<function>XcmsQueryColors</function> -can generate -<errorname>BadColor</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -</sect1> -<sect1 id="Color_Conversion_Context_Functions"> -<title>Color Conversion Context Functions</title> -<!-- .XS --> -<!-- (SN Color Conversion Context Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -This section describes functions to create, modify, -and query Color Conversion Contexts (CCCs). -</para> -<para> -<!-- .LP --> -Associated with each colormap is an initial CCC transparently generated by -Xlib. -<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm> -Therefore, when you specify a colormap as an argument to a function, -you are indirectly specifying a CCC. -<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm> -The CCC attributes that can be modified by the X client are: -</para> -<itemizedlist> - <listitem> - <para> -Client White Point - </para> - </listitem> - <listitem> - <para> -Gamut compression procedure and client data - </para> - </listitem> - <listitem> - <para> -White point adjustment procedure and client data - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The initial values for these attributes are implementation specific. -The CCC attributes for subsequently created CCCs can be defined -by changing the CCC attributes of the default CCC. -<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm> -There is a default CCC associated with each screen. -</para> -<sect2 id="Getting_and_Setting_the_Color_Conversion_Context_of_a_Colormap"> -<title>Getting and Setting the Color Conversion Context of a Colormap</title> -<!-- .XS --> -<!-- (SN Getting and Setting the Color Conversion Context of a Colormap --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the CCC associated with a colormap, use -<function>XcmsCCCOfColormap</function>. -</para> -<indexterm significance="preferred"><primary>XcmsCCCOfColormap</primary></indexterm> -<indexterm><primary>Colormap</primary><secondary>CCC of</secondary></indexterm> -<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscccofcolormap'> -<funcprototype> - <funcdef>XcmsCCC <function>XcmsCCCOfColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCCCOfColormap</function> -function returns the CCC associated with the specified colormap. -Once obtained, -the CCC attributes can be queried or modified. -Unless the CCC associated with the specified colormap is changed with -<function>XcmsSetCCCOfColormap</function>, -this CCC is used when the specified colormap is used as an argument -to color functions. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To change the CCC associated with a colormap, use -<function>XcmsSetCCCOfColormap</function>. -</para> -<indexterm significance="preferred"><primary>XcmsSetCCCOfColormap</primary></indexterm> -<indexterm><primary>Colormap</primary><secondary>CCC of</secondary></indexterm> -<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmssetcccofcolormap'> -<funcprototype> - <funcdef>XcmsCCC <function>XcmsSetCCCOfColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsSetCCCOfColormap</function> -function changes the CCC associated with the specified colormap. -It returns the CCC previously associated with the colormap. -If they are not used again in the application, -CCCs should be freed by calling -<function>XcmsFreeCCC</function>. -Several colormaps may share the same CCC without restriction; this -includes the CCCs generated by Xlib with each colormap. Xlib, however, -creates a new CCC with each new colormap. -</para> -</sect2> -<sect2 id="Obtaining_the_Default_Color_Conversion_Context"> -<title>Obtaining the Default Color Conversion Context</title> -<!-- .XS --> -<!-- (SN Obtaining the Default Color Conversion Context --> -<!-- .XE --> -<para> -<!-- .LP --> -You can change the default CCC attributes for subsequently created CCCs -by changing the CCC attributes of the default CCC. -<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm> -A default CCC is associated with each screen. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the default CCC for a screen, use -<function>XcmsDefaultCCC</function>. -</para> -<indexterm significance="preferred"><primary>XcmsDefaultCCC</primary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm> -<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsdefaultccc'> -<funcprototype> - <funcdef>XcmsCCC <function>XcmsDefaultCCC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsDefaultCCC</function> -function returns the default CCC for the specified screen. -Its visual is the default visual of the screen. -Its initial gamut compression and white point -adjustment procedures as well as the associated client data are implementation -specific. -</para> -</sect2> -<sect2 id="Color_Conversion_Context_Macros"> -<title>Color Conversion Context Macros</title> -<!-- .XS --> -<!-- (SN Color Conversion Context Macros --> -<!-- .XE --> -<para> -<!-- .LP --> -Applications should not directly modify any part of the -<structname>XcmsCCC</structname>. -The following lists the C language macros, their corresponding function -equivalents for other language bindings, and what data they both -can return. -<!-- .sp --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>DisplayOfCCC</primary></indexterm> -<indexterm significance="preferred"><primary>XcmsDisplayOfCCC</primary></indexterm> -<!-- .sM --> - -<funcsynopsis id='displayofccc'> -<funcprototype> - <funcdef><function>DisplayOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<funcsynopsis id='xcmsdisplayofccc'> -<funcprototype> - <funcdef>Display *<function>XcmsDisplayOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Both return the display associated with the specified CCC. -</para> -<!-- .LP --> -<!-- .sp --> -<indexterm significance="preferred"><primary>VisualOfCCC</primary></indexterm> -<indexterm significance="preferred"><primary>XcmsVisualOfCCC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='visualofccc'> -<funcprototype> - <funcdef><function>VisualOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<funcsynopsis id='xcmsvisualofccc'> -<funcprototype> - <funcdef>Visual *<function>XcmsVisualOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Both return the visual associated with the specified CCC. -<!-- .sp --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>ScreenNumberOfCCC</primary></indexterm> -<indexterm significance="preferred"><primary>XcmsScreenNumberOfCCC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='screennumberofccc'> -<funcprototype> - <funcdef><function>ScreenNumberOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<funcsynopsis id='xcmsscreennumberofccc'> -<funcprototype> - <funcdef>int <function>XcmsScreenNumberOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Both return the number of the screen associated with the specified CCC. -<!-- .sp --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>ScreenWhitePointOfCCC</primary></indexterm> -<indexterm significance="preferred"><primary>XcmsScreenWhitePointOfCCC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='screenwhitepointofccc'> -<funcprototype> - <funcdef><function>ScreenWhitePointOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<funcsynopsis id='xcmsscreenwhitepointofccc'> -<funcprototype> - <funcdef>XcmsColor <function>XcmsScreenWhitePointOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Both return the white point of the screen associated with the specified CCC. -<!-- .sp --> -</para> -<!-- .LP --> -<indexterm significance="preferred"><primary>ClientWhitePointOfCCC</primary></indexterm> -<indexterm significance="preferred"><primary>XcmsClientWhitePointOfCCC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='clientwhitepointofccc'> -<funcprototype> - <funcdef> <function>ClientWhitePointOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<funcsynopsis id='xcmsclientwhitepointofccc'> -<funcprototype> - <funcdef>XcmsColor *<function>XcmsClientWhitePointOfCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Both return the Client White Point of the specified CCC. -</para> -</sect2> - -<sect2 id="Modifying_Attributes_of_a_Color_Conversion_Context"> -<title>Modifying Attributes of a Color Conversion Context</title> -<!-- .XS --> -<!-- (SN Modifying Attributes of a Color Conversion Context --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the Client White Point in the CCC, use -<function>XcmsSetWhitePoint</function>. -</para> -<indexterm significance="preferred"><primary>XcmsSetWhitePoint</primary></indexterm> -<indexterm><primary>Client White Point</primary><secondary>of Color Conversion Context</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmssetwhitepoint'> -<funcprototype> - <funcdef>Status <function>XcmsSetWhitePoint</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -<!-- .ds Co new Client White Point --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color</emphasis> - </term> - <listitem> - <para> -Specifies the new Client White Point. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsSetWhitePoint</function> -function changes the Client White Point in the specified CCC. -Note that the pixel member is ignored -and that the color specification is left unchanged upon return. -The format for the new white point must be -<symbol>XcmsCIEXYZFormat</symbol>, -<symbol>XcmsCIEuvYFormat</symbol>, -<symbol>XcmsCIExyYFormat</symbol>, -or -<symbol>XcmsUndefinedFormat</symbol>. -If the color argument is NULL, this function sets the format component of the -Client White Point specification to -<symbol>XcmsUndefinedFormat</symbol>, -indicating that the Client White Point is assumed to be the same as the -Screen White Point. -</para> -<para> -<!-- .LP --> -This function returns nonzero status -if the format for the new white point is valid; -otherwise, it returns zero. - -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set the gamut compression procedure and corresponding client data -in a specified CCC, use -<function>XcmsSetCompressionProc</function>. -</para> -<indexterm significance="preferred"><primary>XcmsSetCompressionProc</primary></indexterm> -<indexterm><primary>Gamut compression</primary><secondary>setting in Color Conversion Context</secondary></indexterm> -<indexterm><primary>Gamut compression</primary><secondary>procedure</secondary></indexterm> -<indexterm><primary>Gamut compression</primary><secondary>client data</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmssetcompressionproc'> -<funcprototype> - <funcdef>XcmsCompressionProc <function>XcmsSetCompressionProc</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsCompressionProc<parameter> compression_proc</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_proc</emphasis> - </term> - <listitem> - <para> -Specifies the gamut compression procedure that is to be applied -when a color lies outside the screen's color gamut. -If NULL is specified and a function using this CCC must convert -a color specification to a device-dependent format and encounters a color -that lies outside the screen's color gamut, -that function will return -<symbol>XcmsFailure</symbol>. -<!-- .ds Cd the gamut compression procedure --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies client data for gamut compression procedure or NULL. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsSetCompressionProc</function> -function first sets the gamut compression procedure and client data -in the specified CCC with the newly specified procedure and client data -and then returns the old procedure. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set the white point adjustment procedure and corresponding client data -in a specified CCC, use -<function>XcmsSetWhiteAdjustProc</function>. -</para> -<indexterm significance="preferred"><primary>XcmsSetWhiteAdjustProc</primary></indexterm> -<indexterm><primary>White point adjustment</primary><secondary>setting in Color Conversion Context</secondary></indexterm> -<indexterm><primary>White point adjustment</primary><secondary>procedure</secondary></indexterm> -<indexterm><primary>White point adjustment</primary><secondary>client data</secondary></indexterm> -<funcsynopsis id='xcmssetwhiteadjustproc'> -<funcprototype> - <funcdef>XcmsWhiteAdjustProc <function>XcmsSetWhiteAdjustProc</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsWhiteAdjustProc<parameter> white_adjust_proc</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>white_adjust_proc</emphasis> - </term> - <listitem> - <para> -Specifies the white point adjustment procedure. -<!-- .ds Cd the white point adjustment procedure --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies client data for white point adjustment procedure or NULL. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsSetWhiteAdjustProc</function> -function first sets the white point adjustment procedure and client data -in the specified CCC with the newly specified procedure and client data -and then returns the old procedure. -</para> -</sect2> -<sect2 id="Creating_and_Freeing_a_Color_Conversion_Context"> -<title>Creating and Freeing a Color Conversion Context</title> -<!-- .XS --> -<!-- (SN Creating and Freeing a Color Conversion Context --> -<!-- .XE --> -<para> -<!-- .LP --> -You can explicitly create a CCC within your application by calling -<function>XcmsCreateCCC</function>. -These created CCCs can then be used by those functions that explicitly -call for a CCC argument. -Old CCCs that will not be used by the application should be freed using -<function>XcmsFreeCCC</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To create a CCC, use -<function>XcmsCreateCCC</function>. -</para> -<indexterm significance="preferred"><primary>XcmsCreateCCC</primary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm> -<indexterm><primary>CCC</primary><secondary>creation</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscreateccc'> -<funcprototype> - <funcdef>XcmsCCC <function>XcmsCreateCCC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> - <paramdef>Visual<parameter> *visual</parameter></paramdef> - <paramdef>XcmsColor<parameter> *client_white_point</parameter></paramdef> - <paramdef>XcmsCompressionProc<parameter> compression_proc</parameter></paramdef> - <paramdef>XPointer<parameter> compression_client_data</parameter></paramdef> - <paramdef>XcmsWhiteAdjustProc<parameter> white_adjust_proc</parameter></paramdef> - <paramdef>XPointer<parameter> white_adjust_client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>visual</emphasis> - </term> - <listitem> - <para> -Specifies the visual type. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_white_point</emphasis> - </term> - <listitem> - <para> -Specifies the Client White Point. -If NULL is specified, -the Client White Point is to be assumed to be the same as the -Screen White Point. -Note that the pixel member is ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_proc</emphasis> - </term> - <listitem> - <para> -Specifies the gamut compression procedure that is to be applied -when a color lies outside the screen's color gamut. -If NULL is specified and a function using this CCC must convert -a color specification to a device-dependent format and encounters a color -that lies outside the screen's color gamut, -that function will return -<symbol>XcmsFailure</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_client_data</emphasis> - </term> - <listitem> - <para> -Specifies client data for use by the gamut compression procedure or NULL. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>white_adjust_proc</emphasis> - </term> - <listitem> - <para> -Specifies the white adjustment procedure that is to be applied -when the Client White Point differs from the Screen White Point. -NULL indicates that no white point adjustment is desired. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>white_adjust_client_data</emphasis> - </term> - <listitem> - <para> -Specifies client data for use with the white point adjustment procedure or NULL. - </para> - </listitem> - </varlistentry> -</variablelist> - - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCreateCCC</function> -function creates a CCC for the specified display, screen, and visual. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free a CCC, use -<function>XcmsFreeCCC</function>. -</para> -<indexterm significance="preferred"><primary>XcmsFreeCCC</primary></indexterm> -<indexterm><primary>Color Conversion Context</primary><secondary>freeing</secondary></indexterm> -<indexterm><primary>CCC</primary><secondary>freeing</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsfreeccc'> -<funcprototype> - <funcdef>void <function>XcmsFreeCCC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsFreeCCC</function> -function frees the memory used for the specified CCC. -Note that default CCCs and those currently associated with colormaps -are ignored. -</para> -</sect2> -</sect1> -<sect1 id="Converting_between_Color_Spaces"> -<title>Converting between Color Spaces</title> -<!-- .XS --> -<!-- (SN Converting between Color Spaces --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To convert an array of color specifications in arbitrary color formats -to a single destination format, use -<function>XcmsConvertColors</function>. -</para> -<indexterm><primary>Color conversion</primary></indexterm> -<indexterm><primary>Color</primary><secondary>conversion</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsConvertColors</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsconvertcolors'> -<funcprototype> - <funcdef>Status <function>XcmsConvertColors</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -If conversion is between device-independent color spaces only -(for example, TekHVC to CIELuv), -the CCC is necessary only to specify the Client White Point. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of color specifications. -Pixel members are ignored and remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_flags_return</emphasis> - </term> - <listitem> - <para> -Returns an array of Boolean values indicating compression status. -If a non-NULL pointer is supplied, -each element of the array is set to -<symbol>True</symbol> -if the corresponding color was compressed and -<symbol>False</symbol> -otherwise. -Pass NULL if the compression status is not useful. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsConvertColors</function> -function converts the color specifications in the specified array of -<structname>XcmsColor</structname> -structures from their current format to a single target format, -using the specified CCC. -When the return value is -<symbol>XcmsFailure</symbol>, -the contents of the color specification array are left unchanged. -</para> -<para> -<!-- .LP --> -The array may contain a mixture of color specification formats -(for example, 3 <acronym>CIE</acronym> XYZ, 2 <acronym>CIE</acronym> Luv, and so on). -When the array contains both device-independent and -device-dependent color specifications and the target_format argument specifies -a device-dependent format (for example, -<symbol>XcmsRGBiFormat</symbol>, -<symbol>XcmsRGBFormat</symbol>), -all specifications are converted to <acronym>CIE</acronym> XYZ format and then to the target -device-dependent format. -</para> -</sect1> -<sect1 id="Callback_Functions"> -<title>Callback Functions</title> -<!-- .XS --> -<!-- (SN Callback Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -This section describes the gamut compression and white point -adjustment callbacks. -</para> -<para> -<!-- .LP --> -The gamut compression procedure specified in the CCC -is called when an attempt to convert a color specification from -<structname>XcmsCIEXYZ</structname> -to a device-dependent format (typically -<structname>XcmsRGBi</structname>) -results in a color that lies outside the screen's color gamut. -If the gamut compression procedure requires client data, this data is passed -via the gamut compression client data in the CCC. -</para> -<para> -<!-- .LP --> -During color specification conversion between device-independent -and device-dependent color spaces, -if a white point adjustment procedure is specified in the CCC, -it is triggered when the Client White Point and Screen White Point differ. -If required, the client data is obtained from the CCC. -</para> -<sect2 id="Prototype_Gamut_Compression_Procedure"> -<title>Prototype Gamut Compression Procedure</title> -<!-- .XS --> -<!-- (SN Prototype Gamut Compression Procedure --> -<!-- .XE --> -<para> -<!-- .LP --> -The gamut compression callback interface must adhere to the -following: -</para> -<indexterm significance="preferred"><primary>XcmsCompressionProc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscompressionproc'> -<funcprototype> - <funcdef>typedef Status<function>(*XcmsCompressionProc</function>)</funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> - <paramdef>unsignedint<parameter> index</parameter></paramdef> - <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of color specifications. -Pixel members should be ignored and must remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>index</emphasis> - </term> - <listitem> - <para> -Specifies the index into the array of -<structname>XcmsColor</structname> -structures for the encountered color specification that lies outside the -screen's color gamut. -Valid values are 0 (for the first element) to ncolors - 1. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_flags_return</emphasis> - </term> - <listitem> - <para> -Returns an array of Boolean values for indicating compression status. -If a non-NULL pointer is supplied -and a color at a given index is compressed, then -<symbol>True</symbol> -should be stored at the corresponding index in this array; -otherwise, the array should not be modified. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -When implementing a gamut compression procedure, consider the following -rules and assumptions: -</para> -<itemizedlist> - <listitem> - <para> -The gamut compression procedure can attempt to compress one or multiple -specifications at a time. - </para> - </listitem> - <listitem> - <para> -When called, elements 0 to index - 1 in the color specification -array can be assumed to fall within the screen's color gamut. -In addition, these color specifications are already in some device-dependent -format (typically -<structname>XcmsRGBi</structname>). -If any modifications are made to these color specifications, -they must be in their initial device-dependent format upon return. - </para> - </listitem> - <listitem> - <para> -When called, the element in the color specification array specified -by the index argument contains the color specification outside the -screen's color gamut encountered by the calling routine. -In addition, this color specification can be assumed to be in -<structname>XcmsCIEXYZ</structname>. -Upon return, this color specification must be in -<structname>XcmsCIEXYZ</structname>. - </para> - </listitem> - <listitem> - <para> -When called, elements from index to ncolors - 1 -in the color specification array may or may not fall within the -screen's color gamut. -In addition, these color specifications can be assumed to be in -<structname>XcmsCIEXYZ</structname>. -If any modifications are made to these color specifications, -they must be in -<structname>XcmsCIEXYZ</structname> -upon return. - </para> - </listitem> - <listitem> - <para> -The color specifications passed to the gamut compression procedure -have already been adjusted to the Screen White Point. -This means that at this point the color specification's white point -is the Screen White Point. - </para> - </listitem> - <listitem> - <para> -If the gamut compression procedure uses a device-independent color space not -initially accessible for use in the color management system, use -<function>XcmsAddColorSpace</function> -to ensure that it is added. - </para> - </listitem> -</itemizedlist> -</sect2> -<sect2 id="Supplied_Gamut_Compression_Procedures"> -<title>Supplied Gamut Compression Procedures</title> -<!-- .XS --> -<!-- (SN Supplied Gamut Compression Procedures --> -<!-- .XE --> -<para> -<!-- .LP --> -The following equations are useful in describing gamut compression -functions: -<!-- .EQ --> -delim %% -<!-- .EN --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -%CIELab~Psychometric~Chroma ~=~ sqrt(a_star sup 2 ~+~ b_star sup 2 )% - -%CIELab~Psychometric~Hue ~=~ tan sup -1 left [ b_star over a_star right ]% - -%CIELuv~Psychometric~Chroma ~=~ sqrt(u_star sup 2 ~+~ v_star sup 2 )% - -%CIELuv~Psychometric~Hue ~=~ tan sup -1 left [ v_star over u_star right ]% -</literallayout> -</para> -<para> -<!-- .LP --> -The gamut compression callback procedures provided by Xlib are as follows: -</para> -<itemizedlist> - <listitem> - <para> -<function>XcmsCIELabClipL</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing or increasing <acronym>CIE</acronym> metric lightness (L*) -in the <acronym>CIE</acronym> L*a*b* color space until the color is within the gamut. -If the Psychometric Chroma of the color specification -is beyond maximum for the Psychometric Hue Angle, -then while maintaining the same Psychometric Hue Angle, -the color will be clipped to the <acronym>CIE</acronym> L*a*b* coordinates of maximum -Psychometric Chroma. -See -<function>XcmsCIELabQueryMaxC</function>. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELabClipab</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing Psychometric Chroma, -while maintaining Psychometric Hue Angle, -until the color is within the gamut. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELabClipLab</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by replacing it with <acronym>CIE</acronym> L*a*b* coordinates -that fall within the color gamut while maintaining the original -Psychometric Hue -Angle and whose vector to the original coordinates is the shortest attainable. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELuvClipL</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing or increasing <acronym>CIE</acronym> metric lightness (L*) -in the <acronym>CIE</acronym> L*u*v* color space until the color is within the gamut. -If the Psychometric Chroma of the color specification -is beyond maximum for the Psychometric Hue Angle, -then, while maintaining the same Psychometric Hue Angle, -the color will be clipped to the <acronym>CIE</acronym> L*u*v* coordinates of maximum -Psychometric Chroma. -See -<function>XcmsCIELuvQueryMaxC</function>. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELuvClipuv</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing -Psychometric Chroma, while maintaining Psychometric Hue Angle, -until the color is within the gamut. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELuvClipLuv</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by replacing it with <acronym>CIE</acronym> L*u*v* coordinates -that fall within the color gamut while maintaining the original -Psychometric Hue -Angle and whose vector to the original coordinates is the shortest attainable. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsTekHVCClipV</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing or increasing the Value dimension -in the TekHVC color space until the color is within the gamut. -If Chroma of the color specification is beyond maximum for the particular Hue, -then, while maintaining the same Hue, -the color will be clipped to the Value and Chroma coordinates -that represent maximum Chroma for that particular Hue. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsTekHVCClipC</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by reducing the Chroma dimension -in the TekHVC color space until the color is within the gamut. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsTekHVCClipVC</function> - </para> - </listitem> - <listitem> - <para> -This brings the encountered out-of-gamut color specification into the -screen's color gamut by replacing it with TekHVC coordinates -that fall within the color gamut while maintaining the original Hue -and whose vector to the original coordinates is the shortest attainable. -No client data is necessary. - </para> - </listitem> -</itemizedlist> -</sect2> -<sect2 id="Prototype_White_Point_Adjustment_Procedure"> -<title>Prototype White Point Adjustment Procedure</title> -<!-- .XS --> -<!-- (SN Prototype White Point Adjustment Procedure --> -<!-- .XE --> -<para> -<!-- .LP --> -The white point adjustment procedure interface must adhere to the following: -</para> -<indexterm significance="preferred"><primary>XcmsWhiteAdjustProc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmswhiteadjustproc'> -<funcprototype> - <funcdef>typedef Status <function>(*XcmsWhiteAdjustProc</function>)</funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> *initial_white_point</parameter></paramdef> - <paramdef>XcmsColor<parameter> *target_white_point</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> - <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>initial_white_point</emphasis> - </term> - <listitem> - <para> -Specifies the initial white point. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_white_point</emphasis> - </term> - <listitem> - <para> -Specifies the target white point. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of color specifications. -Pixel members should be ignored and must remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_flags_return</emphasis> - </term> - <listitem> - <para> -Returns an array of Boolean values for indicating compression status. -If a non-NULL pointer is supplied -and a color at a given index is compressed, then -<symbol>True</symbol> -should be stored at the corresponding index in this array; -otherwise, the array should not be modified. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect2> -<sect2 id="Supplied_White_Point_Adjustment_Procedures"> -<title>Supplied White Point Adjustment Procedures</title> -<!-- .XS --> -<!-- (SN Supplied White Point Adjustment Procedures --> -<!-- .XE --> -<para> -<!-- .LP --> -White point adjustment procedures provided by Xlib are as follows: -</para> -<itemizedlist> - <listitem> - <para> -<function>XcmsCIELabWhiteShiftColors</function> - </para> - </listitem> - <listitem> - <para> -This uses the <acronym>CIE</acronym> L*a*b* color space for adjusting the chromatic character -of colors to compensate for the chromatic differences between the source -and destination white points. -This procedure simply converts the color specifications to -<structname>XcmsCIELab</structname> -using the source white point and then converts to the target specification -format using the destination's white point. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsCIELuvWhiteShiftColors</function> - </para> - </listitem> - <listitem> - <para> -This uses the <acronym>CIE</acronym> L*u*v* color space for adjusting the chromatic character -of colors to compensate for the chromatic differences between the source -and destination white points. -This procedure simply converts the color specifications to -<structname>XcmsCIELuv</structname> -using the source white point and then converts to the target specification -format using the destination's white point. -No client data is necessary. - </para> - </listitem> - <listitem> - <para> -<function>XcmsTekHVCWhiteShiftColors</function> - </para> - </listitem> - <listitem> - <para> -This uses the TekHVC color space for adjusting the chromatic character -of colors to compensate for the chromatic differences between the source -and destination white points. -This procedure simply converts the color specifications to -<structname>XcmsTekHVC</structname> -using the source white point and then converts to the target specification -format using the destination's white point. -An advantage of this procedure over those previously described -is an attempt to minimize hue shift. -No client data is necessary. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -From an implementation point of view, -these white point adjustment procedures convert the color specifications -to a device-independent but white-point-dependent color space -(for example, <acronym>CIE</acronym> L*u*v*, <acronym>CIE</acronym> L*a*b*, TekHVC) using one white point -and then converting those specifications to the target color space -using another white point. -In other words, -the specification goes in the color space with one white point -but comes out with another white point, -resulting in a chromatic shift based on the chromatic displacement -between the initial white point and target white point. -The <acronym>CIE</acronym> color spaces that are assumed to be white-point-independent -are <acronym>CIE</acronym> u'v'Y, <acronym>CIE</acronym> XYZ, and <acronym>CIE</acronym> xyY. -When developing a custom white point adjustment procedure that uses a -device-independent color space not initially accessible for use in the -color management system, use -<function>XcmsAddColorSpace</function> -to ensure that it is added. -</para> -<para> -<!-- .LP --> -As an example, -if the CCC specifies a white point adjustment procedure -and if the Client White Point and Screen White Point differ, the -<function>XcmsAllocColor</function> -function will use the white point adjustment -procedure twice: -</para> -<itemizedlist> - <listitem> - <para> -Once to convert to -<structname>XcmsRGB</structname> - </para> - </listitem> - <listitem> - <para> -A second time to convert from -<structname>XcmsRGB</structname> - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -For example, assume the specification is in -<structname>XcmsCIEuvY</structname> -and the adjustment procedure is -<function>XcmsCIELuvWhiteShiftColors</function>. -During conversion to -<structname>XcmsRGB</structname>, -the call to -<function>XcmsAllocColor</function> -results in the following series of color specification conversions: -<!-- .\" Do these need to be font coded? --> -</para> -<itemizedlist> - <listitem> - <para> -From -<structname>XcmsCIEuvY</structname> -to -<structname>XcmsCIELuv</structname> -using the Client White Point - </para> - </listitem> - <listitem> - <para> -From -<structname>XcmsCIELuv</structname> -to -<structname>XcmsCIEuvY</structname> -using the Screen White Point - </para> - </listitem> - <listitem> - <para> -From -<structname>XcmsCIEuvY</structname> -to -<structname>XcmsCIEXYZ</structname> -(<acronym>CIE</acronym> u'v'Y and XYZ are white-point-independent color spaces) - </para> - </listitem> - <listitem> - <para> -From -<structname>XcmsCIEXYZ</structname> -to -<structname>XcmsRGBi</structname> - </para> - </listitem> - <listitem> - <para> -From -<structname>XcmsRGBi</structname> -to -<structname>XcmsRGB</structname> - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The resulting <acronym>RGB</acronym> specification is passed to -<function>XAllocColor</function>, -and the <acronym>RGB</acronym> -specification returned by -<function>XAllocColor</function> -is converted back to -<structname>XcmsCIEuvY</structname> -by reversing the color conversion sequence. -</para> -</sect2> -</sect1> -<sect1 id="Gamut_Querying_Functions"> -<title>Gamut Querying Functions</title> -<!-- .XS --> -<!-- (SN Gamut Querying Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -This section describes the gamut querying functions that Xlib provides. -These functions allow the client to query the boundary -of the screen's color gamut in terms of the <acronym>CIE</acronym> L*a*b*, <acronym>CIE</acronym> L*u*v*, -and TekHVC color spaces. -<indexterm><primary>Gamut querying</primary></indexterm> -Functions are also provided that allow you to query -the color specification of: -</para> -<itemizedlist> - <listitem> - <para> -White (full-intensity red, green, and blue) - </para> - </listitem> - <listitem> - <para> -Red (full-intensity red while green and blue are zero) - </para> - </listitem> - <listitem> - <para> -Green (full-intensity green while red and blue are zero) - </para> - </listitem> - <listitem> - <para> -Blue (full-intensity blue while red and green are zero) - </para> - </listitem> - <listitem> - <para> -Black (zero-intensity red, green, and blue) - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The white point associated with color specifications passed to -and returned from these gamut querying -functions is assumed to be the Screen White Point. -<indexterm><primary>Screen White Point</primary></indexterm> -This is a reasonable assumption, -because the client is trying to query the screen's color gamut. -</para> -<para> -<!-- .LP --> -The following naming convention is used for the Max and Min functions: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -Xcms<emphasis remap='I'><color_space></emphasis>QueryMax<emphasis remap='I'><dimensions></emphasis> - -Xcms<emphasis remap='I'><color_space></emphasis>QueryMin<emphasis remap='I'><dimensions></emphasis> -</literallayout> -</para> -<para> -<!-- .LP --> -The <dimensions> consists of a letter or letters -that identify the dimensions of the color space -that are not fixed. -For example, -<function>XcmsTekHVCQueryMaxC</function> -is given a fixed Hue and Value for which maximum Chroma is found. -</para> -<sect2 id="Red_Green_and_Blue_Queries"> -<title>Red, Green, and Blue Queries</title> -<!-- .XS --> -<!-- (SN Red, Green, and Blue Queries --> -<!-- .XE --> -<para> -<!-- .LP --> -To obtain the color specification for black -(zero-intensity red, green, and blue), use -<function>XcmsQueryBlack</function>. -</para> -<indexterm significance="preferred"><primary>XcmsQueryBlack</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsqueryblack'> -<funcprototype> - <funcdef>Status <function>XcmsQueryBlack</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. -<!-- .ds Cs zero-intensity red, green, and blue --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the specified target format -for (Cs. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryBlack</function> -function returns the color specification in the specified target format -for zero-intensity red, green, and blue. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the color specification for blue -(full-intensity blue while red and green are zero), use -<function>XcmsQueryBlue</function>. -</para> -<indexterm significance="preferred"><primary>XcmsQueryBlue</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsqueryblue'> -<funcprototype> - <funcdef>Status <function>XcmsQueryBlue</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. -<!-- .ds Cs full-intensity blue while red and green are zero --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the specified target format -for (Cs. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryBlue</function> -function returns the color specification in the specified target format -for full-intensity blue while red and green are zero. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the color specification for green -(full-intensity green while red and blue are zero), use -<function>XcmsQueryGreen</function>. -</para> -<indexterm significance="preferred"><primary>XcmsQueryGreen</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsquerygreen'> -<funcprototype> - <funcdef>Status <function>XcmsQueryGreen</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. -<!-- .ds Cs full-intensity green while red and blue are zero --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the specified target format -for (Cs. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryGreen</function> -function returns the color specification in the specified target format -for full-intensity green while red and blue are zero. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the color specification for red -(full-intensity red while green and blue are zero), use -<function>XcmsQueryRed</function>. -</para> -<indexterm significance="preferred"><primary>XcmsQueryRed</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsqueryred'> -<funcprototype> - <funcdef>Status <function>XcmsQueryRed</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. -<!-- .ds Cs full-intensity red while green and blue are zero --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the specified target format -for (Cs. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryRed</function> -function returns the color specification in the specified target format -for full-intensity red while green and blue are zero. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the color specification for white -(full-intensity red, green, and blue), use -<function>XcmsQueryWhite</function>. -</para> -<indexterm significance="preferred"><primary>XcmsQueryWhite</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsquerywhite'> -<funcprototype> - <funcdef>Status <function>XcmsQueryWhite</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_format</emphasis> - </term> - <listitem> - <para> -Specifies the target color specification format. -<!-- .ds Cs full-intensity red, green, and blue --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the specified target format -for (Cs. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsQueryWhite</function> -function returns the color specification in the specified target format -for full-intensity red, green, and blue. -</para> -</sect2> -<sect2 id="CIELab_Queries"> -<title>CIELab Queries</title> -<!-- .XS --> -<!-- (SN CIELab Queries --> -<!-- .XE --> -<para> -<!-- .LP --> -The following equations are useful in describing the CIELab query functions: -<!-- .EQ --> -delim %% -<!-- .EN --> -</para> -<para> -<!-- .LP --> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm> -<literallayout class="monospaced"> -%CIELab~Psychometric~Chroma ~=~ sqrt(a_star sup 2 ~+~ b_star sup 2 )% - -%CIELab~Psychometric~Hue ~=~ tan sup -1 left [ b_star over a_star right ]% -</literallayout> -<!-- .sp --> -To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum Psychometric Chroma -for a given Psychometric Hue Angle and <acronym>CIE</acronym> metric lightness (L*), use -<function>XcmsCIELabQueryMaxC</function>. -</para> -<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscielabquerymaxc'> -<funcprototype> - <funcdef>Status <function>XcmsCIELabQueryMaxC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> L_star</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ls maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>L_star</emphasis> - </term> - <listitem> - <para> -Specifies the lightness (L*) at which to find (Ls. -<!-- .ds Lc maximum chroma --> -<!-- .ds lC hue angle and lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELabQueryMaxC</function> -function, given a hue angle and lightness, -finds the point of maximum chroma displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*a*b* coordinates. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum <acronym>CIE</acronym> metric lightness (L*) -for a given Psychometric Hue Angle and Psychometric Chroma, use -<function>XcmsCIELabQueryMaxL</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxL</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscielabquerymaxl'> -<funcprototype> - <funcdef>Status <function>XcmsCIELabQueryMaxL</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ch maximum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>chroma</emphasis> - </term> - <listitem> - <para> -Specifies the chroma at which to find (Ch. -<!-- .ds Lc maximum lightness --> -<!-- .ds lC hue angle and chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELabQueryMaxL</function> -function, given a hue angle and chroma, -finds the point in <acronym>CIE</acronym> L*a*b* color space of maximum -lightness (L*) displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*a*b* coordinates. -An -<symbol>XcmsFailure</symbol> -return value usually indicates that the given chroma -is beyond maximum for the given hue angle. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum Psychometric Chroma -for a given Psychometric Hue Angle, use -<function>XcmsCIELabQueryMaxLC</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxLC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscielabquerymaxlc'> -<funcprototype> - <funcdef>Status <function>XcmsCIELabQueryMaxLC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Lc maximum chroma --> -<!-- .ds lC hue angle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELabQueryMaxLC</function> -function, given a hue angle, -finds the point of maximum chroma displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*a*b* coordinates. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*a*b* coordinates of minimum <acronym>CIE</acronym> metric lightness (L*) -for a given Psychometric Hue Angle and Psychometric Chroma, use -<function>XcmsCIELabQueryMinL</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>minimum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELabQueryMinL</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscielabqueryminlc'> -<funcprototype> - <funcdef>Status <function>XcmsCIELabQueryMinL</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha minimum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ch minimum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>chroma</emphasis> - </term> - <listitem> - <para> -Specifies the chroma at which to find (Ch. -<!-- .ds Lc minimum lightness --> -<!-- .ds lC hue angle and chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELabQueryMinL</function> -function, given a hue angle and chroma, -finds the point of minimum lightness (L*) displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*a*b* coordinates. -An -<symbol>XcmsFailure</symbol> -return value usually indicates that the given chroma -is beyond maximum for the given hue angle. -</para> -</sect2> -<sect2 id="CIELuv_Queries"> -<title>CIELuv Queries</title> -<!-- .XS --> -<!-- (SN CIELuv Queries --> -<!-- .XE --> -<para> -<!-- .LP --> -The following equations are useful in describing the CIELuv query functions: -<!-- .EQ --> -delim %% -<!-- .EN --> -</para> -<para> -<!-- .LP --> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm> -<literallayout class="monospaced"> -%CIELuv~Psychometric~Chroma ~=~ sqrt(u_star sup 2 ~+~ v_star sup 2 )% - -%CIELuv~Psychometric~Hue ~=~ tan sup -1 left [ v_star over u_star right ]% -</literallayout> -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum Psychometric Chroma -for a given Psychometric Hue Angle and <acronym>CIE</acronym> metric lightness (L*), use -<function>XcmsCIELuvQueryMaxC</function>. -</para> -<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmxcieluvquerymaxc'> -<funcprototype> - <funcdef>Status <function>XcmsCIELuvQueryMaxC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> L_star</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ls maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>L_star</emphasis> - </term> - <listitem> - <para> -Specifies the lightness (L*) at which to find (Ls. -<!-- .ds Lc maximum chroma --> -<!-- .ds lC hue angle and lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELuvQueryMaxC</function> -function, given a hue angle and lightness, -finds the point of maximum chroma displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*u*v* coordinates. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum <acronym>CIE</acronym> metric lightness (L*) -for a given Psychometric Hue Angle and Psychometric Chroma, use -<function>XcmsCIELuvQueryMaxL</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxL</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscieluvquerymaxl'> -<funcprototype> - <funcdef>Status <function>XcmsCIELuvQueryMaxL</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ls maximum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>L_star</emphasis> - </term> - <listitem> - <para> -Specifies the lightness (L*) at which to find (Ls. -<!-- .ds Lc maximum lightness --> -<!-- .ds lC hue angle and chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELuvQueryMaxL</function> -function, given a hue angle and chroma, -finds the point in <acronym>CIE</acronym> L*u*v* color space of maximum -lightness (L*) displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*u*v* coordinates. -An -<symbol>XcmsFailure</symbol> -return value usually indicates that the given chroma -is beyond maximum for the given hue angle. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum Psychometric Chroma -for a given Psychometric Hue Angle, use -<function>XcmsCIELuvQueryMaxLC</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxLC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscieluvquerymaxlc'> -<funcprototype> - <funcdef>Status <function>XcmsCIELuvQueryMaxLC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha maximum chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Lc maximum chroma --> -<!-- .ds lC hue angle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELuvQueryMaxLC</function> -function, given a hue angle, -finds the point of maximum chroma displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*u*v* coordinates. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the <acronym>CIE</acronym> L*u*v* coordinates of minimum <acronym>CIE</acronym> metric lightness (L*) -for a given Psychometric Hue Angle and Psychometric Chroma, use -<function>XcmsCIELuvQueryMinL</function>. -</para> -<indexterm><primary>Psychometric Hue Angle</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm> -<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>minimum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsCIELuvQueryMinL</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmscieluvqueryminl'> -<funcprototype> - <funcdef>Status <function>XcmsCIELuvQueryMinL</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Ha minimum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue_angle</emphasis> - </term> - <listitem> - <para> -Specifies the hue angle (in degrees) at which to find (Ha. -<!-- .ds Ch minimum lightness --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>chroma</emphasis> - </term> - <listitem> - <para> -Specifies the chroma at which to find (Ch. -<!-- .ds Lc minimum lightness --> -<!-- .ds lC hue angle and chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc -displayable by the screen for the given (lC. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsCIELuvQueryMinL</function> -function, given a hue angle and chroma, -finds the point of minimum lightness (L*) displayable by the screen. -It returns this point in <acronym>CIE</acronym> L*u*v* coordinates. -An -<symbol>XcmsFailure</symbol> -return value usually indicates that the given chroma -is beyond maximum for the given hue angle. -</para> -</sect2> -<sect2 id="TekHVC_Queries"> -<title>TekHVC Queries</title> -<!-- .XS --> -<!-- (SN TekHVC Queries --> -<!-- .XE --> -<para> -<!-- .LP --> -To obtain the maximum Chroma for a given Hue and Value, use -<function>XcmsTekHVCQueryMaxC</function>. -</para> -<indexterm><primary>Chroma</primary></indexterm> -<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmstekhvcquerymaxc'> -<funcprototype> - <funcdef>Status <function>XcmsTekHVCQueryMaxC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue</parameter></paramdef> - <paramdef>XcmsFloat<parameter> value</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Hu in which to find the maximum Chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue</emphasis> - </term> - <listitem> - <para> -Specifies the Hue (Hu. -<!-- .ds Va maximum Chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the Value in which to find the (Va. -<!-- .ds Lc maximum Chroma along with the actual Hue and Value --> -<!-- .ds lC maximum Chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the (Lc at which the (lC was found. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsTekHVCQueryMaxC</function> -function, given a Hue and Value, -determines the maximum Chroma in TekHVC color space -displayable by the screen. -It returns the maximum Chroma along with the actual Hue -and Value at which the maximum Chroma was found. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the maximum Value for a given Hue and Chroma, use -<function>XcmsTekHVCQueryMaxV</function>. -</para> -<indexterm><primary>Value</primary></indexterm> -<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxV</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmstekhvcquerymaxv'> -<funcprototype> - <funcdef>Status <function>XcmsTekHVCQueryMaxV</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Hu in which to find the maximum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue</emphasis> - </term> - <listitem> - <para> -Specifies the Hue (Hu. -<!-- .ds Ch maximum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>chroma</emphasis> - </term> - <listitem> - <para> -Specifies the chroma at which to find (Ch. -<!-- .ds Lc maximum Value along with the Hue and Chroma --> -<!-- .ds lC maximum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the (Lc at which the (lC was found. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsTekHVCQueryMaxV</function> -function, given a Hue and Chroma, -determines the maximum Value in TekHVC color space -displayable by the screen. -It returns the maximum Value and the actual Hue and Chroma -at which the maximum Value was found. -<!-- .sp --> -</para> - -<para> -<!-- .LP --> -To obtain the maximum Chroma and Value at which it is reached -for a specified Hue, use -<function>XcmsTekHVCQueryMaxVC</function>. -</para> -<indexterm><primary>Chroma</primary></indexterm> -<indexterm><primary>Value</primary></indexterm> -<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm> -<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxVC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmstekhvcquerymaxvc'> -<funcprototype> - <funcdef>Status <function>XcmsTekHVCQueryMaxVC</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Hu in which to find the maximum Chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue</emphasis> - </term> - <listitem> - <para> -Specifies the Hue (Hu. -<!-- .ds Lc color specification in \ --> -XcmsTekHVC for the maximum Chroma, the Value at which \ -that maximum Chroma is reached, and the actual Hue -<!-- .ds lC maximum Chroma --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the (Lc at which the (lC was found. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsTekHVCQueryMaxVC</function> -function, given a Hue, -determines the maximum Chroma in TekHVC color space displayable by the screen -and the Value at which that maximum Chroma is reached. -It returns the maximum Chroma, -the Value at which that maximum Chroma is reached, -and the actual Hue for which the maximum Chroma was found. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain a specified number of TekHVC specifications such that they -contain maximum Values for a specified Hue and the -Chroma at which the maximum Values are reached, use -<function>XcmsTekHVCQueryMaxVSamples</function>. -</para> -<indexterm><primary>Chroma</primary></indexterm> -<indexterm><primary>Value</primary></indexterm> -<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm> -<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxVSamples</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmstekhvcquerymaxvsamples'> -<funcprototype> - <funcdef>Status <function>XcmsTekHVCQueryMaxVSamples</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue</parameter></paramdef> - <paramdef>XcmsColor<parameter> colors_return[]</parameter></paramdef> - <paramdef>unsignedint<parameter> nsamples</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Hu for maximum Chroma/Value samples --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue</emphasis> - </term> - <listitem> - <para> -Specifies the Hue (Hu. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nsamples</emphasis> - </term> - <listitem> - <para> -Specifies the number of samples. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_return</emphasis> - </term> - <listitem> - <para> -Returns nsamples of color specifications in XcmsTekHVC -such that the Chroma is the maximum attainable for the Value and Hue. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsTekHVCQueryMaxVSamples</function> -returns nsamples of maximum Value, the Chroma at which that maximum Value -is reached, and the actual Hue for which the maximum Chroma was found. -These sample points may then be used to plot the maximum Value/Chroma -boundary of the screen's color gamut for the specified Hue in TekHVC color -space. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the minimum Value for a given Hue and Chroma, use -<function>XcmsTekHVCQueryMinV</function>. -</para> -<indexterm><primary>Value</primary></indexterm> -<indexterm><primary>Value</primary><secondary>minimum</secondary></indexterm> -<indexterm significance="preferred"><primary>XcmsTekHVCQueryMinV</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmstekhvcqueryminv'> -<funcprototype> - <funcdef>Status <function>XcmsTekHVCQueryMinV</function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsFloat<parameter> hue</parameter></paramdef> - <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. -The CCC's Client White Point and white point adjustment procedures -are ignored. -<!-- .ds Hu in which to find the minimum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hue</emphasis> - </term> - <listitem> - <para> -Specifies the Hue (Hu. -<!-- .ds Va minimum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the Value in which to find the (Va. -<!-- .ds Lc minimum Value and the actual Hue and Chroma --> -<!-- .ds lC minimum Value --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the (Lc at which the (lC was found. -The white point associated with the returned -color specification is the Screen White Point. -The value returned in the pixel member is undefined. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsTekHVCQueryMinV</function> -function, given a Hue and Chroma, -determines the minimum Value in TekHVC color space displayable by the screen. -It returns the minimum Value and the actual Hue and Chroma at which -the minimum Value was found. -</para> - -</sect2> -</sect1> -<sect1 id="Color_Management_Extensions"> -<title>Color Management Extensions</title> -<!-- .XS --> -<!-- (SN Color Management Extensions --> -<!-- .XE --> -<para> -<!-- .LP --> -The Xlib color management facilities can be extended in two ways: -</para> -<itemizedlist> - <listitem> - <para> -Device-Independent Color Spaces - </para> - </listitem> - <listitem> - <para> -Device-independent color spaces that are derivable to <acronym>CIE</acronym> XYZ -space can be added using the -<function>XcmsAddColorSpace</function> -function. - </para> - </listitem> - <listitem> - <para> -Color Characterization Function Set - </para> - </listitem> - <listitem> - <para> -A Color Characterization Function Set consists of -device-dependent color spaces and their functions that -convert between these color spaces and the <acronym>CIE</acronym> XYZ -color space, bundled together for a specific class of output devices. -A function set can be added using the -<function>XcmsAddFunctionSet</function> -function. - </para> - </listitem> -</itemizedlist> -<sect2 id="Color_Spaces"> -<title>Color Spaces</title> -<!-- .XS --> -<!-- (SN Color Spaces --> -<!-- .XE --> -<para> -<!-- .LP --> -The <acronym>CIE</acronym> XYZ color space serves as the hub for all -conversions between device-independent and device-dependent color spaces. -Therefore, the knowledge to convert an -<structname>XcmsColor</structname> -structure to and from <acronym>CIE</acronym> XYZ format is associated with each color space. -For example, conversion from <acronym>CIE</acronym> L*u*v* to <acronym>RGB</acronym> requires the knowledge -to convert from <acronym>CIE</acronym> L*u*v* to <acronym>CIE</acronym> XYZ and from <acronym>CIE</acronym> XYZ to <acronym>RGB</acronym>. -This knowledge is stored as an array of functions that, -when applied in series, will convert the -<structname>XcmsColor</structname> -structure to or from <acronym>CIE</acronym> XYZ format. -This color specification conversion mechanism facilitates -the addition of color spaces. -</para> -<para> -<!-- .LP --> -Of course, when converting between only device-independent color spaces -or only device-dependent color spaces, -shortcuts are taken whenever possible. -For example, conversion from TekHVC to <acronym>CIE</acronym> L*u*v* is performed -by intermediate conversion to <acronym>CIE</acronym> u*v*Y and then to <acronym>CIE</acronym> L*u*v*, -thus bypassing conversion between <acronym>CIE</acronym> u*v*Y and <acronym>CIE</acronym> XYZ. -</para> -</sect2> -<sect2 id="Adding_Device_Independent_Color_Spaces"> -<title>Adding Device-Independent Color Spaces</title> -<!-- .XS --> -<!-- (SN Adding Device-Independent Color Spaces --> -<!-- .XE --> -<para> -<!-- .LP --> -To add a device-independent color space, use -<function>XcmsAddColorSpace</function>. -</para> -<indexterm significance="preferred"><primary>XcmsAddColorSpace</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsaddcolorspace'> -<funcprototype> - <funcdef>Status <function>XcmsAddColorSpace</function></funcdef> - <paramdef>XcmsColorSpace<parameter> *color_space</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>color_space</emphasis> - </term> - <listitem> - <para> -Specifies the device-independent color space to add. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsAddColorSpace</function> -function makes a device-independent color space (actually an -<structname>XcmsColorSpace</structname> -structure) accessible by the color management system. -Because format values for unregistered color spaces are assigned at run time, -they should be treated as private to the client. -If references to an unregistered color space must be made -outside the client (for example, storing color specifications -in a file using the unregistered color space), -then reference should be made by color space prefix -(see -<function>XcmsFormatOfPrefix</function> -and -<function>XcmsPrefixOfFormat</function>). -</para> -<para> -<!-- .LP --> -If the -<structname>XcmsColorSpace</structname> -structure is already accessible in the color management system, -<function>XcmsAddColorSpace</function> -returns -<symbol>XcmsSuccess</symbol>. -</para> -<para> -<!-- .LP --> -Note that added -<structname>XcmsColorSpace</structname>s -must be retained for reference by Xlib. -</para> -</sect2> -<sect2 id="Querying_Color_Space_Format_and_Prefix"> -<title>Querying Color Space Format and Prefix</title> -<!-- .XS --> -<!-- (SN Querying Color Space Format and Prefix --> -<!-- .XE --> -<para> -<!-- .LP --> -To obtain the format associated with the color space -associated with a specified color string prefix, use -<function>XcmsFormatOfPrefix</function>. -</para> -<indexterm significance="preferred"><primary>XcmsFormatOfPrefix</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsformatofprefix'> -<funcprototype> - <funcdef>XcmsColorFormat <function>XcmsFormatOfPrefix</function></funcdef> - <paramdef>char<parameter> *prefix</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>prefix</emphasis> - </term> - <listitem> - <para> -Specifies the string that contains the color space prefix. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsFormatOfPrefix</function> -function returns the format for the specified color space prefix -(for example, the string ``CIEXYZ''). -The prefix is case-insensitive. -If the color space is not accessible in the color management system, -<function>XcmsFormatOfPrefix</function> -returns -<symbol>XcmsUndefinedFormat</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the color string prefix associated with the color space -specified by a color format, use -<function>XcmsPrefixOfFormat</function>. -</para> -<indexterm significance="preferred"><primary>XcmsPrefixOfFormat</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsprefixofformat'> -<funcprototype> - <funcdef>char *<function>XcmsPrefixOfFormat</function></funcdef> - <paramdef>XcmsColorFormat<parameter> format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>format</emphasis> - </term> - <listitem> - <para> -Specifies the color specification format. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsPrefixOfFormat</function> -function returns the string prefix associated with the color specification -encoding specified by the format argument. -Otherwise, if no encoding is found, it returns NULL. -The returned string must be treated as read-only. -</para> -</sect2> -<sect2 id="Creating_Additional_Color_Spaces"> -<title>Creating Additional Color Spaces</title> -<!-- .XS --> -<!-- (SN Creating Additional Color Spaces --> -<!-- .XE --> -<para> -<!-- .LP --> -Color space specific information necessary -for color space conversion and color string parsing is stored in an -<structname>XcmsColorSpace</structname> -structure. -Therefore, a new structure containing this information is required -for each additional color space. -In the case of device-independent color spaces, -a handle to this new structure (that is, by means of a global variable) -is usually made accessible to the client program for use with the -<function>XcmsAddColorSpace</function> -function. -</para> -<para> -<!-- .LP --> -If a new -<structname>XcmsColorSpace</structname> -structure specifies a color space not registered with the X Consortium, -they should be treated as private to the client -because format values for unregistered color spaces are assigned at run time. -If references to an unregistered color space must be made outside the -client (for example, storing color specifications in a file using the -unregistered color space), then reference should be made by color space prefix -(see -<function>XcmsFormatOfPrefix</function> -and -<function>XcmsPrefixOfFormat</function>). -<!-- .sM --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef (*XcmsConversionProc)(); -typedef XcmsConversionProc *XcmsFuncListPtr; - /* A NULL terminated list of function pointers*/ - -typedef struct _XcmsColorSpace { - char *prefix; - XcmsColorFormat format; - XcmsParseStringProc parseString; - XcmsFuncListPtr to_CIEXYZ; - XcmsFuncListPtr from_CIEXYZ; - int inverse_flag; -} XcmsColorSpace; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The prefix member specifies the prefix that indicates a color string -is in this color space's string format. -For example, the strings ``ciexyz'' or ``CIEXYZ'' for <acronym>CIE</acronym> XYZ, -and ``rgb'' or ``<acronym>RGB</acronym>'' for <acronym>RGB</acronym>. -The prefix is case insensitive. -The format member specifies the color specification format. -Formats for unregistered color spaces are assigned at run time. -The parseString member contains a pointer to the function -that can parse a color string into an -<structname>XcmsColor</structname> -structure. -This function returns an integer (int): nonzero if it succeeded -and zero otherwise. -The to_CIEXYZ and from_CIEXYZ members contain pointers, -each to a NULL terminated list of function pointers. -When the list of functions is executed in series, -it will convert the color specified in an -<structname>XcmsColor</structname> -structure from/to the current color space format to/from the <acronym>CIE</acronym> XYZ format. -Each function returns an integer (int): nonzero if it succeeded -and zero otherwise. -The white point to be associated with the colors is specified -explicitly, even though white points can be found in the CCC. -The inverse_flag member, if nonzero, specifies that for each function listed -in to_CIEXYZ, -its inverse function can be found in from_CIEXYZ such that: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -Given: n = number of functions in each list - -for each i, such that 0 <= i < n - from_CIEXYZ[n - i - 1] is the inverse of to_CIEXYZ[i]. -</literallayout> -</para> -<para> -<!-- .LP --> -This allows Xlib to use the shortest conversion path, -thus bypassing <acronym>CIE</acronym> XYZ if possible (for example, TekHVC to <acronym>CIE</acronym> L*u*v*). -</para> -</sect2> -<sect2 id="Parse_String_Callback"> -<title>Parse String Callback</title> -<!-- .XS --> -<!-- (SN Parse String Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The callback in the -<structname>XcmsColorSpace</structname> -structure for parsing a color string for the particular color space must -adhere to the following software interface specification: -</para> -<indexterm significance="preferred"><primary>XcmsParseStringProc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsparsestringproc'> -<funcprototype> - <funcdef>Status <function>XcmsParseStringProc</function></funcdef> - <paramdef>char<parameter> *color_string</parameter></paramdef> - <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>color_string</emphasis> - </term> - <listitem> - <para> -Specifies the color string to parse. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>color_return</emphasis> - </term> - <listitem> - <para> -Returns the color specification in the color space's format. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect2> -<sect2 id="Color_Specification_Conversion_Callback"> -<title>Color Specification Conversion Callback</title> -<!-- .XS --> -<!-- (SN Color Specification Conversion Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -Callback functions in the -<structname>XcmsColorSpace</structname> -structure for converting a color specification between device-independent -spaces must adhere to the -following software interface specification: -</para> -<!-- .sM --> -<funcsynopsis id='conversionproc'> -<funcprototype> - <funcdef>Status <function><replaceable>ConversionProc</replaceable></function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> *white_point</parameter></paramdef> - <paramdef>XcmsColor<parameter> *colors_in_out</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>white_point</emphasis> - </term> - <listitem> - <para> -Specifies the white point associated with color specifications. -The pixel member should be ignored, -and the entire structure remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of color specifications. -Pixel members should be ignored and must remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -Callback functions in the -<structname>XcmsColorSpace</structname> -structure for converting a color specification to or from a device-dependent -space must adhere to the -following software interface specification: -</para> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef>Status <function><replaceable>ConversionProc</replaceable></function></funcdef> - <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef> - <paramdef>XcmsColor<parameter> *colors_in_out</parameter></paramdef> - <paramdef>unsignedint<parameter> ncolors</parameter></paramdef> - <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ccc</emphasis> - </term> - <listitem> - <para> -Specifies the CCC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colors_in_out</emphasis> - </term> - <listitem> - <para> -Specifies an array of color specifications. -Pixel members should be ignored and must remain unchanged upon return. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ncolors</emphasis> - </term> - <listitem> - <para> -Specifies the number of -<structname>XcmsColor</structname> -structures in the color-specification array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>compression_flags_return</emphasis> - </term> - <listitem> - <para> -Returns an array of Boolean values for indicating compression status. -If a non-NULL pointer is supplied -and a color at a given index is compressed, then -<symbol>True</symbol> -should be stored at the corresponding index in this array; -otherwise, the array should not be modified. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -Conversion functions are available globally for use by other color -spaces. -The conversion functions provided by Xlib are: -</para> -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <thead> - <row> - <entry align='center'>Function</entry> - <entry align='center'>Converts from</entry> - <entry align='center'>Converts to</entry> - </row> - </thead> - <tbody> - <row> - <entry><function>XcmsCIELabToCIEXYZ</function></entry> - <entry><symbol>XcmsCIELabFormat</symbol></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIELuvToCIEuvY</function></entry> - <entry><symbol>XcmsCIELuvFormat</symbol></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEXYZToCIELab</function></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - <entry><symbol>XcmsCIELabFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEXYZToCIEuvY</function></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEXYZToCIExyY</function></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - <entry><symbol>XcmsCIExyYFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEXYZToRGBi</function></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - <entry><symbol>XcmsRGBiFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEuvYToCIELuv</function></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - <entry><symbol>XcmsCIELabFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEuvYToCIEXYZ</function></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIEuvYToTekHVC</function></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - <entry><symbol>XcmsTekHVCFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsCIExyYToCIEXYZ</function></entry> - <entry><symbol>XcmsCIExyYFormat</symbol></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsRGBToRGBi</function></entry> - <entry><symbol>XcmsRGBFormat</symbol></entry> - <entry><symbol>XcmsRGBiFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsRGBiToCIEXYZ</function></entry> - <entry><symbol>XcmsRGBiFormat</symbol></entry> - <entry><symbol>XcmsCIEXYZFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsRGBiToRGB</function></entry> - <entry><symbol>XcmsRGBiFormat</symbol></entry> - <entry><symbol>XcmsRGBFormat</symbol></entry> - </row> - <row> - <entry><function>XcmsTekHVCToCIEuvY</function></entry> - <entry><symbol>XcmsTekHVCFormat</symbol></entry> - <entry><symbol>XcmsCIEuvYFormat</symbol></entry> - </row> - </tbody> - </tgroup> -</informaltable> - -</sect2> -<sect2 id="Function_Sets"> -<title>Function Sets</title> -<!-- .XS --> -<!-- (SN Function Sets --> -<!-- .XE --> -<indexterm><primary>Function set</primary></indexterm> -<indexterm><primary>Function set</primary><secondary>LINEAR_RGB</secondary></indexterm> -<para> -<!-- .LP --> -Functions to convert between device-dependent color spaces -and <acronym>CIE</acronym> XYZ may differ for different classes of output devices -(for example, color versus gray monitors). -Therefore, the notion of a Color Characterization Function Set -has been developed. -A function set consists of device-dependent color spaces -and the functions that convert color specifications -between these device-dependent color spaces and the <acronym>CIE</acronym> XYZ color space -appropriate for a particular class of output devices. -The function set also contains a function that reads -color characterization data off root window properties. -It is this characterization data that will differ between devices within -a class of output devices. -<indexterm><primary>Device Color Characterization</primary></indexterm> -For details about how color characterization data is -stored in root window properties, -see the section on Device Color Characterization in the -<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>. -The LINEAR_RGB function set is provided by Xlib -and will support most color monitors. -Function sets may require data that differs -from those needed for the LINEAR_RGB function set. -In that case, -its corresponding data may be stored on different root window properties. -</para> -</sect2> -<sect2 id="Adding_Function_Sets"> -<title>Adding Function Sets</title> -<!-- .XS --> -<!-- (SN Adding Function Sets --> -<!-- .XE --> -<para> -<!-- .LP --> -To add a function set, use -<function>XcmsAddFunctionSet</function>. -</para> -<indexterm significance="preferred"><primary>XcmsAddFunctionSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcmsaddfunctionset'> -<funcprototype> - <funcdef>Status <function>XcmsAddFunctionSet</function></funcdef> - <paramdef>XcmsFunctionSet<parameter> *function_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>function_set</emphasis> - </term> - <listitem> - <para> -Specifies the function set to add. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XcmsAddFunctionSet</function> -function adds a function set to the color management system. -If the function set uses device-dependent -<structname>XcmsColorSpace</structname> -structures not accessible in the color management system, -<function>XcmsAddFunctionSet</function> -adds them. -If an added -<structname>XcmsColorSpace</structname> -structure is for a device-dependent color space not registered -with the X Consortium, -they should be treated as private to the client -because format values for unregistered color spaces are assigned at run time. -If references to an unregistered color space must be made outside the -client (for example, storing color specifications in a file -using the unregistered color space), -then reference should be made by color space prefix -(see -<function>XcmsFormatOfPrefix</function> -and -<function>XcmsPrefixOfFormat</function>). -</para> -<para> -<!-- .LP --> -Additional function sets should be added before any calls to other -Xlib routines are made. -If not, the -<structname>XcmsPerScrnInfo</structname> -member of a previously created -<structname>XcmsCCC</structname> -does not have the opportunity to initialize -with the added function set. -</para> -</sect2> -<sect2 id="Creating_Additional_Function_Sets"> -<title>Creating Additional Function Sets</title> -<!-- .XS --> -<!-- (SN Creating Additional Function Sets --> -<!-- .XE --> -<para> -<!-- .LP --> -The creation of additional function sets should be -required only when an output device does not conform to existing -function sets or when additional device-dependent color spaces are necessary. -A function set consists primarily of a collection of device-dependent -<structname>XcmsColorSpace</structname> -structures and a means to read and store a -screen's color characterization data. -This data is stored in an -<structname>XcmsFunctionSet</structname> -structure. -A handle to this structure (that is, by means of global variable) -is usually made accessible to the client program for use with -<function>XcmsAddFunctionSet</function>. -</para> -<para> -<!-- .LP --> -If a function set uses new device-dependent -<structname>XcmsColorSpace</structname> -structures, -they will be transparently processed into the color management system. -Function sets can share an -<structname>XcmsColorSpace</structname> -structure for a device-dependent color space. -In addition, multiple -<structname>XcmsColorSpace</structname> -structures are allowed for a device-dependent color space; -however, a function set can reference only one of them. -These -<structname>XcmsColorSpace</structname> -structures will differ in the functions to convert to and from <acronym>CIE</acronym> XYZ, -thus tailored for the specific function set. -<!-- .sM --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct _XcmsFunctionSet { - XcmsColorSpace **DDColorSpaces; - XcmsScreenInitProc screenInitProc; - XcmsScreenFreeProc screenFreeProc; -} XcmsFunctionSet; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The DDColorSpaces member is a pointer to a NULL terminated list -of pointers to -<structname>XcmsColorSpace</structname> -structures for the device-dependent color spaces that are supported -by the function set. -The screenInitProc member is set to the callback procedure (see the following -interface specification) that initializes the -<structname>XcmsPerScrnInfo</structname> -structure for a particular screen. -</para> -<para> -<!-- .LP --> -The screen initialization callback must adhere to the following software -interface specification: -<indexterm significance="preferred"><primary>XcmsScreenInitProc</primary></indexterm> -<!-- .sM --> -</para> -<funcsynopsis> -<funcprototype> - <funcdef>typedef Status <function>(*XcmsScreenInitProc</function>)</funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> - <paramdef>ScmsPerScrnInfo<parameter> *screen_info</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_info</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XcmsPerScrnInfo</structname> -structure, which contains the per screen information. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The screen initialization callback in the -<structname>XcmsFunctionSet</structname> -structure fetches the color characterization data (device profile) for -the specified screen, -typically off properties on the -screen's root window. -It then initializes the specified -<structname>XcmsPerScrnInfo</structname> -structure. -<indexterm><primary>Device profile</primary></indexterm> -<indexterm><primary>Color Characterization Data</primary></indexterm> -If successful, the procedure fills in the -<structname>XcmsPerScrnInfo</structname> -structure as follows: -</para> -<itemizedlist> - <listitem> - <para> -It sets the screenData member to the address -of the created device profile data structure -(contents known only by the function set). - </para> - </listitem> - <listitem> - <para> -It next sets the screenWhitePoint member. - </para> - </listitem> - <listitem> - <para> -It next sets the functionSet member to the address of the -<structname>XcmsFunctionSet</structname> -structure. - </para> - </listitem> - <listitem> - <para> -It then sets the state member to -<symbol>XcmsInitSuccess</symbol> -and finally returns -<symbol>XcmsSuccess</symbol>. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -If unsuccessful, the procedure sets the state member to -<symbol>XcmsInitFailure</symbol> -and returns -<symbol>XcmsFailure</symbol>. -</para> -<para> -<!-- .LP --> -The -<structname>XcmsPerScrnInfo</structname> -structure contains: -<!-- .sM --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct _XcmsPerScrnInfo { - XcmsColor screenWhitePoint; - XPointer functionSet; - XPointer screenData; - unsigned char state; - char pad[3]; -} XcmsPerScrnInfo; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The screenWhitePoint member specifies the white point inherent to -the screen. -The functionSet member specifies the appropriate function set. -The screenData member specifies the device profile. -The state member is set to one of the following: -</para> -<itemizedlist> - <listitem> - <para> -<symbol>XcmsInitNone</symbol> -indicates initialization has not been previously attempted. - </para> - </listitem> - <listitem> - <para> -<symbol>XcmsInitFailure</symbol> -indicates initialization has been previously attempted but failed. - </para> - </listitem> - <listitem> - <para> -<symbol>XcmsInitSuccess</symbol> -indicates initialization has been previously attempted and succeeded. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The screen free callback must adhere to the following software -interface specification: -</para> -<funcsynopsis> -<funcprototype> - <funcdef>typedef void (*XcmsScreenFreeProc)</funcdef> - <paramdef>XPointer<parameter> screenData</parameter></paramdef> -</funcprototype> -</funcsynopsis> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screenData</emphasis> - </term> - <listitem> - <para> -Specifies the data to be freed. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -This function is called to free the screenData stored in an -<structname>XcmsPerScrnInfo</structname> -structure. -<!-- .bp --> - -</para> -</sect2> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="color_management_functions">
+<title>Color Management Functions</title>
+<!-- .sp 2 -->
+<!-- .nr H1 6 -->
+<!-- .nr H2 0 -->
+<!-- .nr H3 0 -->
+<!-- .nr H4 0 -->
+<!-- .nr H5 0 -->
+<!-- .na -->
+<para>
+<!-- .LP -->
+<!-- .XS -->
+<!-- Chapter 6: Color Management Functions -->
+<!-- .XE -->
+Each X window always has an associated colormap that
+provides a level of indirection between pixel values and colors displayed
+on the screen.
+Xlib provides functions that you can use to manipulate a colormap.
+The X protocol defines colors using values in the <acronym>RGB</acronym> color space.
+The <acronym>RGB</acronym> color space is device dependent;
+rendering an <acronym>RGB</acronym> value on differing output devices typically results
+in different colors.
+Xlib also provides a means for clients to specify color using
+device-independent color spaces for consistent results across devices.
+Xlib supports device-independent color spaces derivable from the <acronym>CIE</acronym> XYZ
+color space.
+This includes the <acronym>CIE</acronym> XYZ, xyY, L*u*v*, and L*a*b* color spaces as well as
+the TekHVC color space.
+</para>
+<para>
+<!-- .LP -->
+This chapter discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Create, copy, and destroy a colormap
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Specify colors by name or value
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Allocate, modify, and free color cells
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Read entries in a colormap
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Convert between color spaces
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Control aspects of color conversion
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Query the color gamut of a screen
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Add new color spaces
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+All functions, types, and symbols in this chapter with the prefix ``Xcms''
+are defined in
+<filename class="headerfile"><X11/Xcms.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xcms.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xcms.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xcms.h></filename></secondary></indexterm>
+The remaining functions and types are defined in
+<filename class="headerfile"><X11/Xlib.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+Functions in this chapter manipulate the representation of color on the
+screen.
+For each possible value that a pixel can take in a window,
+there is a color cell in the colormap.
+For example,
+if a window is 4 bits deep, pixel values 0 through 15 are defined.
+A colormap is a collection of color cells.
+A color cell consists of a triple of red, green, and blue (<acronym>RGB</acronym>) values.
+The hardware imposes limits on the number of significant
+bits in these values.
+As each pixel is read out of display memory, the pixel
+is looked up in a colormap.
+The <acronym>RGB</acronym> value of the cell determines what color is displayed on the screen.
+On a grayscale display with a black-and-white monitor,
+the values are combined to determine the brightness on the screen.
+</para>
+<para>
+<!-- .LP -->
+Typically, an application allocates color cells or sets of color cells
+to obtain the desired colors.
+The client can allocate read-only cells.
+In which case,
+the pixel values for these colors can be shared among multiple applications,
+and the <acronym>RGB</acronym> value of the cell cannot be changed.
+If the client allocates read/write cells,
+they are exclusively owned by the client,
+and the color associated with the pixel value can be changed at will.
+Cells must be allocated (and, if read/write, initialized with an <acronym>RGB</acronym> value)
+by a client to obtain desired colors.
+The use of pixel value for an
+unallocated cell results in an undefined color.
+</para>
+<para>
+<!-- .LP -->
+Because colormaps are associated with windows, X supports displays
+with multiple colormaps and, indeed, different types of colormaps.
+If there are insufficient colormap resources in the display,
+some windows will display in their true colors, and others
+will display with incorrect colors.
+A window manager usually controls which windows are displayed
+in their true colors if more than one colormap is required for
+the color resources the applications are using.
+At any time, there is a set of installed colormaps for a screen.
+Windows using one of the installed colormaps display with true colors, and
+windows using other colormaps generally display with incorrect colors.
+You can control the set of installed colormaps by using
+<function>XInstallColormap</function>
+and
+<function>XUninstallColormap</function>.
+</para>
+<para>
+<!-- .LP -->
+Colormaps are local to a particular screen.
+Screens always have a default colormap,
+and programs typically allocate cells out of this colormap.
+Generally, you should not write applications that monopolize
+color resources.
+Although some hardware supports multiple colormaps installed at one time,
+many of the hardware displays
+built today support only a single installed colormap, so the primitives
+are written to encourage sharing of colormap entries between applications.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>DefaultColormap</function>
+macro returns the default colormap.
+The
+<function>DefaultVisual</function>
+macro
+returns the default visual type for the specified screen.
+<indexterm><primary>Color map</primary></indexterm>
+Possible visual types are
+<symbol>StaticGray</symbol>,
+<symbol>GrayScale</symbol>,
+<symbol>StaticColor</symbol>,
+<symbol>PseudoColor</symbol>,
+<symbol>TrueColor</symbol>,
+or
+<symbol>DirectColor</symbol>
+(see <link linkend="Visual_Types">section 3.1</link>).
+</para>
+<sect1 id="Color_Structures">
+<title>Color Structures</title>
+<!-- .XS -->
+<!-- (SN Color Structures -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Functions that operate only on <acronym>RGB</acronym> color space values use an
+<structname>XColor</structname>
+structure, which contains:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XColor</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ unsigned long pixel; /* pixel value */
+ unsigned short red, green, blue; /* rgb values */
+ char flags; /* DoRed, DoGreen, DoBlue */
+ char pad;
+} XColor;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The red, green, and blue values are always in the range 0 to 65535
+inclusive, independent of the number of bits actually used in the
+display hardware.
+The server scales these values down to the range used by the hardware.
+Black is represented by (0,0,0),
+and white is represented by (65535,65535,65535).
+<indexterm><primary>Color</primary></indexterm>
+In some functions,
+the flags member controls which of the red, green, and blue members is used
+and can be the inclusive OR of zero or more of
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Functions that operate on all color space values use an
+<structname>XcmsColor</structname>
+structure.
+This structure contains a union of substructures,
+each supporting color specification encoding for a particular color space.
+Like the
+<structname>XColor</structname>
+structure, the
+<structname>XcmsColor</structname>
+structure contains pixel
+and color specification information (the spec member in the
+<structname>XcmsColor</structname>
+structure).
+<indexterm significance="preferred"><primary>XcmsColor</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1i 2.5i -->
+<!-- .ta .5i 1i 2.5i -->
+typedef unsigned long XcmsColorFormat; /* Color Specification Format */
+
+typedef struct {
+ union {
+ XcmsRGB RGB;
+ XcmsRGBi RGBi;
+ XcmsCIEXYZ CIEXYZ;
+ XcmsCIEuvY CIEuvY;
+ XcmsCIExyY CIExyY;
+ XcmsCIELab CIELab;
+ XcmsCIELuv CIELuv;
+ XcmsTekHVC TekHVC;
+ XcmsPad Pad;
+ } spec;
+ unsigned long pixel;
+ XcmsColorFormat format;
+} XcmsColor; /* Xcms Color Structure */
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Because the color specification can be encoded for the various color spaces,
+encoding for the spec member is identified by the format member,
+which is of type
+<type>XcmsColorFormat</type>.
+The following macros define standard formats.
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+#define XcmsUndefinedFormat 0x00000000
+#define XcmsCIEXYZFormat 0x00000001 /* CIE XYZ */
+#define XcmsCIEuvYFormat 0x00000002 /* CIE u'v'Y */
+#define XcmsCIExyYFormat 0x00000003 /* CIE xyY */
+#define XcmsCIELabFormat 0x00000004 /* CIE L*a*b* */
+#define XcmsCIELuvFormat 0x00000005 /* CIE L*u*v* */
+#define XcmsTekHVCFormat 0x00000006 /* TekHVC */
+#define XcmsRGBFormat 0x80000000 /* RGB Device */
+#define XcmsRGBiFormat 0x80000001 /* RGB Intensity */
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Formats for device-independent color spaces are
+distinguishable from those for device-dependent spaces by the 32nd bit.
+If this bit is set,
+it indicates that the color specification is in a device-dependent form;
+otherwise, it is in a device-independent form.
+If the 31st bit is set,
+this indicates that the color space has been added to Xlib at run time
+(see <link linkend="Creating_Additional_Color_Spaces">section 6.12.4</link>).
+The format value for a color space added at run time may be different each
+time the program is executed.
+If references to such a color space must be made outside the client
+(for example, storing a color specification in a file),
+then reference should be made by color space string prefix
+(see
+<function>XcmsFormatOfPrefix</function>
+and
+<function>XcmsPrefixOfFormat</function>).
+</para>
+<para>
+<!-- .LP -->
+Data types that describe the color specification encoding for the various
+color spaces are defined as follows:
+<!-- .sM -->
+<indexterm significance="preferred"><primary>XcmsRGB</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef double XcmsFloat;
+
+typedef struct {
+ unsigned short red; /* 0x0000 to 0xffff */
+ unsigned short green; /* 0x0000 to 0xffff */
+ unsigned short blue; /* 0x0000 to 0xffff */
+} XcmsRGB; /* RGB Device */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsRGBi</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat red; /* 0.0 to 1.0 */
+ XcmsFloat green; /* 0.0 to 1.0 */
+ XcmsFloat blue; /* 0.0 to 1.0 */
+} XcmsRGBi; /* RGB Intensity */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsCIEXYZ</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat X;
+ XcmsFloat Y; /* 0.0 to 1.0 */
+ XcmsFloat Z;
+} XcmsCIEXYZ; /* CIE XYZ */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsCIEuvY</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat u_prime; /* 0.0 to ~0.6 */
+ XcmsFloat v_prime; /* 0.0 to ~0.6 */
+ XcmsFloat Y; /* 0.0 to 1.0 */
+} XcmsCIEuvY; /* CIE u'v'Y */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsCIExyY</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat x; /* 0.0 to ~.75 */
+ XcmsFloat y; /* 0.0 to ~.85 */
+ XcmsFloat Y; /* 0.0 to 1.0 */
+} XcmsCIExyY; /* CIE xyY */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsCIELab</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat L_star; /* 0.0 to 100.0 */
+ XcmsFloat a_star;
+ XcmsFloat b_star;
+} XcmsCIELab; /* CIE L*a*b* */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsCIELuv</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat L_star; /* 0.0 to 100.0 */
+ XcmsFloat u_star;
+ XcmsFloat v_star;
+} XcmsCIELuv; /* CIE L*u*v* */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsTekHVC</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat H; /* 0.0 to 360.0 */
+ XcmsFloat V; /* 0.0 to 100.0 */
+ XcmsFloat C; /* 0.0 to 100.0 */
+} XcmsTekHVC; /* TekHVC */
+</literallayout>
+<indexterm significance="preferred"><primary>XcmsPad</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ XcmsFloat pad0;
+ XcmsFloat pad1;
+ XcmsFloat pad2;
+ XcmsFloat pad3;
+} XcmsPad; /* four doubles */
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The device-dependent formats provided allow color specification in:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<acronym>RGB</acronym> Intensity
+(<structname>XcmsRGBi</structname>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Red, green, and blue linear intensity values,
+floating-point values from 0.0 to 1.0,
+where 1.0 indicates full intensity, 0.5 half intensity, and so on.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<acronym>RGB</acronym> Device
+(<structname>XcmsRGB</structname>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Red, green, and blue values appropriate for the specified output device.
+<structname>XcmsRGB</structname>
+values are of type unsigned short,
+scaled from 0 to 65535 inclusive,
+and are interchangeable with the red, green, and blue values in an
+<structname>XColor</structname>
+structure.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+It is important to note that <acronym>RGB</acronym> Intensity values are not gamma corrected
+values.
+In contrast,
+<acronym>RGB</acronym> Device values generated as a result of converting color specifications
+are always gamma corrected, and
+<acronym>RGB</acronym> Device values acquired as a result of querying a colormap
+or passed in by the client are assumed by Xlib to be gamma corrected.
+The term <emphasis remap='I'><acronym>RGB</acronym> value</emphasis> in this manual always refers to an <acronym>RGB</acronym> Device value.
+</para>
+</sect1>
+<sect1 id="Color_Strings">
+<title>Color Strings</title>
+<!-- .XS -->
+<!-- (SN Color Strings -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides a mechanism for using string names for colors.
+A color string may either contain an abstract color name
+or a numerical color specification.
+Color strings are case-insensitive.
+</para>
+<para>
+<!-- .LP -->
+Color strings are used in the following functions:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<function>XAllocNamedColor</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsAllocNamedColor</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XLookupColor</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsLookupColor</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XParseColor</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XStoreNamedColor</function>
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Xlib supports the use of abstract color names, for example, red or blue.
+A value for this abstract name is obtained by searching one or more color
+name databases.
+Xlib first searches zero or more client-side databases;
+the number, location, and content of these databases is
+implementation-dependent and might depend on the current locale.
+If the name is not found, Xlib then looks for the color in the
+X server's database.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+A numerical color specification
+consists of a color space name and a set of values in the following syntax:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<emphasis remap='I'><color_space_name></emphasis>:<emphasis remap='I'><value>/.../<value></emphasis>
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The following are examples of valid color strings.
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+"CIEXYZ:0.3227/0.28133/0.2493"
+"RGBi:1.0/0.0/0.0"
+"rgb:00/ff/00"
+"CIELuv:50.0/0.0/0.0"
+</literallayout>
+The syntax and semantics of numerical specifications are given
+for each standard color space in the following sections.
+</para>
+<sect2 id="RGB_Device_String_Specification">
+<title><acronym>RGB</acronym> Device String Specification</title>
+<!-- .XS -->
+<!-- (SN <acronym>RGB</acronym> Device String Specification -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An <acronym>RGB</acronym> Device specification is identified by
+the prefix ``rgb:'' and conforms to the following syntax:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+rgb:<emphasis remap='I'><red>/<green>/<blue></emphasis>
+
+ <emphasis remap='I'><red></emphasis>, <emphasis remap='I'><green></emphasis>, <emphasis remap='I'><blue></emphasis> := <emphasis remap='I'>h</emphasis> | <emphasis remap='I'>hh</emphasis> | <emphasis remap='I'>hhh</emphasis> | <emphasis remap='I'>hhhh</emphasis>
+ <emphasis remap='I'>h</emphasis> := single hexadecimal digits (case insignificant)
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+Note that <emphasis remap='I'>h</emphasis> indicates the value scaled in 4 bits,
+<emphasis remap='I'>hh</emphasis> the value scaled in 8 bits,
+<emphasis remap='I'>hhh</emphasis> the value scaled in 12 bits,
+and <emphasis remap='I'>hhhh</emphasis> the value scaled in 16 bits, respectively.
+</para>
+<para>
+<!-- .LP -->
+Typical examples are the strings ``rgb:ea/75/52'' and ``rgb:ccc/320/320'',
+but mixed numbers of hexadecimal digit strings
+(``rgb:ff/a5/0'' and ``rgb:ccc/32/0'')
+are also allowed.
+</para>
+<para>
+<!-- .LP -->
+For backward compatibility, an older syntax for <acronym>RGB</acronym> Device is
+supported, but its continued use is not encouraged.
+The syntax is an initial sharp sign character followed by
+a numeric specification, in one of the following formats:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+<!-- .TA 2i -->
+<!-- .ta 2i -->
+#RGB (4 bits each)
+#RRGGBB (8 bits each)
+#RRRGGGBBB (12 bits each)
+#RRRRGGGGBBBB (16 bits each)
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+The R, G, and B represent single hexadecimal digits.
+When fewer than 16 bits each are specified,
+they represent the most significant bits of the value
+(unlike the ``rgb:'' syntax, in which values are scaled).
+For example, the string ``#3a7'' is the same as ``#3000a0007000''.
+</para>
+</sect2>
+<sect2 id="RGB_Intensity_String_Specification">
+<title><acronym>RGB</acronym> Intensity String Specification</title>
+<!-- .XS -->
+<!-- (SN RGB Intensity String Specification -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An <acronym>RGB</acronym> intensity specification is identified
+by the prefix ``rgbi:'' and conforms to the following syntax:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+rgbi:<emphasis remap='I'><red>/<green>/<blue></emphasis>
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+Note that red, green, and blue are floating-point values
+between 0.0 and 1.0, inclusive.
+The input format for these values is an optional sign,
+a string of numbers possibly containing a decimal point,
+and an optional exponent field containing an E or e
+followed by a possibly signed integer string.
+</para>
+</sect2>
+<sect2 id="Device_Independent_String_Specifications">
+<title>Device-Independent String Specifications</title>
+<!-- .XS -->
+<!-- (SN Device-Independent String Specifications -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The standard device-independent string specifications have
+the following syntax:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+CIEXYZ:<emphasis remap='I'><X>/<Y>/<Z></emphasis>
+CIEuvY:<emphasis remap='I'><u>/<v>/<Y></emphasis>
+CIExyY:<emphasis remap='I'><x>/<y>/<Y></emphasis>
+CIELab:<emphasis remap='I'><L>/<a>/<b></emphasis>
+CIELuv:<emphasis remap='I'><L>/<u>/<v></emphasis>
+TekHVC:<emphasis remap='I'><H>/<V>/<C></emphasis>
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+All of the values (C, H, V, X, Y, Z, a, b, u, v, y, x) are
+floating-point values.
+The syntax for these values is an optional plus or minus sign,
+a string of digits possibly containing a decimal point,
+and an optional exponent field consisting of an ``E'' or ``e''
+followed by an optional plus or minus followed by a string of digits.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Color_Conversion_Contexts_and_Gamut_Mapping">
+<title>Color Conversion Contexts and Gamut Mapping</title>
+<!-- .XS -->
+<!-- (SN Color Conversion Contexts and Gamut Mapping -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When Xlib converts device-independent color specifications
+into device-dependent specifications and vice versa,
+it uses knowledge about the color limitations of the screen hardware.
+This information, typically called the device profile,
+<indexterm><primary>Device profile</primary></indexterm>
+is available in a Color Conversion Context (CCC).
+<indexterm><primary>Color Conversion Context</primary></indexterm>
+<indexterm><primary>CCC</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+Because a specified color may be outside the color gamut of the target screen
+and the white point associated with the color specification may differ
+from the white point inherent to the screen,
+Xlib applies gamut mapping when it encounters certain conditions:
+<indexterm><primary>White point</primary></indexterm>
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Gamut compression occurs when conversion of device-independent
+color specifications to device-dependent color specifications
+results in a color out of the target screen's gamut.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+White adjustment occurs when the inherent white point of the screen
+differs from the white point assumed by the client.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Gamut handling methods are stored as callbacks in the CCC,
+which in turn are used by the color space conversion routines.
+Client data is also stored in the CCC for each callback.
+The CCC also contains the white point the client assumes to be
+associated with color specifications (that is, the Client White Point).
+<indexterm><primary>Client White Point</primary></indexterm>
+<indexterm><primary>Gamut compression</primary></indexterm>
+<indexterm><primary>Gamut handling</primary></indexterm>
+<indexterm><primary>White point adjustment</primary></indexterm>
+The client can specify the gamut handling callbacks and client data
+as well as the Client White Point.
+Xlib does not preclude the X client from performing other
+forms of gamut handling (for example, gamut expansion);
+however, Xlib does not provide direct support for gamut handling
+other than white adjustment and gamut compression.
+</para>
+<para>
+<!-- .LP -->
+Associated with each colormap is an initial CCC transparently generated by
+Xlib.
+<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm>
+Therefore,
+when you specify a colormap as an argument to an Xlib function,
+you are indirectly specifying a CCC.
+<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm>
+There is a default CCC associated with each screen.
+Newly created CCCs inherit attributes from the default CCC,
+so the default CCC attributes can be modified to affect new CCCs.
+<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+Xcms functions in which gamut mapping can occur return
+<type>Status</type>
+and have specific status values defined for them,
+as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<symbol>XcmsFailure</symbol>
+indicates that the function failed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>XcmsSuccess</symbol>
+indicates that the function succeeded.
+In addition,
+if the function performed any color conversion,
+the colors did not need to be compressed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>XcmsSuccessWithCompression</symbol>
+indicates the function performed color conversion
+and at least one of the colors needed to be compressed.
+The gamut compression method is determined by the gamut compression
+procedure in the CCC that is specified directly as a function argument
+or in the CCC indirectly specified by means of the colormap argument.
+ </para>
+ </listitem>
+</itemizedlist>
+</sect1>
+<sect1 id="Creating_Copying_and_Destroying_Colormaps">
+<title>Creating, Copying, and Destroying Colormaps</title>
+<!-- .XS -->
+<!-- (SN Creating, Copying, and Destroying Colormaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To create a colormap for a screen, use
+<function>XCreateColormap</function>.</para>
+<indexterm significance="preferred"><primary>XCreateColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatecolormap'>
+<funcprototype>
+ <funcdef>Colormap <function>XCreateColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Visual<parameter> *visual</parameter></paramdef>
+ <paramdef>int<parameter> alloc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi on whose screen you want to create a colormap -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>visual</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a visual type supported on the screen.
+If the visual type is not one supported by the screen,
+a
+<errorname>BadMatch</errorname>
+error results.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>alloc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap entries to be allocated.
+You can pass
+<symbol>AllocNone</symbol>
+or
+<symbol>AllocAll</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateColormap</function>
+function creates a colormap of the specified visual type for the screen
+on which the specified window resides and returns the colormap ID
+associated with it.
+Note that the specified window is only used to determine the screen.
+</para>
+<para>
+<!-- .LP -->
+The initial values of the colormap entries are undefined for the
+visual classes
+<symbol>GrayScale</symbol>,
+<symbol>PseudoColor</symbol>,
+and
+<symbol>DirectColor</symbol>.
+For
+<symbol>StaticGray</symbol>,
+<symbol>StaticColor</symbol>,
+and
+<symbol>TrueColor</symbol>,
+the entries have defined values,
+but those values are specific to the visual and are not defined by X.
+For
+<symbol>StaticGray</symbol>,
+<symbol>StaticColor</symbol>,
+and
+<symbol>TrueColor</symbol>,
+alloc must be
+<symbol>AllocNone</symbol>,
+or a
+<errorname>BadMatch</errorname>
+error results.
+For the other visual classes,
+if alloc is
+<symbol>AllocNone</symbol>,
+the colormap initially has no allocated entries,
+and clients can allocate them.
+For information about the visual types,
+see <link linkend="Visual_Types">section 3.1</link>.
+</para>
+<para>
+<!-- .LP -->
+If alloc is
+<symbol>AllocAll</symbol>,
+the entire colormap is allocated writable.
+The initial values of all allocated entries are undefined.
+For
+<symbol>GrayScale</symbol>
+and
+<symbol>PseudoColor</symbol>,
+the effect is as if an
+<function>XAllocColorCells</function>
+call returned all pixel values from zero to N - 1,
+where N is the colormap entries value in the specified visual.
+For
+<symbol>DirectColor</symbol>,
+the effect is as if an
+<function>XAllocColorPlanes</function>
+call returned a pixel value of zero and red_mask, green_mask,
+and blue_mask values containing the same bits as the corresponding
+masks in the specified visual.
+However, in all cases,
+none of these entries can be freed by using
+<function>XFreeColors</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateColormap</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a new colormap when the allocation out of a previously
+shared colormap has failed because of resource exhaustion, use
+<function>XCopyColormapAndFree</function>.
+</para>
+<indexterm significance="preferred"><primary>XCopyColormapAndFree</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcopycolormapandfree'>
+<funcprototype>
+ <funcdef>Colormap <function>XCopyColormapAndFree</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCopyColormapAndFree</function>
+function creates a colormap of the same visual type and for the same screen
+as the specified colormap and returns the new colormap ID.
+It also moves all of the client's existing allocation from the specified
+colormap to the new colormap with their color values intact
+and their read-only or writable characteristics intact and frees those entries
+in the specified colormap.
+Color values in other entries in the new colormap are undefined.
+If the specified colormap was created by the client with alloc set to
+<symbol>AllocAll</symbol>,
+the new colormap is also created with
+<symbol>AllocAll</symbol>,
+all color values for all entries are copied from the specified colormap,
+and then all entries in the specified colormap are freed.
+If the specified colormap was not created by the client with
+<symbol>AllocAll</symbol>,
+the allocations to be moved are all those pixels and planes
+that have been allocated by the client using
+<function>XAllocColor</function>,
+<function>XAllocNamedColor</function>,
+<function>XAllocColorCells</function>,
+or
+<function>XAllocColorPlanes</function>
+and that have not been freed since they were allocated.
+</para>
+<para>
+<!-- .LP -->
+<function>XCopyColormapAndFree</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadColor</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy a colormap, use
+<function>XFreeColormap</function>.
+<indexterm significance="preferred"><primary>XFreeColormap</primary></indexterm>
+</para>
+<!-- .sM -->
+<funcsynopsis id='xfreecolormap'>
+<funcprototype>
+ <funcdef><function>XFreeColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Cm that you want to destroy -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap (Cm.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeColormap</function>
+function deletes the association between the colormap resource ID
+and the colormap and frees the colormap storage.
+However, this function has no effect on the default colormap for a screen.
+If the specified colormap is an installed map for a screen,
+it is uninstalled (see
+<function>XUninstallColormap</function>).
+If the specified colormap is defined as the colormap for a window (by
+<function>XCreateWindow</function>,
+<function>XSetWindowColormap</function>,
+or
+<function>XChangeWindowAttributes</function>),
+<function>XFreeColormap</function>
+changes the colormap associated with the window to
+<symbol>None</symbol>
+and generates a
+<symbol>ColormapNotify</symbol>
+event.
+X does not define the colors displayed for a window with a colormap of
+<symbol>None</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreeColormap</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Mapping_Color_Names_to_Values">
+<title>Mapping Color Names to Values</title>
+<!-- .XS -->
+<!-- (SN Mapping Color Names to Values -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map a color name to an <acronym>RGB</acronym> value, use
+<function>XLookupColor</function>.
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm significance="preferred"><primary>XLookupColor</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xlookupcolor'>
+<funcprototype>
+ <funcdef>Status <function>XLookupColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *color_name</parameter></paramdef>
+ <paramdef>XColor*exact_def_return,<parameter> *screen_def_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color name string (for example, red) whose color
+definition structure you want returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>exact_def_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the exact <acronym>RGB</acronym> values.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_def_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the closest <acronym>RGB</acronym> values provided by the hardware.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLookupColor</function>
+function looks up the string name of a color with respect to the screen
+associated with the specified colormap.
+It returns both the exact color values and
+the closest values provided by the screen
+with respect to the visual type of the specified colormap.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+<function>XLookupColor</function>
+returns nonzero if the name is resolved;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+<function>XLookupColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map a color name to the exact <acronym>RGB</acronym> value, use
+<function>XParseColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm significance="preferred"><primary>XParseColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xparsecolor'>
+<funcprototype>
+ <funcdef>Status <function>XParseColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *spec</parameter></paramdef>
+ <paramdef>XColor<parameter> *exact_def_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>spec</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color name string;
+case is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>exact_def_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the exact color value for later use and sets the
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>
+flags.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XParseColor</function>
+function looks up the string name of a color with respect to the screen
+associated with the specified colormap.
+It returns the exact color value.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+<function>XParseColor</function>
+returns nonzero if the name is resolved;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+<function>XParseColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map a color name to a value in an arbitrary color space, use
+<function>XcmsLookupColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsLookupColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmslookupcolor'>
+<funcprototype>
+ <funcdef>Status <function>XcmsLookupColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *color_string</parameter></paramdef>
+ <paramdef>XcmsColor*color_exact_return,<parameter> *color_screen_return</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+<!-- .ds St -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color string(St.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_exact_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification parsed from the color string
+or parsed from the corresponding string found in a color-name database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_screen_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color that can be reproduced on the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>result_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color format for the returned color
+specifications (color_screen_return and color_exact_return arguments).
+If the format is
+<symbol>XcmsUndefinedFormat</symbol>
+and the color string contains a
+numerical color specification,
+the specification is returned in the format used in that numerical
+color specification.
+If the format is
+<symbol>XcmsUndefinedFormat</symbol>
+and the color string contains a color name,
+the specification is returned in the format used
+to store the color in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsLookupColor</function>
+function looks up the string name of a color with respect to the screen
+associated with the specified colormap.
+It returns both the exact color values and
+the closest values provided by the screen
+with respect to the visual type of the specified colormap.
+The values are returned in the format specified by result_format.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+<function>XcmsLookupColor</function>
+returns
+<symbol>XcmsSuccess</symbol>
+or
+<symbol>XcmsSuccessWithCompression</symbol>
+if the name is resolved; otherwise, it returns
+<symbol>XcmsFailure</symbol>.
+If
+<symbol>XcmsSuccessWithCompression</symbol>
+is returned, the color specification returned in
+color_screen_return is the result of gamut compression.
+</para>
+</sect1>
+
+<sect1 id="Allocating_and_Freeing_Color_Cells">
+<title>Allocating and Freeing Color Cells</title>
+<!-- .XS -->
+<!-- (SN Allocating and Freeing Color Cells -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+There are two ways of allocating color cells:
+explicitly as read-only entries, one pixel value at a time,
+or read/write,
+where you can allocate a number of color cells and planes simultaneously.
+<indexterm><primary>Read-only colormap cells</primary></indexterm>
+A read-only cell has its <acronym>RGB</acronym> value set by the server.
+<indexterm><primary>Read/write colormap cells</primary></indexterm>
+Read/write cells do not have defined colors initially;
+functions described in the next section must be used to store values into them.
+Although it is possible for any client to store values into a read/write
+cell allocated by another client,
+read/write cells normally should be considered private to the client
+that allocated them.
+</para>
+<para>
+<!-- .LP -->
+Read-only colormap cells are shared among clients.
+The server counts each allocation and freeing of the cell by clients.
+When the last client frees a shared cell, the cell is finally deallocated.
+If a single client allocates the same read-only cell multiple
+times, the server counts each such allocation, not just the first one.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a read-only color cell with an <acronym>RGB</acronym> value, use
+<function>XAllocColor</function>.
+</para>
+<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm>
+<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XAllocColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xalloccolor'>
+<funcprototype>
+ <funcdef>Status <function>XAllocColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XColor<parameter> *screen_in_out</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies and returns the values actually used in the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocColor</function>
+function allocates a read-only colormap entry corresponding to the closest
+<acronym>RGB</acronym> value supported by the hardware.
+<function>XAllocColor</function>
+returns the pixel value of the color closest to the specified
+<acronym>RGB</acronym> elements supported by the hardware
+and returns the <acronym>RGB</acronym> value actually used.
+The corresponding colormap cell is read-only.
+In addition,
+<function>XAllocColor</function>
+returns nonzero if it succeeded or zero if it failed.
+<indexterm><primary>Color map</primary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm><primary>Allocation</primary><secondary>colormap</secondary></indexterm>
+<indexterm><primary>read-only colormap cells</primary></indexterm>
+Multiple clients that request the same effective <acronym>RGB</acronym> value can be assigned
+the same read-only entry, thus allowing entries to be shared.
+When the last client deallocates a shared cell, it is deallocated.
+<function>XAllocColor</function>
+does not use or affect the flags in the
+<structname>XColor</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<function>XAllocColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+<!-- .EQ -->
+delim %%
+<!-- .EN -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a read-only color cell with a color in arbitrary format, use
+<function>XcmsAllocColor</function>.
+</para>
+<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm>
+<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsAllocColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsalloccolor'>
+<funcprototype>
+ <funcdef>Status <function>XcmsAllocColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_in_out</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color to allocate and returns the pixel and color
+that is actually used in the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>result_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color format for the returned color specification.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsAllocColor</function>
+function is similar to
+<function>XAllocColor</function>
+except the color can be specified in any format.
+The
+<function>XcmsAllocColor</function>
+function ultimately calls
+<function>XAllocColor</function>
+to allocate a read-only color cell (colormap entry) with the specified color.
+<function>XcmsAllocColor</function>
+first converts the color specified
+to an <acronym>RGB</acronym> value and then passes this to
+<function>XAllocColor</function>.
+<function>XcmsAllocColor</function>
+returns the pixel value of the color cell and the color specification
+actually allocated.
+This returned color specification is the result of converting the <acronym>RGB</acronym> value
+returned by
+<function>XAllocColor</function>
+into the format specified with the result_format argument.
+If there is no interest in a returned color specification,
+unnecessary computation can be bypassed if result_format is set to
+<symbol>XcmsRGBFormat</symbol>.
+The corresponding colormap cell is read-only.
+If this routine returns
+<symbol>XcmsFailure</symbol>,
+the color_in_out color specification is left unchanged.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsAllocColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a read-only color cell using a color name and return the closest
+color supported by the hardware in <acronym>RGB</acronym> format, use
+<function>XAllocNamedColor</function>.
+</para>
+<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm>
+<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XAllocNamedColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xallocnamedcolor'>
+<funcprototype>
+ <funcdef>Status <function>XAllocNamedColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *color_name</parameter></paramdef>
+ <paramdef>XColor*screen_def_return,<parameter> *exact_def_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color name string (for example, red) whose color
+definition structure you want returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_def_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the closest <acronym>RGB</acronym> values provided by the hardware.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>exact_def_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the exact <acronym>RGB</acronym> values.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocNamedColor</function>
+function looks up the named color with respect to the screen that is
+associated with the specified colormap.
+It returns both the exact database definition and
+the closest color supported by the screen.
+The allocated color cell is read-only.
+The pixel value is returned in screen_def_return.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+If screen_def_return and exact_def_return
+point to the same structure, the pixel field will be set correctly,
+but the color values are undefined.
+<function>XAllocNamedColor</function>
+returns nonzero if a cell is allocated;
+otherwise, it returns zero.
+</para>
+<para>
+<!-- .LP -->
+<function>XAllocNamedColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a read-only color cell using a color name and return the closest
+color supported by the hardware in an arbitrary format, use
+<function>XcmsAllocNamedColor</function>.
+</para>
+<indexterm><primary>Allocation</primary><secondary>read-only colormap cells</secondary></indexterm>
+<indexterm><primary>Read-only colormap cells</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsAllocNamedColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsallocnamedcolor'>
+<funcprototype>
+ <funcdef>Status <function>XcmsAllocNamedColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *color_string</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_screen_return</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_exact_return</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+<!-- .ds St \ whose color definition structure is to be returned -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color string(St.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_screen_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the pixel value of the color cell and color specification
+that actually is stored for that cell.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_exact_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification parsed from the color string
+or parsed from the corresponding string found in a color-name database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>result_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color format for the returned color
+specifications (color_screen_return and color_exact_return arguments).
+If the format is
+<symbol>XcmsUndefinedFormat</symbol>
+and the color string contains a
+numerical color specification,
+the specification is returned in the format used in that numerical
+color specification.
+If the format is
+<symbol>XcmsUndefinedFormat</symbol>
+and the color string contains a color name,
+the specification is returned in the format used
+to store the color in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsAllocNamedColor</function>
+function is similar to
+<function>XAllocNamedColor</function>
+except that the color returned can be in any format specified.
+This function
+ultimately calls
+<function>XAllocColor</function>
+to allocate a read-only color cell with
+the color specified by a color string.
+The color string is parsed into an
+<structname>XcmsColor</structname>
+structure (see
+<function>XcmsLookupColor</function>),
+converted
+to an <acronym>RGB</acronym> value, and finally passed to
+<function>XAllocColor</function>.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+</para>
+<para>
+<!-- .LP -->
+This function returns both the color specification as a result
+of parsing (exact specification) and the actual color specification
+stored (screen specification).
+This screen specification is the result of converting the <acronym>RGB</acronym> value
+returned by
+<function>XAllocColor</function>
+into the format specified in result_format.
+If there is no interest in a returned color specification,
+unnecessary computation can be bypassed if result_format is set to
+<symbol>XcmsRGBFormat</symbol>.
+If color_screen_return and color_exact_return
+point to the same structure, the pixel field will be set correctly,
+but the color values are undefined.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsAllocNamedColor</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate read/write color cell and color plane combinations for a
+<symbol>PseudoColor</symbol>
+model, use
+<function>XAllocColorCells</function>.
+</para>
+<indexterm><primary>Read/write colormap cells</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Allocation</primary><secondary>read/write colormap cells</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XAllocColorCells</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xalloccolorcells'>
+<funcprototype>
+ <funcdef>Status <function>XAllocColorCells</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>Bool<parameter> contig</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane_masks_return[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> nplanes</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> pixels_return[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> npixels</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>contig</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the planes must be contiguous.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane_mask_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of plane masks.
+<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nplanes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of plane masks that are to be returned in the plane masks
+array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixels_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of pixel values.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npixels</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of pixel values that are to be returned in the
+pixels_return array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocColorCells</function>
+function allocates read/write color cells.
+The number of colors must be positive and the number of planes nonnegative,
+or a
+<errorname>BadValue</errorname>
+error results.
+If ncolors and nplanes are requested,
+then ncolors pixels
+and nplane plane masks are returned.
+No mask will have any bits set to 1 in common with
+any other mask or with any of the pixels.
+By ORing together each pixel with zero or more masks,
+ncolors × 2<superscript><emphasis>nplanes</emphasis></superscript>
+distinct pixels can be produced.
+All of these are
+allocated writable by the request.
+For
+<symbol>GrayScale</symbol>
+or
+<symbol>PseudoColor</symbol>,
+each mask has exactly one bit set to 1.
+For
+<symbol>DirectColor</symbol>,
+each has exactly three bits set to 1.
+If contig is
+<symbol>True</symbol>
+and if all masks are ORed
+together, a single contiguous set of bits set to 1 will be formed for
+<symbol>GrayScale</symbol>
+or
+<symbol>PseudoColor</symbol>
+and three contiguous sets of bits set to 1 (one within each
+pixel subfield) for
+<symbol>DirectColor</symbol>.
+The <acronym>RGB</acronym> values of the allocated
+entries are undefined.
+<function>XAllocColorCells</function>
+returns nonzero if it succeeded or zero if it failed.
+</para>
+<para>
+<!-- .LP -->
+<function>XAllocColorCells</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate read/write color resources for a
+<symbol>DirectColor</symbol>
+model, use
+<function>XAllocColorPlanes</function>.
+</para>
+<indexterm><primary>Read/write colormap planes</primary><secondary>allocating</secondary></indexterm>
+<indexterm><primary>Allocation</primary><secondary>read/write colormap planes</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>allocation</secondary></indexterm>
+<indexterm significance="preferred"><primary>XAllocColorPlanes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xalloccolorplanes'>
+<funcprototype>
+ <funcdef>Status <function>XAllocColorPlanes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>Bool<parameter> contig</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> pixels_return[]</parameter></paramdef>
+ <paramdef>int<parameter> ncolors</parameter></paramdef>
+ <paramdef>intnreds,ngreens,<parameter> nblues</parameter></paramdef>
+ <paramdef>unsignedlong*rmask_return,*gmask_return,<parameter> *bmask_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>contig</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the planes must be contiguous.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixels_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of pixel values.
+<function>XAllocColorPlanes</function>
+returns the pixel values in this array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of pixel values that are to be returned in the
+pixels_return array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nreds</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ngreens</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nblues</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+Specify the number of red, green, and blue planes.
+The value you pass must be nonnegative.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rmask_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gmask_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bmask_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return bit masks for the red, green, and blue planes.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The specified ncolors must be positive;
+and nreds, ngreens, and nblues must be nonnegative,
+or a
+<errorname>BadValue</errorname>
+error results.
+If ncolors colors, nreds reds, ngreens greens, and nblues blues are requested,
+ncolors pixels are returned; and the masks have nreds, ngreens, and
+nblues bits set to 1, respectively.
+If contig is
+<symbol>True</symbol>,
+each mask will have
+a contiguous set of bits set to 1.
+No mask will have any bits set to 1 in common with
+any other mask or with any of the pixels.
+For
+<symbol>DirectColor</symbol>,
+each mask
+will lie within the corresponding pixel subfield.
+By ORing together
+subsets of masks with each pixel value,
+ncolors × 2<superscript><emphasis>(nreds+ngreens+nblues)</emphasis></superscript>
+distinct pixel values can be produced.
+All of these are allocated by the request.
+However, in the
+colormap, there are only
+ncolors × 2<superscript><emphasis>nreds</emphasis></superscript>
+independent red entries,
+ncolors × 2<superscript><emphasis>ngreens</emphasis></superscript>
+independent green entries, and
+ncolors × 2<superscript><emphasis>nblues</emphasis></superscript>
+independent blue entries.
+This is true even for
+<symbol>PseudoColor</symbol>.
+When the colormap entry of a pixel
+value is changed (using
+<function>XStoreColors</function>,
+<function>XStoreColor</function>,
+or
+<function>XStoreNamedColor</function>),
+the pixel is decomposed according to the masks,
+and the corresponding independent entries are updated.
+<function>XAllocColorPlanes</function>
+returns nonzero if it succeeded or zero if it failed.
+</para>
+<para>
+<!-- .LP -->
+<function>XAllocColorPlanes</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm><primary>Freeing</primary><secondary>colors</secondary></indexterm>
+To free colormap cells, use
+<function>XFreeColors</function>.
+<indexterm significance="preferred"><primary>XFreeColors</primary></indexterm>
+<indexterm><primary>Color</primary><secondary>deallocation</secondary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis id='xfreecolors'>
+<funcprototype>
+ <funcdef><function>XFreeColors</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> pixels[]</parameter></paramdef>
+ <paramdef>int<parameter> npixels</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> planes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+<!-- .ds Pi that map to the cells in the specified colormap -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixels</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of pixel values (Pi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npixels</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>planes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the planes you want to free.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeColors</function>
+function frees the cells represented by pixels whose values are in the
+pixels array.
+The planes argument should not have any bits set to 1 in common with any of the
+pixels.
+The set of all pixels is produced by ORing together subsets of
+the planes argument with the pixels.
+The request frees all of these pixels that
+were allocated by the client (using
+<indexterm><primary>XAllocColor</primary></indexterm>
+<indexterm><primary>XAllocNamedColor</primary></indexterm>
+<indexterm><primary>XAllocColorCells</primary></indexterm>
+<indexterm><primary>XAllocColorPlanes</primary></indexterm>
+<function>XAllocColor</function>,
+<function>XAllocNamedColor</function>,
+<function>XAllocColorCells</function>,
+and
+<function>XAllocColorPlanes</function>).
+Note that freeing an
+individual pixel obtained from
+<function>XAllocColorPlanes</function>
+may not actually allow
+it to be reused until all of its related pixels are also freed.
+Similarly,
+a read-only entry is not actually freed until it has been freed by all clients,
+and if a client allocates the same read-only entry multiple times,
+it must free the entry that many times before the entry is actually freed.
+</para>
+<para>
+<!-- .LP -->
+All specified pixels that are allocated by the client in the colormap are
+freed, even if one or more pixels produce an error.
+If a specified pixel is not a valid index into the colormap, a
+<errorname>BadValue</errorname>
+error results.
+If a specified pixel is not allocated by the
+client (that is, is unallocated or is only allocated by another client)
+or if the colormap was created with all entries writable (by passing
+<symbol>AllocAll</symbol>
+to
+<function>XCreateColormap</function>),
+a
+<errorname>BadAccess</errorname>
+error results.
+If more than one pixel is in error,
+the one that gets reported is arbitrary.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreeColors</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Modifying_and_Querying_Colormap_Cells">
+<title>Modifying and Querying Colormap Cells</title>
+<!-- .XS -->
+<!-- (SN Modifying and Querying Colormap Cells -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store an <acronym>RGB</acronym> value in a single colormap cell, use
+<function>XStoreColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XStoreColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorecolor'>
+<funcprototype>
+ <funcdef><function>XStoreColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XColor<parameter> *color</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pixel and <acronym>RGB</acronym> values.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XStoreColor</function>
+function changes the colormap entry of the pixel value specified in the
+pixel member of the
+<structname>XColor</structname>
+structure.
+You specified this value in the
+pixel member of the
+<structname>XColor</structname>
+structure.
+This pixel value must be a read/write cell and a valid index into the colormap.
+If a specified pixel is not a valid index into the colormap,
+a
+<errorname>BadValue</errorname>
+error results.
+<function>XStoreColor</function>
+also changes the red, green, and/or blue color components.
+You specify which color components are to be changed by setting
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and/or
+<symbol>DoBlue</symbol>
+in the flags member of the
+<structname>XColor</structname>
+structure.
+If the colormap is an installed map for its screen,
+the changes are visible immediately.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreColor</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store multiple <acronym>RGB</acronym> values in multiple colormap cells, use
+<function>XStoreColors</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XStoreColors</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorecolors'>
+<funcprototype>
+ <funcdef><function>XStoreColors</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XColor<parameter> color[]</parameter></paramdef>
+ <paramdef>int<parameter> ncolors</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color definition structures to be stored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .\"Specifies the number of color definition structures. -->
+Specifies the number of
+<structname>XColor</structname>
+structures in the color definition array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XStoreColors</function>
+function changes the colormap entries of the pixel values
+specified in the pixel members of the
+<structname>XColor</structname>
+structures.
+You specify which color components are to be changed by setting
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and/or
+<symbol>DoBlue</symbol>
+in the flags member of the
+<structname>XColor</structname>
+structures.
+If the colormap is an installed map for its screen, the
+changes are visible immediately.
+<function>XStoreColors</function>
+changes the specified pixels if they are allocated writable in the colormap
+by any client, even if one or more pixels generates an error.
+If a specified pixel is not a valid index into the colormap, a
+<errorname>BadValue</errorname>
+error results.
+If a specified pixel either is unallocated or is allocated read-only, a
+<errorname>BadAccess</errorname>
+error results.
+If more than one pixel is in error,
+the one that gets reported is arbitrary.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreColors</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store a color of arbitrary format in a single colormap cell, use
+<function>XcmsStoreColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsStoreColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsstorecolor'>
+<funcprototype>
+ <funcdef>Status <function>XcmsStoreColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color cell and the color to store.
+Values specified in this
+<structname>XcmsColor</structname>
+structure remain unchanged on return.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsStoreColor</function>
+function converts the color specified in the
+<structname>XcmsColor</structname>
+structure into <acronym>RGB</acronym> values.
+It then uses this <acronym>RGB</acronym> specification in an
+<structname>XColor</structname>
+structure, whose three flags
+(<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>)
+are set, in a call to
+<function>XStoreColor</function>
+to change the color cell specified by the pixel member of the
+<structname>XcmsColor</structname>
+structure.
+This pixel value must be a valid index for the specified colormap,
+and the color cell specified by the pixel value must be a read/write cell.
+If the pixel value is not a valid index, a
+<errorname>BadValue</errorname>
+error results.
+If the color cell is unallocated or is allocated read-only, a
+<errorname>BadAccess</errorname>
+error results.
+If the colormap is an installed map for its screen,
+the changes are visible immediately.
+</para>
+<para>
+<!-- .LP -->
+Note that
+<function>XStoreColor</function>
+has no return value; therefore, an
+<symbol>XcmsSuccess</symbol>
+return value from this function indicates that the conversion
+to <acronym>RGB</acronym> succeeded and the call to
+<function>XStoreColor</function>
+was made.
+To obtain the actual color stored, use
+<function>XcmsQueryColor</function>.
+Because of the screen's hardware limitations or gamut compression,
+the color stored in the colormap may not be identical
+to the color specified.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsStoreColor</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store multiple colors of arbitrary format in multiple colormap cells, use
+<function>XcmsStoreColors</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsStoreColors</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsstorecolors'>
+<funcprototype>
+ <funcdef>Status <function>XcmsStoreColors</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors[]</parameter></paramdef>
+ <paramdef>int<parameter> ncolors</parameter></paramdef>
+ <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color specification array of
+<structname>XcmsColor</structname>
+structures, each specifying a color cell and the color to store in that
+cell.
+Values specified in the array remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_flags_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of Boolean values indicating compression status.
+If a non-NULL pointer is supplied,
+each element of the array is set to
+<symbol>True</symbol>
+if the corresponding color was compressed and
+<symbol>False</symbol>
+otherwise.
+Pass NULL if the compression status is not useful.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsStoreColors</function>
+function converts the colors specified in the array of
+<structname>XcmsColor</structname>
+structures into <acronym>RGB</acronym> values and then uses these <acronym>RGB</acronym> specifications in
+<structname>XColor</structname>
+structures, whose three flags
+(<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>)
+are set, in a call to
+<function>XStoreColors</function>
+to change the color cells specified by the pixel member of the corresponding
+<structname>XcmsColor</structname>
+structure.
+Each pixel value must be a valid index for the specified colormap,
+and the color cell specified by each pixel value must be a read/write cell.
+If a pixel value is not a valid index, a
+<errorname>BadValue</errorname>
+error results.
+If a color cell is unallocated or is allocated read-only, a
+<errorname>BadAccess</errorname>
+error results.
+If more than one pixel is in error,
+the one that gets reported is arbitrary.
+If the colormap is an installed map for its screen,
+the changes are visible immediately.
+</para>
+<para>
+<!-- .LP -->
+Note that
+<function>XStoreColors</function>
+has no return value; therefore, an
+<symbol>XcmsSuccess</symbol>
+return value from this function indicates that conversions
+to <acronym>RGB</acronym> succeeded and the call to
+<function>XStoreColors</function>
+was made.
+To obtain the actual colors stored, use
+<function>XcmsQueryColors</function>.
+Because of the screen's hardware limitations or gamut compression,
+the colors stored in the colormap may not be identical
+to the colors specified.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsStoreColors</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store a color specified by name in a single colormap cell, use
+<function>XStoreNamedColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>storing</secondary></indexterm>
+<indexterm><primary>Color</primary><secondary>naming</secondary></indexterm>
+<indexterm significance="preferred"><primary>XStoreNamedColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorenamedcolor'>
+<funcprototype>
+ <funcdef><function>XStoreNamedColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>char<parameter> *color</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> pixel</parameter></paramdef>
+ <paramdef>int<parameter> flags</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color name string (for example, red).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixel</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the entry in the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>flags</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which red, green, and blue components are set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XStoreNamedColor</function>
+function looks up the named color with respect to the screen associated with
+the colormap and stores the result in the specified colormap.
+The pixel argument determines the entry in the colormap.
+The flags argument determines which of the red, green, and blue components
+are set.
+You can set this member to the
+bitwise inclusive OR of the bits
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>.
+If the color name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+If the specified pixel is not a valid index into the colormap, a
+<errorname>BadValue</errorname>
+error results.
+If the specified pixel either is unallocated or is allocated read-only, a
+<errorname>BadAccess</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreNamedColor</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadName</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XQueryColor</function>
+and
+<function>XQueryColors</function>
+functions take pixel values in the pixel member of
+<structname>XColor</structname>
+structures and store in the structures the <acronym>RGB</acronym> values for those
+pixels from the specified colormap.
+The values returned for an unallocated entry are undefined.
+These functions also set the flags member in the
+<structname>XColor</structname>
+structure to all three colors.
+If a pixel is not a valid index into the specified colormap, a
+<errorname>BadValue</errorname>
+error results.
+If more than one pixel is in error,
+the one that gets reported is arbitrary.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To query the <acronym>RGB</acronym> value of a single colormap cell, use
+<function>XQueryColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm>
+<indexterm significance="preferred"><primary>XQueryColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerycolor'>
+<funcprototype>
+ <funcdef><function>XQueryColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XColor<parameter> *def_in_out</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>def_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies and returns the <acronym>RGB</acronym> values for the pixel specified in the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryColor</function>
+function returns the current <acronym>RGB</acronym> value for the pixel in the
+<structname>XColor</structname>
+structure and sets the
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>
+flags.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryColor</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To query the <acronym>RGB</acronym> values of multiple colormap cells, use
+<function>XQueryColors</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm>
+<indexterm significance="preferred"><primary>XQueryColors</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerycolors'>
+<funcprototype>
+ <funcdef><function>XQueryColors</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XColor<parameter> defs_in_out[]</parameter></paramdef>
+ <paramdef>int<parameter> ncolors</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>defs_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies and returns an array of color definition structures for the pixel
+specified in the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .\"Specifies the number of color definition structures. -->
+Specifies the number of
+<structname>XColor</structname>
+structures in the color definition array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryColors</function>
+function returns the <acronym>RGB</acronym> value for each pixel in each
+<structname>XColor</structname>
+structure and sets the
+<symbol>DoRed</symbol>,
+<symbol>DoGreen</symbol>,
+and
+<symbol>DoBlue</symbol>
+flags in each structure.
+
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryColors</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To query the color of a single colormap cell in an arbitrary format, use
+<function>XcmsQueryColor</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsQueryColor</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsquerycolor'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryColor</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_in_out</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pixel member that indicates the color cell to query.
+The color specification stored for the color cell is returned in this
+<structname>XcmsColor</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>result_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color format for the returned color specification.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryColor</function>
+function obtains the <acronym>RGB</acronym> value
+for the pixel value in the pixel member of the specified
+<structname>XcmsColor</structname>
+structure and then
+converts the value to the target format as
+specified by the result_format argument.
+If the pixel is not a valid index in the specified colormap, a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsQueryColor</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To query the color of multiple colormap cells in an arbitrary format, use
+<function>XcmsQueryColors</function>.
+</para>
+<indexterm><primary>Color</primary><secondary>querying</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsQueryColors</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsquerycolors'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryColors</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> result_format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of
+<structname>XcmsColor</structname>
+structures, each pixel member indicating the color cell to query.
+The color specifications for the color cells are returned in these structures.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>result_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color format for the returned color specification.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryColors</function>
+function obtains the <acronym>RGB</acronym> values
+for pixel values in the pixel members of
+<structname>XcmsColor</structname>
+structures and then
+converts the values to the target format as
+specified by the result_format argument.
+If a pixel is not a valid index into the specified colormap, a
+<errorname>BadValue</errorname>
+error results.
+If more than one pixel is in error,
+the one that gets reported is arbitrary.
+</para>
+<para>
+<!-- .LP -->
+<function>XcmsQueryColors</function>
+can generate
+<errorname>BadColor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Color_Conversion_Context_Functions">
+<title>Color Conversion Context Functions</title>
+<!-- .XS -->
+<!-- (SN Color Conversion Context Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section describes functions to create, modify,
+and query Color Conversion Contexts (CCCs).
+</para>
+<para>
+<!-- .LP -->
+Associated with each colormap is an initial CCC transparently generated by
+Xlib.
+<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm>
+Therefore, when you specify a colormap as an argument to a function,
+you are indirectly specifying a CCC.
+<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm>
+The CCC attributes that can be modified by the X client are:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Client White Point
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Gamut compression procedure and client data
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+White point adjustment procedure and client data
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The initial values for these attributes are implementation specific.
+The CCC attributes for subsequently created CCCs can be defined
+by changing the CCC attributes of the default CCC.
+<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm>
+There is a default CCC associated with each screen.
+</para>
+<sect2 id="Getting_and_Setting_the_Color_Conversion_Context_of_a_Colormap">
+<title>Getting and Setting the Color Conversion Context of a Colormap</title>
+<!-- .XS -->
+<!-- (SN Getting and Setting the Color Conversion Context of a Colormap -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the CCC associated with a colormap, use
+<function>XcmsCCCOfColormap</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsCCCOfColormap</primary></indexterm>
+<indexterm><primary>Colormap</primary><secondary>CCC of</secondary></indexterm>
+<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscccofcolormap'>
+<funcprototype>
+ <funcdef>XcmsCCC <function>XcmsCCCOfColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCCCOfColormap</function>
+function returns the CCC associated with the specified colormap.
+Once obtained,
+the CCC attributes can be queried or modified.
+Unless the CCC associated with the specified colormap is changed with
+<function>XcmsSetCCCOfColormap</function>,
+this CCC is used when the specified colormap is used as an argument
+to color functions.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To change the CCC associated with a colormap, use
+<function>XcmsSetCCCOfColormap</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsSetCCCOfColormap</primary></indexterm>
+<indexterm><primary>Colormap</primary><secondary>CCC of</secondary></indexterm>
+<indexterm><primary>CCC</primary><secondary>of colormap</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>of colormap</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmssetcccofcolormap'>
+<funcprototype>
+ <funcdef>XcmsCCC <function>XcmsSetCCCOfColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsSetCCCOfColormap</function>
+function changes the CCC associated with the specified colormap.
+It returns the CCC previously associated with the colormap.
+If they are not used again in the application,
+CCCs should be freed by calling
+<function>XcmsFreeCCC</function>.
+Several colormaps may share the same CCC without restriction; this
+includes the CCCs generated by Xlib with each colormap. Xlib, however,
+creates a new CCC with each new colormap.
+</para>
+</sect2>
+<sect2 id="Obtaining_the_Default_Color_Conversion_Context">
+<title>Obtaining the Default Color Conversion Context</title>
+<!-- .XS -->
+<!-- (SN Obtaining the Default Color Conversion Context -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You can change the default CCC attributes for subsequently created CCCs
+by changing the CCC attributes of the default CCC.
+<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm>
+A default CCC is associated with each screen.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the default CCC for a screen, use
+<function>XcmsDefaultCCC</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsDefaultCCC</primary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>default</secondary></indexterm>
+<indexterm><primary>CCC</primary><secondary>default</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsdefaultccc'>
+<funcprototype>
+ <funcdef>XcmsCCC <function>XcmsDefaultCCC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsDefaultCCC</function>
+function returns the default CCC for the specified screen.
+Its visual is the default visual of the screen.
+Its initial gamut compression and white point
+adjustment procedures as well as the associated client data are implementation
+specific.
+</para>
+</sect2>
+<sect2 id="Color_Conversion_Context_Macros">
+<title>Color Conversion Context Macros</title>
+<!-- .XS -->
+<!-- (SN Color Conversion Context Macros -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Applications should not directly modify any part of the
+<structname>XcmsCCC</structname>.
+The following lists the C language macros, their corresponding function
+equivalents for other language bindings, and what data they both
+can return.
+<!-- .sp -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>DisplayOfCCC</primary></indexterm>
+<indexterm significance="preferred"><primary>XcmsDisplayOfCCC</primary></indexterm>
+<!-- .sM -->
+
+<funcsynopsis id='displayofccc'>
+<funcprototype>
+ <funcdef><function>DisplayOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis id='xcmsdisplayofccc'>
+<funcprototype>
+ <funcdef>Display *<function>XcmsDisplayOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Both return the display associated with the specified CCC.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm significance="preferred"><primary>VisualOfCCC</primary></indexterm>
+<indexterm significance="preferred"><primary>XcmsVisualOfCCC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='visualofccc'>
+<funcprototype>
+ <funcdef><function>VisualOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis id='xcmsvisualofccc'>
+<funcprototype>
+ <funcdef>Visual *<function>XcmsVisualOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Both return the visual associated with the specified CCC.
+<!-- .sp -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>ScreenNumberOfCCC</primary></indexterm>
+<indexterm significance="preferred"><primary>XcmsScreenNumberOfCCC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='screennumberofccc'>
+<funcprototype>
+ <funcdef><function>ScreenNumberOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis id='xcmsscreennumberofccc'>
+<funcprototype>
+ <funcdef>int <function>XcmsScreenNumberOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Both return the number of the screen associated with the specified CCC.
+<!-- .sp -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>ScreenWhitePointOfCCC</primary></indexterm>
+<indexterm significance="preferred"><primary>XcmsScreenWhitePointOfCCC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='screenwhitepointofccc'>
+<funcprototype>
+ <funcdef><function>ScreenWhitePointOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<funcsynopsis id='xcmsscreenwhitepointofccc'>
+<funcprototype>
+ <funcdef>XcmsColor <function>XcmsScreenWhitePointOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Both return the white point of the screen associated with the specified CCC.
+<!-- .sp -->
+</para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>ClientWhitePointOfCCC</primary></indexterm>
+<indexterm significance="preferred"><primary>XcmsClientWhitePointOfCCC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='clientwhitepointofccc'>
+<funcprototype>
+ <funcdef> <function>ClientWhitePointOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis id='xcmsclientwhitepointofccc'>
+<funcprototype>
+ <funcdef>XcmsColor *<function>XcmsClientWhitePointOfCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Both return the Client White Point of the specified CCC.
+</para>
+</sect2>
+
+<sect2 id="Modifying_Attributes_of_a_Color_Conversion_Context">
+<title>Modifying Attributes of a Color Conversion Context</title>
+<!-- .XS -->
+<!-- (SN Modifying Attributes of a Color Conversion Context -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the Client White Point in the CCC, use
+<function>XcmsSetWhitePoint</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsSetWhitePoint</primary></indexterm>
+<indexterm><primary>Client White Point</primary><secondary>of Color Conversion Context</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmssetwhitepoint'>
+<funcprototype>
+ <funcdef>Status <function>XcmsSetWhitePoint</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+<!-- .ds Co new Client White Point -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the new Client White Point.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsSetWhitePoint</function>
+function changes the Client White Point in the specified CCC.
+Note that the pixel member is ignored
+and that the color specification is left unchanged upon return.
+The format for the new white point must be
+<symbol>XcmsCIEXYZFormat</symbol>,
+<symbol>XcmsCIEuvYFormat</symbol>,
+<symbol>XcmsCIExyYFormat</symbol>,
+or
+<symbol>XcmsUndefinedFormat</symbol>.
+If the color argument is NULL, this function sets the format component of the
+Client White Point specification to
+<symbol>XcmsUndefinedFormat</symbol>,
+indicating that the Client White Point is assumed to be the same as the
+Screen White Point.
+</para>
+<para>
+<!-- .LP -->
+This function returns nonzero status
+if the format for the new white point is valid;
+otherwise, it returns zero.
+
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set the gamut compression procedure and corresponding client data
+in a specified CCC, use
+<function>XcmsSetCompressionProc</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsSetCompressionProc</primary></indexterm>
+<indexterm><primary>Gamut compression</primary><secondary>setting in Color Conversion Context</secondary></indexterm>
+<indexterm><primary>Gamut compression</primary><secondary>procedure</secondary></indexterm>
+<indexterm><primary>Gamut compression</primary><secondary>client data</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmssetcompressionproc'>
+<funcprototype>
+ <funcdef>XcmsCompressionProc <function>XcmsSetCompressionProc</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsCompressionProc<parameter> compression_proc</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the gamut compression procedure that is to be applied
+when a color lies outside the screen's color gamut.
+If NULL is specified and a function using this CCC must convert
+a color specification to a device-dependent format and encounters a color
+that lies outside the screen's color gamut,
+that function will return
+<symbol>XcmsFailure</symbol>.
+<!-- .ds Cd the gamut compression procedure -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies client data for gamut compression procedure or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsSetCompressionProc</function>
+function first sets the gamut compression procedure and client data
+in the specified CCC with the newly specified procedure and client data
+and then returns the old procedure.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set the white point adjustment procedure and corresponding client data
+in a specified CCC, use
+<function>XcmsSetWhiteAdjustProc</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsSetWhiteAdjustProc</primary></indexterm>
+<indexterm><primary>White point adjustment</primary><secondary>setting in Color Conversion Context</secondary></indexterm>
+<indexterm><primary>White point adjustment</primary><secondary>procedure</secondary></indexterm>
+<indexterm><primary>White point adjustment</primary><secondary>client data</secondary></indexterm>
+<funcsynopsis id='xcmssetwhiteadjustproc'>
+<funcprototype>
+ <funcdef>XcmsWhiteAdjustProc <function>XcmsSetWhiteAdjustProc</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsWhiteAdjustProc<parameter> white_adjust_proc</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>white_adjust_proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the white point adjustment procedure.
+<!-- .ds Cd the white point adjustment procedure -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies client data for white point adjustment procedure or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsSetWhiteAdjustProc</function>
+function first sets the white point adjustment procedure and client data
+in the specified CCC with the newly specified procedure and client data
+and then returns the old procedure.
+</para>
+</sect2>
+<sect2 id="Creating_and_Freeing_a_Color_Conversion_Context">
+<title>Creating and Freeing a Color Conversion Context</title>
+<!-- .XS -->
+<!-- (SN Creating and Freeing a Color Conversion Context -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You can explicitly create a CCC within your application by calling
+<function>XcmsCreateCCC</function>.
+These created CCCs can then be used by those functions that explicitly
+call for a CCC argument.
+Old CCCs that will not be used by the application should be freed using
+<function>XcmsFreeCCC</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To create a CCC, use
+<function>XcmsCreateCCC</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsCreateCCC</primary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>creation</secondary></indexterm>
+<indexterm><primary>CCC</primary><secondary>creation</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscreateccc'>
+<funcprototype>
+ <funcdef>XcmsCCC <function>XcmsCreateCCC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+ <paramdef>Visual<parameter> *visual</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *client_white_point</parameter></paramdef>
+ <paramdef>XcmsCompressionProc<parameter> compression_proc</parameter></paramdef>
+ <paramdef>XPointer<parameter> compression_client_data</parameter></paramdef>
+ <paramdef>XcmsWhiteAdjustProc<parameter> white_adjust_proc</parameter></paramdef>
+ <paramdef>XPointer<parameter> white_adjust_client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>visual</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the visual type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_white_point</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Client White Point.
+If NULL is specified,
+the Client White Point is to be assumed to be the same as the
+Screen White Point.
+Note that the pixel member is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the gamut compression procedure that is to be applied
+when a color lies outside the screen's color gamut.
+If NULL is specified and a function using this CCC must convert
+a color specification to a device-dependent format and encounters a color
+that lies outside the screen's color gamut,
+that function will return
+<symbol>XcmsFailure</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies client data for use by the gamut compression procedure or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>white_adjust_proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the white adjustment procedure that is to be applied
+when the Client White Point differs from the Screen White Point.
+NULL indicates that no white point adjustment is desired.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>white_adjust_client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies client data for use with the white point adjustment procedure or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCreateCCC</function>
+function creates a CCC for the specified display, screen, and visual.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free a CCC, use
+<function>XcmsFreeCCC</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsFreeCCC</primary></indexterm>
+<indexterm><primary>Color Conversion Context</primary><secondary>freeing</secondary></indexterm>
+<indexterm><primary>CCC</primary><secondary>freeing</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsfreeccc'>
+<funcprototype>
+ <funcdef>void <function>XcmsFreeCCC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsFreeCCC</function>
+function frees the memory used for the specified CCC.
+Note that default CCCs and those currently associated with colormaps
+are ignored.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Converting_between_Color_Spaces">
+<title>Converting between Color Spaces</title>
+<!-- .XS -->
+<!-- (SN Converting between Color Spaces -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To convert an array of color specifications in arbitrary color formats
+to a single destination format, use
+<function>XcmsConvertColors</function>.
+</para>
+<indexterm><primary>Color conversion</primary></indexterm>
+<indexterm><primary>Color</primary><secondary>conversion</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsConvertColors</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsconvertcolors'>
+<funcprototype>
+ <funcdef>Status <function>XcmsConvertColors</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+If conversion is between device-independent color spaces only
+(for example, TekHVC to CIELuv),
+the CCC is necessary only to specify the Client White Point.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color specifications.
+Pixel members are ignored and remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_flags_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of Boolean values indicating compression status.
+If a non-NULL pointer is supplied,
+each element of the array is set to
+<symbol>True</symbol>
+if the corresponding color was compressed and
+<symbol>False</symbol>
+otherwise.
+Pass NULL if the compression status is not useful.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsConvertColors</function>
+function converts the color specifications in the specified array of
+<structname>XcmsColor</structname>
+structures from their current format to a single target format,
+using the specified CCC.
+When the return value is
+<symbol>XcmsFailure</symbol>,
+the contents of the color specification array are left unchanged.
+</para>
+<para>
+<!-- .LP -->
+The array may contain a mixture of color specification formats
+(for example, 3 <acronym>CIE</acronym> XYZ, 2 <acronym>CIE</acronym> Luv, and so on).
+When the array contains both device-independent and
+device-dependent color specifications and the target_format argument specifies
+a device-dependent format (for example,
+<symbol>XcmsRGBiFormat</symbol>,
+<symbol>XcmsRGBFormat</symbol>),
+all specifications are converted to <acronym>CIE</acronym> XYZ format and then to the target
+device-dependent format.
+</para>
+</sect1>
+<sect1 id="Callback_Functions">
+<title>Callback Functions</title>
+<!-- .XS -->
+<!-- (SN Callback Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section describes the gamut compression and white point
+adjustment callbacks.
+</para>
+<para>
+<!-- .LP -->
+The gamut compression procedure specified in the CCC
+is called when an attempt to convert a color specification from
+<structname>XcmsCIEXYZ</structname>
+to a device-dependent format (typically
+<structname>XcmsRGBi</structname>)
+results in a color that lies outside the screen's color gamut.
+If the gamut compression procedure requires client data, this data is passed
+via the gamut compression client data in the CCC.
+</para>
+<para>
+<!-- .LP -->
+During color specification conversion between device-independent
+and device-dependent color spaces,
+if a white point adjustment procedure is specified in the CCC,
+it is triggered when the Client White Point and Screen White Point differ.
+If required, the client data is obtained from the CCC.
+</para>
+<sect2 id="Prototype_Gamut_Compression_Procedure">
+<title>Prototype Gamut Compression Procedure</title>
+<!-- .XS -->
+<!-- (SN Prototype Gamut Compression Procedure -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The gamut compression callback interface must adhere to the
+following:
+</para>
+<indexterm significance="preferred"><primary>XcmsCompressionProc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscompressionproc'>
+<funcprototype>
+ <funcdef>typedef Status<function>(*XcmsCompressionProc</function>)</funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+ <paramdef>unsignedint<parameter> index</parameter></paramdef>
+ <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color specifications.
+Pixel members should be ignored and must remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>index</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the index into the array of
+<structname>XcmsColor</structname>
+structures for the encountered color specification that lies outside the
+screen's color gamut.
+Valid values are 0 (for the first element) to ncolors - 1.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_flags_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of Boolean values for indicating compression status.
+If a non-NULL pointer is supplied
+and a color at a given index is compressed, then
+<symbol>True</symbol>
+should be stored at the corresponding index in this array;
+otherwise, the array should not be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When implementing a gamut compression procedure, consider the following
+rules and assumptions:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The gamut compression procedure can attempt to compress one or multiple
+specifications at a time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When called, elements 0 to index - 1 in the color specification
+array can be assumed to fall within the screen's color gamut.
+In addition, these color specifications are already in some device-dependent
+format (typically
+<structname>XcmsRGBi</structname>).
+If any modifications are made to these color specifications,
+they must be in their initial device-dependent format upon return.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When called, the element in the color specification array specified
+by the index argument contains the color specification outside the
+screen's color gamut encountered by the calling routine.
+In addition, this color specification can be assumed to be in
+<structname>XcmsCIEXYZ</structname>.
+Upon return, this color specification must be in
+<structname>XcmsCIEXYZ</structname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When called, elements from index to ncolors - 1
+in the color specification array may or may not fall within the
+screen's color gamut.
+In addition, these color specifications can be assumed to be in
+<structname>XcmsCIEXYZ</structname>.
+If any modifications are made to these color specifications,
+they must be in
+<structname>XcmsCIEXYZ</structname>
+upon return.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The color specifications passed to the gamut compression procedure
+have already been adjusted to the Screen White Point.
+This means that at this point the color specification's white point
+is the Screen White Point.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the gamut compression procedure uses a device-independent color space not
+initially accessible for use in the color management system, use
+<function>XcmsAddColorSpace</function>
+to ensure that it is added.
+ </para>
+ </listitem>
+</itemizedlist>
+</sect2>
+<sect2 id="Supplied_Gamut_Compression_Procedures">
+<title>Supplied Gamut Compression Procedures</title>
+<!-- .XS -->
+<!-- (SN Supplied Gamut Compression Procedures -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following equations are useful in describing gamut compression
+functions:
+<!-- .EQ -->
+delim %%
+<!-- .EN -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+%CIELab~Psychometric~Chroma ~=~ sqrt(a_star sup 2 ~+~ b_star sup 2 )%
+
+%CIELab~Psychometric~Hue ~=~ tan sup -1 left [ b_star over a_star right ]%
+
+%CIELuv~Psychometric~Chroma ~=~ sqrt(u_star sup 2 ~+~ v_star sup 2 )%
+
+%CIELuv~Psychometric~Hue ~=~ tan sup -1 left [ v_star over u_star right ]%
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The gamut compression callback procedures provided by Xlib are as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<function>XcmsCIELabClipL</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing or increasing <acronym>CIE</acronym> metric lightness (L*)
+in the <acronym>CIE</acronym> L*a*b* color space until the color is within the gamut.
+If the Psychometric Chroma of the color specification
+is beyond maximum for the Psychometric Hue Angle,
+then while maintaining the same Psychometric Hue Angle,
+the color will be clipped to the <acronym>CIE</acronym> L*a*b* coordinates of maximum
+Psychometric Chroma.
+See
+<function>XcmsCIELabQueryMaxC</function>.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELabClipab</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing Psychometric Chroma,
+while maintaining Psychometric Hue Angle,
+until the color is within the gamut.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELabClipLab</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by replacing it with <acronym>CIE</acronym> L*a*b* coordinates
+that fall within the color gamut while maintaining the original
+Psychometric Hue
+Angle and whose vector to the original coordinates is the shortest attainable.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELuvClipL</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing or increasing <acronym>CIE</acronym> metric lightness (L*)
+in the <acronym>CIE</acronym> L*u*v* color space until the color is within the gamut.
+If the Psychometric Chroma of the color specification
+is beyond maximum for the Psychometric Hue Angle,
+then, while maintaining the same Psychometric Hue Angle,
+the color will be clipped to the <acronym>CIE</acronym> L*u*v* coordinates of maximum
+Psychometric Chroma.
+See
+<function>XcmsCIELuvQueryMaxC</function>.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELuvClipuv</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing
+Psychometric Chroma, while maintaining Psychometric Hue Angle,
+until the color is within the gamut.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELuvClipLuv</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by replacing it with <acronym>CIE</acronym> L*u*v* coordinates
+that fall within the color gamut while maintaining the original
+Psychometric Hue
+Angle and whose vector to the original coordinates is the shortest attainable.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsTekHVCClipV</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing or increasing the Value dimension
+in the TekHVC color space until the color is within the gamut.
+If Chroma of the color specification is beyond maximum for the particular Hue,
+then, while maintaining the same Hue,
+the color will be clipped to the Value and Chroma coordinates
+that represent maximum Chroma for that particular Hue.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsTekHVCClipC</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by reducing the Chroma dimension
+in the TekHVC color space until the color is within the gamut.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsTekHVCClipVC</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This brings the encountered out-of-gamut color specification into the
+screen's color gamut by replacing it with TekHVC coordinates
+that fall within the color gamut while maintaining the original Hue
+and whose vector to the original coordinates is the shortest attainable.
+No client data is necessary.
+ </para>
+ </listitem>
+</itemizedlist>
+</sect2>
+<sect2 id="Prototype_White_Point_Adjustment_Procedure">
+<title>Prototype White Point Adjustment Procedure</title>
+<!-- .XS -->
+<!-- (SN Prototype White Point Adjustment Procedure -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The white point adjustment procedure interface must adhere to the following:
+</para>
+<indexterm significance="preferred"><primary>XcmsWhiteAdjustProc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmswhiteadjustproc'>
+<funcprototype>
+ <funcdef>typedef Status <function>(*XcmsWhiteAdjustProc</function>)</funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *initial_white_point</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *target_white_point</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors_in_out[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+ <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>initial_white_point</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the initial white point.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_white_point</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target white point.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color specifications.
+Pixel members should be ignored and must remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_flags_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of Boolean values for indicating compression status.
+If a non-NULL pointer is supplied
+and a color at a given index is compressed, then
+<symbol>True</symbol>
+should be stored at the corresponding index in this array;
+otherwise, the array should not be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect2>
+<sect2 id="Supplied_White_Point_Adjustment_Procedures">
+<title>Supplied White Point Adjustment Procedures</title>
+<!-- .XS -->
+<!-- (SN Supplied White Point Adjustment Procedures -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+White point adjustment procedures provided by Xlib are as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<function>XcmsCIELabWhiteShiftColors</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This uses the <acronym>CIE</acronym> L*a*b* color space for adjusting the chromatic character
+of colors to compensate for the chromatic differences between the source
+and destination white points.
+This procedure simply converts the color specifications to
+<structname>XcmsCIELab</structname>
+using the source white point and then converts to the target specification
+format using the destination's white point.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsCIELuvWhiteShiftColors</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This uses the <acronym>CIE</acronym> L*u*v* color space for adjusting the chromatic character
+of colors to compensate for the chromatic differences between the source
+and destination white points.
+This procedure simply converts the color specifications to
+<structname>XcmsCIELuv</structname>
+using the source white point and then converts to the target specification
+format using the destination's white point.
+No client data is necessary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<function>XcmsTekHVCWhiteShiftColors</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+This uses the TekHVC color space for adjusting the chromatic character
+of colors to compensate for the chromatic differences between the source
+and destination white points.
+This procedure simply converts the color specifications to
+<structname>XcmsTekHVC</structname>
+using the source white point and then converts to the target specification
+format using the destination's white point.
+An advantage of this procedure over those previously described
+is an attempt to minimize hue shift.
+No client data is necessary.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+From an implementation point of view,
+these white point adjustment procedures convert the color specifications
+to a device-independent but white-point-dependent color space
+(for example, <acronym>CIE</acronym> L*u*v*, <acronym>CIE</acronym> L*a*b*, TekHVC) using one white point
+and then converting those specifications to the target color space
+using another white point.
+In other words,
+the specification goes in the color space with one white point
+but comes out with another white point,
+resulting in a chromatic shift based on the chromatic displacement
+between the initial white point and target white point.
+The <acronym>CIE</acronym> color spaces that are assumed to be white-point-independent
+are <acronym>CIE</acronym> u'v'Y, <acronym>CIE</acronym> XYZ, and <acronym>CIE</acronym> xyY.
+When developing a custom white point adjustment procedure that uses a
+device-independent color space not initially accessible for use in the
+color management system, use
+<function>XcmsAddColorSpace</function>
+to ensure that it is added.
+</para>
+<para>
+<!-- .LP -->
+As an example,
+if the CCC specifies a white point adjustment procedure
+and if the Client White Point and Screen White Point differ, the
+<function>XcmsAllocColor</function>
+function will use the white point adjustment
+procedure twice:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Once to convert to
+<structname>XcmsRGB</structname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A second time to convert from
+<structname>XcmsRGB</structname>
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+For example, assume the specification is in
+<structname>XcmsCIEuvY</structname>
+and the adjustment procedure is
+<function>XcmsCIELuvWhiteShiftColors</function>.
+During conversion to
+<structname>XcmsRGB</structname>,
+the call to
+<function>XcmsAllocColor</function>
+results in the following series of color specification conversions:
+<!-- .\" Do these need to be font coded? -->
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+From
+<structname>XcmsCIEuvY</structname>
+to
+<structname>XcmsCIELuv</structname>
+using the Client White Point
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+From
+<structname>XcmsCIELuv</structname>
+to
+<structname>XcmsCIEuvY</structname>
+using the Screen White Point
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+From
+<structname>XcmsCIEuvY</structname>
+to
+<structname>XcmsCIEXYZ</structname>
+(<acronym>CIE</acronym> u'v'Y and XYZ are white-point-independent color spaces)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+From
+<structname>XcmsCIEXYZ</structname>
+to
+<structname>XcmsRGBi</structname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+From
+<structname>XcmsRGBi</structname>
+to
+<structname>XcmsRGB</structname>
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The resulting <acronym>RGB</acronym> specification is passed to
+<function>XAllocColor</function>,
+and the <acronym>RGB</acronym>
+specification returned by
+<function>XAllocColor</function>
+is converted back to
+<structname>XcmsCIEuvY</structname>
+by reversing the color conversion sequence.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Gamut_Querying_Functions">
+<title>Gamut Querying Functions</title>
+<!-- .XS -->
+<!-- (SN Gamut Querying Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section describes the gamut querying functions that Xlib provides.
+These functions allow the client to query the boundary
+of the screen's color gamut in terms of the <acronym>CIE</acronym> L*a*b*, <acronym>CIE</acronym> L*u*v*,
+and TekHVC color spaces.
+<indexterm><primary>Gamut querying</primary></indexterm>
+Functions are also provided that allow you to query
+the color specification of:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+White (full-intensity red, green, and blue)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Red (full-intensity red while green and blue are zero)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Green (full-intensity green while red and blue are zero)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Blue (full-intensity blue while red and green are zero)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Black (zero-intensity red, green, and blue)
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The white point associated with color specifications passed to
+and returned from these gamut querying
+functions is assumed to be the Screen White Point.
+<indexterm><primary>Screen White Point</primary></indexterm>
+This is a reasonable assumption,
+because the client is trying to query the screen's color gamut.
+</para>
+<para>
+<!-- .LP -->
+The following naming convention is used for the Max and Min functions:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Xcms<emphasis remap='I'><color_space></emphasis>QueryMax<emphasis remap='I'><dimensions></emphasis>
+
+Xcms<emphasis remap='I'><color_space></emphasis>QueryMin<emphasis remap='I'><dimensions></emphasis>
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The <dimensions> consists of a letter or letters
+that identify the dimensions of the color space
+that are not fixed.
+For example,
+<function>XcmsTekHVCQueryMaxC</function>
+is given a fixed Hue and Value for which maximum Chroma is found.
+</para>
+<sect2 id="Red_Green_and_Blue_Queries">
+<title>Red, Green, and Blue Queries</title>
+<!-- .XS -->
+<!-- (SN Red, Green, and Blue Queries -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To obtain the color specification for black
+(zero-intensity red, green, and blue), use
+<function>XcmsQueryBlack</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsQueryBlack</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsqueryblack'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryBlack</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+<!-- .ds Cs zero-intensity red, green, and blue -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the specified target format
+for (Cs.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryBlack</function>
+function returns the color specification in the specified target format
+for zero-intensity red, green, and blue.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the color specification for blue
+(full-intensity blue while red and green are zero), use
+<function>XcmsQueryBlue</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsQueryBlue</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsqueryblue'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryBlue</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+<!-- .ds Cs full-intensity blue while red and green are zero -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the specified target format
+for (Cs.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryBlue</function>
+function returns the color specification in the specified target format
+for full-intensity blue while red and green are zero.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the color specification for green
+(full-intensity green while red and blue are zero), use
+<function>XcmsQueryGreen</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsQueryGreen</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsquerygreen'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryGreen</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+<!-- .ds Cs full-intensity green while red and blue are zero -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the specified target format
+for (Cs.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryGreen</function>
+function returns the color specification in the specified target format
+for full-intensity green while red and blue are zero.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the color specification for red
+(full-intensity red while green and blue are zero), use
+<function>XcmsQueryRed</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsQueryRed</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsqueryred'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryRed</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+<!-- .ds Cs full-intensity red while green and blue are zero -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the specified target format
+for (Cs.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryRed</function>
+function returns the color specification in the specified target format
+for full-intensity red while green and blue are zero.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the color specification for white
+(full-intensity red, green, and blue), use
+<function>XcmsQueryWhite</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsQueryWhite</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsquerywhite'>
+<funcprototype>
+ <funcdef>Status <function>XcmsQueryWhite</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColorFormat<parameter> target_format</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the target color specification format.
+<!-- .ds Cs full-intensity red, green, and blue -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the specified target format
+for (Cs.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsQueryWhite</function>
+function returns the color specification in the specified target format
+for full-intensity red, green, and blue.
+</para>
+</sect2>
+<sect2 id="CIELab_Queries">
+<title>CIELab Queries</title>
+<!-- .XS -->
+<!-- (SN CIELab Queries -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following equations are useful in describing the CIELab query functions:
+<!-- .EQ -->
+delim %%
+<!-- .EN -->
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm>
+<literallayout class="monospaced">
+%CIELab~Psychometric~Chroma ~=~ sqrt(a_star sup 2 ~+~ b_star sup 2 )%
+
+%CIELab~Psychometric~Hue ~=~ tan sup -1 left [ b_star over a_star right ]%
+</literallayout>
+<!-- .sp -->
+To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum Psychometric Chroma
+for a given Psychometric Hue Angle and <acronym>CIE</acronym> metric lightness (L*), use
+<function>XcmsCIELabQueryMaxC</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscielabquerymaxc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELabQueryMaxC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> L_star</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ls maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>L_star</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the lightness (L*) at which to find (Ls.
+<!-- .ds Lc maximum chroma -->
+<!-- .ds lC hue angle and lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELabQueryMaxC</function>
+function, given a hue angle and lightness,
+finds the point of maximum chroma displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*a*b* coordinates.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum <acronym>CIE</acronym> metric lightness (L*)
+for a given Psychometric Hue Angle and Psychometric Chroma, use
+<function>XcmsCIELabQueryMaxL</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxL</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscielabquerymaxl'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELabQueryMaxL</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ch maximum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>chroma</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the chroma at which to find (Ch.
+<!-- .ds Lc maximum lightness -->
+<!-- .ds lC hue angle and chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELabQueryMaxL</function>
+function, given a hue angle and chroma,
+finds the point in <acronym>CIE</acronym> L*a*b* color space of maximum
+lightness (L*) displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*a*b* coordinates.
+An
+<symbol>XcmsFailure</symbol>
+return value usually indicates that the given chroma
+is beyond maximum for the given hue angle.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*a*b* coordinates of maximum Psychometric Chroma
+for a given Psychometric Hue Angle, use
+<function>XcmsCIELabQueryMaxLC</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELabQueryMaxLC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscielabquerymaxlc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELabQueryMaxLC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Lc maximum chroma -->
+<!-- .ds lC hue angle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELabQueryMaxLC</function>
+function, given a hue angle,
+finds the point of maximum chroma displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*a*b* coordinates.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*a*b* coordinates of minimum <acronym>CIE</acronym> metric lightness (L*)
+for a given Psychometric Hue Angle and Psychometric Chroma, use
+<function>XcmsCIELabQueryMinL</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>minimum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELabQueryMinL</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscielabqueryminlc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELabQueryMinL</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha minimum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ch minimum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>chroma</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the chroma at which to find (Ch.
+<!-- .ds Lc minimum lightness -->
+<!-- .ds lC hue angle and chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*a*b* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELabQueryMinL</function>
+function, given a hue angle and chroma,
+finds the point of minimum lightness (L*) displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*a*b* coordinates.
+An
+<symbol>XcmsFailure</symbol>
+return value usually indicates that the given chroma
+is beyond maximum for the given hue angle.
+</para>
+</sect2>
+<sect2 id="CIELuv_Queries">
+<title>CIELuv Queries</title>
+<!-- .XS -->
+<!-- (SN CIELuv Queries -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following equations are useful in describing the CIELuv query functions:
+<!-- .EQ -->
+delim %%
+<!-- .EN -->
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm>
+<literallayout class="monospaced">
+%CIELuv~Psychometric~Chroma ~=~ sqrt(u_star sup 2 ~+~ v_star sup 2 )%
+
+%CIELuv~Psychometric~Hue ~=~ tan sup -1 left [ v_star over u_star right ]%
+</literallayout>
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum Psychometric Chroma
+for a given Psychometric Hue Angle and <acronym>CIE</acronym> metric lightness (L*), use
+<function>XcmsCIELuvQueryMaxC</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmxcieluvquerymaxc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELuvQueryMaxC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> L_star</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ls maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>L_star</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the lightness (L*) at which to find (Ls.
+<!-- .ds Lc maximum chroma -->
+<!-- .ds lC hue angle and lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELuvQueryMaxC</function>
+function, given a hue angle and lightness,
+finds the point of maximum chroma displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*u*v* coordinates.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum <acronym>CIE</acronym> metric lightness (L*)
+for a given Psychometric Hue Angle and Psychometric Chroma, use
+<function>XcmsCIELuvQueryMaxL</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxL</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscieluvquerymaxl'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELuvQueryMaxL</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ls maximum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>L_star</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the lightness (L*) at which to find (Ls.
+<!-- .ds Lc maximum lightness -->
+<!-- .ds lC hue angle and chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELuvQueryMaxL</function>
+function, given a hue angle and chroma,
+finds the point in <acronym>CIE</acronym> L*u*v* color space of maximum
+lightness (L*) displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*u*v* coordinates.
+An
+<symbol>XcmsFailure</symbol>
+return value usually indicates that the given chroma
+is beyond maximum for the given hue angle.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*u*v* coordinates of maximum Psychometric Chroma
+for a given Psychometric Hue Angle, use
+<function>XcmsCIELuvQueryMaxLC</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary>Psychometric Chroma</primary><secondary>maximum</secondary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELuvQueryMaxLC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscieluvquerymaxlc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELuvQueryMaxLC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha maximum chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Lc maximum chroma -->
+<!-- .ds lC hue angle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELuvQueryMaxLC</function>
+function, given a hue angle,
+finds the point of maximum chroma displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*u*v* coordinates.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the <acronym>CIE</acronym> L*u*v* coordinates of minimum <acronym>CIE</acronym> metric lightness (L*)
+for a given Psychometric Hue Angle and Psychometric Chroma, use
+<function>XcmsCIELuvQueryMinL</function>.
+</para>
+<indexterm><primary>Psychometric Hue Angle</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary></indexterm>
+<indexterm><primary><acronym>CIE</acronym> metric lightness</primary><secondary>minimum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsCIELuvQueryMinL</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmscieluvqueryminl'>
+<funcprototype>
+ <funcdef>Status <function>XcmsCIELuvQueryMinL</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue_angle</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Ha minimum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue_angle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the hue angle (in degrees) at which to find (Ha.
+<!-- .ds Ch minimum lightness -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>chroma</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the chroma at which to find (Ch.
+<!-- .ds Lc minimum lightness -->
+<!-- .ds lC hue angle and chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <acronym>CIE</acronym> L*u*v* coordinates of (Lc
+displayable by the screen for the given (lC.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsCIELuvQueryMinL</function>
+function, given a hue angle and chroma,
+finds the point of minimum lightness (L*) displayable by the screen.
+It returns this point in <acronym>CIE</acronym> L*u*v* coordinates.
+An
+<symbol>XcmsFailure</symbol>
+return value usually indicates that the given chroma
+is beyond maximum for the given hue angle.
+</para>
+</sect2>
+<sect2 id="TekHVC_Queries">
+<title>TekHVC Queries</title>
+<!-- .XS -->
+<!-- (SN TekHVC Queries -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To obtain the maximum Chroma for a given Hue and Value, use
+<function>XcmsTekHVCQueryMaxC</function>.
+</para>
+<indexterm><primary>Chroma</primary></indexterm>
+<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmstekhvcquerymaxc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsTekHVCQueryMaxC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> value</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Hu in which to find the maximum Chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Hue (Hu.
+<!-- .ds Va maximum Chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Value in which to find the (Va.
+<!-- .ds Lc maximum Chroma along with the actual Hue and Value -->
+<!-- .ds lC maximum Chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the (Lc at which the (lC was found.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsTekHVCQueryMaxC</function>
+function, given a Hue and Value,
+determines the maximum Chroma in TekHVC color space
+displayable by the screen.
+It returns the maximum Chroma along with the actual Hue
+and Value at which the maximum Chroma was found.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the maximum Value for a given Hue and Chroma, use
+<function>XcmsTekHVCQueryMaxV</function>.
+</para>
+<indexterm><primary>Value</primary></indexterm>
+<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxV</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmstekhvcquerymaxv'>
+<funcprototype>
+ <funcdef>Status <function>XcmsTekHVCQueryMaxV</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Hu in which to find the maximum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Hue (Hu.
+<!-- .ds Ch maximum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>chroma</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the chroma at which to find (Ch.
+<!-- .ds Lc maximum Value along with the Hue and Chroma -->
+<!-- .ds lC maximum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the (Lc at which the (lC was found.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsTekHVCQueryMaxV</function>
+function, given a Hue and Chroma,
+determines the maximum Value in TekHVC color space
+displayable by the screen.
+It returns the maximum Value and the actual Hue and Chroma
+at which the maximum Value was found.
+<!-- .sp -->
+</para>
+
+<para>
+<!-- .LP -->
+To obtain the maximum Chroma and Value at which it is reached
+for a specified Hue, use
+<function>XcmsTekHVCQueryMaxVC</function>.
+</para>
+<indexterm><primary>Chroma</primary></indexterm>
+<indexterm><primary>Value</primary></indexterm>
+<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm>
+<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxVC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmstekhvcquerymaxvc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsTekHVCQueryMaxVC</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Hu in which to find the maximum Chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Hue (Hu.
+<!-- .ds Lc color specification in \ -->
+XcmsTekHVC for the maximum Chroma, the Value at which \
+that maximum Chroma is reached, and the actual Hue
+<!-- .ds lC maximum Chroma -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the (Lc at which the (lC was found.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsTekHVCQueryMaxVC</function>
+function, given a Hue,
+determines the maximum Chroma in TekHVC color space displayable by the screen
+and the Value at which that maximum Chroma is reached.
+It returns the maximum Chroma,
+the Value at which that maximum Chroma is reached,
+and the actual Hue for which the maximum Chroma was found.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain a specified number of TekHVC specifications such that they
+contain maximum Values for a specified Hue and the
+Chroma at which the maximum Values are reached, use
+<function>XcmsTekHVCQueryMaxVSamples</function>.
+</para>
+<indexterm><primary>Chroma</primary></indexterm>
+<indexterm><primary>Value</primary></indexterm>
+<indexterm><primary>Chroma</primary><secondary>maximum</secondary></indexterm>
+<indexterm><primary>Value</primary><secondary>maximum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsTekHVCQueryMaxVSamples</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmstekhvcquerymaxvsamples'>
+<funcprototype>
+ <funcdef>Status <function>XcmsTekHVCQueryMaxVSamples</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> colors_return[]</parameter></paramdef>
+ <paramdef>unsignedint<parameter> nsamples</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Hu for maximum Chroma/Value samples -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Hue (Hu.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nsamples</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of samples.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns nsamples of color specifications in XcmsTekHVC
+such that the Chroma is the maximum attainable for the Value and Hue.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsTekHVCQueryMaxVSamples</function>
+returns nsamples of maximum Value, the Chroma at which that maximum Value
+is reached, and the actual Hue for which the maximum Chroma was found.
+These sample points may then be used to plot the maximum Value/Chroma
+boundary of the screen's color gamut for the specified Hue in TekHVC color
+space.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the minimum Value for a given Hue and Chroma, use
+<function>XcmsTekHVCQueryMinV</function>.
+</para>
+<indexterm><primary>Value</primary></indexterm>
+<indexterm><primary>Value</primary><secondary>minimum</secondary></indexterm>
+<indexterm significance="preferred"><primary>XcmsTekHVCQueryMinV</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmstekhvcqueryminv'>
+<funcprototype>
+ <funcdef>Status <function>XcmsTekHVCQueryMinV</function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> hue</parameter></paramdef>
+ <paramdef>XcmsFloat<parameter> chroma</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+The CCC's Client White Point and white point adjustment procedures
+are ignored.
+<!-- .ds Hu in which to find the minimum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hue</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Hue (Hu.
+<!-- .ds Va minimum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the Value in which to find the (Va.
+<!-- .ds Lc minimum Value and the actual Hue and Chroma -->
+<!-- .ds lC minimum Value -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the (Lc at which the (lC was found.
+The white point associated with the returned
+color specification is the Screen White Point.
+The value returned in the pixel member is undefined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsTekHVCQueryMinV</function>
+function, given a Hue and Chroma,
+determines the minimum Value in TekHVC color space displayable by the screen.
+It returns the minimum Value and the actual Hue and Chroma at which
+the minimum Value was found.
+</para>
+
+</sect2>
+</sect1>
+<sect1 id="Color_Management_Extensions">
+<title>Color Management Extensions</title>
+<!-- .XS -->
+<!-- (SN Color Management Extensions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The Xlib color management facilities can be extended in two ways:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Device-Independent Color Spaces
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Device-independent color spaces that are derivable to <acronym>CIE</acronym> XYZ
+space can be added using the
+<function>XcmsAddColorSpace</function>
+function.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Color Characterization Function Set
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A Color Characterization Function Set consists of
+device-dependent color spaces and their functions that
+convert between these color spaces and the <acronym>CIE</acronym> XYZ
+color space, bundled together for a specific class of output devices.
+A function set can be added using the
+<function>XcmsAddFunctionSet</function>
+function.
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Color_Spaces">
+<title>Color Spaces</title>
+<!-- .XS -->
+<!-- (SN Color Spaces -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The <acronym>CIE</acronym> XYZ color space serves as the hub for all
+conversions between device-independent and device-dependent color spaces.
+Therefore, the knowledge to convert an
+<structname>XcmsColor</structname>
+structure to and from <acronym>CIE</acronym> XYZ format is associated with each color space.
+For example, conversion from <acronym>CIE</acronym> L*u*v* to <acronym>RGB</acronym> requires the knowledge
+to convert from <acronym>CIE</acronym> L*u*v* to <acronym>CIE</acronym> XYZ and from <acronym>CIE</acronym> XYZ to <acronym>RGB</acronym>.
+This knowledge is stored as an array of functions that,
+when applied in series, will convert the
+<structname>XcmsColor</structname>
+structure to or from <acronym>CIE</acronym> XYZ format.
+This color specification conversion mechanism facilitates
+the addition of color spaces.
+</para>
+<para>
+<!-- .LP -->
+Of course, when converting between only device-independent color spaces
+or only device-dependent color spaces,
+shortcuts are taken whenever possible.
+For example, conversion from TekHVC to <acronym>CIE</acronym> L*u*v* is performed
+by intermediate conversion to <acronym>CIE</acronym> u*v*Y and then to <acronym>CIE</acronym> L*u*v*,
+thus bypassing conversion between <acronym>CIE</acronym> u*v*Y and <acronym>CIE</acronym> XYZ.
+</para>
+</sect2>
+<sect2 id="Adding_Device_Independent_Color_Spaces">
+<title>Adding Device-Independent Color Spaces</title>
+<!-- .XS -->
+<!-- (SN Adding Device-Independent Color Spaces -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To add a device-independent color space, use
+<function>XcmsAddColorSpace</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsAddColorSpace</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsaddcolorspace'>
+<funcprototype>
+ <funcdef>Status <function>XcmsAddColorSpace</function></funcdef>
+ <paramdef>XcmsColorSpace<parameter> *color_space</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_space</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the device-independent color space to add.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsAddColorSpace</function>
+function makes a device-independent color space (actually an
+<structname>XcmsColorSpace</structname>
+structure) accessible by the color management system.
+Because format values for unregistered color spaces are assigned at run time,
+they should be treated as private to the client.
+If references to an unregistered color space must be made
+outside the client (for example, storing color specifications
+in a file using the unregistered color space),
+then reference should be made by color space prefix
+(see
+<function>XcmsFormatOfPrefix</function>
+and
+<function>XcmsPrefixOfFormat</function>).
+</para>
+<para>
+<!-- .LP -->
+If the
+<structname>XcmsColorSpace</structname>
+structure is already accessible in the color management system,
+<function>XcmsAddColorSpace</function>
+returns
+<symbol>XcmsSuccess</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Note that added
+<structname>XcmsColorSpace</structname>s
+must be retained for reference by Xlib.
+</para>
+</sect2>
+<sect2 id="Querying_Color_Space_Format_and_Prefix">
+<title>Querying Color Space Format and Prefix</title>
+<!-- .XS -->
+<!-- (SN Querying Color Space Format and Prefix -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To obtain the format associated with the color space
+associated with a specified color string prefix, use
+<function>XcmsFormatOfPrefix</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsFormatOfPrefix</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsformatofprefix'>
+<funcprototype>
+ <funcdef>XcmsColorFormat <function>XcmsFormatOfPrefix</function></funcdef>
+ <paramdef>char<parameter> *prefix</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prefix</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string that contains the color space prefix.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsFormatOfPrefix</function>
+function returns the format for the specified color space prefix
+(for example, the string ``CIEXYZ'').
+The prefix is case-insensitive.
+If the color space is not accessible in the color management system,
+<function>XcmsFormatOfPrefix</function>
+returns
+<symbol>XcmsUndefinedFormat</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the color string prefix associated with the color space
+specified by a color format, use
+<function>XcmsPrefixOfFormat</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsPrefixOfFormat</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsprefixofformat'>
+<funcprototype>
+ <funcdef>char *<function>XcmsPrefixOfFormat</function></funcdef>
+ <paramdef>XcmsColorFormat<parameter> format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color specification format.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsPrefixOfFormat</function>
+function returns the string prefix associated with the color specification
+encoding specified by the format argument.
+Otherwise, if no encoding is found, it returns NULL.
+The returned string must be treated as read-only.
+</para>
+</sect2>
+<sect2 id="Creating_Additional_Color_Spaces">
+<title>Creating Additional Color Spaces</title>
+<!-- .XS -->
+<!-- (SN Creating Additional Color Spaces -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Color space specific information necessary
+for color space conversion and color string parsing is stored in an
+<structname>XcmsColorSpace</structname>
+structure.
+Therefore, a new structure containing this information is required
+for each additional color space.
+In the case of device-independent color spaces,
+a handle to this new structure (that is, by means of a global variable)
+is usually made accessible to the client program for use with the
+<function>XcmsAddColorSpace</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+If a new
+<structname>XcmsColorSpace</structname>
+structure specifies a color space not registered with the X Consortium,
+they should be treated as private to the client
+because format values for unregistered color spaces are assigned at run time.
+If references to an unregistered color space must be made outside the
+client (for example, storing color specifications in a file using the
+unregistered color space), then reference should be made by color space prefix
+(see
+<function>XcmsFormatOfPrefix</function>
+and
+<function>XcmsPrefixOfFormat</function>).
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef (*XcmsConversionProc)();
+typedef XcmsConversionProc *XcmsFuncListPtr;
+ /* A NULL terminated list of function pointers*/
+
+typedef struct _XcmsColorSpace {
+ char *prefix;
+ XcmsColorFormat format;
+ XcmsParseStringProc parseString;
+ XcmsFuncListPtr to_CIEXYZ;
+ XcmsFuncListPtr from_CIEXYZ;
+ int inverse_flag;
+} XcmsColorSpace;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The prefix member specifies the prefix that indicates a color string
+is in this color space's string format.
+For example, the strings ``ciexyz'' or ``CIEXYZ'' for <acronym>CIE</acronym> XYZ,
+and ``rgb'' or ``<acronym>RGB</acronym>'' for <acronym>RGB</acronym>.
+The prefix is case insensitive.
+The format member specifies the color specification format.
+Formats for unregistered color spaces are assigned at run time.
+The parseString member contains a pointer to the function
+that can parse a color string into an
+<structname>XcmsColor</structname>
+structure.
+This function returns an integer (int): nonzero if it succeeded
+and zero otherwise.
+The to_CIEXYZ and from_CIEXYZ members contain pointers,
+each to a NULL terminated list of function pointers.
+When the list of functions is executed in series,
+it will convert the color specified in an
+<structname>XcmsColor</structname>
+structure from/to the current color space format to/from the <acronym>CIE</acronym> XYZ format.
+Each function returns an integer (int): nonzero if it succeeded
+and zero otherwise.
+The white point to be associated with the colors is specified
+explicitly, even though white points can be found in the CCC.
+The inverse_flag member, if nonzero, specifies that for each function listed
+in to_CIEXYZ,
+its inverse function can be found in from_CIEXYZ such that:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Given: n = number of functions in each list
+
+for each i, such that 0 <= i < n
+ from_CIEXYZ[n - i - 1] is the inverse of to_CIEXYZ[i].
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+This allows Xlib to use the shortest conversion path,
+thus bypassing <acronym>CIE</acronym> XYZ if possible (for example, TekHVC to <acronym>CIE</acronym> L*u*v*).
+</para>
+</sect2>
+<sect2 id="Parse_String_Callback">
+<title>Parse String Callback</title>
+<!-- .XS -->
+<!-- (SN Parse String Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The callback in the
+<structname>XcmsColorSpace</structname>
+structure for parsing a color string for the particular color space must
+adhere to the following software interface specification:
+</para>
+<indexterm significance="preferred"><primary>XcmsParseStringProc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsparsestringproc'>
+<funcprototype>
+ <funcdef>Status <function>XcmsParseStringProc</function></funcdef>
+ <paramdef>char<parameter> *color_string</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *color_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the color string to parse.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>color_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the color specification in the color space's format.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect2>
+<sect2 id="Color_Specification_Conversion_Callback">
+<title>Color Specification Conversion Callback</title>
+<!-- .XS -->
+<!-- (SN Color Specification Conversion Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Callback functions in the
+<structname>XcmsColorSpace</structname>
+structure for converting a color specification between device-independent
+spaces must adhere to the
+following software interface specification:
+</para>
+<!-- .sM -->
+<funcsynopsis id='conversionproc'>
+<funcprototype>
+ <funcdef>Status <function><replaceable>ConversionProc</replaceable></function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *white_point</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *colors_in_out</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>white_point</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the white point associated with color specifications.
+The pixel member should be ignored,
+and the entire structure remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color specifications.
+Pixel members should be ignored and must remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+Callback functions in the
+<structname>XcmsColorSpace</structname>
+structure for converting a color specification to or from a device-dependent
+space must adhere to the
+following software interface specification:
+</para>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>Status <function><replaceable>ConversionProc</replaceable></function></funcdef>
+ <paramdef>XcmsCCC<parameter> ccc</parameter></paramdef>
+ <paramdef>XcmsColor<parameter> *colors_in_out</parameter></paramdef>
+ <paramdef>unsignedint<parameter> ncolors</parameter></paramdef>
+ <paramdef>Bool<parameter> compression_flags_return[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ccc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the CCC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colors_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of color specifications.
+Pixel members should be ignored and must remain unchanged upon return.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ncolors</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of
+<structname>XcmsColor</structname>
+structures in the color-specification array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>compression_flags_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of Boolean values for indicating compression status.
+If a non-NULL pointer is supplied
+and a color at a given index is compressed, then
+<symbol>True</symbol>
+should be stored at the corresponding index in this array;
+otherwise, the array should not be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Conversion functions are available globally for use by other color
+spaces.
+The conversion functions provided by Xlib are:
+</para>
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry align='center'>Function</entry>
+ <entry align='center'>Converts from</entry>
+ <entry align='center'>Converts to</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><function>XcmsCIELabToCIEXYZ</function></entry>
+ <entry><symbol>XcmsCIELabFormat</symbol></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIELuvToCIEuvY</function></entry>
+ <entry><symbol>XcmsCIELuvFormat</symbol></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEXYZToCIELab</function></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ <entry><symbol>XcmsCIELabFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEXYZToCIEuvY</function></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEXYZToCIExyY</function></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ <entry><symbol>XcmsCIExyYFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEXYZToRGBi</function></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ <entry><symbol>XcmsRGBiFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEuvYToCIELuv</function></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ <entry><symbol>XcmsCIELabFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEuvYToCIEXYZ</function></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIEuvYToTekHVC</function></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ <entry><symbol>XcmsTekHVCFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsCIExyYToCIEXYZ</function></entry>
+ <entry><symbol>XcmsCIExyYFormat</symbol></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsRGBToRGBi</function></entry>
+ <entry><symbol>XcmsRGBFormat</symbol></entry>
+ <entry><symbol>XcmsRGBiFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsRGBiToCIEXYZ</function></entry>
+ <entry><symbol>XcmsRGBiFormat</symbol></entry>
+ <entry><symbol>XcmsCIEXYZFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsRGBiToRGB</function></entry>
+ <entry><symbol>XcmsRGBiFormat</symbol></entry>
+ <entry><symbol>XcmsRGBFormat</symbol></entry>
+ </row>
+ <row>
+ <entry><function>XcmsTekHVCToCIEuvY</function></entry>
+ <entry><symbol>XcmsTekHVCFormat</symbol></entry>
+ <entry><symbol>XcmsCIEuvYFormat</symbol></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+</sect2>
+<sect2 id="Function_Sets">
+<title>Function Sets</title>
+<!-- .XS -->
+<!-- (SN Function Sets -->
+<!-- .XE -->
+<indexterm><primary>Function set</primary></indexterm>
+<indexterm><primary>Function set</primary><secondary>LINEAR_RGB</secondary></indexterm>
+<para>
+<!-- .LP -->
+Functions to convert between device-dependent color spaces
+and <acronym>CIE</acronym> XYZ may differ for different classes of output devices
+(for example, color versus gray monitors).
+Therefore, the notion of a Color Characterization Function Set
+has been developed.
+A function set consists of device-dependent color spaces
+and the functions that convert color specifications
+between these device-dependent color spaces and the <acronym>CIE</acronym> XYZ color space
+appropriate for a particular class of output devices.
+The function set also contains a function that reads
+color characterization data off root window properties.
+It is this characterization data that will differ between devices within
+a class of output devices.
+<indexterm><primary>Device Color Characterization</primary></indexterm>
+For details about how color characterization data is
+stored in root window properties,
+see the section on Device Color Characterization in the
+<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>.
+The LINEAR_RGB function set is provided by Xlib
+and will support most color monitors.
+Function sets may require data that differs
+from those needed for the LINEAR_RGB function set.
+In that case,
+its corresponding data may be stored on different root window properties.
+</para>
+</sect2>
+<sect2 id="Adding_Function_Sets">
+<title>Adding Function Sets</title>
+<!-- .XS -->
+<!-- (SN Adding Function Sets -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To add a function set, use
+<function>XcmsAddFunctionSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XcmsAddFunctionSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcmsaddfunctionset'>
+<funcprototype>
+ <funcdef>Status <function>XcmsAddFunctionSet</function></funcdef>
+ <paramdef>XcmsFunctionSet<parameter> *function_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>function_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the function set to add.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XcmsAddFunctionSet</function>
+function adds a function set to the color management system.
+If the function set uses device-dependent
+<structname>XcmsColorSpace</structname>
+structures not accessible in the color management system,
+<function>XcmsAddFunctionSet</function>
+adds them.
+If an added
+<structname>XcmsColorSpace</structname>
+structure is for a device-dependent color space not registered
+with the X Consortium,
+they should be treated as private to the client
+because format values for unregistered color spaces are assigned at run time.
+If references to an unregistered color space must be made outside the
+client (for example, storing color specifications in a file
+using the unregistered color space),
+then reference should be made by color space prefix
+(see
+<function>XcmsFormatOfPrefix</function>
+and
+<function>XcmsPrefixOfFormat</function>).
+</para>
+<para>
+<!-- .LP -->
+Additional function sets should be added before any calls to other
+Xlib routines are made.
+If not, the
+<structname>XcmsPerScrnInfo</structname>
+member of a previously created
+<structname>XcmsCCC</structname>
+does not have the opportunity to initialize
+with the added function set.
+</para>
+</sect2>
+<sect2 id="Creating_Additional_Function_Sets">
+<title>Creating Additional Function Sets</title>
+<!-- .XS -->
+<!-- (SN Creating Additional Function Sets -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The creation of additional function sets should be
+required only when an output device does not conform to existing
+function sets or when additional device-dependent color spaces are necessary.
+A function set consists primarily of a collection of device-dependent
+<structname>XcmsColorSpace</structname>
+structures and a means to read and store a
+screen's color characterization data.
+This data is stored in an
+<structname>XcmsFunctionSet</structname>
+structure.
+A handle to this structure (that is, by means of global variable)
+is usually made accessible to the client program for use with
+<function>XcmsAddFunctionSet</function>.
+</para>
+<para>
+<!-- .LP -->
+If a function set uses new device-dependent
+<structname>XcmsColorSpace</structname>
+structures,
+they will be transparently processed into the color management system.
+Function sets can share an
+<structname>XcmsColorSpace</structname>
+structure for a device-dependent color space.
+In addition, multiple
+<structname>XcmsColorSpace</structname>
+structures are allowed for a device-dependent color space;
+however, a function set can reference only one of them.
+These
+<structname>XcmsColorSpace</structname>
+structures will differ in the functions to convert to and from <acronym>CIE</acronym> XYZ,
+thus tailored for the specific function set.
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct _XcmsFunctionSet {
+ XcmsColorSpace **DDColorSpaces;
+ XcmsScreenInitProc screenInitProc;
+ XcmsScreenFreeProc screenFreeProc;
+} XcmsFunctionSet;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The DDColorSpaces member is a pointer to a NULL terminated list
+of pointers to
+<structname>XcmsColorSpace</structname>
+structures for the device-dependent color spaces that are supported
+by the function set.
+The screenInitProc member is set to the callback procedure (see the following
+interface specification) that initializes the
+<structname>XcmsPerScrnInfo</structname>
+structure for a particular screen.
+</para>
+<para>
+<!-- .LP -->
+The screen initialization callback must adhere to the following software
+interface specification:
+<indexterm significance="preferred"><primary>XcmsScreenInitProc</primary></indexterm>
+<!-- .sM -->
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>typedef Status <function>(*XcmsScreenInitProc</function>)</funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+ <paramdef>ScmsPerScrnInfo<parameter> *screen_info</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_info</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XcmsPerScrnInfo</structname>
+structure, which contains the per screen information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The screen initialization callback in the
+<structname>XcmsFunctionSet</structname>
+structure fetches the color characterization data (device profile) for
+the specified screen,
+typically off properties on the
+screen's root window.
+It then initializes the specified
+<structname>XcmsPerScrnInfo</structname>
+structure.
+<indexterm><primary>Device profile</primary></indexterm>
+<indexterm><primary>Color Characterization Data</primary></indexterm>
+If successful, the procedure fills in the
+<structname>XcmsPerScrnInfo</structname>
+structure as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+It sets the screenData member to the address
+of the created device profile data structure
+(contents known only by the function set).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It next sets the screenWhitePoint member.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It next sets the functionSet member to the address of the
+<structname>XcmsFunctionSet</structname>
+structure.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+It then sets the state member to
+<symbol>XcmsInitSuccess</symbol>
+and finally returns
+<symbol>XcmsSuccess</symbol>.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+If unsuccessful, the procedure sets the state member to
+<symbol>XcmsInitFailure</symbol>
+and returns
+<symbol>XcmsFailure</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XcmsPerScrnInfo</structname>
+structure contains:
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct _XcmsPerScrnInfo {
+ XcmsColor screenWhitePoint;
+ XPointer functionSet;
+ XPointer screenData;
+ unsigned char state;
+ char pad[3];
+} XcmsPerScrnInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The screenWhitePoint member specifies the white point inherent to
+the screen.
+The functionSet member specifies the appropriate function set.
+The screenData member specifies the device profile.
+The state member is set to one of the following:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<symbol>XcmsInitNone</symbol>
+indicates initialization has not been previously attempted.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>XcmsInitFailure</symbol>
+indicates initialization has been previously attempted but failed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<symbol>XcmsInitSuccess</symbol>
+indicates initialization has been previously attempted and succeeded.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The screen free callback must adhere to the following software
+interface specification:
+</para>
+<funcsynopsis>
+<funcprototype>
+ <funcdef>typedef void (*XcmsScreenFreeProc)</funcdef>
+ <paramdef>XPointer<parameter> screenData</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screenData</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data to be freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+This function is called to free the screenData stored in an
+<structname>XcmsPerScrnInfo</structname>
+structure.
+<!-- .bp -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH07.xml b/libX11/specs/libX11/CH07.xml index 0b873078a..38baccc39 100644 --- a/libX11/specs/libX11/CH07.xml +++ b/libX11/specs/libX11/CH07.xml @@ -1,3402 +1,3402 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="graphics_context_functions"> -<title>Graphics Context Functions</title> - -<para> -A number of resources are used when performing graphics operations in X. Most information -about performing graphics (for example, foreground color, background color, line style, and so -on) is stored in resources called graphics contexts (GCs). Most graphics operations (see chapter -8) take a GC as an argument. Although in theory the X protocol permits sharing of GCs between -applications, it is expected that applications will use their own GCs when performing operations. -Sharing of GCs is highly discouraged because the library may cache GC state. -</para> -<para> -Graphics operations can be performed to either windows or pixmaps, which collectively are -called drawables. Each drawable exists on a single screen. A GC is created for a specific screen -and drawable depth and can only be used with drawables of matching screen and depth. -</para> -<para> -This chapter discusses how to: -</para> -<itemizedlist> - <listitem><para>Manipulate graphics context/state</para></listitem> - <listitem><para>Use graphics context convenience functions</para></listitem> -</itemizedlist> - -<sect1 id="Manipulating_Graphics_Context_State"> -<title>Manipulating Graphics Context/State</title> -<!-- .XS --> -<!-- (SN Manipulating Graphics Context/State --> -<!-- .XE --> -<para> -<!-- .LP --> -Most attributes of graphics operations are stored in GCs. -These include line width, line style, plane mask, foreground, background, -tile, stipple, clipping region, end style, join style, and so on. -Graphics operations (for example, drawing lines) use these values -to determine the actual drawing operation. -Extensions to X may add additional components to GCs. -The contents of a GC are private to Xlib. -</para> -<para> -<!-- .LP --> -Xlib implements a write-back cache for all elements of a GC that are not -resource IDs to allow Xlib to implement the transparent coalescing of changes -to GCs. -For example, -a call to -<function>XSetForeground</function> -of a GC followed by a call to -<function>XSetLineAttributes</function> -results in only a single-change GC protocol request to the server. -GCs are neither expected nor encouraged to be shared between client -applications, so this write-back caching should present no problems. -Applications cannot share GCs without external synchronization. -Therefore, -sharing GCs between applications is highly discouraged. -</para> -<para> -<!-- .LP --> -To set an attribute of a GC, -set the appropriate member of the -<structname>XGCValues</structname> -structure and OR in the corresponding value bitmask in your subsequent calls to -<function>XCreateGC</function>. -The symbols for the value mask bits and the -<structname>XGCValues</structname> -structure are: -<!-- .sM --> -</para> - - -<literallayout class="monospaced"> -/* GC attribute value mask bits */ - -#define GCFunction (1L<<0) -#define GCPlaneMask (1L<<1) -#define GCForeground (1L<<2) -#define GCBackground (1L<<3) -#define GCLineWidth (1L<<4) -#define GCLineStyle (1L<<5) -#define GCCapStyle (1L<<6) -#define GCJoinStyle (1L<<7) -#define GCFillStyle (1L<<8) -#define GCFillRule (1L<<9) -#define GCTile (1L<<10) -#define GCStipple (1L<<11) -#define GCTileStipXOrigin (1L<<12) -#define GCTileStipYOrigin (1L<<13) -#define GCFont (1L<<14) -#define GCSubwindowMode (1L<<15) -#define GCGraphicsExposures (1L<<16) -#define GCClipXOrigin (1L<<17) -#define GCClipYOrigin (1L<<18) -#define GCClipMask (1L<<19) -#define GCDashOffset (1L<<20) -#define GCDashList (1L<<21) -#define GCArcMode (1L<<22) -</literallayout> - -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -/* Values */ - -typedef struct { - int function; /* logical operation */ - unsigned long plane_mask; /* plane mask */ - unsigned long foreground; /* foreground pixel */ - unsigned long background; /* background pixel */ - int line_width; /* line width (in pixels) */ - int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ - int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ - int join_style; /* JoinMiter, JoinRound, JoinBevel */ - int fill_style; /* FillSolid, FillTiled, FillStippled FillOpaqueStippled*/ - int fill_rule; /* EvenOddRule, WindingRule */ - int arc_mode; /* ArcChord, ArcPieSlice */ - Pixmap tile; /* tile pixmap for tiling operations */ - Pixmap stipple; /* stipple 1 plane pixmap for stippling */ - int ts_x_origin; /* offset for tile or stipple operations */ - int ts_y_origin - Font font; /* default text font for text operations */ - int subwindow_mode; /* ClipByChildren, IncludeInferiors */ - Bool graphics_exposures; /* boolean, should exposures be generated */ - int clip_x_origin; /* origin for clipping */ - int clip_y_origin; - Pixmap clip_mask; /* bitmap clipping; other calls for rects */ - int dash_offset; /* patterned/dashed line information */ - char dashes; -} XGCValues; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The default GC values are: -</para> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='center'>Component</entry> - <entry align='center'>Default</entry> - </row> - </thead> - <tbody> - <row> - <entry>function</entry> - <entry><symbol>GXcopy</symbol></entry> - </row> - <row> - <entry>plane_mask</entry> - <entry>All ones</entry> - </row> - <row> - <entry>foreground</entry> - <entry>0</entry> - </row> - <row> - <entry>background</entry> - <entry>1</entry> - </row> - <row> - <entry>line_width</entry> - <entry>0</entry> - </row> - <row> - <entry>line_style</entry> - <entry><symbol>LineSolid</symbol></entry> - </row> - <row> - <entry>cap_style</entry> - <entry><symbol>CapButt</symbol></entry> - </row> - <row> - <entry>join_style</entry> - <entry><symbol>JoinMiter</symbol></entry> - </row> - <row> - <entry>fill_style</entry> - <entry><symbol>FillSolid</symbol></entry> - </row> - <row> - <entry>fill_rule</entry> - <entry><symbol>EvenOddRule</symbol></entry> - </row> - <row> - <entry>arc_mode</entry> - <entry><symbol>ArcPieSlice</symbol></entry> - </row> - <row> - <entry>tile</entry> - <entry> - <para>Pixmap of unspecified size filled with foreground pixel</para> - <para>(that is, client specified pixel if any, else 0)</para> - <para>(subsequent changes to foreground do not affect this pixmap)</para> - </entry> - </row> - <row> - <entry>stipple</entry> - <entry>Pixmap of unspecified size filled with ones</entry> - </row> - <row> - <entry>ts_x_origin</entry> - <entry>0</entry> - </row> - <row> - <entry>ts_y_origin</entry> - <entry>0</entry> - </row> - <row> - <entry>font</entry> - <entry><implementation dependent></entry> - </row> - <row> - <entry>subwindow_mode</entry> - <entry><symbol>ClipByChildren</symbol></entry> - </row> - <row> - <entry>graphics_exposures</entry> - <entry><symbol>True</symbol></entry> - </row> - <row> - <entry>clip_x_origin</entry> - <entry>0</entry> - </row> - <row> - <entry>clip_y_origin</entry> - <entry>0</entry> - </row> - <row> - <entry>clip_mask</entry> - <entry><symbol>None</symbol></entry> - </row> - <row> - <entry>dash_offset</entry> - <entry>0</entry> - </row> - <row> - <entry>dashes</entry> - <entry>4 (that is, the list [4, 4])</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Note that foreground and background are not set to any values likely -to be useful in a window. -</para> - -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>Display Functions</primary></indexterm> -<indexterm significance="preferred"><primary>Source</primary></indexterm> -<indexterm significance="preferred"><primary>Destination</primary></indexterm> -The function attributes of a GC are used when you update a section of -a drawable (the destination) with bits from somewhere else (the source). -The function in a GC defines how the new destination bits are to be -computed from the source bits and the old destination bits. -<symbol>GXcopy</symbol> -is typically the most useful because it will work on a color display, -but special applications may use other functions, -particularly in concert with particular planes of a color display. -The 16 GC functions, defined in -<filename class="headerfile"><X11/X.h></filename>, -<indexterm type="file"><primary><filename class="headerfile">X11/X.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X.h></filename></secondary></indexterm> -are: -</para> -<!-- .\" are listed in Table 5-1 along with the --> -<!-- .\"the associated hexadecimal code --> -<!-- .\" and operation. --> -<!-- .\".CP T 1 --> -<!-- .\"Display Functions --> -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <thead> - <row> - <entry align='center'>Function Name</entry> - <entry align='center'>Value</entry> - <entry align='center'>Operation</entry> - </row> - </thead> - <tbody> - <row> - <entry><symbol>GXclear</symbol></entry> - <entry>0x0</entry> - <entry>0</entry> - </row> - <row> - <entry><symbol>GXand</symbol></entry> - <entry>0x1</entry> - <entry>src AND dst</entry> - </row> - <row> - <entry><symbol>GXandReverse</symbol></entry> - <entry>0x2</entry> - <entry>src AND NOT dst</entry> - </row> - <row> - <entry><symbol>GXcopy</symbol></entry> - <entry>0x3</entry> - <entry>src</entry> - </row> - <row> - <entry><symbol>GXandInverted</symbol></entry> - <entry>0x4</entry> - <entry>(NOT src) AND dst</entry> - </row> - <row> - <entry><symbol>GXnoop</symbol></entry> - <entry>0x5</entry> - <entry>dst</entry> - </row> - <row> - <entry><symbol>GXxor</symbol></entry> - <entry>0x6</entry> - <entry>src XOR dst</entry> - </row> - <row> - <entry><symbol>GXor</symbol></entry> - <entry>0x7</entry> - <entry>src OR dst</entry> - </row> - <row> - <entry><symbol>GXnor</symbol></entry> - <entry>0x8</entry> - <entry>(NOT src) AND (NOT dst)</entry> - </row> - <row> - <entry><symbol>GXequiv</symbol></entry> - <entry>0x9</entry> - <entry>(NOT src) XOR dst</entry> - </row> - <row> - <entry><symbol>GXinvert</symbol></entry> - <entry>0xa</entry> - <entry>NOT dst</entry> - </row> - <row> - <entry><symbol>GXorReverse</symbol></entry> - <entry>0xb</entry> - <entry>src OR (NOT dst)</entry> - </row> - <row> - <entry><symbol>GXcopyInverted</symbol></entry> - <entry>0xc</entry> - <entry>NOT src</entry> - </row> - <row> - <entry><symbol>GXorInverted</symbol></entry> - <entry>0xd</entry> - <entry>(NOT src) OR dst</entry> - </row> - <row> - <entry><symbol>GXnand</symbol></entry> - <entry>0xe</entry> - <entry>(NOT src) OR (NOT dst)</entry> - </row> - <row> - <entry><symbol>GXset</symbol></entry> - <entry>0xf</entry> - <entry>1</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Many graphics operations depend on either pixel values or planes in a GC. -<indexterm><primary>Pixel value</primary></indexterm> -The planes attribute is of type long, and it specifies which planes of the -destination are to be modified, one bit per plane. -<indexterm><primary>Plane</primary><secondary>mask</secondary></indexterm> -A monochrome display has only one plane and -will be the least significant bit of the word. -As planes are added to the display hardware, they will occupy more -significant bits in the plane mask. -</para> -<para> -<!-- .LP --> -In graphics operations, given a source and destination pixel, -the result is computed bitwise on corresponding bits of the pixels. -That is, a Boolean operation is performed in each bit plane. -The plane_mask restricts the operation to a subset of planes. -A macro constant -<symbol>AllPlanes</symbol> -can be used to refer to all planes of the screen simultaneously. -The result is computed by the following: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -((src FUNC dst) AND plane-mask) OR (dst AND (NOT plane-mask)) -</literallayout> -</para> -<para> -<!-- .LP --> -Range checking is not performed on the values for foreground, -background, or plane_mask. -They are simply truncated to the appropriate -number of bits. -The line-width is measured in pixels and either can be greater than or equal to -one (wide line) or can be the special value zero (thin line). -</para> -<para> -<!-- .LP --> -Wide lines are drawn centered on the path described by the graphics request. -Unless otherwise specified by the join-style or cap-style, -the bounding box of a wide line with endpoints [x1, y1], [x2, y2] and -width w is a rectangle with vertices at the following real coordinates: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -[x1-(w*sn/2), y1+(w*cs/2)], [x1+(w*sn/2), y1-(w*cs/2)], -[x2-(w*sn/2), y2+(w*cs/2)], [x2+(w*sn/2), y2-(w*cs/2)] -</literallayout> -</para> -<para> -<!-- .LP --> -Here sn is the sine of the angle of the line, -and cs is the cosine of the angle of the line. -A pixel is part of the line and so is drawn -if the center of the pixel is fully inside the bounding box -(which is viewed as having infinitely thin edges). -If the center of the pixel is exactly on the bounding box, -it is part of the line if and only if the interior is immediately to its right -(x increasing direction). -Pixels with centers on a horizontal edge are a special case and are part of -the line if and only if the interior or the boundary is immediately below -(y increasing direction) and the interior or the boundary is immediately -to the right (x increasing direction). -</para> -<para> -<!-- .LP --> -Thin lines (zero line-width) are one-pixel-wide lines drawn using an -unspecified, device-dependent algorithm. -There are only two constraints on this algorithm. -</para> -<itemizedlist> - <listitem> - <para> -If a line is drawn unclipped from [x1,y1] to [x2,y2] and -if another line is drawn unclipped from [x1+dx,y1+dy] to [x2+dx,y2+dy], -a point [x,y] is touched by drawing the first line -if and only if the point [x+dx,y+dy] is touched by drawing the second line. - </para> - </listitem> - <listitem> - <para> -The effective set of points comprising a line cannot be affected by clipping. -That is, a point is touched in a clipped line if and only if the point -lies inside the clipping region and the point would be touched -by the line when drawn unclipped. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -A wide line drawn from [x1,y1] to [x2,y2] always draws the same pixels -as a wide line drawn from [x2,y2] to [x1,y1], not counting cap-style -and join-style. -It is recommended that this property be true for thin lines, -but this is not required. -A line-width of zero may differ from a line-width of one in which pixels are -drawn. -This permits the use of many manufacturers' line drawing hardware, -which may run many times faster than the more precisely specified -wide lines. -</para> -<para> -<!-- .LP --> -In general, -drawing a thin line will be faster than drawing a wide line of width one. -However, because of their different drawing algorithms, -thin lines may not mix well aesthetically with wide lines. -If it is desirable to obtain precise and uniform results across all displays, -a client should always use a line-width of one rather than a line-width of zero. -</para> -<para> -<!-- .LP --> -The line-style defines which sections of a line are drawn: -</para> - -<variablelist> - <varlistentry> - <term><symbol>LineSolid</symbol></term> - <listitem> - <para>The full path of the line is drawn.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>LineDoubleDash</symbol></term> - <listitem> - <para> -The full path of the line is drawn, -but the even dashes are filled differently -from the odd dashes (see fill-style) with <!-- xref --> -<symbol>CapButt</symbol> -style used where even and odd dashes meet. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>LineOnOffDash</symbol></term> - <listitem> - <para> -Only the even dashes are drawn, -and cap-style applies to -all internal ends of the individual dashes, -except -<symbol>CapNotLast</symbol> -is treated as -<symbol>CapButt</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -The cap-style defines how the endpoints of a path are drawn: -</para> - -<variablelist> - <varlistentry> - <term><symbol>CapNotLast</symbol></term> - <listitem> - <para> -This is equivalent to -<symbol>CapButt</symbol> -except that for a line-width of zero the final endpoint is not drawn. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><symbol>CapButt</symbol></term> - <listitem> - <para> -The line is square at the endpoint (perpendicular to the slope of the line) -with no projection beyond. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>CapRound</symbol></term> - <listitem> - <para> -The line has a circular arc with the diameter equal to the line-width, -centered on the endpoint. -(This is equivalent to -<symbol>CapButt</symbol> -for line-width of zero). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>CapProjecting</symbol></term> - <listitem> - <para> -The line is square at the end, but the path continues beyond the endpoint -for a distance equal to half the line-width. -(This is equivalent to -<symbol>CapButt</symbol> -for line-width of zero). - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -The join-style defines how corners are drawn for wide lines: -</para> - -<variablelist> - <varlistentry> - <term><symbol>JoinMiter</symbol></term> - <listitem> - <para> -The outer edges of two lines extend to meet at an angle. -However, if the angle is less than 11 degrees, -then a -<symbol>JoinBevel</symbol> -join-style is used instead. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>JoinRound</symbol></term> - <listitem> - <para> -The corner is a circular arc with the diameter equal to the line-width, -centered on the joinpoint. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><symbol>JoinBevel</symbol></term> - <listitem> - <para> -The corner has -<symbol>CapButt</symbol> -endpoint styles with the triangular notch filled. - </para> - </listitem> - </varlistentry> -</variablelist> - - -<para> -<!-- .LP --> -For a line with coincident endpoints (x1=x2, y1=y2), -when the cap-style is applied to both endpoints, -the semantics depends on the line-width and the cap-style: -</para> - -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <tbody> - <row> - <entry><symbol>CapNotLast</symbol></entry> - <entry>thin</entry> - <entry>The results are device dependent, - but the desired effect is that nothing is drawn.</entry> - </row> - <row> - <entry><symbol>CapButt</symbol></entry> - <entry>thin</entry> - <entry>The results are device dependent, - but the desired effect is that a single pixel is drawn.</entry> - </row> - <row> - <entry><symbol>CapRound</symbol></entry> - <entry>thin</entry> - <entry>The results are the same as for - <symbol>CapButt</symbol> /thin.</entry> - </row> - <row> - <entry><symbol>CapProjecting</symbol></entry> - <entry>thin</entry> - <entry>The results are the same as for - <symbol>CapButt</symbol> /thin.</entry> - </row> - <row> - <entry><symbol>CapButt</symbol></entry> - <entry>wide</entry> - <entry>Nothing is drawn.</entry> - </row> - <row> - <entry><symbol>CapRound</symbol></entry> - <entry>wide</entry> - <entry>The closed path is a circle, centered at the endpoint, and - with the diameter equal to the line-width.</entry> - </row> - <row> - <entry><symbol>CapProjecting</symbol></entry> - <entry>wide</entry> - <entry>The closed path is a square, aligned with the coordinate axes, centered at the - endpoint, and with the sides equal to the line-width.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -For a line with coincident endpoints (x1=x2, y1=y2), -when the join-style is applied at one or both endpoints, -the effect is as if the line was removed from the overall path. -However, if the total path consists of or is reduced to a single point joined -with itself, the effect is the same as when the cap-style is applied at both -endpoints. -</para> -<para> -<!-- .LP --> -The tile/stipple represents an infinite two-dimensional plane, -with the tile/stipple replicated in all dimensions. -When that plane is superimposed on the drawable -for use in a graphics operation, the upper-left corner -of some instance of the tile/stipple is at the coordinates within -the drawable specified by the tile/stipple origin. -The tile/stipple and clip origins are interpreted relative to the -origin of whatever destination drawable is specified in a graphics -request. -The tile pixmap must have the same root and depth as the GC, -or a -<errorname>BadMatch</errorname> -error results. -The stipple pixmap must have depth one and must have the same root as the -GC, or a -<errorname>BadMatch</errorname> -error results. -For stipple operations where the fill-style is -<symbol>FillStippled</symbol> -but not -<symbol>FillOpaqueStippled</symbol>, -the stipple pattern is tiled in a -single plane and acts as an additional clip mask to be ANDed with the clip-mask. -Although some sizes may be faster to use than others, -any size pixmap can be used for tiling or stippling. -</para> - -<para> -<!-- .LP --> -The fill-style defines the contents of the source for line, text, and -fill requests. -For all text and fill requests (for example, -<function>XDrawText</function>, -<function>XDrawText16</function>, -<function>XFillRectangle</function>, -<function>XFillPolygon</function>, -and -<function>XFillArc</function>); -for line requests -with line-style -<symbol>LineSolid</symbol> -(for example, -<function>XDrawLine</function>, -<function>XDrawSegments</function>, -<function>XDrawRectangle</function>, -<function>XDrawArc</function>); -and for the even dashes for line requests with line-style -<symbol>LineOnOffDash</symbol> -or -<symbol>LineDoubleDash</symbol>, -the following apply: -</para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>FillSolid</symbol></entry> - <entry>Foreground</entry> - </row> - <row> - <entry><symbol>FillTiled</symbol></entry> - <entry>Tile</entry> - </row> - <row> - <entry><symbol>FillOpaqueStippled</symbol></entry> - <entry>A tile with the same width and height as stipple, - but with background everywhere stipple has a zero - and with foreground everywhere stipple has a one</entry> - </row> - <row> - <entry><symbol>FillStippled</symbol></entry> - <entry>Foreground masked by stipple</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -When drawing lines with line-style -<symbol>LineDoubleDash</symbol>, -the odd dashes are controlled by the fill-style in the following manner: -</para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>FillSolid</symbol></entry> - <entry>Background</entry> - </row> - <row> - <entry><symbol>FillTiled</symbol></entry> - <entry>Same as for even dashes</entry> - </row> - <row> - <entry><symbol>FillOpaqueStippled</symbol></entry> - <entry>Same as for even dashes</entry> - </row> - <row> - <entry><symbol>FillStippled</symbol></entry> - <entry>Background masked by stipple</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Storing a pixmap in a GC might or might not result in a copy -being made. -If the pixmap is later used as the destination for a graphics request, -the change might or might not be reflected in the GC. -If the pixmap is used simultaneously in a graphics request both as -a destination and as a tile or stipple, -the results are undefined. -</para> -<para> -<!-- .LP --> -For optimum performance, -you should draw as much as possible with the same GC -(without changing its components). -The costs of changing GC components relative to using different GCs -depend on the display hardware and the server implementation. -It is quite likely that some amount of GC information will be -cached in display hardware and that such hardware can only cache a small number -of GCs. -</para> -<para> -<!-- .LP --> -The dashes value is actually a simplified form of the -more general patterns that can be set with -<function>XSetDashes</function>. -Specifying a -value of N is equivalent to specifying the two-element list [N, N] in -<function>XSetDashes</function>. -The value must be nonzero, -or a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -The clip-mask restricts writes to the destination drawable. -If the clip-mask is set to a pixmap, -it must have depth one and have the same root as the GC, -or a -<errorname>BadMatch</errorname> -error results. -If clip-mask is set to -<symbol>None</symbol>, -the pixels are always drawn regardless of the clip origin. -The clip-mask also can be set by calling the -<function>XSetClipRectangles</function> -or -<function>XSetRegion</function> -functions. -Only pixels where the clip-mask has a bit set to 1 are drawn. -Pixels are not drawn outside the area covered by the clip-mask -or where the clip-mask has a bit set to 0. -The clip-mask affects all graphics requests. -The clip-mask does not clip sources. -The clip-mask origin is interpreted relative to the origin of whatever -destination drawable is specified in a graphics request. -</para> -<para> -<!-- .LP --> -You can set the subwindow-mode to -<symbol>ClipByChildren</symbol> -or -<symbol>IncludeInferiors</symbol>. -For -<symbol>ClipByChildren</symbol>, -both source and destination windows are -additionally clipped by all viewable -<symbol>InputOutput</symbol> -children. -For -<symbol>IncludeInferiors</symbol>, -neither source nor destination window is clipped by inferiors. -This will result in including subwindow contents in the source -and drawing through subwindow boundaries of the destination. -The use of -<symbol>IncludeInferiors</symbol> -on a window of one depth with mapped -inferiors of differing depth is not illegal, but the semantics are -undefined by the core protocol. -</para> -<para> -<!-- .LP --> -The fill-rule defines what pixels are inside (drawn) for -paths given in -<function>XFillPolygon</function> -requests and can be set to -<symbol>EvenOddRule</symbol> -or -<symbol>WindingRule</symbol>. -For -<symbol>EvenOddRule</symbol>, -a point is inside if -an infinite ray with the point as origin crosses the path an odd number -of times. -For -<symbol>WindingRule</symbol>, -a point is inside if an infinite ray with the -point as origin crosses an unequal number of clockwise and -counterclockwise directed path segments. -A clockwise directed path segment is one that crosses the ray from left to -right as observed from the point. -A counterclockwise segment is one that crosses the ray from right to left -as observed from the point. -The case where a directed line segment is coincident with the ray is -uninteresting because you can simply choose a different ray that is not -coincident with a segment. -</para> -<para> -<!-- .LP --> -For both -<symbol>EvenOddRule</symbol> -and -<symbol>WindingRule</symbol>, -a point is infinitely small, -and the path is an infinitely thin line. -A pixel is inside if the center point of the pixel is inside -and the center point is not on the boundary. -If the center point is on the boundary, -the pixel is inside if and only if the polygon interior is immediately to -its right (x increasing direction). -Pixels with centers on a horizontal edge are a special case -and are inside if and only if the polygon interior is immediately below -(y increasing direction). -</para> -<para> -<!-- .LP --> -The arc-mode controls filling in the -<function>XFillArcs</function> -function and can be set to -<symbol>ArcPieSlice</symbol> -or -<symbol>ArcChord</symbol>. -For -<symbol>ArcPieSlice</symbol>, -the arcs are pie-slice filled. -For -<symbol>ArcChord</symbol>, -the arcs are chord filled. -</para> -<para> -<!-- .LP --> -The graphics-exposure flag controls -<symbol>GraphicsExpose</symbol> -event generation -for -<function>XCopyArea</function> -and -<function>XCopyPlane</function> -requests (and any similar requests defined by extensions). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a new GC that is usable on a given screen with a -depth of drawable, use -<function>XCreateGC</function>. -</para> -<indexterm><primary>Graphics context</primary><secondary>initializing</secondary></indexterm> -<indexterm significance="preferred"><primary>XCreateGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreategc'> -<funcprototype> - <funcdef>GC <function>XCreateGC</function></funcdef> - <paramdef>Display <parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> - <paramdef>XGCValues *<parameter>values</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. -<!-- .ds Vm set using the information in the specified values structure --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which components in the GC are to be (Vm. -This argument is the bitwise inclusive OR of zero or more of the valid -GC component mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values</emphasis> - </term> - <listitem> - <para> -Specifies any values as specified by the valuemask. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateGC</function> -function creates a graphics context and returns a GC. -The GC can be used with any destination drawable having the same root -and depth as the specified drawable. -Use with other drawables results in a -<errorname>BadMatch</errorname> -error. -</para> -<para> -<!-- .LP --> -<function>XCreateGC</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadDrawable</errorname>, -<errorname>BadFont</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To copy components from a source GC to a destination GC, use -<function>XCopyGC</function>. -</para> -<indexterm significance="preferred"><primary>XCopyGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcopygc'> -<funcprototype> - <funcdef><function>XCopyGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GCsrc,<parameter> dest</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src</emphasis> - </term> - <listitem> - <para> -Specifies the components of the source GC. -<!-- .ds Vm copied to the destination GC --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which components in the GC are to be (Vm. -This argument is the bitwise inclusive OR of zero or more of the valid -GC component mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest</emphasis> - </term> - <listitem> - <para> -Specifies the destination GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCopyGC</function> -function copies the specified components from the source GC -to the destination GC. -The source and destination GCs must have the same root and depth, -or a -<errorname>BadMatch</errorname> -error results. -The valuemask specifies which component to copy, as for -<function>XCreateGC</function>. -</para> -<para> -<!-- .LP --> -<function>XCopyGC</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change the components in a given GC, use -<function>XChangeGC</function>. -</para> -<indexterm significance="preferred"><primary>XChangeGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangegc'> -<funcprototype> - <funcdef><function>XChangeGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> - <paramdef>XGCValues<parameter> *values</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Vm changed using information in the specified values structure --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which components in the GC are to be (Vm. -This argument is the bitwise inclusive OR of zero or more of the valid -GC component mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values</emphasis> - </term> - <listitem> - <para> -Specifies any values as specified by the valuemask. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangeGC</function> -function changes the components specified by valuemask for -the specified GC. -The values argument contains the values to be set. -The values and restrictions are the same as for -<function>XCreateGC</function>. -Changing the clip-mask overrides any previous -<function>XSetClipRectangles</function> -request on the context. -Changing the dash-offset or dash-list -overrides any previous -<function>XSetDashes</function> -request on the context. -The order in which components are verified and altered is server dependent. -If an error is generated, a subset of the components may have been altered. -</para> -<para> -<!-- .LP --> -<function>XChangeGC</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadFont</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain components of a given GC, use -<function>XGetGCValues</function>. -</para> -<indexterm significance="preferred"><primary>XGetGCValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetgcvalues'> -<funcprototype> - <funcdef>Status <function>XGetGCValues</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef> - <paramdef>XGCValues<parameter> *values_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Vm returned in the values_return argument --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>valuemask</emphasis> - </term> - <listitem> - <para> -Specifies which components in the GC are to be (Vm. -This argument is the bitwise inclusive OR of zero or more of the valid -GC component mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values_return</emphasis> - </term> - <listitem> - <para> -Returns the GC values in the specified -<structname>XGCValues</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetGCValues</function> -function returns the components specified by valuemask for the specified GC. -If the valuemask contains a valid set of GC mask bits -(<symbol>GCFunction</symbol>, -<symbol>GCPlaneMask</symbol>, -<symbol>GCForeground</symbol>, -<symbol>GCBackground</symbol>, -<symbol>GCLineWidth</symbol>, -<symbol>GCLineStyle</symbol>, -<symbol>GCCapStyle</symbol>, -<symbol>GCJoinStyle</symbol>, -<symbol>GCFillStyle</symbol>, -<symbol>GCFillRule</symbol>, -<symbol>GCTile</symbol>, -<symbol>GCStipple</symbol>, -<symbol>GCTileStipXOrigin</symbol>, -<symbol>GCTileStipYOrigin</symbol>, -<symbol>GCFont</symbol>, -<symbol>GCSubwindowMode</symbol>, -<symbol>GCGraphicsExposures</symbol>, -<symbol>GCClipXOrigin</symbol>, -<symbol>GCClipYOrigin</symbol>, -<symbol>GCDashOffset</symbol>, -or -<symbol>GCArcMode</symbol>) -and no error occurs, -<function>XGetGCValues</function> -sets the requested components in values_return and returns a nonzero status. -Otherwise, it returns a zero status. -Note that the clip-mask and dash-list (represented by the -<symbol>GCClipMask</symbol> -and -<symbol>GCDashList</symbol> -bits, respectively, in the valuemask) -cannot be requested. -Also note that an invalid resource ID (with one or more of the three -most significant bits set to 1) will be returned for -<symbol>GCFont</symbol>, -<symbol>GCTile</symbol>, -and -<symbol>GCStipple</symbol> -if the component has never been explicitly set by the client. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free a given GC, use -<function>XFreeGC</function>. -</para> -<indexterm significance="preferred"><primary>XFreeGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreegc'> -<funcprototype> - <funcdef><function>XFreeGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeGC</function> -function destroys the specified GC as well as all the associated storage. -</para> -<para> -<!-- .LP --> -<function>XFreeGC</function> -can generate a -<errorname>BadGC</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the -<type>GContext</type> -resource ID for a given GC, use -<function>XGContextFromGC</function>. -</para> -<indexterm significance="preferred"><primary>XGContextFromGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgcontextfromgc'> -<funcprototype> - <funcdef>GContext <function>XGContextFromGC</function></funcdef> - <paramdef>GC<parameter> gc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Gc for which you want the resource ID --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC (Gc. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -Xlib usually defers sending changes to the components of a GC to the server -until a graphics function is actually called with that GC. -This permits batching of component changes into a single server request. -In some circumstances, however, it may be necessary for the client -to explicitly force sending the changes to the server. -An example might be when a protocol extension uses the GC indirectly, -in such a way that the extension interface cannot know what GC will be used. -To force sending GC component changes, use -<function>XFlushGC</function>. -</para> -<indexterm significance="preferred"><primary>XFlushGC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xflushgc'> -<funcprototype> - <funcdef>void <function>XFlushGC</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect1> -<sect1 id="Using_Graphics_Context_Convenience_Routines"> -<title>Using Graphics Context Convenience Routines</title> -<!-- .XS --> -<!-- (SN Using Graphics Context Convenience Routines --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses how to set the: -</para> -<itemizedlist> - <listitem> - <para> -Foreground, background, plane mask, or function components - </para> - </listitem> - <listitem> - <para> -Line attributes and dashes components - </para> - </listitem> - <listitem> - <para> -Fill style and fill rule components - </para> - </listitem> - <listitem> - <para> -Fill tile and stipple components - </para> - </listitem> - <listitem> - <para> -Font component - </para> - </listitem> - <listitem> - <para> -Clip region component - </para> - </listitem> - <listitem> - <para> -Arc mode, subwindow mode, and graphics exposure components - </para> - </listitem> -</itemizedlist> -<sect2 id="Setting_the_Foreground_Background_Function_or_Plane_Mask"> -<title>Setting the Foreground, Background, Function, or Plane Mask</title> -<!-- .XS --> -<!-- (SN Setting the Foreground, Background, Function, or Plane Mask --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the foreground, background, plane mask, and function components -for a given GC, use -<function>XSetState</function>. -</para> -<indexterm significance="preferred"><primary>XSetState</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetstate'> -<funcprototype> - <funcdef><function>XSetState</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlongforeground,<parameter> background</parameter></paramdef> - <paramdef>int<parameter> function</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>foreground</emphasis> - </term> - <listitem> - <para> -Specifies the foreground you want to set for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background</emphasis> - </term> - <listitem> - <para> -Specifies the background you want to set for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>function</emphasis> - </term> - <listitem> - <para> -Specifies the function you want to set for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane_mask</emphasis> - </term> - <listitem> - <para> -Specifies the plane mask. -<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** --> - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetState</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the foreground of a given GC, use -<function>XSetForeground</function>. -</para> -<indexterm significance="preferred"><primary>XSetForeground</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetforeground'> -<funcprototype> - <funcdef><function>XSetForeground</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlong<parameter> foreground</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>foreground</emphasis> - </term> - <listitem> - <para> -Specifies the foreground you want to set for the specified GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetForeground</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the background of a given GC, use -<function>XSetBackground</function>. -</para> -<indexterm significance="preferred"><primary>XSetBackground</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetbackground'> -<funcprototype> - <funcdef><function>XSetBackground</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlong<parameter> background</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>background</emphasis> - </term> - <listitem> - <para> -Specifies the background you want to set for the specified GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetBackground</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the display function in a given GC, use -<function>XSetFunction</function>. -</para> -<indexterm significance="preferred"><primary>XSetFunction</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetfunction'> -<funcprototype> - <funcdef><function>XSetFunction</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> function</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>function</emphasis> - </term> - <listitem> - <para> -Specifies the function you want to set for the specified GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetFunction</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the plane mask of a given GC, use -<function>XSetPlaneMask</function>. -</para> -<indexterm significance="preferred"><primary>XSetPlaneMask</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetplanemask'> -<funcprototype> - <funcdef><function>XSetPlaneMask</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane_mask</emphasis> - </term> - <listitem> - <para> -Specifies the plane mask. -<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** --> - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetPlaneMask</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_the_Line_Attributes_and_Dashes"> -<title>Setting the Line Attributes and Dashes</title> -<!-- .XS --> -<!-- (SN Setting the Line Attributes and Dashes --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the line drawing components of a given GC, use -<function>XSetLineAttributes</function>. -</para> -<indexterm significance="preferred"><primary>XSetLineAttributes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetlineattributes'> -<funcprototype> - <funcdef><function>XSetLineAttributes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>unsignedint<parameter> line_width</parameter></paramdef> - <paramdef>int<parameter> line_style</parameter></paramdef> - <paramdef>int<parameter> cap_style</parameter></paramdef> - <paramdef>int<parameter> join_style</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>line_width</emphasis> - </term> - <listitem> - <para> -Specifies the line-width you want to set for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>line_style</emphasis> - </term> - <listitem> - <para> -Specifies the line-style you want to set for the specified GC. -You can pass -<symbol>LineSolid</symbol>, -<symbol>LineOnOffDash</symbol>, -or -<symbol>LineDoubleDash</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cap_style</emphasis> - </term> - <listitem> - <para> -Specifies the line-style and cap-style you want to set for the specified GC. -You can pass -<symbol>CapNotLast</symbol>, -<symbol>CapButt</symbol>, -<symbol>CapRound</symbol>, -or -<symbol>CapProjecting</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>join_style</emphasis> - </term> - <listitem> - <para> -Specifies the line join-style you want to set for the specified GC. -You can pass -<symbol>JoinMiter</symbol>, -<symbol>JoinRound</symbol>, -or -<symbol>JoinBevel</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetLineAttributes</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the dash-offset and dash-list for dashed line styles of a given GC, use -<function>XSetDashes</function>. -</para> -<indexterm significance="preferred"><primary>XSetDashes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetdashes'> -<funcprototype> - <funcdef><function>XSetDashes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> dash_offset</parameter></paramdef> - <paramdef>char<parameter> dash_list[]</parameter></paramdef> - <paramdef>int<parameter> n</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dash_offset</emphasis> - </term> - <listitem> - <para> -Specifies the phase of the pattern for the dashed line-style you want to set -for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dash_list</emphasis> - </term> - <listitem> - <para> -Specifies the dash-list for the dashed line-style -you want to set for the specified GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>n</emphasis> - </term> - <listitem> - <para> -Specifies the number of elements in dash_list. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetDashes</function> -function sets the dash-offset and dash-list attributes for dashed line styles -in the specified GC. -There must be at least one element in the specified dash_list, -or a -<errorname>BadValue</errorname> -error results. -The initial and alternating elements (second, fourth, and so on) -of the dash_list are the even dashes, and -the others are the odd dashes. -Each element specifies a dash length in pixels. -All of the elements must be nonzero, -or a -<errorname>BadValue</errorname> -error results. -Specifying an odd-length list is equivalent to specifying the same list -concatenated with itself to produce an even-length list. -</para> -<para> -<!-- .LP --> -The dash-offset defines the phase of the pattern, -specifying how many pixels into the dash-list the pattern -should actually begin in any single graphics request. -Dashing is continuous through path elements combined with a join-style -but is reset to the dash-offset between each sequence of joined lines. -</para> -<para> -<!-- .LP --> -The unit of measure for dashes is the same for the ordinary coordinate system. -Ideally, a dash length is measured along the slope of the line, but implementations -are only required to match this ideal for horizontal and vertical lines. -Failing the ideal semantics, it is suggested that the length be measured along the -major axis of the line. -The major axis is defined as the x axis for lines drawn at an angle of between -−45 and +45 degrees or between 135 and 225 degrees from the x axis. -For all other lines, the major axis is the y axis. -</para> -<para> -<!-- .LP --> -<function>XSetDashes</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_the_Fill_Style_and_Fill_Rule_"> -<title>Setting the Fill Style and Fill Rule </title> -<!-- .XS --> -<!-- (SN Setting the Fill Style and Fill Rule --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the fill-style of a given GC, use -<function>XSetFillStyle</function>. -</para> -<indexterm significance="preferred"><primary>XSetFillStyle</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetfillstyle'> -<funcprototype> - <funcdef><function>XSetFillStyle</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> fill_style</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fill_style</emphasis> - </term> - <listitem> - <para> -Specifies the fill-style you want to set for the specified GC. -You can pass -<symbol>FillSolid</symbol>, -<symbol>FillTiled</symbol>, -<symbol>FillStippled</symbol>, -or -<symbol>FillOpaqueStippled</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetFillStyle</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the fill-rule of a given GC, use -<function>XSetFillRule</function>. -</para> -<indexterm significance="preferred"><primary>XSetFillRule</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetfillrule'> -<funcprototype> - <funcdef><function>XSetFillRule</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> fill_rule</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fill_rule</emphasis> - </term> - <listitem> - <para> -Specifies the fill-rule you want to set for the specified GC. -You can pass -<symbol>EvenOddRule</symbol> -or -<symbol>WindingRule</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetFillRule</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_the_Fill_Tile_and_Stipple_"> -<title>Setting the Fill Tile and Stipple </title> -<!-- .XS --> -<!-- (SN Setting the Fill Tile and Stipple --> -<!-- .XE --> -<para> -<!-- .LP --> -Some displays have hardware support for tiling or -stippling with patterns of specific sizes. -Tiling and stippling operations that restrict themselves to those specific -sizes run much faster than such operations with arbitrary size patterns. -Xlib provides functions that you can use to determine the best size, -tile, or stipple for the display -as well as to set the tile or stipple shape and the tile or stipple origin. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the best size of a tile, stipple, or cursor, use -<function>XQueryBestSize</function>. -</para> -<indexterm significance="preferred"><primary>XQueryBestSize</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerybestsize'> -<funcprototype> - <funcdef>Status <function>XQueryBestSize</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> class</parameter></paramdef> - <paramdef>Drawable<parameter> which_screen</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class</emphasis> - </term> - <listitem> - <para> -Specifies the class that you are interested in. -You can pass -<symbol>TileShape</symbol>, -<symbol>CursorShape</symbol>, -or -<symbol>StippleShape</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>which_screen</emphasis> - </term> - <listitem> - <para> -Specifies any drawable on the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height of the object best supported -by the display hardware. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryBestSize</function> -function returns the best or closest size to the specified size. -For -<symbol>CursorShape</symbol>, -this is the largest size that can be fully displayed on the screen specified by -which_screen. -For -<symbol>TileShape</symbol>, -this is the size that can be tiled fastest. -For -<symbol>StippleShape</symbol>, -this is the size that can be stippled fastest. -For -<symbol>CursorShape</symbol>, -the drawable indicates the desired screen. -For -<symbol>TileShape</symbol> -and -<symbol>StippleShape</symbol>, -the drawable indicates the screen and possibly the window class and depth. -An -<symbol>InputOnly</symbol> -window cannot be used as the drawable for -<symbol>TileShape</symbol> -or -<symbol>StippleShape</symbol>, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XQueryBestSize</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the best fill tile shape, use -<function>XQueryBestTile</function>. -</para> -<indexterm significance="preferred"><primary>XQueryBestTile</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerybesttile'> -<funcprototype> - <funcdef>Status <function>XQueryBestTile</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> which_screen</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>which_screen</emphasis> - </term> - <listitem> - <para> -Specifies any drawable on the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height of the object best supported -by the display hardware. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryBestTile</function> -function returns the best or closest size, that is, the size that can be -tiled fastest on the screen specified by which_screen. -The drawable indicates the screen and possibly the window class and depth. -If an -<symbol>InputOnly</symbol> -window is used as the drawable, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XQueryBestTile</function> -can generate -<errorname>BadDrawable</errorname> -and -<errorname>BadMatch</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the best stipple shape, use -<function>XQueryBestStipple</function>. -</para> -<indexterm significance="preferred"><primary>XQueryBestStipple</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerybeststipple'> -<funcprototype> - <funcdef>Status <function>XQueryBestStipple</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> which_screen</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>which_screen</emphasis> - </term> - <listitem> - <para> -Specifies any drawable on the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height of the object best supported -by the display hardware. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryBestStipple</function> -function returns the best or closest size, that is, the size that can be -stippled fastest on the screen specified by which_screen. -The drawable indicates the screen and possibly the window class and depth. -If an -<symbol>InputOnly</symbol> -window is used as the drawable, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XQueryBestStipple</function> -can generate -<errorname>BadDrawable</errorname> -and -<errorname>BadMatch</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the fill tile of a given GC, use -<function>XSetTile</function>. -</para> -<indexterm significance="preferred"><primary>XSetTile</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsettile'> -<funcprototype> - <funcdef><function>XSetTile</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Pixmap<parameter> tile</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>tile</emphasis> - </term> - <listitem> - <para> -Specifies the fill tile you want to set for the specified GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The tile and GC must have the same depth, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XSetTile</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadPixmap</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the stipple of a given GC, use -<function>XSetStipple</function>. -</para> -<indexterm significance="preferred"><primary>XSetStipple</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetstipple'> -<funcprototype> - <funcdef><function>XSetStipple</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Pixmap<parameter> stipple</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>stipple</emphasis> - </term> - <listitem> - <para> -Specifies the stipple you want to set for the specified GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The stipple must have a depth of one, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XSetStipple</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadPixmap</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the tile or stipple origin of a given GC, use -<function>XSetTSOrigin</function>. -</para> -<indexterm significance="preferred"><primary>XSetTSOrigin</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsettsorigin'> -<funcprototype> - <funcdef><function>XSetTSOrigin</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intts_x_origin,<parameter> ts_y_origin</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ts_x_origin</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ts_y_origin</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates of the tile and stipple origin. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -When graphics requests call for tiling or stippling, -the parent's origin will be interpreted relative to whatever destination -drawable is specified in the graphics request. -</para> -<para> -<!-- .LP --> -<function>XSetTSOrigin</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_the_Current_Font_"> -<title>Setting the Current Font </title> -<!-- .XS --> -<!-- (SN Setting the Current Font --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the current font of a given GC, use -<function>XSetFont</function>. -</para> -<indexterm significance="preferred"><primary>XSetFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetfont'> -<funcprototype> - <funcdef><function>XSetFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Font<parameter> font</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font</emphasis> - </term> - <listitem> - <para> -Specifies the font. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetFont</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadFont</errorname>, -and -<errorname>BadGC</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_the_Clip_Region"> -<title>Setting the Clip Region</title> -<!-- .XS --> -<!-- (SN Setting the Clip Region --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set the clip-origin -and the clip-mask or set the clip-mask to a list of rectangles. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the clip-origin of a given GC, use -<function>XSetClipOrigin</function>. -</para> -<indexterm significance="preferred"><primary>XSetClipOrigin</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetcliporigin'> -<funcprototype> - <funcdef><function>XSetClipOrigin</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intclip_x_origin,<parameter> clip_y_origin</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>clip_x_origin</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>clip_y_origin</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates of the clip-mask origin. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The clip-mask origin is interpreted relative to the origin of whatever -destination drawable is specified in the graphics request. -</para> -<para> -<!-- .LP --> -<function>XSetClipOrigin</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the clip-mask of a given GC to the specified pixmap, use -<function>XSetClipMask</function>. -</para> -<indexterm significance="preferred"><primary>XSetClipMask</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetclipmask'> -<funcprototype> - <funcdef><function>XSetClipMask</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Pixmap<parameter> pixmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixmap</emphasis> - </term> - <listitem> - <para> -Specifies the pixmap or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the clip-mask is set to -<symbol>None</symbol>, -the pixels are always drawn (regardless of the clip-origin). -</para> -<para> -<!-- .LP --> -<function>XSetClipMask</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadPixmap</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the clip-mask of a given GC to the specified list of rectangles, use -<function>XSetClipRectangles</function>. -</para> -<indexterm significance="preferred"><primary>XSetClipRectangles</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetcliprectangles'> -<funcprototype> - <funcdef><function>XSetClipRectangles</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intclip_x_origin,<parameter> clip_y_origin</parameter></paramdef> - <paramdef>XRectangle<parameter> rectangles[]</parameter></paramdef> - <paramdef>int<parameter> n</parameter></paramdef> - <paramdef>int<parameter> ordering</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>clip_x_origin</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>clip_y_origin</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates of the clip-mask origin. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rectangles</emphasis> - </term> - <listitem> - <para> -Specifies an array of rectangles that define the clip-mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>n</emphasis> - </term> - <listitem> - <para> -Specifies the number of rectangles. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ordering</emphasis> - </term> - <listitem> - <para> -Specifies the ordering relations on the rectangles. -You can pass -<symbol>Unsorted</symbol>, -<symbol>YSorted</symbol>, -<symbol>YXSorted</symbol>, -or -<symbol>YXBanded</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetClipRectangles</function> -function changes the clip-mask in the specified GC -to the specified list of rectangles and sets the clip origin. -The output is clipped to remain contained within the -rectangles. -The clip-origin is interpreted relative to the origin of -whatever destination drawable is specified in a graphics request. -The rectangle coordinates are interpreted relative to the clip-origin. -The rectangles should be nonintersecting, or the graphics results will be -undefined. -Note that the list of rectangles can be empty, -which effectively disables output. -This is the opposite of passing -<symbol>None</symbol> -as the clip-mask in -<function>XCreateGC</function>, -<function>XChangeGC</function>, -and -<function>XSetClipMask</function>. -</para> -<para> -<!-- .LP --> -If known by the client, ordering relations on the rectangles can be -specified with the ordering argument. -This may provide faster operation -by the server. -If an incorrect ordering is specified, the X server may generate a -<errorname>BadMatch</errorname> -error, but it is not required to do so. -If no error is generated, the graphics -results are undefined. -<symbol>Unsorted</symbol> -means the rectangles are in arbitrary order. -<symbol>YSorted</symbol> -means that the rectangles are nondecreasing in their Y origin. -<symbol>YXSorted</symbol> -additionally constrains -<symbol>YSorted</symbol> -order in that all -rectangles with an equal Y origin are nondecreasing in their X -origin. -<symbol>YXBanded</symbol> -additionally constrains -<symbol>YXSorted</symbol> -by requiring that, -for every possible Y scanline, all rectangles that include that -scanline have an identical Y origins and Y extents. -</para> -<para> -<!-- .LP --> -<function>XSetClipRectangles</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -Xlib provides a set of basic functions for performing -region arithmetic. -For information about these functions, -see <link linkend="Manipulating_Regions">section 16.5</link>. -</para> -</sect2> -<sect2 id="Setting_the_Arc_Mode_Subwindow_Mode_and_Graphics_Exposure_"> -<title>Setting the Arc Mode, Subwindow Mode, and Graphics Exposure </title> -<!-- .XS --> -<!-- (SN Setting the Arc Mode, Subwindow Mode, and Graphics Exposure --> -<!-- .XE --> -<para> -<!-- .LP --> -To set the arc mode of a given GC, use -<function>XSetArcMode</function>. -</para> -<indexterm significance="preferred"><primary>XSetArcMode</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetarcmode'> -<funcprototype> - <funcdef><function>XSetArcMode</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> arc_mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arc_mode</emphasis> - </term> - <listitem> - <para> -Specifies the arc mode. -You can pass -<symbol>ArcChord</symbol> -or -<symbol>ArcPieSlice</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetArcMode</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the subwindow mode of a given GC, use -<function>XSetSubwindowMode</function>. -</para> -<indexterm significance="preferred"><primary>XSetSubwindowMode</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetsubwindowmode'> -<funcprototype> - <funcdef><function>XSetSubwindowMode</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> subwindow_mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>subwindow_mode</emphasis> - </term> - <listitem> - <para> -Specifies the subwindow mode. -You can pass -<symbol>ClipByChildren</symbol> -or -<symbol>IncludeInferiors</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetSubwindowMode</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the graphics-exposures flag of a given GC, use -<function>XSetGraphicsExposures</function>. -</para> -<indexterm significance="preferred"><primary>XSetGraphicsExposures</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetgraphicsexposures'> -<funcprototype> - <funcdef><function>XSetGraphicsExposures</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Bool<parameter> graphics_exposures</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>graphics_exposures</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether you want -<symbol>GraphicsExpose</symbol> -and -<symbol>NoExpose</symbol> -events to be reported when calling -<function>XCopyArea</function> -and -<function>XCopyPlane</function> -with this GC. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XSetGraphicsExposures</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -<!-- .bp --> - -</para> -</sect2> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="graphics_context_functions">
+<title>Graphics Context Functions</title>
+
+<para>
+A number of resources are used when performing graphics operations in X. Most information
+about performing graphics (for example, foreground color, background color, line style, and so
+on) is stored in resources called graphics contexts (GCs). Most graphics operations (see chapter
+8) take a GC as an argument. Although in theory the X protocol permits sharing of GCs between
+applications, it is expected that applications will use their own GCs when performing operations.
+Sharing of GCs is highly discouraged because the library may cache GC state.
+</para>
+<para>
+Graphics operations can be performed to either windows or pixmaps, which collectively are
+called drawables. Each drawable exists on a single screen. A GC is created for a specific screen
+and drawable depth and can only be used with drawables of matching screen and depth.
+</para>
+<para>
+This chapter discusses how to:
+</para>
+<itemizedlist>
+ <listitem><para>Manipulate graphics context/state</para></listitem>
+ <listitem><para>Use graphics context convenience functions</para></listitem>
+</itemizedlist>
+
+<sect1 id="Manipulating_Graphics_Context_State">
+<title>Manipulating Graphics Context/State</title>
+<!-- .XS -->
+<!-- (SN Manipulating Graphics Context/State -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Most attributes of graphics operations are stored in GCs.
+These include line width, line style, plane mask, foreground, background,
+tile, stipple, clipping region, end style, join style, and so on.
+Graphics operations (for example, drawing lines) use these values
+to determine the actual drawing operation.
+Extensions to X may add additional components to GCs.
+The contents of a GC are private to Xlib.
+</para>
+<para>
+<!-- .LP -->
+Xlib implements a write-back cache for all elements of a GC that are not
+resource IDs to allow Xlib to implement the transparent coalescing of changes
+to GCs.
+For example,
+a call to
+<function>XSetForeground</function>
+of a GC followed by a call to
+<function>XSetLineAttributes</function>
+results in only a single-change GC protocol request to the server.
+GCs are neither expected nor encouraged to be shared between client
+applications, so this write-back caching should present no problems.
+Applications cannot share GCs without external synchronization.
+Therefore,
+sharing GCs between applications is highly discouraged.
+</para>
+<para>
+<!-- .LP -->
+To set an attribute of a GC,
+set the appropriate member of the
+<structname>XGCValues</structname>
+structure and OR in the corresponding value bitmask in your subsequent calls to
+<function>XCreateGC</function>.
+The symbols for the value mask bits and the
+<structname>XGCValues</structname>
+structure are:
+<!-- .sM -->
+</para>
+
+
+<literallayout class="monospaced">
+/* GC attribute value mask bits */
+
+#define GCFunction (1L<<0)
+#define GCPlaneMask (1L<<1)
+#define GCForeground (1L<<2)
+#define GCBackground (1L<<3)
+#define GCLineWidth (1L<<4)
+#define GCLineStyle (1L<<5)
+#define GCCapStyle (1L<<6)
+#define GCJoinStyle (1L<<7)
+#define GCFillStyle (1L<<8)
+#define GCFillRule (1L<<9)
+#define GCTile (1L<<10)
+#define GCStipple (1L<<11)
+#define GCTileStipXOrigin (1L<<12)
+#define GCTileStipYOrigin (1L<<13)
+#define GCFont (1L<<14)
+#define GCSubwindowMode (1L<<15)
+#define GCGraphicsExposures (1L<<16)
+#define GCClipXOrigin (1L<<17)
+#define GCClipYOrigin (1L<<18)
+#define GCClipMask (1L<<19)
+#define GCDashOffset (1L<<20)
+#define GCDashList (1L<<21)
+#define GCArcMode (1L<<22)
+</literallayout>
+
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+/* Values */
+
+typedef struct {
+ int function; /* logical operation */
+ unsigned long plane_mask; /* plane mask */
+ unsigned long foreground; /* foreground pixel */
+ unsigned long background; /* background pixel */
+ int line_width; /* line width (in pixels) */
+ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
+ int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */
+ int join_style; /* JoinMiter, JoinRound, JoinBevel */
+ int fill_style; /* FillSolid, FillTiled, FillStippled FillOpaqueStippled*/
+ int fill_rule; /* EvenOddRule, WindingRule */
+ int arc_mode; /* ArcChord, ArcPieSlice */
+ Pixmap tile; /* tile pixmap for tiling operations */
+ Pixmap stipple; /* stipple 1 plane pixmap for stippling */
+ int ts_x_origin; /* offset for tile or stipple operations */
+ int ts_y_origin
+ Font font; /* default text font for text operations */
+ int subwindow_mode; /* ClipByChildren, IncludeInferiors */
+ Bool graphics_exposures; /* boolean, should exposures be generated */
+ int clip_x_origin; /* origin for clipping */
+ int clip_y_origin;
+ Pixmap clip_mask; /* bitmap clipping; other calls for rects */
+ int dash_offset; /* patterned/dashed line information */
+ char dashes;
+} XGCValues;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The default GC values are:
+</para>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='center'>Component</entry>
+ <entry align='center'>Default</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>function</entry>
+ <entry><symbol>GXcopy</symbol></entry>
+ </row>
+ <row>
+ <entry>plane_mask</entry>
+ <entry>All ones</entry>
+ </row>
+ <row>
+ <entry>foreground</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>background</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>line_width</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>line_style</entry>
+ <entry><symbol>LineSolid</symbol></entry>
+ </row>
+ <row>
+ <entry>cap_style</entry>
+ <entry><symbol>CapButt</symbol></entry>
+ </row>
+ <row>
+ <entry>join_style</entry>
+ <entry><symbol>JoinMiter</symbol></entry>
+ </row>
+ <row>
+ <entry>fill_style</entry>
+ <entry><symbol>FillSolid</symbol></entry>
+ </row>
+ <row>
+ <entry>fill_rule</entry>
+ <entry><symbol>EvenOddRule</symbol></entry>
+ </row>
+ <row>
+ <entry>arc_mode</entry>
+ <entry><symbol>ArcPieSlice</symbol></entry>
+ </row>
+ <row>
+ <entry>tile</entry>
+ <entry>
+ <para>Pixmap of unspecified size filled with foreground pixel</para>
+ <para>(that is, client specified pixel if any, else 0)</para>
+ <para>(subsequent changes to foreground do not affect this pixmap)</para>
+ </entry>
+ </row>
+ <row>
+ <entry>stipple</entry>
+ <entry>Pixmap of unspecified size filled with ones</entry>
+ </row>
+ <row>
+ <entry>ts_x_origin</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>ts_y_origin</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>font</entry>
+ <entry><implementation dependent></entry>
+ </row>
+ <row>
+ <entry>subwindow_mode</entry>
+ <entry><symbol>ClipByChildren</symbol></entry>
+ </row>
+ <row>
+ <entry>graphics_exposures</entry>
+ <entry><symbol>True</symbol></entry>
+ </row>
+ <row>
+ <entry>clip_x_origin</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>clip_y_origin</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>clip_mask</entry>
+ <entry><symbol>None</symbol></entry>
+ </row>
+ <row>
+ <entry>dash_offset</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry>dashes</entry>
+ <entry>4 (that is, the list [4, 4])</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Note that foreground and background are not set to any values likely
+to be useful in a window.
+</para>
+
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>Display Functions</primary></indexterm>
+<indexterm significance="preferred"><primary>Source</primary></indexterm>
+<indexterm significance="preferred"><primary>Destination</primary></indexterm>
+The function attributes of a GC are used when you update a section of
+a drawable (the destination) with bits from somewhere else (the source).
+The function in a GC defines how the new destination bits are to be
+computed from the source bits and the old destination bits.
+<symbol>GXcopy</symbol>
+is typically the most useful because it will work on a color display,
+but special applications may use other functions,
+particularly in concert with particular planes of a color display.
+The 16 GC functions, defined in
+<filename class="headerfile"><X11/X.h></filename>,
+<indexterm type="file"><primary><filename class="headerfile">X11/X.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/X.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/X.h></filename></secondary></indexterm>
+are:
+</para>
+<!-- .\" are listed in Table 5-1 along with the -->
+<!-- .\"the associated hexadecimal code -->
+<!-- .\" and operation. -->
+<!-- .\".CP T 1 -->
+<!-- .\"Display Functions -->
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry align='center'>Function Name</entry>
+ <entry align='center'>Value</entry>
+ <entry align='center'>Operation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><symbol>GXclear</symbol></entry>
+ <entry>0x0</entry>
+ <entry>0</entry>
+ </row>
+ <row>
+ <entry><symbol>GXand</symbol></entry>
+ <entry>0x1</entry>
+ <entry>src AND dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXandReverse</symbol></entry>
+ <entry>0x2</entry>
+ <entry>src AND NOT dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXcopy</symbol></entry>
+ <entry>0x3</entry>
+ <entry>src</entry>
+ </row>
+ <row>
+ <entry><symbol>GXandInverted</symbol></entry>
+ <entry>0x4</entry>
+ <entry>(NOT src) AND dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXnoop</symbol></entry>
+ <entry>0x5</entry>
+ <entry>dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXxor</symbol></entry>
+ <entry>0x6</entry>
+ <entry>src XOR dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXor</symbol></entry>
+ <entry>0x7</entry>
+ <entry>src OR dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXnor</symbol></entry>
+ <entry>0x8</entry>
+ <entry>(NOT src) AND (NOT dst)</entry>
+ </row>
+ <row>
+ <entry><symbol>GXequiv</symbol></entry>
+ <entry>0x9</entry>
+ <entry>(NOT src) XOR dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXinvert</symbol></entry>
+ <entry>0xa</entry>
+ <entry>NOT dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXorReverse</symbol></entry>
+ <entry>0xb</entry>
+ <entry>src OR (NOT dst)</entry>
+ </row>
+ <row>
+ <entry><symbol>GXcopyInverted</symbol></entry>
+ <entry>0xc</entry>
+ <entry>NOT src</entry>
+ </row>
+ <row>
+ <entry><symbol>GXorInverted</symbol></entry>
+ <entry>0xd</entry>
+ <entry>(NOT src) OR dst</entry>
+ </row>
+ <row>
+ <entry><symbol>GXnand</symbol></entry>
+ <entry>0xe</entry>
+ <entry>(NOT src) OR (NOT dst)</entry>
+ </row>
+ <row>
+ <entry><symbol>GXset</symbol></entry>
+ <entry>0xf</entry>
+ <entry>1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Many graphics operations depend on either pixel values or planes in a GC.
+<indexterm><primary>Pixel value</primary></indexterm>
+The planes attribute is of type long, and it specifies which planes of the
+destination are to be modified, one bit per plane.
+<indexterm><primary>Plane</primary><secondary>mask</secondary></indexterm>
+A monochrome display has only one plane and
+will be the least significant bit of the word.
+As planes are added to the display hardware, they will occupy more
+significant bits in the plane mask.
+</para>
+<para>
+<!-- .LP -->
+In graphics operations, given a source and destination pixel,
+the result is computed bitwise on corresponding bits of the pixels.
+That is, a Boolean operation is performed in each bit plane.
+The plane_mask restricts the operation to a subset of planes.
+A macro constant
+<symbol>AllPlanes</symbol>
+can be used to refer to all planes of the screen simultaneously.
+The result is computed by the following:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+((src FUNC dst) AND plane-mask) OR (dst AND (NOT plane-mask))
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Range checking is not performed on the values for foreground,
+background, or plane_mask.
+They are simply truncated to the appropriate
+number of bits.
+The line-width is measured in pixels and either can be greater than or equal to
+one (wide line) or can be the special value zero (thin line).
+</para>
+<para>
+<!-- .LP -->
+Wide lines are drawn centered on the path described by the graphics request.
+Unless otherwise specified by the join-style or cap-style,
+the bounding box of a wide line with endpoints [x1, y1], [x2, y2] and
+width w is a rectangle with vertices at the following real coordinates:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+[x1-(w*sn/2), y1+(w*cs/2)], [x1+(w*sn/2), y1-(w*cs/2)],
+[x2-(w*sn/2), y2+(w*cs/2)], [x2+(w*sn/2), y2-(w*cs/2)]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Here sn is the sine of the angle of the line,
+and cs is the cosine of the angle of the line.
+A pixel is part of the line and so is drawn
+if the center of the pixel is fully inside the bounding box
+(which is viewed as having infinitely thin edges).
+If the center of the pixel is exactly on the bounding box,
+it is part of the line if and only if the interior is immediately to its right
+(x increasing direction).
+Pixels with centers on a horizontal edge are a special case and are part of
+the line if and only if the interior or the boundary is immediately below
+(y increasing direction) and the interior or the boundary is immediately
+to the right (x increasing direction).
+</para>
+<para>
+<!-- .LP -->
+Thin lines (zero line-width) are one-pixel-wide lines drawn using an
+unspecified, device-dependent algorithm.
+There are only two constraints on this algorithm.
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If a line is drawn unclipped from [x1,y1] to [x2,y2] and
+if another line is drawn unclipped from [x1+dx,y1+dy] to [x2+dx,y2+dy],
+a point [x,y] is touched by drawing the first line
+if and only if the point [x+dx,y+dy] is touched by drawing the second line.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The effective set of points comprising a line cannot be affected by clipping.
+That is, a point is touched in a clipped line if and only if the point
+lies inside the clipping region and the point would be touched
+by the line when drawn unclipped.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+A wide line drawn from [x1,y1] to [x2,y2] always draws the same pixels
+as a wide line drawn from [x2,y2] to [x1,y1], not counting cap-style
+and join-style.
+It is recommended that this property be true for thin lines,
+but this is not required.
+A line-width of zero may differ from a line-width of one in which pixels are
+drawn.
+This permits the use of many manufacturers' line drawing hardware,
+which may run many times faster than the more precisely specified
+wide lines.
+</para>
+<para>
+<!-- .LP -->
+In general,
+drawing a thin line will be faster than drawing a wide line of width one.
+However, because of their different drawing algorithms,
+thin lines may not mix well aesthetically with wide lines.
+If it is desirable to obtain precise and uniform results across all displays,
+a client should always use a line-width of one rather than a line-width of zero.
+</para>
+<para>
+<!-- .LP -->
+The line-style defines which sections of a line are drawn:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><symbol>LineSolid</symbol></term>
+ <listitem>
+ <para>The full path of the line is drawn.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>LineDoubleDash</symbol></term>
+ <listitem>
+ <para>
+The full path of the line is drawn,
+but the even dashes are filled differently
+from the odd dashes (see fill-style) with <!-- xref -->
+<symbol>CapButt</symbol>
+style used where even and odd dashes meet.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>LineOnOffDash</symbol></term>
+ <listitem>
+ <para>
+Only the even dashes are drawn,
+and cap-style applies to
+all internal ends of the individual dashes,
+except
+<symbol>CapNotLast</symbol>
+is treated as
+<symbol>CapButt</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+The cap-style defines how the endpoints of a path are drawn:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><symbol>CapNotLast</symbol></term>
+ <listitem>
+ <para>
+This is equivalent to
+<symbol>CapButt</symbol>
+except that for a line-width of zero the final endpoint is not drawn.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>CapButt</symbol></term>
+ <listitem>
+ <para>
+The line is square at the endpoint (perpendicular to the slope of the line)
+with no projection beyond.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>CapRound</symbol></term>
+ <listitem>
+ <para>
+The line has a circular arc with the diameter equal to the line-width,
+centered on the endpoint.
+(This is equivalent to
+<symbol>CapButt</symbol>
+for line-width of zero).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>CapProjecting</symbol></term>
+ <listitem>
+ <para>
+The line is square at the end, but the path continues beyond the endpoint
+for a distance equal to half the line-width.
+(This is equivalent to
+<symbol>CapButt</symbol>
+for line-width of zero).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The join-style defines how corners are drawn for wide lines:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><symbol>JoinMiter</symbol></term>
+ <listitem>
+ <para>
+The outer edges of two lines extend to meet at an angle.
+However, if the angle is less than 11 degrees,
+then a
+<symbol>JoinBevel</symbol>
+join-style is used instead.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>JoinRound</symbol></term>
+ <listitem>
+ <para>
+The corner is a circular arc with the diameter equal to the line-width,
+centered on the joinpoint.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>JoinBevel</symbol></term>
+ <listitem>
+ <para>
+The corner has
+<symbol>CapButt</symbol>
+endpoint styles with the triangular notch filled.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+
+<para>
+<!-- .LP -->
+For a line with coincident endpoints (x1=x2, y1=y2),
+when the cap-style is applied to both endpoints,
+the semantics depends on the line-width and the cap-style:
+</para>
+
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <tbody>
+ <row>
+ <entry><symbol>CapNotLast</symbol></entry>
+ <entry>thin</entry>
+ <entry>The results are device dependent,
+ but the desired effect is that nothing is drawn.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapButt</symbol></entry>
+ <entry>thin</entry>
+ <entry>The results are device dependent,
+ but the desired effect is that a single pixel is drawn.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapRound</symbol></entry>
+ <entry>thin</entry>
+ <entry>The results are the same as for
+ <symbol>CapButt</symbol> /thin.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapProjecting</symbol></entry>
+ <entry>thin</entry>
+ <entry>The results are the same as for
+ <symbol>CapButt</symbol> /thin.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapButt</symbol></entry>
+ <entry>wide</entry>
+ <entry>Nothing is drawn.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapRound</symbol></entry>
+ <entry>wide</entry>
+ <entry>The closed path is a circle, centered at the endpoint, and
+ with the diameter equal to the line-width.</entry>
+ </row>
+ <row>
+ <entry><symbol>CapProjecting</symbol></entry>
+ <entry>wide</entry>
+ <entry>The closed path is a square, aligned with the coordinate axes, centered at the
+ endpoint, and with the sides equal to the line-width.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+For a line with coincident endpoints (x1=x2, y1=y2),
+when the join-style is applied at one or both endpoints,
+the effect is as if the line was removed from the overall path.
+However, if the total path consists of or is reduced to a single point joined
+with itself, the effect is the same as when the cap-style is applied at both
+endpoints.
+</para>
+<para>
+<!-- .LP -->
+The tile/stipple represents an infinite two-dimensional plane,
+with the tile/stipple replicated in all dimensions.
+When that plane is superimposed on the drawable
+for use in a graphics operation, the upper-left corner
+of some instance of the tile/stipple is at the coordinates within
+the drawable specified by the tile/stipple origin.
+The tile/stipple and clip origins are interpreted relative to the
+origin of whatever destination drawable is specified in a graphics
+request.
+The tile pixmap must have the same root and depth as the GC,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The stipple pixmap must have depth one and must have the same root as the
+GC, or a
+<errorname>BadMatch</errorname>
+error results.
+For stipple operations where the fill-style is
+<symbol>FillStippled</symbol>
+but not
+<symbol>FillOpaqueStippled</symbol>,
+the stipple pattern is tiled in a
+single plane and acts as an additional clip mask to be ANDed with the clip-mask.
+Although some sizes may be faster to use than others,
+any size pixmap can be used for tiling or stippling.
+</para>
+
+<para>
+<!-- .LP -->
+The fill-style defines the contents of the source for line, text, and
+fill requests.
+For all text and fill requests (for example,
+<function>XDrawText</function>,
+<function>XDrawText16</function>,
+<function>XFillRectangle</function>,
+<function>XFillPolygon</function>,
+and
+<function>XFillArc</function>);
+for line requests
+with line-style
+<symbol>LineSolid</symbol>
+(for example,
+<function>XDrawLine</function>,
+<function>XDrawSegments</function>,
+<function>XDrawRectangle</function>,
+<function>XDrawArc</function>);
+and for the even dashes for line requests with line-style
+<symbol>LineOnOffDash</symbol>
+or
+<symbol>LineDoubleDash</symbol>,
+the following apply:
+</para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>FillSolid</symbol></entry>
+ <entry>Foreground</entry>
+ </row>
+ <row>
+ <entry><symbol>FillTiled</symbol></entry>
+ <entry>Tile</entry>
+ </row>
+ <row>
+ <entry><symbol>FillOpaqueStippled</symbol></entry>
+ <entry>A tile with the same width and height as stipple,
+ but with background everywhere stipple has a zero
+ and with foreground everywhere stipple has a one</entry>
+ </row>
+ <row>
+ <entry><symbol>FillStippled</symbol></entry>
+ <entry>Foreground masked by stipple</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+When drawing lines with line-style
+<symbol>LineDoubleDash</symbol>,
+the odd dashes are controlled by the fill-style in the following manner:
+</para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>FillSolid</symbol></entry>
+ <entry>Background</entry>
+ </row>
+ <row>
+ <entry><symbol>FillTiled</symbol></entry>
+ <entry>Same as for even dashes</entry>
+ </row>
+ <row>
+ <entry><symbol>FillOpaqueStippled</symbol></entry>
+ <entry>Same as for even dashes</entry>
+ </row>
+ <row>
+ <entry><symbol>FillStippled</symbol></entry>
+ <entry>Background masked by stipple</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Storing a pixmap in a GC might or might not result in a copy
+being made.
+If the pixmap is later used as the destination for a graphics request,
+the change might or might not be reflected in the GC.
+If the pixmap is used simultaneously in a graphics request both as
+a destination and as a tile or stipple,
+the results are undefined.
+</para>
+<para>
+<!-- .LP -->
+For optimum performance,
+you should draw as much as possible with the same GC
+(without changing its components).
+The costs of changing GC components relative to using different GCs
+depend on the display hardware and the server implementation.
+It is quite likely that some amount of GC information will be
+cached in display hardware and that such hardware can only cache a small number
+of GCs.
+</para>
+<para>
+<!-- .LP -->
+The dashes value is actually a simplified form of the
+more general patterns that can be set with
+<function>XSetDashes</function>.
+Specifying a
+value of N is equivalent to specifying the two-element list [N, N] in
+<function>XSetDashes</function>.
+The value must be nonzero,
+or a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The clip-mask restricts writes to the destination drawable.
+If the clip-mask is set to a pixmap,
+it must have depth one and have the same root as the GC,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If clip-mask is set to
+<symbol>None</symbol>,
+the pixels are always drawn regardless of the clip origin.
+The clip-mask also can be set by calling the
+<function>XSetClipRectangles</function>
+or
+<function>XSetRegion</function>
+functions.
+Only pixels where the clip-mask has a bit set to 1 are drawn.
+Pixels are not drawn outside the area covered by the clip-mask
+or where the clip-mask has a bit set to 0.
+The clip-mask affects all graphics requests.
+The clip-mask does not clip sources.
+The clip-mask origin is interpreted relative to the origin of whatever
+destination drawable is specified in a graphics request.
+</para>
+<para>
+<!-- .LP -->
+You can set the subwindow-mode to
+<symbol>ClipByChildren</symbol>
+or
+<symbol>IncludeInferiors</symbol>.
+For
+<symbol>ClipByChildren</symbol>,
+both source and destination windows are
+additionally clipped by all viewable
+<symbol>InputOutput</symbol>
+children.
+For
+<symbol>IncludeInferiors</symbol>,
+neither source nor destination window is clipped by inferiors.
+This will result in including subwindow contents in the source
+and drawing through subwindow boundaries of the destination.
+The use of
+<symbol>IncludeInferiors</symbol>
+on a window of one depth with mapped
+inferiors of differing depth is not illegal, but the semantics are
+undefined by the core protocol.
+</para>
+<para>
+<!-- .LP -->
+The fill-rule defines what pixels are inside (drawn) for
+paths given in
+<function>XFillPolygon</function>
+requests and can be set to
+<symbol>EvenOddRule</symbol>
+or
+<symbol>WindingRule</symbol>.
+For
+<symbol>EvenOddRule</symbol>,
+a point is inside if
+an infinite ray with the point as origin crosses the path an odd number
+of times.
+For
+<symbol>WindingRule</symbol>,
+a point is inside if an infinite ray with the
+point as origin crosses an unequal number of clockwise and
+counterclockwise directed path segments.
+A clockwise directed path segment is one that crosses the ray from left to
+right as observed from the point.
+A counterclockwise segment is one that crosses the ray from right to left
+as observed from the point.
+The case where a directed line segment is coincident with the ray is
+uninteresting because you can simply choose a different ray that is not
+coincident with a segment.
+</para>
+<para>
+<!-- .LP -->
+For both
+<symbol>EvenOddRule</symbol>
+and
+<symbol>WindingRule</symbol>,
+a point is infinitely small,
+and the path is an infinitely thin line.
+A pixel is inside if the center point of the pixel is inside
+and the center point is not on the boundary.
+If the center point is on the boundary,
+the pixel is inside if and only if the polygon interior is immediately to
+its right (x increasing direction).
+Pixels with centers on a horizontal edge are a special case
+and are inside if and only if the polygon interior is immediately below
+(y increasing direction).
+</para>
+<para>
+<!-- .LP -->
+The arc-mode controls filling in the
+<function>XFillArcs</function>
+function and can be set to
+<symbol>ArcPieSlice</symbol>
+or
+<symbol>ArcChord</symbol>.
+For
+<symbol>ArcPieSlice</symbol>,
+the arcs are pie-slice filled.
+For
+<symbol>ArcChord</symbol>,
+the arcs are chord filled.
+</para>
+<para>
+<!-- .LP -->
+The graphics-exposure flag controls
+<symbol>GraphicsExpose</symbol>
+event generation
+for
+<function>XCopyArea</function>
+and
+<function>XCopyPlane</function>
+requests (and any similar requests defined by extensions).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a new GC that is usable on a given screen with a
+depth of drawable, use
+<function>XCreateGC</function>.
+</para>
+<indexterm><primary>Graphics context</primary><secondary>initializing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XCreateGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreategc'>
+<funcprototype>
+ <funcdef>GC <function>XCreateGC</function></funcdef>
+ <paramdef>Display <parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XGCValues *<parameter>values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+<!-- .ds Vm set using the information in the specified values structure -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which components in the GC are to be (Vm.
+This argument is the bitwise inclusive OR of zero or more of the valid
+GC component mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any values as specified by the valuemask.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateGC</function>
+function creates a graphics context and returns a GC.
+The GC can be used with any destination drawable having the same root
+and depth as the specified drawable.
+Use with other drawables results in a
+<errorname>BadMatch</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateGC</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadDrawable</errorname>,
+<errorname>BadFont</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To copy components from a source GC to a destination GC, use
+<function>XCopyGC</function>.
+</para>
+<indexterm significance="preferred"><primary>XCopyGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcopygc'>
+<funcprototype>
+ <funcdef><function>XCopyGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GCsrc,<parameter> dest</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the components of the source GC.
+<!-- .ds Vm copied to the destination GC -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which components in the GC are to be (Vm.
+This argument is the bitwise inclusive OR of zero or more of the valid
+GC component mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the destination GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCopyGC</function>
+function copies the specified components from the source GC
+to the destination GC.
+The source and destination GCs must have the same root and depth,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The valuemask specifies which component to copy, as for
+<function>XCreateGC</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XCopyGC</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change the components in a given GC, use
+<function>XChangeGC</function>.
+</para>
+<indexterm significance="preferred"><primary>XChangeGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangegc'>
+<funcprototype>
+ <funcdef><function>XChangeGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XGCValues<parameter> *values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Vm changed using information in the specified values structure -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which components in the GC are to be (Vm.
+This argument is the bitwise inclusive OR of zero or more of the valid
+GC component mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any values as specified by the valuemask.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangeGC</function>
+function changes the components specified by valuemask for
+the specified GC.
+The values argument contains the values to be set.
+The values and restrictions are the same as for
+<function>XCreateGC</function>.
+Changing the clip-mask overrides any previous
+<function>XSetClipRectangles</function>
+request on the context.
+Changing the dash-offset or dash-list
+overrides any previous
+<function>XSetDashes</function>
+request on the context.
+The order in which components are verified and altered is server dependent.
+If an error is generated, a subset of the components may have been altered.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeGC</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadFont</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain components of a given GC, use
+<function>XGetGCValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetGCValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetgcvalues'>
+<funcprototype>
+ <funcdef>Status <function>XGetGCValues</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> valuemask</parameter></paramdef>
+ <paramdef>XGCValues<parameter> *values_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Vm returned in the values_return argument -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>valuemask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which components in the GC are to be (Vm.
+This argument is the bitwise inclusive OR of zero or more of the valid
+GC component mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the GC values in the specified
+<structname>XGCValues</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetGCValues</function>
+function returns the components specified by valuemask for the specified GC.
+If the valuemask contains a valid set of GC mask bits
+(<symbol>GCFunction</symbol>,
+<symbol>GCPlaneMask</symbol>,
+<symbol>GCForeground</symbol>,
+<symbol>GCBackground</symbol>,
+<symbol>GCLineWidth</symbol>,
+<symbol>GCLineStyle</symbol>,
+<symbol>GCCapStyle</symbol>,
+<symbol>GCJoinStyle</symbol>,
+<symbol>GCFillStyle</symbol>,
+<symbol>GCFillRule</symbol>,
+<symbol>GCTile</symbol>,
+<symbol>GCStipple</symbol>,
+<symbol>GCTileStipXOrigin</symbol>,
+<symbol>GCTileStipYOrigin</symbol>,
+<symbol>GCFont</symbol>,
+<symbol>GCSubwindowMode</symbol>,
+<symbol>GCGraphicsExposures</symbol>,
+<symbol>GCClipXOrigin</symbol>,
+<symbol>GCClipYOrigin</symbol>,
+<symbol>GCDashOffset</symbol>,
+or
+<symbol>GCArcMode</symbol>)
+and no error occurs,
+<function>XGetGCValues</function>
+sets the requested components in values_return and returns a nonzero status.
+Otherwise, it returns a zero status.
+Note that the clip-mask and dash-list (represented by the
+<symbol>GCClipMask</symbol>
+and
+<symbol>GCDashList</symbol>
+bits, respectively, in the valuemask)
+cannot be requested.
+Also note that an invalid resource ID (with one or more of the three
+most significant bits set to 1) will be returned for
+<symbol>GCFont</symbol>,
+<symbol>GCTile</symbol>,
+and
+<symbol>GCStipple</symbol>
+if the component has never been explicitly set by the client.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free a given GC, use
+<function>XFreeGC</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreegc'>
+<funcprototype>
+ <funcdef><function>XFreeGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeGC</function>
+function destroys the specified GC as well as all the associated storage.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreeGC</function>
+can generate a
+<errorname>BadGC</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the
+<type>GContext</type>
+resource ID for a given GC, use
+<function>XGContextFromGC</function>.
+</para>
+<indexterm significance="preferred"><primary>XGContextFromGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgcontextfromgc'>
+<funcprototype>
+ <funcdef>GContext <function>XGContextFromGC</function></funcdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Gc for which you want the resource ID -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC (Gc.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+Xlib usually defers sending changes to the components of a GC to the server
+until a graphics function is actually called with that GC.
+This permits batching of component changes into a single server request.
+In some circumstances, however, it may be necessary for the client
+to explicitly force sending the changes to the server.
+An example might be when a protocol extension uses the GC indirectly,
+in such a way that the extension interface cannot know what GC will be used.
+To force sending GC component changes, use
+<function>XFlushGC</function>.
+</para>
+<indexterm significance="preferred"><primary>XFlushGC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xflushgc'>
+<funcprototype>
+ <funcdef>void <function>XFlushGC</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect1>
+<sect1 id="Using_Graphics_Context_Convenience_Routines">
+<title>Using Graphics Context Convenience Routines</title>
+<!-- .XS -->
+<!-- (SN Using Graphics Context Convenience Routines -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses how to set the:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Foreground, background, plane mask, or function components
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Line attributes and dashes components
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Fill style and fill rule components
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Fill tile and stipple components
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Font component
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Clip region component
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Arc mode, subwindow mode, and graphics exposure components
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Setting_the_Foreground_Background_Function_or_Plane_Mask">
+<title>Setting the Foreground, Background, Function, or Plane Mask</title>
+<!-- .XS -->
+<!-- (SN Setting the Foreground, Background, Function, or Plane Mask -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the foreground, background, plane mask, and function components
+for a given GC, use
+<function>XSetState</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetState</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetstate'>
+<funcprototype>
+ <funcdef><function>XSetState</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlongforeground,<parameter> background</parameter></paramdef>
+ <paramdef>int<parameter> function</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>foreground</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the foreground you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the background you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>function</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the function you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the plane mask.
+<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetState</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the foreground of a given GC, use
+<function>XSetForeground</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetForeground</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetforeground'>
+<funcprototype>
+ <funcdef><function>XSetForeground</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> foreground</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>foreground</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the foreground you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetForeground</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the background of a given GC, use
+<function>XSetBackground</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetBackground</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetbackground'>
+<funcprototype>
+ <funcdef><function>XSetBackground</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> background</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>background</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the background you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetBackground</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the display function in a given GC, use
+<function>XSetFunction</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetFunction</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetfunction'>
+<funcprototype>
+ <funcdef><function>XSetFunction</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> function</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>function</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the function you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetFunction</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the plane mask of a given GC, use
+<function>XSetPlaneMask</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetPlaneMask</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetplanemask'>
+<funcprototype>
+ <funcdef><function>XSetPlaneMask</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the plane mask.
+<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetPlaneMask</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_the_Line_Attributes_and_Dashes">
+<title>Setting the Line Attributes and Dashes</title>
+<!-- .XS -->
+<!-- (SN Setting the Line Attributes and Dashes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the line drawing components of a given GC, use
+<function>XSetLineAttributes</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetLineAttributes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetlineattributes'>
+<funcprototype>
+ <funcdef><function>XSetLineAttributes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>unsignedint<parameter> line_width</parameter></paramdef>
+ <paramdef>int<parameter> line_style</parameter></paramdef>
+ <paramdef>int<parameter> cap_style</parameter></paramdef>
+ <paramdef>int<parameter> join_style</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>line_width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the line-width you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>line_style</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the line-style you want to set for the specified GC.
+You can pass
+<symbol>LineSolid</symbol>,
+<symbol>LineOnOffDash</symbol>,
+or
+<symbol>LineDoubleDash</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cap_style</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the line-style and cap-style you want to set for the specified GC.
+You can pass
+<symbol>CapNotLast</symbol>,
+<symbol>CapButt</symbol>,
+<symbol>CapRound</symbol>,
+or
+<symbol>CapProjecting</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>join_style</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the line join-style you want to set for the specified GC.
+You can pass
+<symbol>JoinMiter</symbol>,
+<symbol>JoinRound</symbol>,
+or
+<symbol>JoinBevel</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetLineAttributes</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the dash-offset and dash-list for dashed line styles of a given GC, use
+<function>XSetDashes</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetDashes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetdashes'>
+<funcprototype>
+ <funcdef><function>XSetDashes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> dash_offset</parameter></paramdef>
+ <paramdef>char<parameter> dash_list[]</parameter></paramdef>
+ <paramdef>int<parameter> n</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dash_offset</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the phase of the pattern for the dashed line-style you want to set
+for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dash_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the dash-list for the dashed line-style
+you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>n</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of elements in dash_list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetDashes</function>
+function sets the dash-offset and dash-list attributes for dashed line styles
+in the specified GC.
+There must be at least one element in the specified dash_list,
+or a
+<errorname>BadValue</errorname>
+error results.
+The initial and alternating elements (second, fourth, and so on)
+of the dash_list are the even dashes, and
+the others are the odd dashes.
+Each element specifies a dash length in pixels.
+All of the elements must be nonzero,
+or a
+<errorname>BadValue</errorname>
+error results.
+Specifying an odd-length list is equivalent to specifying the same list
+concatenated with itself to produce an even-length list.
+</para>
+<para>
+<!-- .LP -->
+The dash-offset defines the phase of the pattern,
+specifying how many pixels into the dash-list the pattern
+should actually begin in any single graphics request.
+Dashing is continuous through path elements combined with a join-style
+but is reset to the dash-offset between each sequence of joined lines.
+</para>
+<para>
+<!-- .LP -->
+The unit of measure for dashes is the same for the ordinary coordinate system.
+Ideally, a dash length is measured along the slope of the line, but implementations
+are only required to match this ideal for horizontal and vertical lines.
+Failing the ideal semantics, it is suggested that the length be measured along the
+major axis of the line.
+The major axis is defined as the x axis for lines drawn at an angle of between
+−45 and +45 degrees or between 135 and 225 degrees from the x axis.
+For all other lines, the major axis is the y axis.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetDashes</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_the_Fill_Style_and_Fill_Rule_">
+<title>Setting the Fill Style and Fill Rule </title>
+<!-- .XS -->
+<!-- (SN Setting the Fill Style and Fill Rule -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the fill-style of a given GC, use
+<function>XSetFillStyle</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetFillStyle</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetfillstyle'>
+<funcprototype>
+ <funcdef><function>XSetFillStyle</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> fill_style</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fill_style</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fill-style you want to set for the specified GC.
+You can pass
+<symbol>FillSolid</symbol>,
+<symbol>FillTiled</symbol>,
+<symbol>FillStippled</symbol>,
+or
+<symbol>FillOpaqueStippled</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetFillStyle</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the fill-rule of a given GC, use
+<function>XSetFillRule</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetFillRule</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetfillrule'>
+<funcprototype>
+ <funcdef><function>XSetFillRule</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> fill_rule</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fill_rule</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fill-rule you want to set for the specified GC.
+You can pass
+<symbol>EvenOddRule</symbol>
+or
+<symbol>WindingRule</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetFillRule</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_the_Fill_Tile_and_Stipple_">
+<title>Setting the Fill Tile and Stipple </title>
+<!-- .XS -->
+<!-- (SN Setting the Fill Tile and Stipple -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some displays have hardware support for tiling or
+stippling with patterns of specific sizes.
+Tiling and stippling operations that restrict themselves to those specific
+sizes run much faster than such operations with arbitrary size patterns.
+Xlib provides functions that you can use to determine the best size,
+tile, or stipple for the display
+as well as to set the tile or stipple shape and the tile or stipple origin.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the best size of a tile, stipple, or cursor, use
+<function>XQueryBestSize</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryBestSize</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerybestsize'>
+<funcprototype>
+ <funcdef>Status <function>XQueryBestSize</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> class</parameter></paramdef>
+ <paramdef>Drawable<parameter> which_screen</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the class that you are interested in.
+You can pass
+<symbol>TileShape</symbol>,
+<symbol>CursorShape</symbol>,
+or
+<symbol>StippleShape</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>which_screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any drawable on the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height of the object best supported
+by the display hardware.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryBestSize</function>
+function returns the best or closest size to the specified size.
+For
+<symbol>CursorShape</symbol>,
+this is the largest size that can be fully displayed on the screen specified by
+which_screen.
+For
+<symbol>TileShape</symbol>,
+this is the size that can be tiled fastest.
+For
+<symbol>StippleShape</symbol>,
+this is the size that can be stippled fastest.
+For
+<symbol>CursorShape</symbol>,
+the drawable indicates the desired screen.
+For
+<symbol>TileShape</symbol>
+and
+<symbol>StippleShape</symbol>,
+the drawable indicates the screen and possibly the window class and depth.
+An
+<symbol>InputOnly</symbol>
+window cannot be used as the drawable for
+<symbol>TileShape</symbol>
+or
+<symbol>StippleShape</symbol>,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryBestSize</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the best fill tile shape, use
+<function>XQueryBestTile</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryBestTile</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerybesttile'>
+<funcprototype>
+ <funcdef>Status <function>XQueryBestTile</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> which_screen</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>which_screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any drawable on the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height of the object best supported
+by the display hardware.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryBestTile</function>
+function returns the best or closest size, that is, the size that can be
+tiled fastest on the screen specified by which_screen.
+The drawable indicates the screen and possibly the window class and depth.
+If an
+<symbol>InputOnly</symbol>
+window is used as the drawable, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryBestTile</function>
+can generate
+<errorname>BadDrawable</errorname>
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the best stipple shape, use
+<function>XQueryBestStipple</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryBestStipple</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerybeststipple'>
+<funcprototype>
+ <funcdef>Status <function>XQueryBestStipple</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> which_screen</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>which_screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any drawable on the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height of the object best supported
+by the display hardware.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryBestStipple</function>
+function returns the best or closest size, that is, the size that can be
+stippled fastest on the screen specified by which_screen.
+The drawable indicates the screen and possibly the window class and depth.
+If an
+<symbol>InputOnly</symbol>
+window is used as the drawable, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryBestStipple</function>
+can generate
+<errorname>BadDrawable</errorname>
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the fill tile of a given GC, use
+<function>XSetTile</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetTile</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsettile'>
+<funcprototype>
+ <funcdef><function>XSetTile</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Pixmap<parameter> tile</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>tile</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fill tile you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The tile and GC must have the same depth,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetTile</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadPixmap</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the stipple of a given GC, use
+<function>XSetStipple</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetStipple</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetstipple'>
+<funcprototype>
+ <funcdef><function>XSetStipple</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Pixmap<parameter> stipple</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>stipple</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the stipple you want to set for the specified GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The stipple must have a depth of one,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetStipple</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadPixmap</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the tile or stipple origin of a given GC, use
+<function>XSetTSOrigin</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetTSOrigin</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsettsorigin'>
+<funcprototype>
+ <funcdef><function>XSetTSOrigin</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intts_x_origin,<parameter> ts_y_origin</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ts_x_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ts_y_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates of the tile and stipple origin.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When graphics requests call for tiling or stippling,
+the parent's origin will be interpreted relative to whatever destination
+drawable is specified in the graphics request.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetTSOrigin</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_the_Current_Font_">
+<title>Setting the Current Font </title>
+<!-- .XS -->
+<!-- (SN Setting the Current Font -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the current font of a given GC, use
+<function>XSetFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetfont'>
+<funcprototype>
+ <funcdef><function>XSetFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Font<parameter> font</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetFont</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadFont</errorname>,
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_the_Clip_Region">
+<title>Setting the Clip Region</title>
+<!-- .XS -->
+<!-- (SN Setting the Clip Region -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set the clip-origin
+and the clip-mask or set the clip-mask to a list of rectangles.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the clip-origin of a given GC, use
+<function>XSetClipOrigin</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetClipOrigin</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetcliporigin'>
+<funcprototype>
+ <funcdef><function>XSetClipOrigin</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intclip_x_origin,<parameter> clip_y_origin</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>clip_x_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>clip_y_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates of the clip-mask origin.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The clip-mask origin is interpreted relative to the origin of whatever
+destination drawable is specified in the graphics request.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetClipOrigin</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the clip-mask of a given GC to the specified pixmap, use
+<function>XSetClipMask</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetClipMask</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetclipmask'>
+<funcprototype>
+ <funcdef><function>XSetClipMask</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Pixmap<parameter> pixmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pixmap or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the clip-mask is set to
+<symbol>None</symbol>,
+the pixels are always drawn (regardless of the clip-origin).
+</para>
+<para>
+<!-- .LP -->
+<function>XSetClipMask</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadPixmap</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the clip-mask of a given GC to the specified list of rectangles, use
+<function>XSetClipRectangles</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetClipRectangles</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetcliprectangles'>
+<funcprototype>
+ <funcdef><function>XSetClipRectangles</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intclip_x_origin,<parameter> clip_y_origin</parameter></paramdef>
+ <paramdef>XRectangle<parameter> rectangles[]</parameter></paramdef>
+ <paramdef>int<parameter> n</parameter></paramdef>
+ <paramdef>int<parameter> ordering</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>clip_x_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>clip_y_origin</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates of the clip-mask origin.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rectangles</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of rectangles that define the clip-mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>n</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of rectangles.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ordering</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the ordering relations on the rectangles.
+You can pass
+<symbol>Unsorted</symbol>,
+<symbol>YSorted</symbol>,
+<symbol>YXSorted</symbol>,
+or
+<symbol>YXBanded</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetClipRectangles</function>
+function changes the clip-mask in the specified GC
+to the specified list of rectangles and sets the clip origin.
+The output is clipped to remain contained within the
+rectangles.
+The clip-origin is interpreted relative to the origin of
+whatever destination drawable is specified in a graphics request.
+The rectangle coordinates are interpreted relative to the clip-origin.
+The rectangles should be nonintersecting, or the graphics results will be
+undefined.
+Note that the list of rectangles can be empty,
+which effectively disables output.
+This is the opposite of passing
+<symbol>None</symbol>
+as the clip-mask in
+<function>XCreateGC</function>,
+<function>XChangeGC</function>,
+and
+<function>XSetClipMask</function>.
+</para>
+<para>
+<!-- .LP -->
+If known by the client, ordering relations on the rectangles can be
+specified with the ordering argument.
+This may provide faster operation
+by the server.
+If an incorrect ordering is specified, the X server may generate a
+<errorname>BadMatch</errorname>
+error, but it is not required to do so.
+If no error is generated, the graphics
+results are undefined.
+<symbol>Unsorted</symbol>
+means the rectangles are in arbitrary order.
+<symbol>YSorted</symbol>
+means that the rectangles are nondecreasing in their Y origin.
+<symbol>YXSorted</symbol>
+additionally constrains
+<symbol>YSorted</symbol>
+order in that all
+rectangles with an equal Y origin are nondecreasing in their X
+origin.
+<symbol>YXBanded</symbol>
+additionally constrains
+<symbol>YXSorted</symbol>
+by requiring that,
+for every possible Y scanline, all rectangles that include that
+scanline have an identical Y origins and Y extents.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetClipRectangles</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+Xlib provides a set of basic functions for performing
+region arithmetic.
+For information about these functions,
+see <link linkend="Manipulating_Regions">section 16.5</link>.
+</para>
+</sect2>
+<sect2 id="Setting_the_Arc_Mode_Subwindow_Mode_and_Graphics_Exposure_">
+<title>Setting the Arc Mode, Subwindow Mode, and Graphics Exposure </title>
+<!-- .XS -->
+<!-- (SN Setting the Arc Mode, Subwindow Mode, and Graphics Exposure -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To set the arc mode of a given GC, use
+<function>XSetArcMode</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetArcMode</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetarcmode'>
+<funcprototype>
+ <funcdef><function>XSetArcMode</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> arc_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arc_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the arc mode.
+You can pass
+<symbol>ArcChord</symbol>
+or
+<symbol>ArcPieSlice</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetArcMode</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the subwindow mode of a given GC, use
+<function>XSetSubwindowMode</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetSubwindowMode</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetsubwindowmode'>
+<funcprototype>
+ <funcdef><function>XSetSubwindowMode</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> subwindow_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>subwindow_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the subwindow mode.
+You can pass
+<symbol>ClipByChildren</symbol>
+or
+<symbol>IncludeInferiors</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetSubwindowMode</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the graphics-exposures flag of a given GC, use
+<function>XSetGraphicsExposures</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetGraphicsExposures</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetgraphicsexposures'>
+<funcprototype>
+ <funcdef><function>XSetGraphicsExposures</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Bool<parameter> graphics_exposures</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>graphics_exposures</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether you want
+<symbol>GraphicsExpose</symbol>
+and
+<symbol>NoExpose</symbol>
+events to be reported when calling
+<function>XCopyArea</function>
+and
+<function>XCopyPlane</function>
+with this GC.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XSetGraphicsExposures</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+<!-- .bp -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH08.xml b/libX11/specs/libX11/CH08.xml index 8e0bae629..948040982 100644 --- a/libX11/specs/libX11/CH08.xml +++ b/libX11/specs/libX11/CH08.xml @@ -1,5967 +1,5967 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="graphics_functions"> -<title>Graphics Functions</title> -<para> -Once you have established a connection to a display, you can use the Xlib graphics functions to: -</para> -<itemizedlist> - <listitem><para>Clear and copy areas</para></listitem> - <listitem><para>Draw points, lines, rectangles, and arcs</para></listitem> - <listitem><para>Fill areas</para></listitem> - <listitem><para>Manipulate fonts</para></listitem> - <listitem><para>Draw text</para></listitem> - <listitem><para>Transfer images between clients and the server</para></listitem> -</itemizedlist> -<para> -If the same drawable and GC is used for each call, Xlib batches back-to-back -calls to XDrawPoint, XDrawLine, XDrawRectangle, XFillArc, and XFillRectangle. -Note that this reduces the total number of requests sent to the server. -</para> -<sect1 id="Clearing_Areas"> -<title>Clearing Areas</title> -<!-- .XS --> -<!-- (SN Clearing Areas --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to clear an area or the entire window. -Because pixmaps do not have defined backgrounds, -they cannot be filled by using the functions described in this section. -Instead, to accomplish an analogous operation on a pixmap, -you should use -<function>XFillRectangle</function>, -which sets the pixmap to a known value. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To clear a rectangular area of a given window, use -<function>XClearArea</function>. -</para> -<indexterm><primary>Areas</primary><secondary>clearing</secondary></indexterm> -<indexterm><primary>Clearing</primary><secondary>areas</secondary></indexterm> -<indexterm significance="preferred"><primary>XClearArea</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcleararea'> -<funcprototype> - <funcdef><function>XClearArea</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>Bool<parameter> exposures</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. -<!-- .ds Xy , which are relative to the origin of the window \ --> -and specify the upper-left corner of the rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the dimensions of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>exposures</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates if -<symbol>Expose</symbol> -events are to be generated. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XClearArea</function> -function paints a rectangular area in the specified window according to the -specified dimensions with the window's background pixel or pixmap. -The subwindow-mode effectively is -<symbol>ClipByChildren</symbol>. -If width is zero, it -is replaced with the current width of the window minus x. -If height is -zero, it is replaced with the current height of the window minus y. -If the window has a defined background tile, -the rectangle clipped by any children is filled with this tile. -If the window has -background -<symbol>None</symbol>, -the contents of the window are not changed. -In either -case, if exposures is -<symbol>True</symbol>, -one or more -<symbol>Expose</symbol> -events are generated for regions of the rectangle that are either visible or are -being retained in a backing store. -If you specify a window whose class is -<symbol>InputOnly</symbol>, -a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XClearArea</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To clear the entire area in a given window, use -<function>XClearWindow</function>. -</para> -<indexterm><primary>Window</primary><secondary>clearing</secondary></indexterm> -<indexterm><primary>Clearing</primary><secondary>windows</secondary></indexterm> -<indexterm significance="preferred"><primary>XClearWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xclearwindow'> -<funcprototype> - <funcdef><function>XClearWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XClearWindow</function> -function clears the entire area in the specified window and is -equivalent to -<function>XClearArea</function> -(display, w, 0, 0, 0, 0, -<symbol>False</symbol>). -If the window has a defined background tile, the rectangle is tiled with a -plane-mask of all ones and -<symbol>GXcopy</symbol> -function. -If the window has -background -<symbol>None</symbol>, -the contents of the window are not changed. -If you specify a window whose class is -<symbol>InputOnly</symbol>, -a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XClearWindow</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Copying_Areas"> -<title>Copying Areas</title> -<!-- .XS --> -<!-- (SN Copying Areas --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to copy an area or a bit plane. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To copy an area between drawables of the same -root and depth, use -<function>XCopyArea</function>. -</para> -<indexterm><primary>Areas</primary><secondary>copying</secondary></indexterm> -<indexterm><primary>Copying</primary><secondary>areas</secondary></indexterm> -<indexterm significance="preferred"><primary>XCopyArea</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcopyarea'> -<funcprototype> - <funcdef><function>XCopyArea</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawablesrc,<parameter> dest</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest</emphasis> - </term> - <listitem> - <para> -Specify the source and destination rectangles to be combined. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates, -which are relative to the origin of the source rectangle -and specify its upper-left corner. -<!-- .ds Wh , which are the dimensions of both the source \ --> -and destination rectangles - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. -<!-- .ds Dx , which are relative to the origin of the destination rectangle \ --> -and specify its upper-left corner - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Dx. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCopyArea</function> -function combines the specified rectangle of src with the specified rectangle -of dest. -The drawables must have the same root and depth, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -If regions of the source rectangle are obscured and have not been -retained in backing store -or if regions outside the boundaries of the source drawable are specified, -those regions are not copied. -Instead, the -following occurs on all corresponding destination regions that are either -visible or are retained in backing store. -If the destination is a window with a background other than -<symbol>None</symbol>, -corresponding regions -of the destination are tiled with that background -(with plane-mask of all ones and -<symbol>GXcopy</symbol> -function). -Regardless of tiling or whether the destination is a window or a pixmap, -if graphics-exposures is -<symbol>True</symbol>, -then -<symbol>GraphicsExpose</symbol> -events for all corresponding destination regions are generated. -If graphics-exposures is -<symbol>True</symbol> -but no -<symbol>GraphicsExpose</symbol> -events are generated, a -<symbol>NoExpose</symbol> -event is generated. -Note that by default graphics-exposures is -<symbol>True</symbol> -in new GCs. -</para> -<para> -<!-- .LP --> -This function uses these GC components: function, plane-mask, -subwindow-mode, graphics-exposures, clip-x-origin, -clip-y-origin, and clip-mask. -</para> -<para> -<!-- .LP --> -<function>XCopyArea</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To copy a single bit plane of a given drawable, use -<function>XCopyPlane</function>. -</para> -<indexterm><primary>Plane</primary><secondary>copying</secondary></indexterm> -<indexterm><primary>Copying</primary><secondary>planes</secondary></indexterm> -<indexterm significance="preferred"><primary>XCopyPlane</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcopyplane'> -<funcprototype> - <funcdef><function>XCopyPlane</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawablesrc,<parameter> dest</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest</emphasis> - </term> - <listitem> - <para> -Specify the source and destination rectangles to be combined. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates, -which are relative to the origin of the source rectangle -and specify its upper-left corner. -<!-- .ds Wh , which are the dimensions of both the source and destination rectangles --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. -<!-- .ds Dx , which are relative to the origin of the destination rectangle \ --> -and specify its upper-left corner - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Dx. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane</emphasis> - </term> - <listitem> - <para> -Specifies the bit plane. -You must set exactly one bit to 1. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCopyPlane</function> -function uses a single bit plane of the specified source rectangle -combined with the specified GC to modify the specified rectangle of dest. -The drawables must have the same root but need not have the same depth. -If the drawables do not have the same root, a -<errorname>BadMatch</errorname> -error results. -If plane does not have exactly one bit set to 1 and the value of plane -is not less than %2 sup n%, where <emphasis remap='I'>n</emphasis> is the depth of src, a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -Effectively, -<function>XCopyPlane</function> -forms a pixmap of the same depth as the rectangle of dest and with a -size specified by the source region. -It uses the foreground/background pixels in the GC (foreground -everywhere the bit plane in src contains a bit set to 1, -background everywhere the bit plane in src contains a bit set to 0) -and the equivalent of a -<systemitem>CopyArea</systemitem> -protocol request is performed with all the same exposure semantics. -This can also be thought of as using the specified region of the source -bit plane as a stipple with a fill-style of -<symbol>FillOpaqueStippled</symbol> -for filling a rectangular area of the destination. -</para> -<para> -<!-- .LP --> -This function uses these GC components: function, plane-mask, foreground, -background, subwindow-mode, graphics-exposures, clip-x-origin, clip-y-origin, -and clip-mask. -</para> -<para> -<!-- .LP --> -<function>XCopyPlane</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect1> -<sect1 id="Drawing_Points_Lines_Rectangles_and_Arcs"> -<title>Drawing Points, Lines, Rectangles, and Arcs</title> -<!-- .XS --> -<!-- (SN Drawing Points, Lines, Rectangles, and Arcs --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to draw: -</para> -<itemizedlist> - <listitem> - <para> -A single point or multiple points - </para> - </listitem> - <listitem> - <para> -A single line or multiple lines - </para> - </listitem> - <listitem> - <para> -A single rectangle or multiple rectangles - </para> - </listitem> - <listitem> - <para> -A single arc or multiple arcs - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Some of the functions described in the following sections -use these structures: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XSegment</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - short x1, y1, x2, y2; -} XSegment; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XPoint</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - short x, y; -} XPoint; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XRectangle</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - short x, y; - unsigned short width, height; -} XRectangle; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>XArc</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - short x, y; - unsigned short width, height; - short angle1, angle2; /* Degrees * 64 */ -} XArc; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -All x and y members are signed integers. -The width and height members are 16-bit unsigned integers. -You should be careful not to generate coordinates and sizes -out of the 16-bit ranges, because the protocol only has 16-bit fields -for these values. -</para> -<sect2 id="Drawing_Single_and_Multiple_Points"> -<title>Drawing Single and Multiple Points</title> -<!-- .XS --> -<!-- (SN Drawing Single and Multiple Points --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Points</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>points</secondary></indexterm> -<indexterm><primary>XDrawPoints</primary></indexterm> -<indexterm><primary>XDrawPoint</primary></indexterm> -</para> -<para> -<!-- .LP --> -To draw a single point in a given drawable, use -<function>XDrawPoint</function>. -</para> -<indexterm significance="preferred"><primary>XDrawPoint</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawpoint'> -<funcprototype> - <funcdef><function>XDrawPoint</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates where you want the point drawn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw multiple points in a given drawable, use -<function>XDrawPoints</function>. -</para> -<indexterm significance="preferred"><primary>XDrawPoints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawpoints'> -<funcprototype> - <funcdef><function>XDrawPoints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XPoint<parameter> *points</parameter></paramdef> - <paramdef>int<parameter> npoints</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>points</emphasis> - </term> - <listitem> - <para> -Specifies an array of points. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npoints</emphasis> - </term> - <listitem> - <para> -Specifies the number of points in the array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the coordinate mode. -You can pass -<symbol>CoordModeOrigin</symbol> -or -<symbol>CoordModePrevious</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawPoint</function> -function uses the foreground pixel and function components of the -GC to draw a single point into the specified drawable; -<function>XDrawPoints</function> -draws multiple points this way. -<symbol>CoordModeOrigin</symbol> -treats all coordinates as relative to the origin, -and -<symbol>CoordModePrevious</symbol> -treats all coordinates after the first as relative to the previous point. -<function>XDrawPoints</function> -draws the points in the order listed in the array. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: function, plane-mask, -foreground, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. -</para> -<para> -<!-- .LP --> -<function>XDrawPoint</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -<function>XDrawPoints</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Drawing_Single_and_Multiple_Lines"> -<title>Drawing Single and Multiple Lines</title> -<!-- .XS --> -<!-- (SN Drawing Single and Multiple Lines --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Lines</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>lines</secondary></indexterm> -<indexterm><primary>XDrawLine</primary></indexterm> -<indexterm><primary>XDrawLines</primary></indexterm> -<indexterm><primary>Polygons</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>polygons</secondary></indexterm> -<indexterm><primary>XDrawSegments</primary></indexterm> -</para> -<para> -<!-- .LP --> -To draw a single line between two points in a given drawable, use -<function>XDrawLine</function>. -</para> -<indexterm significance="preferred"><primary>XDrawLine</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawline'> -<funcprototype> - <funcdef><function>XDrawLine</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx1,y1,x2,<parameter> y2</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x1</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y1</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x2</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y2</emphasis> - </term> - <listitem> - <para> -Specify the points (x1, y1) and (x2, y2) to be connected. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw multiple lines in a given drawable, use -<function>XDrawLines</function>. -</para> -<indexterm significance="preferred"><primary>XDrawLines</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawlines'> -<funcprototype> - <funcdef><function>XDrawLines</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XPoint<parameter> *points</parameter></paramdef> - <paramdef>int<parameter> npoints</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>points</emphasis> - </term> - <listitem> - <para> -Specifies an array of points. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npoints</emphasis> - </term> - <listitem> - <para> -Specifies the number of points in the array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the coordinate mode. -You can pass -<symbol>CoordModeOrigin</symbol> -or -<symbol>CoordModePrevious</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw multiple, unconnected lines in a given drawable, -use -<function>XDrawSegments</function>. -</para> -<indexterm significance="preferred"><primary>XDrawSegments</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawsegments'> -<funcprototype> - <funcdef><function>XDrawSegments</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XSegment<parameter> *segments</parameter></paramdef> - <paramdef>int<parameter> nsegments</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>segments</emphasis> - </term> - <listitem> - <para> -Specifies an array of segments. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nsegments</emphasis> - </term> - <listitem> - <para> -Specifies the number of segments in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawLine</function> -function uses the components of the specified GC to -draw a line between the specified set of points (x1, y1) and (x2, y2). -It does not perform joining at coincident endpoints. -For any given line, -<function>XDrawLine</function> -does not draw a pixel more than once. -If lines intersect, the intersecting pixels are drawn multiple times. -</para> -<para> -<!-- .LP --> -The -<function>XDrawLines</function> -function uses the components of the specified GC to draw -npoints-1 lines between each pair of points (point[i], point[i+1]) -in the array of -<structname>XPoint</structname> -structures. -It draws the lines in the order listed in the array. -The lines join correctly at all intermediate points, and if the first and last -points coincide, the first and last lines also join correctly. -For any given line, -<function>XDrawLines</function> -does not draw a pixel more than once. -If thin (zero line-width) lines intersect, -the intersecting pixels are drawn multiple times. -If wide lines intersect, the intersecting pixels are drawn only once, as though -the entire -<systemitem>PolyLine</systemitem> -protocol request were a single, filled shape. -<symbol>CoordModeOrigin</symbol> -treats all coordinates as relative to the origin, -and -<symbol>CoordModePrevious</symbol> -treats all coordinates after the first as relative to the previous point. -</para> -<para> -<!-- .LP --> -The -<function>XDrawSegments</function> -function draws multiple, unconnected lines. -For each segment, -<function>XDrawSegments</function> -draws a -line between (x1, y1) and (x2, y2). -It draws the lines in the order listed in the array of -<structname>XSegment</structname> -structures and does not perform joining at coincident endpoints. -For any given line, -<function>XDrawSegments</function> -does not draw a pixel more than once. -If lines intersect, the intersecting pixels are drawn multiple times. -</para> -<para> -<!-- .LP --> -All three functions use these GC components: -function, plane-mask, line-width, -line-style, cap-style, fill-style, subwindow-mode, -clip-x-origin, clip-y-origin, and clip-mask. -The -<function>XDrawLines</function> -function also uses the join-style GC component. -All three functions also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -tile-stipple-y-origin, dash-offset, and dash-list. -</para> -<para> -<!-- .LP --> -<function>XDrawLine</function>, -<function>XDrawLines</function>, -and -<function>XDrawSegments</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -<function>XDrawLines</function> -also can generate -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Drawing_Single_and_Multiple_Rectangles_"> -<title>Drawing Single and Multiple Rectangles </title> -<!-- .XS --> -<!-- (SN Drawing Single and Multiple Rectangles --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Rectangles</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>rectangles</secondary></indexterm> -<indexterm><primary>XDrawRectangle</primary></indexterm> -<indexterm><primary>XDrawRectangles</primary></indexterm> -</para> -<para> -<!-- .LP --> -To draw the outline of a single rectangle in a given drawable, use -<function>XDrawRectangle</function>. -</para> -<indexterm significance="preferred"><primary>XDrawRectangle</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawrectangle'> -<funcprototype> - <funcdef><function>XDrawRectangle</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which specify the upper-left corner of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which specify the dimensions of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw the outline of multiple rectangles -in a given drawable, use -<function>XDrawRectangles</function>. -</para> -<indexterm significance="preferred"><primary>XDrawRectangles</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawrectangles'> -<funcprototype> - <funcdef><function>XDrawRectangles</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XRectangle<parameter> rectangles[]</parameter></paramdef> - <paramdef>int<parameter> nrectangles</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rectangles</emphasis> - </term> - <listitem> - <para> -Specifies an array of rectangles. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nrectangles</emphasis> - </term> - <listitem> - <para> -Specifies the number of rectangles in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawRectangle</function> -and -<function>XDrawRectangles</function> -functions draw the outlines of the specified rectangle or rectangles as -if a five-point -<systemitem>PolyLine</systemitem> -protocol request were specified for each rectangle: -</para> -<itemizedlist> - <listitem> - <para> -[x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y] - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -For the specified rectangle or rectangles, -these functions do not draw a pixel more than once. -<function>XDrawRectangles</function> -draws the rectangles in the order listed in the array. -If rectangles intersect, -the intersecting pixels are drawn multiple times. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, line-width, -line-style, cap-style, join-style, fill-style, -subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -tile-stipple-y-origin, dash-offset, and dash-list. -</para> -<para> -<!-- .LP --> -<function>XDrawRectangle</function> -and -<function>XDrawRectangles</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -<sect2 id="Drawing_Single_and_Multiple_Arcs"> -<title>Drawing Single and Multiple Arcs</title> -<!-- .XS --> -<!-- (SN Drawing Single and Multiple Arcs --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Drawing</primary><secondary>arcs</secondary></indexterm> -<indexterm><primary>XDrawArc</primary></indexterm> -<indexterm><primary>Arcs</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>XDrawArcs</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To draw a single arc in a given drawable, use -<function>XDrawArc</function>. -</para> -<indexterm significance="preferred"><primary>XDrawArc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawarc'> -<funcprototype> - <funcdef><function>XDrawArc</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>intangle1,<parameter> angle2</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the drawable \ --> -and specify the upper-left corner of the bounding rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the major and minor axes of the arc --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>angle1</emphasis> - </term> - <listitem> - <para> -Specifies the start of the arc relative to the three-o'clock position -from the center, in units of degrees * 64. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>angle2</emphasis> - </term> - <listitem> - <para> -Specifies the path and extent of the arc relative to the start of the -arc, in units of degrees * 64. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw multiple arcs in a given drawable, use -<function>XDrawArcs</function>. -</para> -<indexterm significance="preferred"><primary>XDrawArcs</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawarcs'> -<funcprototype> - <funcdef><function>XDrawArcs</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XArc<parameter> *arcs</parameter></paramdef> - <paramdef>int<parameter> narcs</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arcs</emphasis> - </term> - <listitem> - <para> -Specifies an array of arcs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>narcs</emphasis> - </term> - <listitem> - <para> -Specifies the number of arcs in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .EQ --> -delim %% -<!-- .EN --> -<function>XDrawArc</function> -draws a single circular or elliptical arc, and -<function>XDrawArcs</function> -draws multiple circular or elliptical arcs. -Each arc is specified by a rectangle and two angles. -The center of the circle or ellipse is the center of the -rectangle, and the major and minor axes are specified by the width and height. -Positive angles indicate counterclockwise motion, -and negative angles indicate clockwise motion. -If the magnitude of angle2 is greater than 360 degrees, -<function>XDrawArc</function> -or -<function>XDrawArcs</function> -truncates it to 360 degrees. -</para> -<para> -<!-- .LP --> -For an arc specified as %[ ~x, ~y, ~width , ~height, ~angle1, ~angle2 ]%, -the origin of the major and minor axes is at -% [ x +^ {width over 2} , ~y +^ {height over 2} ]%, -and the infinitely thin path describing the entire circle or ellipse -intersects the horizontal axis at % [ x, ~y +^ {height over 2} ]% and -% [ x +^ width , ~y +^ { height over 2 }] % -and intersects the vertical axis at % [ x +^ { width over 2 } , ~y ]% and -% [ x +^ { width over 2 }, ~y +^ height ]%. -These coordinates can be fractional -and so are not truncated to discrete coordinates. -The path should be defined by the ideal mathematical path. -For a wide line with line-width lw, -the bounding outlines for filling are given -by the two infinitely thin paths consisting of all points whose perpendicular -distance from the path of the circle/ellipse is equal to lw/2 -(which may be a fractional value). -The cap-style and join-style are applied the same as for a line -corresponding to the tangent of the circle/ellipse at the endpoint. -</para> -<para> -<!-- .LP --> -For an arc specified as % [ ~x, ~y, ~width, ~height, ~angle1, ~angle2 ]%, -the angles must be specified -in the effectively skewed coordinate system of the ellipse (for a -circle, the angles and coordinate systems are identical). The -relationship between these angles and angles expressed in the normal -coordinate system of the screen (as measured with a protractor) is as -follows: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -% roman "skewed-angle" ~ = ~ atan left ( tan ( roman "normal-angle" ) - * width over height right ) +^ adjust% -</literallayout> -</para> -<para> -<!-- .LP --> -The skewed-angle and normal-angle are expressed in radians (rather -than in degrees scaled by 64) in the range % [ 0 , ~2 pi ]% and where atan -returns a value in the range % [ - pi over 2 , ~pi over 2 ] % -and adjust is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA 1i 2i --> -<!-- .ta 1i 2i --> -%0% for normal-angle in the range % [ 0 , ~pi over 2 ]% -%pi% for normal-angle in the range % [ pi over 2 , ~{3 pi} over 2 ]% -%2 pi% for normal-angle in the range % [ {3 pi} over 2 , ~2 pi ]% -</literallayout> -</para> -<para> -<!-- .LP --> -For any given arc, -<function>XDrawArc</function> -and -<function>XDrawArcs</function> -do not draw a pixel more than once. -If two arcs join correctly and if the line-width is greater than zero -and the arcs intersect, -<function>XDrawArc</function> -and -<function>XDrawArcs</function> -do not draw a pixel more than once. -Otherwise, -the intersecting pixels of intersecting arcs are drawn multiple times. -Specifying an arc with one endpoint and a clockwise extent draws the same pixels -as specifying the other endpoint and an equivalent counterclockwise extent, -except as it affects joins. -</para> -<para> -<!-- .LP --> -If the last point in one arc coincides with the first point in the following -arc, the two arcs will join correctly. -If the first point in the first arc coincides with the last point in the last -arc, the two arcs will join correctly. -By specifying one axis to be zero, a horizontal or vertical line can be -drawn. -Angles are computed based solely on the coordinate system and ignore the -aspect ratio. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, line-width, line-style, cap-style, join-style, -fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -tile-stipple-y-origin, dash-offset, and dash-list. -</para> -<para> -<!-- .LP --> -<function>XDrawArc</function> -and -<function>XDrawArcs</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -</sect1> -<sect1 id="Filling_Areas"> -<title>Filling Areas</title> -<!-- .XS --> -<!-- (SN Filling Areas --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to fill: -</para> -<itemizedlist> - <listitem> - <para> -A single rectangle or multiple rectangles - </para> - </listitem> - <listitem> - <para> -A single polygon - </para> - </listitem> - <listitem> - <para> -A single arc or multiple arcs - </para> - </listitem> -</itemizedlist> -<sect2 id="Filling_Single_and_Multiple_Rectangles"> -<title>Filling Single and Multiple Rectangles</title> -<!-- .XS --> -<!-- (SN Filling Single and Multiple Rectangles --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Filling</primary><secondary>rectangles</secondary></indexterm> -<indexterm><primary>XFillRectangle</primary></indexterm> -<indexterm><primary>Rectangle</primary><secondary>filling</secondary></indexterm> -<indexterm><primary>XFillRectangles</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To fill a single rectangular area in a given drawable, use -<function>XFillRectangle</function>. -</para> -<indexterm significance="preferred"><primary>XFillRectangle</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfillrectangle'> -<funcprototype> - <funcdef><function>XFillRectangle</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the drawable \ --> -and specify the upper-left corner of the rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the dimensions of the rectangle to be filled --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To fill multiple rectangular areas in a given drawable, use -<function>XFillRectangles</function>. -</para> -<indexterm significance="preferred"><primary>XFillRectangles</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfillrectangles'> -<funcprototype> - <funcdef><function>XFillRectangles</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XRectangle<parameter> *rectangles</parameter></paramdef> - <paramdef>int<parameter> nrectangles</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rectangles</emphasis> - </term> - <listitem> - <para> -Specifies an array of rectangles. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nrectangles</emphasis> - </term> - <listitem> - <para> -Specifies the number of rectangles in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFillRectangle</function> -and -<function>XFillRectangles</function> -functions fill the specified rectangle or rectangles -as if a four-point -<systemitem>FillPolygon</systemitem> -protocol request were specified for each rectangle: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -[x,y] [x+width,y] [x+width,y+height] [x,y+height] -</literallayout> -</para> -<para> -<!-- .LP --> -Each function uses the x and y coordinates, -width and height dimensions, and GC you specify. -</para> -<para> -<!-- .LP --> -<function>XFillRectangles</function> -fills the rectangles in the order listed in the array. -For any given rectangle, -<function>XFillRectangle</function> -and -<function>XFillRectangles</function> -do not draw a pixel more than once. -If rectangles intersect, the intersecting pixels are -drawn multiple times. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, fill-style, subwindow-mode, -clip-x-origin, clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -and tile-stipple-y-origin. -</para> -<para> -<!-- .LP --> -<function>XFillRectangle</function> -and -<function>XFillRectangles</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -<sect2 id="Filling_a_Single_Polygon"> -<title>Filling a Single Polygon</title> -<!-- .XS --> -<!-- (SN Filling a Single Polygon --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To fill a polygon area in a given drawable, use -<function>XFillPolygon</function>. -<indexterm><primary>Polygons</primary><secondary>filling</secondary></indexterm> -<indexterm><primary>Filling</primary><secondary>polygon</secondary></indexterm> -</para> -<indexterm significance="preferred"><primary>XFillPolygon</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfillpolygon'> -<funcprototype> - <funcdef><function>XFillPolygon</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XPoint<parameter> *points</parameter></paramdef> - <paramdef>int<parameter> npoints</parameter></paramdef> - <paramdef>int<parameter> shape</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>points</emphasis> - </term> - <listitem> - <para> -Specifies an array of points. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npoints</emphasis> - </term> - <listitem> - <para> -Specifies the number of points in the array. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>shape</emphasis> - </term> - <listitem> - <para> -Specifies a shape that helps the server to improve performance. -You can pass -<symbol>Complex</symbol>, -<symbol>Convex</symbol>, -or -<symbol>Nonconvex</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the coordinate mode. -You can pass -<symbol>CoordModeOrigin</symbol> -or -<symbol>CoordModePrevious</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XFillPolygon</function> -fills the region closed by the specified path. -The path is closed -automatically if the last point in the list does not coincide with the -first point. -<function>XFillPolygon</function> -does not draw a pixel of the region more than once. -<symbol>CoordModeOrigin</symbol> -treats all coordinates as relative to the origin, -and -<symbol>CoordModePrevious</symbol> -treats all coordinates after the first as relative to the previous point. -</para> -<para> -<!-- .LP --> -Depending on the specified shape, the following occurs: -</para> -<itemizedlist> - <listitem> - <para> -If shape is -<symbol>Complex</symbol>, -the path may self-intersect. -Note that contiguous coincident points in the path are not treated -as self-intersection. - </para> - </listitem> - <listitem> - <para> -If shape is -<symbol>Convex</symbol>, -for every pair of points inside the polygon, -the line segment connecting them does not intersect the path. -If known by the client, -specifying -<symbol>Convex</symbol> -can improve performance. -If you specify -<symbol>Convex</symbol> -for a path that is not convex, -the graphics results are undefined. - </para> - </listitem> - <listitem> - <para> -If shape is -<symbol>Nonconvex</symbol>, -the path does not self-intersect, but the shape is not -wholly convex. -If known by the client, -specifying -<symbol>Nonconvex</symbol> -instead of -<symbol>Complex</symbol> -may improve performance. -If you specify -<symbol>Nonconvex</symbol> -for a self-intersecting path, the graphics results are undefined. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The fill-rule of the GC controls the filling behavior of -self-intersecting polygons. -</para> -<para> -<!-- .LP --> -This function uses these GC components: -function, plane-mask, fill-style, fill-rule, subwindow-mode, clip-x-origin, -clip-y-origin, and clip-mask. -It also uses these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -and tile-stipple-y-origin. -</para> -<para> -<!-- .LP --> -<function>XFillPolygon</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Filling_Single_and_Multiple_Arcs"> -<title>Filling Single and Multiple Arcs</title> -<!-- .XS --> -<!-- (SN Filling Single and Multiple Arcs --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>XFillArc</primary></indexterm> -<indexterm><primary>Arcs</primary><secondary>filling</secondary></indexterm> -<indexterm><primary>Filling</primary><secondary>arcs</secondary></indexterm> -To fill a single arc in a given drawable, use -<function>XFillArc</function>. -</para> -<indexterm significance="preferred"><primary>XFillArc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfillarc'> -<funcprototype> - <funcdef><function>XFillArc</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>intangle1,<parameter> angle2</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the drawable \ --> -and specify the upper-left corner of the bounding rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which are the major and minor axes of the arc --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>angle1</emphasis> - </term> - <listitem> - <para> -Specifies the start of the arc relative to the three-o'clock position -from the center, in units of degrees * 64. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>angle2</emphasis> - </term> - <listitem> - <para> -Specifies the path and extent of the arc relative to the start of the -arc, in units of degrees * 64. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To fill multiple arcs in a given drawable, use -<function>XFillArcs</function>. -</para> -<indexterm significance="preferred"><primary>XFillArcs</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfillarcs'> -<funcprototype> - <funcdef><function>XFillArcs</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XArc<parameter> *arcs</parameter></paramdef> - <paramdef>int<parameter> narcs</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arcs</emphasis> - </term> - <listitem> - <para> -Specifies an array of arcs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>narcs</emphasis> - </term> - <listitem> - <para> -Specifies the number of arcs in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -For each arc, -<function>XFillArc</function> -or -<function>XFillArcs</function> -fills the region closed by the infinitely thin path -described by the specified arc and, depending on the -arc-mode specified in the GC, one or two line segments. -For -<symbol>ArcChord</symbol>, -the single line segment joining the endpoints of the arc is used. -For -<symbol>ArcPieSlice</symbol>, -the two line segments joining the endpoints of the arc with the center -point are used. -<function>XFillArcs</function> -fills the arcs in the order listed in the array. -For any given arc, -<function>XFillArc</function> -and -<function>XFillArcs</function> -do not draw a pixel more than once. -If regions intersect, -the intersecting pixels are drawn multiple times. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, fill-style, arc-mode, subwindow-mode, clip-x-origin, -clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -and tile-stipple-y-origin. -</para> -<para> -<!-- .LP --> -<function>XFillArc</function> -and -<function>XFillArcs</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -</sect1> -<sect1 id="Font_Metrics"> -<title>Font Metrics</title> -<!-- .XS --> -<!-- (SN Font Metrics --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Font</primary></indexterm> -A font is a graphical description of a set of characters that are used to -increase efficiency whenever a set of small, similar sized patterns are -repeatedly used. -</para> -<para> -<!-- .LP --> -This section discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Load and free fonts - </para> - </listitem> - <listitem> - <para> -Obtain and free font names - </para> - </listitem> - <listitem> - <para> -Compute character string sizes - </para> - </listitem> - <listitem> - <para> -Compute logical extents - </para> - </listitem> - <listitem> - <para> -Query character string sizes - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The X server loads fonts whenever a program requests a new font. -The server can cache fonts for quick lookup. -Fonts are global across all screens in a server. -Several levels are possible when dealing with fonts. -Most applications simply use -<function>XLoadQueryFont</function> -to load a font and query the font metrics. -</para> -<para> -<!-- .LP --> -Characters in fonts are regarded as masks. -Except for image text requests, -the only pixels modified are those in which bits are set to 1 in the character. -This means that it makes sense to draw text using stipples or tiles -(for example, many menus gray-out unusable entries). -</para> -<para> -<!-- .LP --> -<!-- .sM --> -The -<structname>XFontStruct</structname> -structure contains all of the information for the font -and consists of the font-specific information as well as -a pointer to an array of -<structname>XCharStruct</structname> -structures for the -characters contained in the font. -The -<structname>XFontStruct</structname>, -<structname>XFontProp</structname>, -and -<structname>XCharStruct</structname> -structures contain: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XCharStruct</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - short lbearing; /* origin to left edge of raster */ - short rbearing; /* origin to right edge of raster */ - short width; /* advance to next char's origin */ - short ascent; /* baseline to top edge of raster */ - short descent; /* baseline to bottom edge of raster */ - unsigned short attributes; /* per char flags (not predefined) */ -} XCharStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XFontProp</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 1i 3i --> -<!-- .ta .5i 1i 3i --> -typedef struct { - Atom name; - unsigned long card32; -} XFontProp; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XChar2b</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { /* normal 16 bit characters are two bytes */ - unsigned char byte1; - unsigned char byte2; -} XChar2b; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XFontStruct</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - Font fid; /* Font id for this font */ - unsigned direction; /* hint about the direction font is painted */ - unsigned min_char_or_byte2; /* first character */ - unsigned max_char_or_byte2; /* last character */ - unsigned min_byte1; /* first row that exists */ - unsigned max_byte1; /* last row that exists */ - Bool all_chars_exist; /* flag if all characters have nonzero size */ - unsigned default_char; /* char to print for undefined character */ - int n_properties; /* how many properties there are */ - XFontProp *properties; /* pointer to array of additional properties */ - XCharStruct min_bounds; /* minimum bounds over all existing char */ - XCharStruct max_bounds; /* maximum bounds over all existing char */ - XCharStruct *per_char; /* first_char to last_char information */ - int ascent; /* logical extent above baseline for spacing */ - int descent; /* logical descent below baseline for spacing */ -} XFontStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -X supports single byte/character, two bytes/character matrix, -and 16-bit character text operations. -Note that any of these forms can be used with a font, but a -single byte/character text request can only specify a single byte -(that is, the first row of a 2-byte font). -You should view 2-byte fonts as a two-dimensional matrix of defined -characters: byte1 specifies the range of defined rows and -byte2 defines the range of defined columns of the font. -Single byte/character fonts have one row defined, and the byte2 range -specified in the structure defines a range of characters. -</para> -<para> -<!-- .LP --> -The bounding box of a character is defined by the -<structname>XCharStruct</structname> -of that character. -When characters are absent from a font, -the default_char is used. -When fonts have all characters of the same size, -only the information in the -<structname>XFontStruct</structname> -min and max bounds are used. -</para> -<para> -<!-- .LP --> -The members of the -<structname>XFontStruct</structname> -have the following semantics: -</para> -<itemizedlist> - <listitem> - <para> -The direction member can be either -<symbol>FontLeftToRight</symbol> -or -<symbol>FontRightToLeft</symbol>. -It is just a hint as to whether most -<structname>XCharStruct</structname> -elements -have a positive -(<symbol>FontLeftToRight</symbol>) -or a negative -(<symbol>FontRightToLeft</symbol>) -character width -metric. -The core protocol defines no support for vertical text. - </para> - </listitem> - <listitem> - <para> -If the min_byte1 and max_byte1 members are both zero, min_char_or_byte2 -specifies the linear character index corresponding to the first element -of the per_char array, and max_char_or_byte2 specifies the linear character -index of the last element. - </para> - </listitem> - <listitem> - <para> -If either min_byte1 or max_byte1 are nonzero, both -min_char_or_byte2 and max_char_or_byte2 are less than 256, -and the 2-byte character index values corresponding to the -per_char array element N (counting from 0) are: - </para> - </listitem> - <listitem> - <para> -<!-- .nf --> - byte1 = N/D + min_byte1 -<!-- .br --> - byte2 = N\\D + min_char_or_byte2 - </para> - </listitem> - <listitem> - <para> -<!-- .fi --> -where: - </para> - </listitem> - <listitem> - <para> -<!-- .nf --> - D = max_char_or_byte2 - min_char_or_byte2 + 1 - / = integer division - \\ = integer modulus -<!-- .fi --> - </para> - </listitem> - <listitem> - <para> -If the per_char pointer is NULL, -all glyphs between the first and last character indexes -inclusive have the same information, -as given by both min_bounds and max_bounds. - </para> - </listitem> - <listitem> - <para> -If all_chars_exist is -<symbol>True</symbol>, -all characters in the per_char array have nonzero bounding boxes. - </para> - </listitem> - <listitem> - <para> -The default_char member specifies the character that will be used when an -undefined or nonexistent character is printed. -The default_char is a 16-bit character (not a 2-byte character). -For a font using 2-byte matrix format, -the default_char has byte1 in the most-significant byte -and byte2 in the least significant byte. -If the default_char itself specifies an undefined or nonexistent character, -no printing is performed for an undefined or nonexistent character. - </para> - </listitem> - <listitem> - <para> -The min_bounds and max_bounds members contain the most extreme values of -each individual -<structname>XCharStruct</structname> -component over all elements of this array -(and ignore nonexistent characters). -The bounding box of the font (the smallest -rectangle enclosing the shape obtained by superimposing all of the -characters at the same origin [x,y]) has its upper-left coordinate at: -<literallayout class="monospaced"> - [x + min_bounds.lbearing, y - max_bounds.ascent] -</literallayout> - </para> - </listitem> - <listitem> - <para> -Its width is: -<literallayout class="monospaced"> - max_bounds.rbearing - min_bounds.lbearing -</literallayout> - </para> - </listitem> - <listitem> - <para> -Its height is: -<literallayout class="monospaced"> - max_bounds.ascent + max_bounds.descent -</literallayout> - </para> - </listitem> - <listitem> - <para> -The ascent member is the logical extent of the font above the baseline that is -used for determining line spacing. -Specific characters may extend beyond -this. - </para> - </listitem> - <listitem> - <para> -The descent member is the logical extent of the font at or below the -baseline that is used for determining line spacing. -Specific characters may extend beyond this. - </para> - </listitem> - <listitem> - <para> -If the baseline is at Y-coordinate y, -the logical extent of the font is inclusive between the Y-coordinate -values (y - font.ascent) and (y + font.descent - 1). -Typically, -the minimum interline spacing between rows of text is given -by ascent + descent. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -For a character origin at [x,y], -the bounding box of a character (that is, -the smallest rectangle that encloses the character's shape) -described in terms of -<structname>XCharStruct</structname> -components is a rectangle with its upper-left corner at: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -[x + lbearing, y - ascent] -</literallayout> -</para> -<para> -<!-- .LP --> -Its width is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -rbearing - lbearing -</literallayout> -</para> -<para> -<!-- .LP --> -Its height is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -ascent + descent -</literallayout> -</para> -<para> -<!-- .LP --> -The origin for the next character is defined to be: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -[x + width, y] -</literallayout> -</para> -<para> -<!-- .LP --> -The lbearing member defines the extent of the left edge of the character ink -from the origin. -The rbearing member defines the extent of the right edge of the character ink -from the origin. -The ascent member defines the extent of the top edge of the character ink -from the origin. -The descent member defines the extent of the bottom edge of the character ink -from the origin. -The width member defines the logical width of the character. -</para> -<para> -<!-- .LP --> -Note that the baseline (the y position of the character origin) -is logically viewed as being the scanline just below nondescending characters. -When descent is zero, -only pixels with Y-coordinates less than y are drawn, -and the origin is logically viewed as being coincident with the left edge of -a nonkerned character. -When lbearing is zero, -no pixels with X-coordinate less than x are drawn. -Any of the -<structname>XCharStruct</structname> -metric members could be negative. -If the width is negative, -the next character will be placed to the left of the current origin. -</para> -<para> -<!-- .LP --> -The X protocol does not define the interpretation of the attributes member -in the -<structname>XCharStruct</structname> -structure. -A nonexistent character is represented with all members of its -<structname>XCharStruct</structname> -set to zero. -</para> -<para> -<!-- .LP --> -A font is not guaranteed to have any properties. -The interpretation of the property value (for example, long or unsigned long) -must be derived from <emphasis remap='I'>a priori</emphasis> knowledge of the property. -A basic set of font properties is specified in the X Consortium standard -<emphasis remap='I'>X Logical Font Description Conventions</emphasis>. -</para> -<sect2 id="Loading_and_Freeing_Fonts"> -<title>Loading and Freeing Fonts</title> -<!-- .XS --> -<!-- (SN Loading and Freeing Fonts --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to load fonts, get font information, -unload fonts, and free font information. -<indexterm><primary>Fonts</primary><secondary>getting information</secondary></indexterm> -<indexterm><primary>Fonts</primary><secondary>unloading</secondary></indexterm> -<indexterm><primary>Fonts</primary><secondary>freeing font information</secondary></indexterm> -A few font functions use a -<type>GContext</type> -resource ID or a font ID interchangeably. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To load a given font, use -<function>XLoadFont</function>. -</para> -<indexterm significance="preferred"><primary>XLoadFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xloadfont'> -<funcprototype> - <funcdef>Font <function>XLoadFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the name of the font, -which is a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLoadFont</function> -function loads the specified font and returns its associated font ID. -If the font name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -When the characters ``?'' and ``*'' are used in a font name, a -pattern match is performed and any matching font is used. -In the pattern, -the ``?'' character will match any single character, -and the ``*'' character will match any number of characters. -A structured format for font names is specified in the X Consortium standard -<emphasis remap='I'>X Logical Font Description Conventions</emphasis>. -If -<function>XLoadFont</function> -was unsuccessful at loading the specified font, -a -<errorname>BadName</errorname> -error results. -Fonts are not associated with a particular screen -and can be stored as a component -of any GC. -When the font is no longer needed, call -<function>XUnloadFont</function>. -</para> -<para> -<!-- .LP --> -<function>XLoadFont</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadName</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return information about an available font, use -<function>XQueryFont</function>. -</para> -<indexterm significance="preferred"><primary>XQueryFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xqueryfont'> -<funcprototype> - <funcdef>XFontStruct *<function>XQueryFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> font_ID</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ID</emphasis> - </term> - <listitem> - <para> -Specifies the font ID or the -<type>GContext</type> -ID. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryFont</function> -function returns a pointer to the -<structname>XFontStruct</structname> -structure, which contains information associated with the font. -You can query a font or the font stored in a GC. -The font ID stored in the -<structname>XFontStruct</structname> -structure will be the -<type>GContext</type> -ID, and you need to be careful when using this ID in other functions -(see -<function>XGContextFromGC</function>). -If the font does not exist, -<function>XQueryFont</function> -returns NULL. -To free this data, use -<function>XFreeFontInfo</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To perform a -<function>XLoadFont</function> -and -<function>XQueryFont</function> -in a single operation, use -<function>XLoadQueryFont</function>. -</para> -<indexterm significance="preferred"><primary>XLoadQueryFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xloadqueryfont'> -<funcprototype> - <funcdef>XFontStruct *<function>XLoadQueryFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the name of the font, -which is a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLoadQueryFont</function> -function provides the most common way for accessing a font. -<function>XLoadQueryFont</function> -both opens (loads) the specified font and returns a pointer to the -appropriate -<structname>XFontStruct</structname> -structure. -If the font name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -If the font does not exist, -<function>XLoadQueryFont</function> -returns NULL. -</para> -<para> -<!-- .LP --> -<function>XLoadQueryFont</function> -can generate a -<errorname>BadAlloc</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To unload the font and free the storage used by the font structure -that was allocated by -<function>XQueryFont</function> -or -<function>XLoadQueryFont</function>, -use -<function>XFreeFont</function>. -</para> -<indexterm significance="preferred"><primary>XFreeFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreefont'> -<funcprototype> - <funcdef><function>XFreeFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the storage associated with the font. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeFont</function> -function deletes the association between the font resource ID and the specified -font and frees the -<structname>XFontStruct</structname> -structure. -The font itself will be freed when no other resource references it. -The data and the font should not be referenced again. -</para> -<para> -<!-- .LP --> -<function>XFreeFont</function> -can generate a -<errorname>BadFont</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return a given font property, use -<function>XGetFontProperty</function>. -</para> -<indexterm significance="preferred"><primary>XGetFontProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetfontproperty'> -<funcprototype> - <funcdef>Bool <function>XGetFontProperty</function></funcdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> - <paramdef>Atom<parameter> atom</parameter></paramdef> - <paramdef>unsignedlong<parameter> *value_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the storage associated with the font. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>atom</emphasis> - </term> - <listitem> - <para> -Specifies the atom for the property name you want returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_return</emphasis> - </term> - <listitem> - <para> -Returns the value of the font property. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Given the atom for that property, -the -<function>XGetFontProperty</function> -function returns the value of the specified font property. -<function>XGetFontProperty</function> -also returns -<symbol>False</symbol> -if the property was not defined or -<symbol>True</symbol> -if it was defined. -A set of predefined atoms exists for font properties, -which can be found in -<filename class="headerfile"><X11/Xatom.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -This set contains the standard properties associated with -a font. -Although it is not guaranteed, -it is likely that the predefined font properties will be present. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To unload a font that was loaded by -<function>XLoadFont</function>, -use -<function>XUnloadFont</function>. -</para> -<indexterm significance="preferred"><primary>XUnloadFont</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunloadfont'> -<funcprototype> - <funcdef><function>XUnloadFont</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Font<parameter> font</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font</emphasis> - </term> - <listitem> - <para> -Specifies the font. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnloadFont</function> -function deletes the association between the font resource ID and the specified font. -The font itself will be freed when no other resource references it. -The font should not be referenced again. -</para> -<para> -<!-- .LP --> -<function>XUnloadFont</function> -can generate a -<errorname>BadFont</errorname> -error. -</para> -</sect2> -<sect2 id="Obtaining_and_Freeing_Font_Names_and_Information"> -<title>Obtaining and Freeing Font Names and Information</title> -<!-- .XS --> -<!-- (SN Obtaining and Freeing Font Names and Information --> -<!-- .XE --> -<para> -<!-- .LP --> -You obtain font names and information by matching a wildcard specification -when querying a font type for a list of available sizes and so on. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return a list of the available font names, use -<function>XListFonts</function>. -</para> -<indexterm significance="preferred"><primary>XListFonts</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlistfonts'> -<funcprototype> - <funcdef>char **<function>XListFonts</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *pattern</parameter></paramdef> - <paramdef>int<parameter> maxnames</parameter></paramdef> - <paramdef>int<parameter> *actual_count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pattern</emphasis> - </term> - <listitem> - <para> -Specifies the null-terminated pattern string that can contain wildcard -characters. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>maxnames</emphasis> - </term> - <listitem> - <para> -Specifies the maximum number of names to be returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>actual_count_return</emphasis> - </term> - <listitem> - <para> -Returns the actual number of font names. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListFonts</function> -function returns an array of available font names -(as controlled by the font search path; see -<function>XSetFontPath</function>) -that match the string you passed to the pattern argument. -The pattern string can contain any characters, -but each asterisk (*) is a wildcard for any number of characters, -and each question mark (?) is a wildcard for a single character. -If the pattern string is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -Each returned string is null-terminated. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned strings are in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -If there are no matching font names, -<function>XListFonts</function> -returns NULL. -The client should call -<function>XFreeFontNames</function> -when finished with the result to free the memory. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free a font name array, use -<function>XFreeFontNames</function>. -</para> -<indexterm significance="preferred"><primary>XFreeFontNames</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreefontnames'> -<funcprototype> - <funcdef><function>XFreeFontNames</function></funcdef> - <paramdef>char<parameter> *list[]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the array of strings you want to free. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeFontNames</function> -function frees the array and strings returned by -<function>XListFonts</function> -or -<function>XListFontsWithInfo</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the names and information about available fonts, use -<function>XListFontsWithInfo</function>. -</para> -<indexterm significance="preferred"><primary>XListFontsWithInfo</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlistfontswithinfo'> -<funcprototype> - <funcdef>char **<function>XListFontsWithInfo</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *pattern</parameter></paramdef> - <paramdef>int<parameter> maxnames</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> - <paramdef>XFontStruct<parameter> **info_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pattern</emphasis> - </term> - <listitem> - <para> -Specifies the null-terminated pattern string that can contain wildcard -characters. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>maxnames</emphasis> - </term> - <listitem> - <para> -Specifies the maximum number of names to be returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the actual number of matched font names. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>info_return</emphasis> - </term> - <listitem> - <para> -Returns the font information. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListFontsWithInfo</function> -function returns a list of font names that match the specified pattern and their -associated font information. -The list of names is limited to size specified by maxnames. -The information returned for each font is identical to what -<function>XLoadQueryFont</function> -would return except that the per-character metrics are not returned. -The pattern string can contain any characters, -but each asterisk (*) is a wildcard for any number of characters, -and each question mark (?) is a wildcard for a single character. -If the pattern string is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Use of uppercase or lowercase does not matter. -Each returned string is null-terminated. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned strings are in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -If there are no matching font names, -<function>XListFontsWithInfo</function> -returns NULL. -</para> -<para> -<!-- .LP --> -To free only the allocated name array, -the client should call -<function>XFreeFontNames</function>. -To free both the name array and the font information array -or to free just the font information array, -the client should call -<function>XFreeFontInfo</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free font structures and font names, use -<function>XFreeFontInfo</function>. -</para> -<indexterm significance="preferred"><primary>XFreeFontInfo</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreefontinfo'> -<funcprototype> - <funcdef><function>XFreeFontInfo</function></funcdef> - <paramdef>char<parameter> **names</parameter></paramdef> - <paramdef>XFontStruct<parameter> *free_info</parameter></paramdef> - <paramdef>int<parameter> actual_count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>names</emphasis> - </term> - <listitem> - <para> -Specifies the list of font names. - - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>free_info</emphasis> - </term> - <listitem> - <para> -Specifies the font information. - - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>actual_count</emphasis> - </term> - <listitem> - <para> -Specifies the actual number of font names. - - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeFontInfo</function> -function frees a font structure or an array of font structures -and optionally an array of font names. -If NULL is passed for names, no font names are freed. -If a font structure for an open font (returned by -<function>XLoadQueryFont</function>) -is passed, the structure is freed, -but the font is not closed; use -<function>XUnloadFont</function> -to close the font. -</para> -</sect2> -<sect2 id="Computing_Character_String_Sizes"> -<title>Computing Character String Sizes</title> -<!-- .XS --> -<!-- (SN Computing Character String Sizes --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to compute the width, -the logical extents, -and the server information about 8-bit and 2-byte text strings. -<indexterm><primary>XTextWidth</primary></indexterm> -<indexterm><primary>XTextWidth16</primary></indexterm> -The width is computed by adding the character widths of all the characters. -It does not matter if the font is an 8-bit or 2-byte font. -These functions return the sum of the character metrics in pixels. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To determine the width of an 8-bit character string, use -<function>XTextWidth</function>. -</para> -<indexterm significance="preferred"><primary>XTextWidth</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtextwidth'> -<funcprototype> - <funcdef>int <function>XTextWidth</function></funcdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the font used for the width computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the character count in the specified string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To determine the width of a 2-byte character string, use -<function>XTextWidth16</function>. -</para> -<indexterm significance="preferred"><primary>XTextWidth16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtextwidth16'> -<funcprototype> - <funcdef>int <function>XTextWidth16</function></funcdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> - <paramdef>XChar2b<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the font used for the width computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the character count in the specified string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect2> -<sect2 id="Computing_Logical_Extents"> -<title>Computing Logical Extents</title> -<!-- .XS --> -<!-- (SN Computing Logical Extents --> -<!-- .XE --> -<para> -<!-- .LP --> -To compute the bounding box of an 8-bit character string in a given font, use -<function>XTextExtents</function>. -</para> -<indexterm significance="preferred"><primary>XTextExtents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtextextents'> -<funcprototype> - <funcdef><function>XTextExtents</function></funcdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> nchars</parameter></paramdef> - <paramdef>int<parameter> *direction_return</parameter></paramdef> - <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef> - <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XFontStruct</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>direction_return</emphasis> - </term> - <listitem> - <para> -Returns the value of the direction hint -(<symbol>FontLeftToRight</symbol> -or -<symbol>FontRightToLeft</symbol>). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ascent_return</emphasis> - </term> - <listitem> - <para> -Returns the font ascent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_descent_return</emphasis> - </term> - <listitem> - <para> -Returns the font descent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_return</emphasis> - </term> - <listitem> - <para> -Returns the overall size in the specified -<structname>XCharStruct</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To compute the bounding box of a 2-byte character string in a given font, use -<function>XTextExtents16</function>. -</para> -<indexterm significance="preferred"><primary>XTextExtents16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtextextents16'> -<funcprototype> - <funcdef><function>XTextExtents16</function></funcdef> - <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef> - <paramdef>XChar2b<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> nchars</parameter></paramdef> - <paramdef>int<parameter> *direction_return</parameter></paramdef> - <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef> - <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_struct</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XFontStruct</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>direction_return</emphasis> - </term> - <listitem> - <para> -Returns the value of the direction hint -(<symbol>FontLeftToRight</symbol> -or -<symbol>FontRightToLeft</symbol>). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ascent_return</emphasis> - </term> - <listitem> - <para> -Returns the font ascent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_descent_return</emphasis> - </term> - <listitem> - <para> -Returns the font descent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_return</emphasis> - </term> - <listitem> - <para> -Returns the overall size in the specified -<structname>XCharStruct</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XTextExtents</function> -and -<function>XTextExtents16</function> -functions -perform the size computation locally and, thereby, -avoid the round-trip overhead of -<function>XQueryTextExtents</function> -and -<function>XQueryTextExtents16</function>. -Both functions return an -<structname>XCharStruct</structname> -structure, whose members are set to the values as follows. -</para> -<para> -<!-- .LP --> -The ascent member is set to the maximum of the ascent metrics of all -characters in the string. -The descent member is set to the maximum of the descent metrics. -The width member is set to the sum of the character-width metrics of all -characters in the string. -For each character in the string, -let W be the sum of the character-width metrics of all characters preceding -it in the string. -Let L be the left-side-bearing metric of the character plus W. -Let R be the right-side-bearing metric of the character plus W. -The lbearing member is set to the minimum L of all characters in the string. -The rbearing member is set to the maximum R. -</para> -<para> -<!-- .LP --> -For fonts defined with linear indexing rather than 2-byte matrix indexing, -each -<structname>XChar2b</structname> -structure is interpreted as a 16-bit number with byte1 as the -most significant byte. -If the font has no defined default character, -undefined characters in the string are taken to have all zero metrics. -</para> -</sect2> -<sect2 id="Querying_Character_String_Sizes"> -<title>Querying Character String Sizes</title> -<!-- .XS --> -<!-- (SN Querying Character String Sizes --> -<!-- .XE --> -<para> -<!-- .LP --> -To query the server for the bounding box of an 8-bit character string in a -given font, use -<function>XQueryTextExtents</function>. -</para> -<indexterm significance="preferred"><primary>XQueryTextExtents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerytextextents'> -<funcprototype> - <funcdef><function>XQueryTextExtents</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> font_ID</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> nchars</parameter></paramdef> - <paramdef>int<parameter> *direction_return</parameter></paramdef> - <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef> - <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ID</emphasis> - </term> - <listitem> - <para> -Specifies either the font ID or the -<type>GContext</type> -ID that contains the font. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>direction_return</emphasis> - </term> - <listitem> - <para> -Returns the value of the direction hint -(<symbol>FontLeftToRight</symbol> -or -<symbol>FontRightToLeft</symbol>). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ascent_return</emphasis> - </term> - <listitem> - <para> -Returns the font ascent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_descent_return</emphasis> - </term> - <listitem> - <para> -Returns the font descent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_return</emphasis> - </term> - <listitem> - <para> -Returns the overall size in the specified -<structname>XCharStruct</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To query the server for the bounding box of a 2-byte character string -in a given font, use -<function>XQueryTextExtents16</function>. -</para> -<indexterm significance="preferred"><primary>XQueryTextExtents16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerytextextents16'> -<funcprototype> - <funcdef><function>XQueryTextExtents16</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> font_ID</parameter></paramdef> - <paramdef>XChar2b<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> nchars</parameter></paramdef> - <paramdef>int<parameter> *direction_return</parameter></paramdef> - <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef> - <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ID</emphasis> - </term> - <listitem> - <para> -Specifies either the font ID or the -<type>GContext</type> -ID that contains the font. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>direction_return</emphasis> - </term> - <listitem> - <para> -Returns the value of the direction hint -(<symbol>FontLeftToRight</symbol> -or -<symbol>FontRightToLeft</symbol>). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_ascent_return</emphasis> - </term> - <listitem> - <para> -Returns the font ascent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_descent_return</emphasis> - </term> - <listitem> - <para> -Returns the font descent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_return</emphasis> - </term> - <listitem> - <para> -Returns the overall size in the specified -<structname>XCharStruct</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryTextExtents</function> -and -<function>XQueryTextExtents16</function> -functions return the bounding box of the specified 8-bit and 16-bit -character string in the specified font or the font contained in the -specified GC. -These functions query the X server and, therefore, suffer the round-trip -overhead that is avoided by -<function>XTextExtents</function> -and -<function>XTextExtents16</function>. -Both functions return a -<structname>XCharStruct</structname> -structure, whose members are set to the values as follows. -</para> -<para> -<!-- .LP --> -The ascent member is set to the maximum of the ascent metrics -of all characters in the string. -The descent member is set to the maximum of the descent metrics. -The width member is set to the sum of the character-width metrics -of all characters in the string. -For each character in the string, -let W be the sum of the character-width metrics of all characters preceding -it in the string. -Let L be the left-side-bearing metric of the character plus W. -Let R be the right-side-bearing metric of the character plus W. -The lbearing member is set to the minimum L of all characters in the string. -The rbearing member is set to the maximum R. -</para> -<para> -<!-- .LP --> -For fonts defined with linear indexing rather than 2-byte matrix indexing, -each -<structname>XChar2b</structname> -structure is interpreted as a 16-bit number with byte1 as the -most significant byte. -If the font has no defined default character, -undefined characters in the string are taken to have all zero metrics. -</para> -<para> -<!-- .LP --> -Characters with all zero metrics are ignored. -If the font has no defined default_char, -the undefined characters in the string are also ignored. -</para> -<para> -<!-- .LP --> -<function>XQueryTextExtents</function> -and -<function>XQueryTextExtents16</function> -can generate -<errorname>BadFont</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -</sect2> -</sect1> -<sect1 id="Drawing_Text"> -<title>Drawing Text</title> -<!-- .XS --> -<!-- (SN Drawing Text --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses how to draw: -</para> -<itemizedlist> - <listitem> - <para> -Complex text - </para> - </listitem> - <listitem> - <para> -Text characters - </para> - </listitem> - <listitem> - <para> -Image text characters - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The fundamental text functions -<function>XDrawText</function> -and -<function>XDrawText16</function> -use the following structures: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XTextItem</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - char *chars; /* pointer to string */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* Font to print it in, None don't change */ -} XTextItem; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XTextItem16</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - XChar2b *chars; /* pointer to two-byte characters */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* font to print it in, None don't change */ -} XTextItem16; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -If the font member is not -<symbol>None</symbol>, -the font is changed before printing and also is stored in the GC. -If an error was generated during text drawing, -the previous items may have been drawn. -The baseline of the characters are drawn starting at the x and y -coordinates that you pass in the text drawing functions. -</para> -<para> -<!-- .LP --> -For example, consider the background rectangle drawn by -<function>XDrawImageString</function>. -If you want the upper-left corner of the background rectangle -to be at pixel coordinate (x,y), pass the (x,y + ascent) -as the baseline origin coordinates to the text functions. -The ascent is the font ascent, as given in the -<structname>XFontStruct</structname> -structure. -If you want the lower-left corner of the background rectangle -to be at pixel coordinate (x,y), pass the (x,y - descent + 1) -as the baseline origin coordinates to the text functions. -The descent is the font descent, as given in the -<structname>XFontStruct</structname> -structure. -</para> -<sect2 id="Drawing_Complex_Text"> -<title>Drawing Complex Text</title> -<!-- .XS --> -<!-- (SN Drawing Complex Text --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Text</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>text items</secondary></indexterm> -</para> -<para> -<!-- .LP --> -To draw 8-bit characters in a given drawable, use -<function>XDrawText</function>. -</para> -<indexterm significance="preferred"><primary>XDrawText</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawtext'> -<funcprototype> - <funcdef><function>XDrawText</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XTextItem<parameter> *items</parameter></paramdef> - <paramdef>int<parameter> nitems</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>items</emphasis> - </term> - <listitem> - <para> -Specifies an array of text items. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nitems</emphasis> - </term> - <listitem> - <para> -Specifies the number of text items in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw 2-byte characters in a given drawable, use -<function>XDrawText16</function>. -</para> -<indexterm significance="preferred"><primary>XDrawText16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawtext16'> -<funcprototype> - <funcdef><function>XDrawText16</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XTextItem16<parameter> *items</parameter></paramdef> - <paramdef>int<parameter> nitems</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>items</emphasis> - </term> - <listitem> - <para> -Specifies an array of text items. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nitems</emphasis> - </term> - <listitem> - <para> -Specifies the number of text items in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawText16</function> -function is similar to -<function>XDrawText</function> -except that it uses 2-byte or 16-bit characters. -Both functions allow complex spacing and font shifts between counted strings. -</para> -<para> -<!-- .LP --> -Each text item is processed in turn. -A font member other than -<symbol>None</symbol> -in an item causes the font to be stored in the GC -and used for subsequent text. -A text element delta specifies an additional change -in the position along the x axis before the string is drawn. -The delta is always added to the character origin -and is not dependent on any characteristics of the font. -Each character image, as defined by the font in the GC, is treated as an -additional mask for a fill operation on the drawable. -The drawable is modified only where the font character has a bit set to 1. -If a text item generates a -<errorname>BadFont</errorname> -error, the previous text items may have been drawn. -</para> -<para> -<!-- .LP --> -For fonts defined with linear indexing rather than 2-byte matrix indexing, -each -<structname>XChar2b</structname> -structure is interpreted as a 16-bit number with byte1 as the -most significant byte. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, fill-style, font, subwindow-mode, -clip-x-origin, clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -and tile-stipple-y-origin. -</para> -<para> -<!-- .LP --> -<function>XDrawText</function> -and -<function>XDrawText16</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadFont</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -<sect2 id="Drawing_Text_Characters"> -<title>Drawing Text Characters</title> -<!-- .XS --> -<!-- (SN Drawing Text Characters --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Strings</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>strings</secondary></indexterm> -To draw 8-bit characters in a given drawable, use -<function>XDrawString</function>. -</para> -<indexterm significance="preferred"><primary>XDrawString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawstring'> -<funcprototype> - <funcdef><function>XDrawString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>int<parameter> x</parameter></paramdef> - <paramdef>int<parameter> y</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw 2-byte characters in a given drawable, use -<function>XDrawString16</function>. -</para> -<indexterm significance="preferred"><primary>XDrawString16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawstring16'> -<funcprototype> - <funcdef><function>XDrawString16</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XChar2b<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Each character image, as defined by the font in the GC, is treated as an -additional mask for a fill operation on the drawable. -The drawable is modified only where the font character has a bit set to 1. -For fonts defined with 2-byte matrix indexing -and used with -<function>XDrawString16</function>, -each byte is used as a byte2 with a byte1 of zero. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -function, plane-mask, fill-style, font, subwindow-mode, clip-x-origin, -clip-y-origin, and clip-mask. -They also use these GC mode-dependent components: -foreground, background, tile, stipple, tile-stipple-x-origin, -and tile-stipple-y-origin. -</para> -<para> -<!-- .LP --> -<function>XDrawString</function> -and -<function>XDrawString16</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -</sect2> -<sect2 id="Drawing_Image_Text_Characters"> -<title>Drawing Image Text Characters</title> -<!-- .XS --> -<!-- (SN Drawing Image Text Characters --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Image text</primary><secondary>drawing</secondary></indexterm> -<indexterm><primary>Drawing</primary><secondary>image text</secondary></indexterm> -Some applications, in particular terminal emulators, need to -print image text in which both the foreground and background bits of -each character are painted. -This prevents annoying flicker on many displays. -<indexterm><primary>XDrawImageString</primary></indexterm> -<indexterm><primary>XDrawImageString16</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To draw 8-bit image text characters in a given drawable, use -<function>XDrawImageString</function>. -</para> -<indexterm significance="preferred"><primary>XDrawImageString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawimagestring'> -<funcprototype> - <funcdef><function>XDrawImageString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw 2-byte image text characters in a given drawable, use -<function>XDrawImageString16</function>. -</para> -<indexterm significance="preferred"><primary>XDrawImageString16</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdrawimagestring16'> -<funcprototype> - <funcdef><function>XDrawImageString16</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XChar2b<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy , which are relative to the origin of the specified drawable \ --> -and define the origin of the first character - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDrawImageString16</function> -function is similar to -<function>XDrawImageString</function> -except that it uses 2-byte or 16-bit characters. -Both functions also use both the foreground and background pixels -of the GC in the destination. -</para> -<para> -<!-- .LP --> -The effect is first to fill a -destination rectangle with the background pixel defined in the GC and then -to paint the text with the foreground pixel. -The upper-left corner of the filled rectangle is at: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -[x, y - font-ascent] -</literallayout> -</para> -<para> -<!-- .LP --> -The width is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -overall-width -</literallayout> -</para> -<para> -<!-- .LP --> -The height is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -font-ascent + font-descent -</literallayout> -</para> -<para> -<!-- .LP --> -The overall-width, font-ascent, and font-descent -are as would be returned by -<function>XQueryTextExtents</function> -using gc and string. -The function and fill-style defined in the GC are ignored for these functions. -The effective function is -<symbol>GXcopy</symbol>, -and the effective fill-style is -<symbol>FillSolid</symbol>. -</para> -<para> -<!-- .LP --> -For fonts defined with 2-byte matrix indexing -and used with -<function>XDrawImageString</function>, -each byte is used as a byte2 with a byte1 of zero. -</para> -<para> -<!-- .LP --> -Both functions use these GC components: -plane-mask, foreground, background, font, subwindow-mode, clip-x-origin, -clip-y-origin, and clip-mask. -</para> -<para> -<!-- .LP --> -<function>XDrawImageString</function> -and -<function>XDrawImageString16</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadMatch</errorname> -errors. -</para> -<para> -<!-- .LP --> -</para> -</sect2> -</sect1> -<sect1 id="Transferring_Images_between_Client_and_Server"> -<title>Transferring Images between Client and Server</title> -<!-- .XS --> -<!-- (SN Transferring Images between Client and Server --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to transfer images between a client -and the server. -Because the server may require diverse data formats, -Xlib provides an image object that fully describes the data in memory -and that provides for basic operations on that data. -You should reference the data -through the image object rather than referencing the data directly. -However, some implementations of the Xlib library may efficiently deal with -frequently used data formats by replacing -functions in the procedure vector with special case functions. -Supported operations include destroying the image, getting a pixel, -storing a pixel, extracting a subimage of an image, and adding a constant -to an image (see <link linkend="Manipulating_Images">section 16.8</link>). -</para> -<para> -<!-- .LP --> -All the image manipulation functions discussed in this section make use of -the -<structname>XImage</structname> -structure, -which describes an image as it exists in the client's memory. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XImage</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 1i 3i --> -<!-- .ta .5i 1i 3i --> -typedef struct _XImage { - int width, height; /* size of image */ - int xoffset; /* number of pixels offset in X direction */ - int format; /* XYBitmap, XYPixmap, ZPixmap */ - char *data; /* pointer to image data */ - int byte_order; /* data byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* quant. of scanline 8, 16, 32 */ - int bitmap_bit_order; /* LSBFirst, MSBFirst */ - int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ - int depth; /* depth of image */ - int bytes_per_line; /* accelerator to next scanline */ - int bits_per_pixel; /* bits per pixel (ZPixmap) */ - unsigned long red_mask; /* bits in z arrangement */ - unsigned long green_mask; - unsigned long blue_mask; - XPointer obdata; /* hook for the object routines to hang on */ - struct funcs { /* image manipulation routines */ - struct _XImage *(*create_image)(); - int (*destroy_image)(); - unsigned long (*get_pixel)(); - int (*put_pixel)(); - struct _XImage *(*sub_image)(); - int (*add_pixel)(); - } f; -} XImage; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To initialize the image manipulation routines of an image structure, use -<function>XInitImage</function>. -</para> -<indexterm significance="preferred"><primary>XInitImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinitimage'> -<funcprototype> - <funcdef>Status <function>XInitImage</function></funcdef> - <paramdef>XImage<parameter> *image</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInitImage</function> -function initializes the internal image manipulation routines of an -image structure, based on the values of the various structure members. -All fields other than the manipulation routines must already be initialized. -If the bytes_per_line member is zero, -<function>XInitImage</function> -will assume the image data is contiguous in memory and set the -bytes_per_line member to an appropriate value based on the other -members; otherwise, the value of bytes_per_line is not changed. -All of the manipulation routines are initialized to functions -that other Xlib image manipulation functions need to operate on the -type of image specified by the rest of the structure. -</para> -<para> -<!-- .LP --> -This function must be called for any image constructed by the client -before passing it to any other Xlib function. -Image structures created or returned by Xlib do not need to be -initialized in this fashion. -</para> -<para> -<!-- .LP --> -This function returns a nonzero status if initialization of the -structure is successful. It returns zero if it detected some error -or inconsistency in the structure, in which case the image is not changed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To combine an image with a rectangle of a drawable on the display, -use -<function>XPutImage</function>. -</para> -<indexterm significance="preferred"><primary>XPutImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xputimage'> -<funcprototype> - <funcdef><function>XPutImage</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>XImage<parameter> *image</parameter></paramdef> - <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef> - <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>image</emphasis> - </term> - <listitem> - <para> -Specifies the image you want combined with the rectangle. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_x</emphasis> - </term> - <listitem> - <para> -Specifies the offset in X from the left edge of the image defined -by the -<structname>XImage</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_y</emphasis> - </term> - <listitem> - <para> -Specifies the offset in Y from the top edge of the image defined -by the -<structname>XImage</structname> -structure. -<!-- .ds Dx , which are relative to the origin of the drawable \ --> -and are the coordinates of the subimage - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Dx. -<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPutImage</function> -function -combines an image with a rectangle of the specified drawable. -The section of the image defined by the src_x, src_y, width, and height -arguments is drawn on the specified part of the drawable. -If -<symbol>XYBitmap</symbol> -format is used, the depth of the image must be one, -or a -<errorname>BadMatch</errorname> -error results. -The foreground pixel in the GC defines the source for the one bits in the image, -and the background pixel defines the source for the zero bits. -For -<symbol>XYPixmap</symbol> -and -<symbol>ZPixmap</symbol>, -the depth of the image must match the depth of the drawable, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -If the characteristics of the image (for example, byte_order and bitmap_unit) -differ from what the server requires, -<function>XPutImage</function> -automatically makes the appropriate -conversions. -</para> -<para> -<!-- .LP --> -This function uses these GC components: -function, plane-mask, subwindow-mode, clip-x-origin, clip-y-origin, -and clip-mask. -It also uses these GC mode-dependent components: -foreground and background. -</para> -<para> -<!-- .LP --> -<function>XPutImage</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return the contents of a rectangle in a given drawable on the display, -use -<function>XGetImage</function>. -This function specifically supports rudimentary screen dumps. -</para> -<indexterm significance="preferred"><primary>XGetImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetimage'> -<funcprototype> - <funcdef>XImage *<function>XGetImage</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef> - <paramdef>int<parameter> format</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. -<!-- .ds Xy , which are relative to the origin of the drawable \ --> -and define the upper-left corner of the rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane_mask</emphasis> - </term> - <listitem> - <para> -Specifies the plane mask. -<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>format</emphasis> - </term> - <listitem> - <para> -Specifies the format for the image. -You can pass -<symbol>XYPixmap</symbol> -or -<symbol>ZPixmap</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetImage</function> -function returns a pointer to an -<structname>XImage</structname> -structure. -This structure provides you with the contents of the specified rectangle of -the drawable in the format you specify. -If the format argument is -<symbol>XYPixmap</symbol>, -the image contains only the bit planes you passed to the plane_mask argument. -If the plane_mask argument only requests a subset of the planes of the -display, the depth of the returned image will be the number of planes -requested. -If the format argument is -<symbol>ZPixmap</symbol>, -<function>XGetImage</function> -returns as zero the bits in all planes not -specified in the plane_mask argument. -The function performs no range checking on the values in plane_mask and ignores -extraneous bits. -</para> -<para> -<!-- .LP --> -<function>XGetImage</function> -returns the depth of the image to the depth member of the -<structname>XImage</structname> -structure. -The depth of the image is as specified when the drawable was created, -except when getting a subset of the planes in -<symbol>XYPixmap</symbol> -format, when the depth is given by the number of bits set to 1 in plane_mask. -</para> -<para> -<!-- .LP --> -If the drawable is a pixmap, -the given rectangle must be wholly contained within the pixmap, -or a -<errorname>BadMatch</errorname> -error results. -If the drawable is a window, -the window must be viewable, -and it must be the case that if there were no inferiors or overlapping windows, -the specified rectangle of the window would be fully visible on the screen -and wholly contained within the outside edges of the window, -or a -<errorname>BadMatch</errorname> -error results. -Note that the borders of the window can be included and read with -this request. -If the window has backing-store, the backing-store contents are -returned for regions of the window that are obscured by noninferior -windows. -If the window does not have backing-store, -the returned contents of such obscured regions are undefined. -The returned contents of visible regions of inferiors -of a different depth than the specified window's depth are also undefined. -The pointer cursor image is not included in the returned contents. -If a problem occurs, -<function>XGetImage</function> -returns NULL. -</para> -<para> -<!-- .LP --> -<function>XGetImage</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To copy the contents of a rectangle on the display -to a location within a preexisting image structure, use -<function>XGetSubImage</function>. -</para> -<indexterm significance="preferred"><primary>XGetSubImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetsubimage'> -<funcprototype> - <funcdef>XImage *<function>XGetSubImage</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef> - <paramdef>int<parameter> format</parameter></paramdef> - <paramdef>XImage<parameter> *dest_image</parameter></paramdef> - <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. -<!-- .ds Xy , which are relative to the origin of the drawable \ --> -and define the upper-left corner of the rectangle - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>plane_mask</emphasis> - </term> - <listitem> - <para> -Specifies the plane mask. -<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>format</emphasis> - </term> - <listitem> - <para> -Specifies the format for the image. -You can pass -<symbol>XYPixmap</symbol> -or -<symbol>ZPixmap</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_image</emphasis> - </term> - <listitem> - <para> -Specifies the destination image. -<!-- .ds Dx , which are relative to the origin of the destination rectangle, \ --> -specify its upper-left corner, and determine where the subimage \ -is placed in the destination image - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Dx. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetSubImage</function> -function updates dest_image with the specified subimage in the same manner as -<function>XGetImage</function>. -If the format argument is -<symbol>XYPixmap</symbol>, -the image contains only the bit planes you passed to the plane_mask argument. -If the format argument is -<symbol>ZPixmap</symbol>, -<function>XGetSubImage</function> -returns as zero the bits in all planes not -specified in the plane_mask argument. -The function performs no range checking on the values in plane_mask and ignores -extraneous bits. -As a convenience, -<function>XGetSubImage</function> -returns a pointer to the same -<structname>XImage</structname> -structure specified by dest_image. -</para> -<para> -<!-- .LP --> -The depth of the destination -<structname>XImage</structname> -structure must be the same as that of the drawable. -If the specified subimage does not fit at the specified location -on the destination image, the right and bottom edges are clipped. -If the drawable is a pixmap, -the given rectangle must be wholly contained within the pixmap, -or a -<errorname>BadMatch</errorname> -error results. -If the drawable is a window, -the window must be viewable, -and it must be the case that if there were no inferiors or overlapping windows, -the specified rectangle of the window would be fully visible on the screen -and wholly contained within the outside edges of the window, -or a -<errorname>BadMatch</errorname> -error results. -If the window has backing-store, -then the backing-store contents are returned for regions of the window -that are obscured by noninferior windows. -If the window does not have backing-store, -the returned contents of such obscured regions are undefined. -The returned contents of visible regions of inferiors -of a different depth than the specified window's depth are also undefined. -If a problem occurs, -<function>XGetSubImage</function> -returns NULL. -</para> -<para> -<!-- .LP --> -<function>XGetSubImage</function> -can generate -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadMatch</errorname>, -and -<errorname>BadValue</errorname> -errors. -<!-- .bp --> - - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="graphics_functions">
+<title>Graphics Functions</title>
+<para>
+Once you have established a connection to a display, you can use the Xlib graphics functions to:
+</para>
+<itemizedlist>
+ <listitem><para>Clear and copy areas</para></listitem>
+ <listitem><para>Draw points, lines, rectangles, and arcs</para></listitem>
+ <listitem><para>Fill areas</para></listitem>
+ <listitem><para>Manipulate fonts</para></listitem>
+ <listitem><para>Draw text</para></listitem>
+ <listitem><para>Transfer images between clients and the server</para></listitem>
+</itemizedlist>
+<para>
+If the same drawable and GC is used for each call, Xlib batches back-to-back
+calls to XDrawPoint, XDrawLine, XDrawRectangle, XFillArc, and XFillRectangle.
+Note that this reduces the total number of requests sent to the server.
+</para>
+<sect1 id="Clearing_Areas">
+<title>Clearing Areas</title>
+<!-- .XS -->
+<!-- (SN Clearing Areas -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to clear an area or the entire window.
+Because pixmaps do not have defined backgrounds,
+they cannot be filled by using the functions described in this section.
+Instead, to accomplish an analogous operation on a pixmap,
+you should use
+<function>XFillRectangle</function>,
+which sets the pixmap to a known value.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To clear a rectangular area of a given window, use
+<function>XClearArea</function>.
+</para>
+<indexterm><primary>Areas</primary><secondary>clearing</secondary></indexterm>
+<indexterm><primary>Clearing</primary><secondary>areas</secondary></indexterm>
+<indexterm significance="preferred"><primary>XClearArea</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcleararea'>
+<funcprototype>
+ <funcdef><function>XClearArea</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>Bool<parameter> exposures</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+<!-- .ds Xy , which are relative to the origin of the window \ -->
+and specify the upper-left corner of the rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the dimensions of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>exposures</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates if
+<symbol>Expose</symbol>
+events are to be generated.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XClearArea</function>
+function paints a rectangular area in the specified window according to the
+specified dimensions with the window's background pixel or pixmap.
+The subwindow-mode effectively is
+<symbol>ClipByChildren</symbol>.
+If width is zero, it
+is replaced with the current width of the window minus x.
+If height is
+zero, it is replaced with the current height of the window minus y.
+If the window has a defined background tile,
+the rectangle clipped by any children is filled with this tile.
+If the window has
+background
+<symbol>None</symbol>,
+the contents of the window are not changed.
+In either
+case, if exposures is
+<symbol>True</symbol>,
+one or more
+<symbol>Expose</symbol>
+events are generated for regions of the rectangle that are either visible or are
+being retained in a backing store.
+If you specify a window whose class is
+<symbol>InputOnly</symbol>,
+a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XClearArea</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To clear the entire area in a given window, use
+<function>XClearWindow</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>clearing</secondary></indexterm>
+<indexterm><primary>Clearing</primary><secondary>windows</secondary></indexterm>
+<indexterm significance="preferred"><primary>XClearWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xclearwindow'>
+<funcprototype>
+ <funcdef><function>XClearWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XClearWindow</function>
+function clears the entire area in the specified window and is
+equivalent to
+<function>XClearArea</function>
+(display, w, 0, 0, 0, 0,
+<symbol>False</symbol>).
+If the window has a defined background tile, the rectangle is tiled with a
+plane-mask of all ones and
+<symbol>GXcopy</symbol>
+function.
+If the window has
+background
+<symbol>None</symbol>,
+the contents of the window are not changed.
+If you specify a window whose class is
+<symbol>InputOnly</symbol>,
+a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XClearWindow</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Copying_Areas">
+<title>Copying Areas</title>
+<!-- .XS -->
+<!-- (SN Copying Areas -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to copy an area or a bit plane.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To copy an area between drawables of the same
+root and depth, use
+<function>XCopyArea</function>.
+</para>
+<indexterm><primary>Areas</primary><secondary>copying</secondary></indexterm>
+<indexterm><primary>Copying</primary><secondary>areas</secondary></indexterm>
+<indexterm significance="preferred"><primary>XCopyArea</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcopyarea'>
+<funcprototype>
+ <funcdef><function>XCopyArea</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawablesrc,<parameter> dest</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the source and destination rectangles to be combined.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates,
+which are relative to the origin of the source rectangle
+and specify its upper-left corner.
+<!-- .ds Wh , which are the dimensions of both the source \ -->
+and destination rectangles
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+<!-- .ds Dx , which are relative to the origin of the destination rectangle \ -->
+and specify its upper-left corner
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Dx.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCopyArea</function>
+function combines the specified rectangle of src with the specified rectangle
+of dest.
+The drawables must have the same root and depth,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If regions of the source rectangle are obscured and have not been
+retained in backing store
+or if regions outside the boundaries of the source drawable are specified,
+those regions are not copied.
+Instead, the
+following occurs on all corresponding destination regions that are either
+visible or are retained in backing store.
+If the destination is a window with a background other than
+<symbol>None</symbol>,
+corresponding regions
+of the destination are tiled with that background
+(with plane-mask of all ones and
+<symbol>GXcopy</symbol>
+function).
+Regardless of tiling or whether the destination is a window or a pixmap,
+if graphics-exposures is
+<symbol>True</symbol>,
+then
+<symbol>GraphicsExpose</symbol>
+events for all corresponding destination regions are generated.
+If graphics-exposures is
+<symbol>True</symbol>
+but no
+<symbol>GraphicsExpose</symbol>
+events are generated, a
+<symbol>NoExpose</symbol>
+event is generated.
+Note that by default graphics-exposures is
+<symbol>True</symbol>
+in new GCs.
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components: function, plane-mask,
+subwindow-mode, graphics-exposures, clip-x-origin,
+clip-y-origin, and clip-mask.
+</para>
+<para>
+<!-- .LP -->
+<function>XCopyArea</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To copy a single bit plane of a given drawable, use
+<function>XCopyPlane</function>.
+</para>
+<indexterm><primary>Plane</primary><secondary>copying</secondary></indexterm>
+<indexterm><primary>Copying</primary><secondary>planes</secondary></indexterm>
+<indexterm significance="preferred"><primary>XCopyPlane</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcopyplane'>
+<funcprototype>
+ <funcdef><function>XCopyPlane</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawablesrc,<parameter> dest</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the source and destination rectangles to be combined.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates,
+which are relative to the origin of the source rectangle
+and specify its upper-left corner.
+<!-- .ds Wh , which are the dimensions of both the source and destination rectangles -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+<!-- .ds Dx , which are relative to the origin of the destination rectangle \ -->
+and specify its upper-left corner
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Dx.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the bit plane.
+You must set exactly one bit to 1.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCopyPlane</function>
+function uses a single bit plane of the specified source rectangle
+combined with the specified GC to modify the specified rectangle of dest.
+The drawables must have the same root but need not have the same depth.
+If the drawables do not have the same root, a
+<errorname>BadMatch</errorname>
+error results.
+If plane does not have exactly one bit set to 1 and the value of plane
+is not less than %2 sup n%, where <emphasis remap='I'>n</emphasis> is the depth of src, a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+Effectively,
+<function>XCopyPlane</function>
+forms a pixmap of the same depth as the rectangle of dest and with a
+size specified by the source region.
+It uses the foreground/background pixels in the GC (foreground
+everywhere the bit plane in src contains a bit set to 1,
+background everywhere the bit plane in src contains a bit set to 0)
+and the equivalent of a
+<systemitem>CopyArea</systemitem>
+protocol request is performed with all the same exposure semantics.
+This can also be thought of as using the specified region of the source
+bit plane as a stipple with a fill-style of
+<symbol>FillOpaqueStippled</symbol>
+for filling a rectangular area of the destination.
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components: function, plane-mask, foreground,
+background, subwindow-mode, graphics-exposures, clip-x-origin, clip-y-origin,
+and clip-mask.
+</para>
+<para>
+<!-- .LP -->
+<function>XCopyPlane</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Drawing_Points_Lines_Rectangles_and_Arcs">
+<title>Drawing Points, Lines, Rectangles, and Arcs</title>
+<!-- .XS -->
+<!-- (SN Drawing Points, Lines, Rectangles, and Arcs -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to draw:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A single point or multiple points
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single line or multiple lines
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single rectangle or multiple rectangles
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single arc or multiple arcs
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Some of the functions described in the following sections
+use these structures:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XSegment</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ short x1, y1, x2, y2;
+} XSegment;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XPoint</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ short x, y;
+} XPoint;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XRectangle</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+} XRectangle;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>XArc</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ short x, y;
+ unsigned short width, height;
+ short angle1, angle2; /* Degrees * 64 */
+} XArc;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+All x and y members are signed integers.
+The width and height members are 16-bit unsigned integers.
+You should be careful not to generate coordinates and sizes
+out of the 16-bit ranges, because the protocol only has 16-bit fields
+for these values.
+</para>
+<sect2 id="Drawing_Single_and_Multiple_Points">
+<title>Drawing Single and Multiple Points</title>
+<!-- .XS -->
+<!-- (SN Drawing Single and Multiple Points -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Points</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>points</secondary></indexterm>
+<indexterm><primary>XDrawPoints</primary></indexterm>
+<indexterm><primary>XDrawPoint</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+To draw a single point in a given drawable, use
+<function>XDrawPoint</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawPoint</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawpoint'>
+<funcprototype>
+ <funcdef><function>XDrawPoint</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates where you want the point drawn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw multiple points in a given drawable, use
+<function>XDrawPoints</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawPoints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawpoints'>
+<funcprototype>
+ <funcdef><function>XDrawPoints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XPoint<parameter> *points</parameter></paramdef>
+ <paramdef>int<parameter> npoints</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>points</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of points.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npoints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of points in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the coordinate mode.
+You can pass
+<symbol>CoordModeOrigin</symbol>
+or
+<symbol>CoordModePrevious</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawPoint</function>
+function uses the foreground pixel and function components of the
+GC to draw a single point into the specified drawable;
+<function>XDrawPoints</function>
+draws multiple points this way.
+<symbol>CoordModeOrigin</symbol>
+treats all coordinates as relative to the origin,
+and
+<symbol>CoordModePrevious</symbol>
+treats all coordinates after the first as relative to the previous point.
+<function>XDrawPoints</function>
+draws the points in the order listed in the array.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components: function, plane-mask,
+foreground, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawPoint</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+<function>XDrawPoints</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Drawing_Single_and_Multiple_Lines">
+<title>Drawing Single and Multiple Lines</title>
+<!-- .XS -->
+<!-- (SN Drawing Single and Multiple Lines -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Lines</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>lines</secondary></indexterm>
+<indexterm><primary>XDrawLine</primary></indexterm>
+<indexterm><primary>XDrawLines</primary></indexterm>
+<indexterm><primary>Polygons</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>polygons</secondary></indexterm>
+<indexterm><primary>XDrawSegments</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+To draw a single line between two points in a given drawable, use
+<function>XDrawLine</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawLine</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawline'>
+<funcprototype>
+ <funcdef><function>XDrawLine</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx1,y1,x2,<parameter> y2</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x1</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y1</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x2</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y2</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the points (x1, y1) and (x2, y2) to be connected.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw multiple lines in a given drawable, use
+<function>XDrawLines</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawLines</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawlines'>
+<funcprototype>
+ <funcdef><function>XDrawLines</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XPoint<parameter> *points</parameter></paramdef>
+ <paramdef>int<parameter> npoints</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>points</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of points.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npoints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of points in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the coordinate mode.
+You can pass
+<symbol>CoordModeOrigin</symbol>
+or
+<symbol>CoordModePrevious</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw multiple, unconnected lines in a given drawable,
+use
+<function>XDrawSegments</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawSegments</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawsegments'>
+<funcprototype>
+ <funcdef><function>XDrawSegments</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XSegment<parameter> *segments</parameter></paramdef>
+ <paramdef>int<parameter> nsegments</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>segments</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of segments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nsegments</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of segments in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawLine</function>
+function uses the components of the specified GC to
+draw a line between the specified set of points (x1, y1) and (x2, y2).
+It does not perform joining at coincident endpoints.
+For any given line,
+<function>XDrawLine</function>
+does not draw a pixel more than once.
+If lines intersect, the intersecting pixels are drawn multiple times.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XDrawLines</function>
+function uses the components of the specified GC to draw
+npoints-1 lines between each pair of points (point[i], point[i+1])
+in the array of
+<structname>XPoint</structname>
+structures.
+It draws the lines in the order listed in the array.
+The lines join correctly at all intermediate points, and if the first and last
+points coincide, the first and last lines also join correctly.
+For any given line,
+<function>XDrawLines</function>
+does not draw a pixel more than once.
+If thin (zero line-width) lines intersect,
+the intersecting pixels are drawn multiple times.
+If wide lines intersect, the intersecting pixels are drawn only once, as though
+the entire
+<systemitem>PolyLine</systemitem>
+protocol request were a single, filled shape.
+<symbol>CoordModeOrigin</symbol>
+treats all coordinates as relative to the origin,
+and
+<symbol>CoordModePrevious</symbol>
+treats all coordinates after the first as relative to the previous point.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XDrawSegments</function>
+function draws multiple, unconnected lines.
+For each segment,
+<function>XDrawSegments</function>
+draws a
+line between (x1, y1) and (x2, y2).
+It draws the lines in the order listed in the array of
+<structname>XSegment</structname>
+structures and does not perform joining at coincident endpoints.
+For any given line,
+<function>XDrawSegments</function>
+does not draw a pixel more than once.
+If lines intersect, the intersecting pixels are drawn multiple times.
+</para>
+<para>
+<!-- .LP -->
+All three functions use these GC components:
+function, plane-mask, line-width,
+line-style, cap-style, fill-style, subwindow-mode,
+clip-x-origin, clip-y-origin, and clip-mask.
+The
+<function>XDrawLines</function>
+function also uses the join-style GC component.
+All three functions also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+tile-stipple-y-origin, dash-offset, and dash-list.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawLine</function>,
+<function>XDrawLines</function>,
+and
+<function>XDrawSegments</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+<function>XDrawLines</function>
+also can generate
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Drawing_Single_and_Multiple_Rectangles_">
+<title>Drawing Single and Multiple Rectangles </title>
+<!-- .XS -->
+<!-- (SN Drawing Single and Multiple Rectangles -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Rectangles</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>rectangles</secondary></indexterm>
+<indexterm><primary>XDrawRectangle</primary></indexterm>
+<indexterm><primary>XDrawRectangles</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+To draw the outline of a single rectangle in a given drawable, use
+<function>XDrawRectangle</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawRectangle</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawrectangle'>
+<funcprototype>
+ <funcdef><function>XDrawRectangle</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which specify the upper-left corner of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which specify the dimensions of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw the outline of multiple rectangles
+in a given drawable, use
+<function>XDrawRectangles</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawRectangles</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawrectangles'>
+<funcprototype>
+ <funcdef><function>XDrawRectangles</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XRectangle<parameter> rectangles[]</parameter></paramdef>
+ <paramdef>int<parameter> nrectangles</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rectangles</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of rectangles.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nrectangles</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of rectangles in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawRectangle</function>
+and
+<function>XDrawRectangles</function>
+functions draw the outlines of the specified rectangle or rectangles as
+if a five-point
+<systemitem>PolyLine</systemitem>
+protocol request were specified for each rectangle:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+[x,y] [x+width,y] [x+width,y+height] [x,y+height] [x,y]
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+For the specified rectangle or rectangles,
+these functions do not draw a pixel more than once.
+<function>XDrawRectangles</function>
+draws the rectangles in the order listed in the array.
+If rectangles intersect,
+the intersecting pixels are drawn multiple times.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, line-width,
+line-style, cap-style, join-style, fill-style,
+subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+tile-stipple-y-origin, dash-offset, and dash-list.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawRectangle</function>
+and
+<function>XDrawRectangles</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Drawing_Single_and_Multiple_Arcs">
+<title>Drawing Single and Multiple Arcs</title>
+<!-- .XS -->
+<!-- (SN Drawing Single and Multiple Arcs -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Drawing</primary><secondary>arcs</secondary></indexterm>
+<indexterm><primary>XDrawArc</primary></indexterm>
+<indexterm><primary>Arcs</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>XDrawArcs</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To draw a single arc in a given drawable, use
+<function>XDrawArc</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawArc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawarc'>
+<funcprototype>
+ <funcdef><function>XDrawArc</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>intangle1,<parameter> angle2</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the drawable \ -->
+and specify the upper-left corner of the bounding rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the major and minor axes of the arc -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>angle1</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the start of the arc relative to the three-o'clock position
+from the center, in units of degrees * 64.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>angle2</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the path and extent of the arc relative to the start of the
+arc, in units of degrees * 64.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw multiple arcs in a given drawable, use
+<function>XDrawArcs</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawArcs</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawarcs'>
+<funcprototype>
+ <funcdef><function>XDrawArcs</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XArc<parameter> *arcs</parameter></paramdef>
+ <paramdef>int<parameter> narcs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arcs</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of arcs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>narcs</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arcs in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .EQ -->
+delim %%
+<!-- .EN -->
+<function>XDrawArc</function>
+draws a single circular or elliptical arc, and
+<function>XDrawArcs</function>
+draws multiple circular or elliptical arcs.
+Each arc is specified by a rectangle and two angles.
+The center of the circle or ellipse is the center of the
+rectangle, and the major and minor axes are specified by the width and height.
+Positive angles indicate counterclockwise motion,
+and negative angles indicate clockwise motion.
+If the magnitude of angle2 is greater than 360 degrees,
+<function>XDrawArc</function>
+or
+<function>XDrawArcs</function>
+truncates it to 360 degrees.
+</para>
+<para>
+<!-- .LP -->
+For an arc specified as %[ ~x, ~y, ~width , ~height, ~angle1, ~angle2 ]%,
+the origin of the major and minor axes is at
+% [ x +^ {width over 2} , ~y +^ {height over 2} ]%,
+and the infinitely thin path describing the entire circle or ellipse
+intersects the horizontal axis at % [ x, ~y +^ {height over 2} ]% and
+% [ x +^ width , ~y +^ { height over 2 }] %
+and intersects the vertical axis at % [ x +^ { width over 2 } , ~y ]% and
+% [ x +^ { width over 2 }, ~y +^ height ]%.
+These coordinates can be fractional
+and so are not truncated to discrete coordinates.
+The path should be defined by the ideal mathematical path.
+For a wide line with line-width lw,
+the bounding outlines for filling are given
+by the two infinitely thin paths consisting of all points whose perpendicular
+distance from the path of the circle/ellipse is equal to lw/2
+(which may be a fractional value).
+The cap-style and join-style are applied the same as for a line
+corresponding to the tangent of the circle/ellipse at the endpoint.
+</para>
+<para>
+<!-- .LP -->
+For an arc specified as % [ ~x, ~y, ~width, ~height, ~angle1, ~angle2 ]%,
+the angles must be specified
+in the effectively skewed coordinate system of the ellipse (for a
+circle, the angles and coordinate systems are identical). The
+relationship between these angles and angles expressed in the normal
+coordinate system of the screen (as measured with a protractor) is as
+follows:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+% roman "skewed-angle" ~ = ~ atan left ( tan ( roman "normal-angle" )
+ * width over height right ) +^ adjust%
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The skewed-angle and normal-angle are expressed in radians (rather
+than in degrees scaled by 64) in the range % [ 0 , ~2 pi ]% and where atan
+returns a value in the range % [ - pi over 2 , ~pi over 2 ] %
+and adjust is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA 1i 2i -->
+<!-- .ta 1i 2i -->
+%0% for normal-angle in the range % [ 0 , ~pi over 2 ]%
+%pi% for normal-angle in the range % [ pi over 2 , ~{3 pi} over 2 ]%
+%2 pi% for normal-angle in the range % [ {3 pi} over 2 , ~2 pi ]%
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+For any given arc,
+<function>XDrawArc</function>
+and
+<function>XDrawArcs</function>
+do not draw a pixel more than once.
+If two arcs join correctly and if the line-width is greater than zero
+and the arcs intersect,
+<function>XDrawArc</function>
+and
+<function>XDrawArcs</function>
+do not draw a pixel more than once.
+Otherwise,
+the intersecting pixels of intersecting arcs are drawn multiple times.
+Specifying an arc with one endpoint and a clockwise extent draws the same pixels
+as specifying the other endpoint and an equivalent counterclockwise extent,
+except as it affects joins.
+</para>
+<para>
+<!-- .LP -->
+If the last point in one arc coincides with the first point in the following
+arc, the two arcs will join correctly.
+If the first point in the first arc coincides with the last point in the last
+arc, the two arcs will join correctly.
+By specifying one axis to be zero, a horizontal or vertical line can be
+drawn.
+Angles are computed based solely on the coordinate system and ignore the
+aspect ratio.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, line-width, line-style, cap-style, join-style,
+fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+tile-stipple-y-origin, dash-offset, and dash-list.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawArc</function>
+and
+<function>XDrawArcs</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Filling_Areas">
+<title>Filling Areas</title>
+<!-- .XS -->
+<!-- (SN Filling Areas -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to fill:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A single rectangle or multiple rectangles
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single polygon
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single arc or multiple arcs
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Filling_Single_and_Multiple_Rectangles">
+<title>Filling Single and Multiple Rectangles</title>
+<!-- .XS -->
+<!-- (SN Filling Single and Multiple Rectangles -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Filling</primary><secondary>rectangles</secondary></indexterm>
+<indexterm><primary>XFillRectangle</primary></indexterm>
+<indexterm><primary>Rectangle</primary><secondary>filling</secondary></indexterm>
+<indexterm><primary>XFillRectangles</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To fill a single rectangular area in a given drawable, use
+<function>XFillRectangle</function>.
+</para>
+<indexterm significance="preferred"><primary>XFillRectangle</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfillrectangle'>
+<funcprototype>
+ <funcdef><function>XFillRectangle</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the drawable \ -->
+and specify the upper-left corner of the rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the dimensions of the rectangle to be filled -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To fill multiple rectangular areas in a given drawable, use
+<function>XFillRectangles</function>.
+</para>
+<indexterm significance="preferred"><primary>XFillRectangles</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfillrectangles'>
+<funcprototype>
+ <funcdef><function>XFillRectangles</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *rectangles</parameter></paramdef>
+ <paramdef>int<parameter> nrectangles</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rectangles</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of rectangles.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nrectangles</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of rectangles in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFillRectangle</function>
+and
+<function>XFillRectangles</function>
+functions fill the specified rectangle or rectangles
+as if a four-point
+<systemitem>FillPolygon</systemitem>
+protocol request were specified for each rectangle:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+[x,y] [x+width,y] [x+width,y+height] [x,y+height]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Each function uses the x and y coordinates,
+width and height dimensions, and GC you specify.
+</para>
+<para>
+<!-- .LP -->
+<function>XFillRectangles</function>
+fills the rectangles in the order listed in the array.
+For any given rectangle,
+<function>XFillRectangle</function>
+and
+<function>XFillRectangles</function>
+do not draw a pixel more than once.
+If rectangles intersect, the intersecting pixels are
+drawn multiple times.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, fill-style, subwindow-mode,
+clip-x-origin, clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+and tile-stipple-y-origin.
+</para>
+<para>
+<!-- .LP -->
+<function>XFillRectangle</function>
+and
+<function>XFillRectangles</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Filling_a_Single_Polygon">
+<title>Filling a Single Polygon</title>
+<!-- .XS -->
+<!-- (SN Filling a Single Polygon -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To fill a polygon area in a given drawable, use
+<function>XFillPolygon</function>.
+<indexterm><primary>Polygons</primary><secondary>filling</secondary></indexterm>
+<indexterm><primary>Filling</primary><secondary>polygon</secondary></indexterm>
+</para>
+<indexterm significance="preferred"><primary>XFillPolygon</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfillpolygon'>
+<funcprototype>
+ <funcdef><function>XFillPolygon</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XPoint<parameter> *points</parameter></paramdef>
+ <paramdef>int<parameter> npoints</parameter></paramdef>
+ <paramdef>int<parameter> shape</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>points</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of points.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npoints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of points in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>shape</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a shape that helps the server to improve performance.
+You can pass
+<symbol>Complex</symbol>,
+<symbol>Convex</symbol>,
+or
+<symbol>Nonconvex</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the coordinate mode.
+You can pass
+<symbol>CoordModeOrigin</symbol>
+or
+<symbol>CoordModePrevious</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XFillPolygon</function>
+fills the region closed by the specified path.
+The path is closed
+automatically if the last point in the list does not coincide with the
+first point.
+<function>XFillPolygon</function>
+does not draw a pixel of the region more than once.
+<symbol>CoordModeOrigin</symbol>
+treats all coordinates as relative to the origin,
+and
+<symbol>CoordModePrevious</symbol>
+treats all coordinates after the first as relative to the previous point.
+</para>
+<para>
+<!-- .LP -->
+Depending on the specified shape, the following occurs:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If shape is
+<symbol>Complex</symbol>,
+the path may self-intersect.
+Note that contiguous coincident points in the path are not treated
+as self-intersection.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If shape is
+<symbol>Convex</symbol>,
+for every pair of points inside the polygon,
+the line segment connecting them does not intersect the path.
+If known by the client,
+specifying
+<symbol>Convex</symbol>
+can improve performance.
+If you specify
+<symbol>Convex</symbol>
+for a path that is not convex,
+the graphics results are undefined.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If shape is
+<symbol>Nonconvex</symbol>,
+the path does not self-intersect, but the shape is not
+wholly convex.
+If known by the client,
+specifying
+<symbol>Nonconvex</symbol>
+instead of
+<symbol>Complex</symbol>
+may improve performance.
+If you specify
+<symbol>Nonconvex</symbol>
+for a self-intersecting path, the graphics results are undefined.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The fill-rule of the GC controls the filling behavior of
+self-intersecting polygons.
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components:
+function, plane-mask, fill-style, fill-rule, subwindow-mode, clip-x-origin,
+clip-y-origin, and clip-mask.
+It also uses these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+and tile-stipple-y-origin.
+</para>
+<para>
+<!-- .LP -->
+<function>XFillPolygon</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Filling_Single_and_Multiple_Arcs">
+<title>Filling Single and Multiple Arcs</title>
+<!-- .XS -->
+<!-- (SN Filling Single and Multiple Arcs -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>XFillArc</primary></indexterm>
+<indexterm><primary>Arcs</primary><secondary>filling</secondary></indexterm>
+<indexterm><primary>Filling</primary><secondary>arcs</secondary></indexterm>
+To fill a single arc in a given drawable, use
+<function>XFillArc</function>.
+</para>
+<indexterm significance="preferred"><primary>XFillArc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfillarc'>
+<funcprototype>
+ <funcdef><function>XFillArc</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>intangle1,<parameter> angle2</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the drawable \ -->
+and specify the upper-left corner of the bounding rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which are the major and minor axes of the arc -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>angle1</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the start of the arc relative to the three-o'clock position
+from the center, in units of degrees * 64.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>angle2</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the path and extent of the arc relative to the start of the
+arc, in units of degrees * 64.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To fill multiple arcs in a given drawable, use
+<function>XFillArcs</function>.
+</para>
+<indexterm significance="preferred"><primary>XFillArcs</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfillarcs'>
+<funcprototype>
+ <funcdef><function>XFillArcs</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XArc<parameter> *arcs</parameter></paramdef>
+ <paramdef>int<parameter> narcs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arcs</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of arcs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>narcs</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arcs in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+For each arc,
+<function>XFillArc</function>
+or
+<function>XFillArcs</function>
+fills the region closed by the infinitely thin path
+described by the specified arc and, depending on the
+arc-mode specified in the GC, one or two line segments.
+For
+<symbol>ArcChord</symbol>,
+the single line segment joining the endpoints of the arc is used.
+For
+<symbol>ArcPieSlice</symbol>,
+the two line segments joining the endpoints of the arc with the center
+point are used.
+<function>XFillArcs</function>
+fills the arcs in the order listed in the array.
+For any given arc,
+<function>XFillArc</function>
+and
+<function>XFillArcs</function>
+do not draw a pixel more than once.
+If regions intersect,
+the intersecting pixels are drawn multiple times.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, fill-style, arc-mode, subwindow-mode, clip-x-origin,
+clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+and tile-stipple-y-origin.
+</para>
+<para>
+<!-- .LP -->
+<function>XFillArc</function>
+and
+<function>XFillArcs</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Font_Metrics">
+<title>Font Metrics</title>
+<!-- .XS -->
+<!-- (SN Font Metrics -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Font</primary></indexterm>
+A font is a graphical description of a set of characters that are used to
+increase efficiency whenever a set of small, similar sized patterns are
+repeatedly used.
+</para>
+<para>
+<!-- .LP -->
+This section discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Load and free fonts
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtain and free font names
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Compute character string sizes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Compute logical extents
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Query character string sizes
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The X server loads fonts whenever a program requests a new font.
+The server can cache fonts for quick lookup.
+Fonts are global across all screens in a server.
+Several levels are possible when dealing with fonts.
+Most applications simply use
+<function>XLoadQueryFont</function>
+to load a font and query the font metrics.
+</para>
+<para>
+<!-- .LP -->
+Characters in fonts are regarded as masks.
+Except for image text requests,
+the only pixels modified are those in which bits are set to 1 in the character.
+This means that it makes sense to draw text using stipples or tiles
+(for example, many menus gray-out unusable entries).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+The
+<structname>XFontStruct</structname>
+structure contains all of the information for the font
+and consists of the font-specific information as well as
+a pointer to an array of
+<structname>XCharStruct</structname>
+structures for the
+characters contained in the font.
+The
+<structname>XFontStruct</structname>,
+<structname>XFontProp</structname>,
+and
+<structname>XCharStruct</structname>
+structures contain:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XCharStruct</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ short lbearing; /* origin to left edge of raster */
+ short rbearing; /* origin to right edge of raster */
+ short width; /* advance to next char's origin */
+ short ascent; /* baseline to top edge of raster */
+ short descent; /* baseline to bottom edge of raster */
+ unsigned short attributes; /* per char flags (not predefined) */
+} XCharStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XFontProp</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 1i 3i -->
+<!-- .ta .5i 1i 3i -->
+typedef struct {
+ Atom name;
+ unsigned long card32;
+} XFontProp;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XChar2b</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct { /* normal 16 bit characters are two bytes */
+ unsigned char byte1;
+ unsigned char byte2;
+} XChar2b;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XFontStruct</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ XExtData *ext_data; /* hook for extension to hang data */
+ Font fid; /* Font id for this font */
+ unsigned direction; /* hint about the direction font is painted */
+ unsigned min_char_or_byte2; /* first character */
+ unsigned max_char_or_byte2; /* last character */
+ unsigned min_byte1; /* first row that exists */
+ unsigned max_byte1; /* last row that exists */
+ Bool all_chars_exist; /* flag if all characters have nonzero size */
+ unsigned default_char; /* char to print for undefined character */
+ int n_properties; /* how many properties there are */
+ XFontProp *properties; /* pointer to array of additional properties */
+ XCharStruct min_bounds; /* minimum bounds over all existing char */
+ XCharStruct max_bounds; /* maximum bounds over all existing char */
+ XCharStruct *per_char; /* first_char to last_char information */
+ int ascent; /* logical extent above baseline for spacing */
+ int descent; /* logical descent below baseline for spacing */
+} XFontStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+X supports single byte/character, two bytes/character matrix,
+and 16-bit character text operations.
+Note that any of these forms can be used with a font, but a
+single byte/character text request can only specify a single byte
+(that is, the first row of a 2-byte font).
+You should view 2-byte fonts as a two-dimensional matrix of defined
+characters: byte1 specifies the range of defined rows and
+byte2 defines the range of defined columns of the font.
+Single byte/character fonts have one row defined, and the byte2 range
+specified in the structure defines a range of characters.
+</para>
+<para>
+<!-- .LP -->
+The bounding box of a character is defined by the
+<structname>XCharStruct</structname>
+of that character.
+When characters are absent from a font,
+the default_char is used.
+When fonts have all characters of the same size,
+only the information in the
+<structname>XFontStruct</structname>
+min and max bounds are used.
+</para>
+<para>
+<!-- .LP -->
+The members of the
+<structname>XFontStruct</structname>
+have the following semantics:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The direction member can be either
+<symbol>FontLeftToRight</symbol>
+or
+<symbol>FontRightToLeft</symbol>.
+It is just a hint as to whether most
+<structname>XCharStruct</structname>
+elements
+have a positive
+(<symbol>FontLeftToRight</symbol>)
+or a negative
+(<symbol>FontRightToLeft</symbol>)
+character width
+metric.
+The core protocol defines no support for vertical text.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the min_byte1 and max_byte1 members are both zero, min_char_or_byte2
+specifies the linear character index corresponding to the first element
+of the per_char array, and max_char_or_byte2 specifies the linear character
+index of the last element.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If either min_byte1 or max_byte1 are nonzero, both
+min_char_or_byte2 and max_char_or_byte2 are less than 256,
+and the 2-byte character index values corresponding to the
+per_char array element N (counting from 0) are:
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<!-- .nf -->
+ byte1 = N/D + min_byte1
+<!-- .br -->
+ byte2 = N\\D + min_char_or_byte2
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<!-- .fi -->
+where:
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<!-- .nf -->
+ D = max_char_or_byte2 - min_char_or_byte2 + 1
+ / = integer division
+ \\ = integer modulus
+<!-- .fi -->
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the per_char pointer is NULL,
+all glyphs between the first and last character indexes
+inclusive have the same information,
+as given by both min_bounds and max_bounds.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If all_chars_exist is
+<symbol>True</symbol>,
+all characters in the per_char array have nonzero bounding boxes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The default_char member specifies the character that will be used when an
+undefined or nonexistent character is printed.
+The default_char is a 16-bit character (not a 2-byte character).
+For a font using 2-byte matrix format,
+the default_char has byte1 in the most-significant byte
+and byte2 in the least significant byte.
+If the default_char itself specifies an undefined or nonexistent character,
+no printing is performed for an undefined or nonexistent character.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The min_bounds and max_bounds members contain the most extreme values of
+each individual
+<structname>XCharStruct</structname>
+component over all elements of this array
+(and ignore nonexistent characters).
+The bounding box of the font (the smallest
+rectangle enclosing the shape obtained by superimposing all of the
+characters at the same origin [x,y]) has its upper-left coordinate at:
+<literallayout class="monospaced">
+ [x + min_bounds.lbearing, y - max_bounds.ascent]
+</literallayout>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Its width is:
+<literallayout class="monospaced">
+ max_bounds.rbearing - min_bounds.lbearing
+</literallayout>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Its height is:
+<literallayout class="monospaced">
+ max_bounds.ascent + max_bounds.descent
+</literallayout>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The ascent member is the logical extent of the font above the baseline that is
+used for determining line spacing.
+Specific characters may extend beyond
+this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The descent member is the logical extent of the font at or below the
+baseline that is used for determining line spacing.
+Specific characters may extend beyond this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the baseline is at Y-coordinate y,
+the logical extent of the font is inclusive between the Y-coordinate
+values (y - font.ascent) and (y + font.descent - 1).
+Typically,
+the minimum interline spacing between rows of text is given
+by ascent + descent.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+For a character origin at [x,y],
+the bounding box of a character (that is,
+the smallest rectangle that encloses the character's shape)
+described in terms of
+<structname>XCharStruct</structname>
+components is a rectangle with its upper-left corner at:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+[x + lbearing, y - ascent]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Its width is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+rbearing - lbearing
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Its height is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+ascent + descent
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The origin for the next character is defined to be:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+[x + width, y]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The lbearing member defines the extent of the left edge of the character ink
+from the origin.
+The rbearing member defines the extent of the right edge of the character ink
+from the origin.
+The ascent member defines the extent of the top edge of the character ink
+from the origin.
+The descent member defines the extent of the bottom edge of the character ink
+from the origin.
+The width member defines the logical width of the character.
+</para>
+<para>
+<!-- .LP -->
+Note that the baseline (the y position of the character origin)
+is logically viewed as being the scanline just below nondescending characters.
+When descent is zero,
+only pixels with Y-coordinates less than y are drawn,
+and the origin is logically viewed as being coincident with the left edge of
+a nonkerned character.
+When lbearing is zero,
+no pixels with X-coordinate less than x are drawn.
+Any of the
+<structname>XCharStruct</structname>
+metric members could be negative.
+If the width is negative,
+the next character will be placed to the left of the current origin.
+</para>
+<para>
+<!-- .LP -->
+The X protocol does not define the interpretation of the attributes member
+in the
+<structname>XCharStruct</structname>
+structure.
+A nonexistent character is represented with all members of its
+<structname>XCharStruct</structname>
+set to zero.
+</para>
+<para>
+<!-- .LP -->
+A font is not guaranteed to have any properties.
+The interpretation of the property value (for example, long or unsigned long)
+must be derived from <emphasis remap='I'>a priori</emphasis> knowledge of the property.
+A basic set of font properties is specified in the X Consortium standard
+<emphasis remap='I'>X Logical Font Description Conventions</emphasis>.
+</para>
+<sect2 id="Loading_and_Freeing_Fonts">
+<title>Loading and Freeing Fonts</title>
+<!-- .XS -->
+<!-- (SN Loading and Freeing Fonts -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to load fonts, get font information,
+unload fonts, and free font information.
+<indexterm><primary>Fonts</primary><secondary>getting information</secondary></indexterm>
+<indexterm><primary>Fonts</primary><secondary>unloading</secondary></indexterm>
+<indexterm><primary>Fonts</primary><secondary>freeing font information</secondary></indexterm>
+A few font functions use a
+<type>GContext</type>
+resource ID or a font ID interchangeably.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To load a given font, use
+<function>XLoadFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XLoadFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xloadfont'>
+<funcprototype>
+ <funcdef>Font <function>XLoadFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the font,
+which is a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLoadFont</function>
+function loads the specified font and returns its associated font ID.
+If the font name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+When the characters ``?'' and ``*'' are used in a font name, a
+pattern match is performed and any matching font is used.
+In the pattern,
+the ``?'' character will match any single character,
+and the ``*'' character will match any number of characters.
+A structured format for font names is specified in the X Consortium standard
+<emphasis remap='I'>X Logical Font Description Conventions</emphasis>.
+If
+<function>XLoadFont</function>
+was unsuccessful at loading the specified font,
+a
+<errorname>BadName</errorname>
+error results.
+Fonts are not associated with a particular screen
+and can be stored as a component
+of any GC.
+When the font is no longer needed, call
+<function>XUnloadFont</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XLoadFont</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadName</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return information about an available font, use
+<function>XQueryFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xqueryfont'>
+<funcprototype>
+ <funcdef>XFontStruct *<function>XQueryFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> font_ID</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ID</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font ID or the
+<type>GContext</type>
+ID.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryFont</function>
+function returns a pointer to the
+<structname>XFontStruct</structname>
+structure, which contains information associated with the font.
+You can query a font or the font stored in a GC.
+The font ID stored in the
+<structname>XFontStruct</structname>
+structure will be the
+<type>GContext</type>
+ID, and you need to be careful when using this ID in other functions
+(see
+<function>XGContextFromGC</function>).
+If the font does not exist,
+<function>XQueryFont</function>
+returns NULL.
+To free this data, use
+<function>XFreeFontInfo</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To perform a
+<function>XLoadFont</function>
+and
+<function>XQueryFont</function>
+in a single operation, use
+<function>XLoadQueryFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XLoadQueryFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xloadqueryfont'>
+<funcprototype>
+ <funcdef>XFontStruct *<function>XLoadQueryFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the font,
+which is a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLoadQueryFont</function>
+function provides the most common way for accessing a font.
+<function>XLoadQueryFont</function>
+both opens (loads) the specified font and returns a pointer to the
+appropriate
+<structname>XFontStruct</structname>
+structure.
+If the font name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+If the font does not exist,
+<function>XLoadQueryFont</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+<function>XLoadQueryFont</function>
+can generate a
+<errorname>BadAlloc</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To unload the font and free the storage used by the font structure
+that was allocated by
+<function>XQueryFont</function>
+or
+<function>XLoadQueryFont</function>,
+use
+<function>XFreeFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreefont'>
+<funcprototype>
+ <funcdef><function>XFreeFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the storage associated with the font.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeFont</function>
+function deletes the association between the font resource ID and the specified
+font and frees the
+<structname>XFontStruct</structname>
+structure.
+The font itself will be freed when no other resource references it.
+The data and the font should not be referenced again.
+</para>
+<para>
+<!-- .LP -->
+<function>XFreeFont</function>
+can generate a
+<errorname>BadFont</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return a given font property, use
+<function>XGetFontProperty</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetFontProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetfontproperty'>
+<funcprototype>
+ <funcdef>Bool <function>XGetFontProperty</function></funcdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+ <paramdef>Atom<parameter> atom</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> *value_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the storage associated with the font.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>atom</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the atom for the property name you want returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value of the font property.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Given the atom for that property,
+the
+<function>XGetFontProperty</function>
+function returns the value of the specified font property.
+<function>XGetFontProperty</function>
+also returns
+<symbol>False</symbol>
+if the property was not defined or
+<symbol>True</symbol>
+if it was defined.
+A set of predefined atoms exists for font properties,
+which can be found in
+<filename class="headerfile"><X11/Xatom.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+This set contains the standard properties associated with
+a font.
+Although it is not guaranteed,
+it is likely that the predefined font properties will be present.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To unload a font that was loaded by
+<function>XLoadFont</function>,
+use
+<function>XUnloadFont</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnloadFont</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunloadfont'>
+<funcprototype>
+ <funcdef><function>XUnloadFont</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Font<parameter> font</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnloadFont</function>
+function deletes the association between the font resource ID and the specified font.
+The font itself will be freed when no other resource references it.
+The font should not be referenced again.
+</para>
+<para>
+<!-- .LP -->
+<function>XUnloadFont</function>
+can generate a
+<errorname>BadFont</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Obtaining_and_Freeing_Font_Names_and_Information">
+<title>Obtaining and Freeing Font Names and Information</title>
+<!-- .XS -->
+<!-- (SN Obtaining and Freeing Font Names and Information -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You obtain font names and information by matching a wildcard specification
+when querying a font type for a list of available sizes and so on.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return a list of the available font names, use
+<function>XListFonts</function>.
+</para>
+<indexterm significance="preferred"><primary>XListFonts</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlistfonts'>
+<funcprototype>
+ <funcdef>char **<function>XListFonts</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *pattern</parameter></paramdef>
+ <paramdef>int<parameter> maxnames</parameter></paramdef>
+ <paramdef>int<parameter> *actual_count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pattern</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the null-terminated pattern string that can contain wildcard
+characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>maxnames</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the maximum number of names to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>actual_count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the actual number of font names.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListFonts</function>
+function returns an array of available font names
+(as controlled by the font search path; see
+<function>XSetFontPath</function>)
+that match the string you passed to the pattern argument.
+The pattern string can contain any characters,
+but each asterisk (*) is a wildcard for any number of characters,
+and each question mark (?) is a wildcard for a single character.
+If the pattern string is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+Each returned string is null-terminated.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned strings are in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+If there are no matching font names,
+<function>XListFonts</function>
+returns NULL.
+The client should call
+<function>XFreeFontNames</function>
+when finished with the result to free the memory.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free a font name array, use
+<function>XFreeFontNames</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeFontNames</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreefontnames'>
+<funcprototype>
+ <funcdef><function>XFreeFontNames</function></funcdef>
+ <paramdef>char<parameter> *list[]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the array of strings you want to free.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeFontNames</function>
+function frees the array and strings returned by
+<function>XListFonts</function>
+or
+<function>XListFontsWithInfo</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the names and information about available fonts, use
+<function>XListFontsWithInfo</function>.
+</para>
+<indexterm significance="preferred"><primary>XListFontsWithInfo</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlistfontswithinfo'>
+<funcprototype>
+ <funcdef>char **<function>XListFontsWithInfo</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *pattern</parameter></paramdef>
+ <paramdef>int<parameter> maxnames</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+ <paramdef>XFontStruct<parameter> **info_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pattern</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the null-terminated pattern string that can contain wildcard
+characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>maxnames</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the maximum number of names to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the actual number of matched font names.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>info_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListFontsWithInfo</function>
+function returns a list of font names that match the specified pattern and their
+associated font information.
+The list of names is limited to size specified by maxnames.
+The information returned for each font is identical to what
+<function>XLoadQueryFont</function>
+would return except that the per-character metrics are not returned.
+The pattern string can contain any characters,
+but each asterisk (*) is a wildcard for any number of characters,
+and each question mark (?) is a wildcard for a single character.
+If the pattern string is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Use of uppercase or lowercase does not matter.
+Each returned string is null-terminated.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned strings are in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+If there are no matching font names,
+<function>XListFontsWithInfo</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+To free only the allocated name array,
+the client should call
+<function>XFreeFontNames</function>.
+To free both the name array and the font information array
+or to free just the font information array,
+the client should call
+<function>XFreeFontInfo</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free font structures and font names, use
+<function>XFreeFontInfo</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeFontInfo</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreefontinfo'>
+<funcprototype>
+ <funcdef><function>XFreeFontInfo</function></funcdef>
+ <paramdef>char<parameter> **names</parameter></paramdef>
+ <paramdef>XFontStruct<parameter> *free_info</parameter></paramdef>
+ <paramdef>int<parameter> actual_count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>names</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of font names.
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>free_info</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font information.
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>actual_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the actual number of font names.
+
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeFontInfo</function>
+function frees a font structure or an array of font structures
+and optionally an array of font names.
+If NULL is passed for names, no font names are freed.
+If a font structure for an open font (returned by
+<function>XLoadQueryFont</function>)
+is passed, the structure is freed,
+but the font is not closed; use
+<function>XUnloadFont</function>
+to close the font.
+</para>
+</sect2>
+<sect2 id="Computing_Character_String_Sizes">
+<title>Computing Character String Sizes</title>
+<!-- .XS -->
+<!-- (SN Computing Character String Sizes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to compute the width,
+the logical extents,
+and the server information about 8-bit and 2-byte text strings.
+<indexterm><primary>XTextWidth</primary></indexterm>
+<indexterm><primary>XTextWidth16</primary></indexterm>
+The width is computed by adding the character widths of all the characters.
+It does not matter if the font is an 8-bit or 2-byte font.
+These functions return the sum of the character metrics in pixels.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To determine the width of an 8-bit character string, use
+<function>XTextWidth</function>.
+</para>
+<indexterm significance="preferred"><primary>XTextWidth</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtextwidth'>
+<funcprototype>
+ <funcdef>int <function>XTextWidth</function></funcdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font used for the width computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character count in the specified string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To determine the width of a 2-byte character string, use
+<function>XTextWidth16</function>.
+</para>
+<indexterm significance="preferred"><primary>XTextWidth16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtextwidth16'>
+<funcprototype>
+ <funcdef>int <function>XTextWidth16</function></funcdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+ <paramdef>XChar2b<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font used for the width computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character count in the specified string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect2>
+<sect2 id="Computing_Logical_Extents">
+<title>Computing Logical Extents</title>
+<!-- .XS -->
+<!-- (SN Computing Logical Extents -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To compute the bounding box of an 8-bit character string in a given font, use
+<function>XTextExtents</function>.
+</para>
+<indexterm significance="preferred"><primary>XTextExtents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtextextents'>
+<funcprototype>
+ <funcdef><function>XTextExtents</function></funcdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> nchars</parameter></paramdef>
+ <paramdef>int<parameter> *direction_return</parameter></paramdef>
+ <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef>
+ <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XFontStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>direction_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value of the direction hint
+(<symbol>FontLeftToRight</symbol>
+or
+<symbol>FontRightToLeft</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ascent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font ascent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_descent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font descent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall size in the specified
+<structname>XCharStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To compute the bounding box of a 2-byte character string in a given font, use
+<function>XTextExtents16</function>.
+</para>
+<indexterm significance="preferred"><primary>XTextExtents16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtextextents16'>
+<funcprototype>
+ <funcdef><function>XTextExtents16</function></funcdef>
+ <paramdef>XFontStruct<parameter> *font_struct</parameter></paramdef>
+ <paramdef>XChar2b<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> nchars</parameter></paramdef>
+ <paramdef>int<parameter> *direction_return</parameter></paramdef>
+ <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef>
+ <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XFontStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>direction_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value of the direction hint
+(<symbol>FontLeftToRight</symbol>
+or
+<symbol>FontRightToLeft</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ascent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font ascent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_descent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font descent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall size in the specified
+<structname>XCharStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XTextExtents</function>
+and
+<function>XTextExtents16</function>
+functions
+perform the size computation locally and, thereby,
+avoid the round-trip overhead of
+<function>XQueryTextExtents</function>
+and
+<function>XQueryTextExtents16</function>.
+Both functions return an
+<structname>XCharStruct</structname>
+structure, whose members are set to the values as follows.
+</para>
+<para>
+<!-- .LP -->
+The ascent member is set to the maximum of the ascent metrics of all
+characters in the string.
+The descent member is set to the maximum of the descent metrics.
+The width member is set to the sum of the character-width metrics of all
+characters in the string.
+For each character in the string,
+let W be the sum of the character-width metrics of all characters preceding
+it in the string.
+Let L be the left-side-bearing metric of the character plus W.
+Let R be the right-side-bearing metric of the character plus W.
+The lbearing member is set to the minimum L of all characters in the string.
+The rbearing member is set to the maximum R.
+</para>
+<para>
+<!-- .LP -->
+For fonts defined with linear indexing rather than 2-byte matrix indexing,
+each
+<structname>XChar2b</structname>
+structure is interpreted as a 16-bit number with byte1 as the
+most significant byte.
+If the font has no defined default character,
+undefined characters in the string are taken to have all zero metrics.
+</para>
+</sect2>
+<sect2 id="Querying_Character_String_Sizes">
+<title>Querying Character String Sizes</title>
+<!-- .XS -->
+<!-- (SN Querying Character String Sizes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To query the server for the bounding box of an 8-bit character string in a
+given font, use
+<function>XQueryTextExtents</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryTextExtents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerytextextents'>
+<funcprototype>
+ <funcdef><function>XQueryTextExtents</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> font_ID</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> nchars</parameter></paramdef>
+ <paramdef>int<parameter> *direction_return</parameter></paramdef>
+ <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef>
+ <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ID</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies either the font ID or the
+<type>GContext</type>
+ID that contains the font.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>direction_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value of the direction hint
+(<symbol>FontLeftToRight</symbol>
+or
+<symbol>FontRightToLeft</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ascent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font ascent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_descent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font descent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall size in the specified
+<structname>XCharStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To query the server for the bounding box of a 2-byte character string
+in a given font, use
+<function>XQueryTextExtents16</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryTextExtents16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerytextextents16'>
+<funcprototype>
+ <funcdef><function>XQueryTextExtents16</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> font_ID</parameter></paramdef>
+ <paramdef>XChar2b<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> nchars</parameter></paramdef>
+ <paramdef>int<parameter> *direction_return</parameter></paramdef>
+ <paramdef>int*font_ascent_return,<parameter> *font_descent_return</parameter></paramdef>
+ <paramdef>XCharStruct<parameter> *overall_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ID</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies either the font ID or the
+<type>GContext</type>
+ID that contains the font.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>direction_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value of the direction hint
+(<symbol>FontLeftToRight</symbol>
+or
+<symbol>FontRightToLeft</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_ascent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font ascent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_descent_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the font descent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall size in the specified
+<structname>XCharStruct</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryTextExtents</function>
+and
+<function>XQueryTextExtents16</function>
+functions return the bounding box of the specified 8-bit and 16-bit
+character string in the specified font or the font contained in the
+specified GC.
+These functions query the X server and, therefore, suffer the round-trip
+overhead that is avoided by
+<function>XTextExtents</function>
+and
+<function>XTextExtents16</function>.
+Both functions return a
+<structname>XCharStruct</structname>
+structure, whose members are set to the values as follows.
+</para>
+<para>
+<!-- .LP -->
+The ascent member is set to the maximum of the ascent metrics
+of all characters in the string.
+The descent member is set to the maximum of the descent metrics.
+The width member is set to the sum of the character-width metrics
+of all characters in the string.
+For each character in the string,
+let W be the sum of the character-width metrics of all characters preceding
+it in the string.
+Let L be the left-side-bearing metric of the character plus W.
+Let R be the right-side-bearing metric of the character plus W.
+The lbearing member is set to the minimum L of all characters in the string.
+The rbearing member is set to the maximum R.
+</para>
+<para>
+<!-- .LP -->
+For fonts defined with linear indexing rather than 2-byte matrix indexing,
+each
+<structname>XChar2b</structname>
+structure is interpreted as a 16-bit number with byte1 as the
+most significant byte.
+If the font has no defined default character,
+undefined characters in the string are taken to have all zero metrics.
+</para>
+<para>
+<!-- .LP -->
+Characters with all zero metrics are ignored.
+If the font has no defined default_char,
+the undefined characters in the string are also ignored.
+</para>
+<para>
+<!-- .LP -->
+<function>XQueryTextExtents</function>
+and
+<function>XQueryTextExtents16</function>
+can generate
+<errorname>BadFont</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Drawing_Text">
+<title>Drawing Text</title>
+<!-- .XS -->
+<!-- (SN Drawing Text -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses how to draw:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Complex text
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Text characters
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Image text characters
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The fundamental text functions
+<function>XDrawText</function>
+and
+<function>XDrawText16</function>
+use the following structures:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XTextItem</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ char *chars; /* pointer to string */
+ int nchars; /* number of characters */
+ int delta; /* delta between strings */
+ Font font; /* Font to print it in, None don't change */
+} XTextItem;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XTextItem16</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ XChar2b *chars; /* pointer to two-byte characters */
+ int nchars; /* number of characters */
+ int delta; /* delta between strings */
+ Font font; /* font to print it in, None don't change */
+} XTextItem16;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the font member is not
+<symbol>None</symbol>,
+the font is changed before printing and also is stored in the GC.
+If an error was generated during text drawing,
+the previous items may have been drawn.
+The baseline of the characters are drawn starting at the x and y
+coordinates that you pass in the text drawing functions.
+</para>
+<para>
+<!-- .LP -->
+For example, consider the background rectangle drawn by
+<function>XDrawImageString</function>.
+If you want the upper-left corner of the background rectangle
+to be at pixel coordinate (x,y), pass the (x,y + ascent)
+as the baseline origin coordinates to the text functions.
+The ascent is the font ascent, as given in the
+<structname>XFontStruct</structname>
+structure.
+If you want the lower-left corner of the background rectangle
+to be at pixel coordinate (x,y), pass the (x,y - descent + 1)
+as the baseline origin coordinates to the text functions.
+The descent is the font descent, as given in the
+<structname>XFontStruct</structname>
+structure.
+</para>
+<sect2 id="Drawing_Complex_Text">
+<title>Drawing Complex Text</title>
+<!-- .XS -->
+<!-- (SN Drawing Complex Text -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Text</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>text items</secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+To draw 8-bit characters in a given drawable, use
+<function>XDrawText</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawText</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawtext'>
+<funcprototype>
+ <funcdef><function>XDrawText</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XTextItem<parameter> *items</parameter></paramdef>
+ <paramdef>int<parameter> nitems</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>items</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of text items.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nitems</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of text items in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw 2-byte characters in a given drawable, use
+<function>XDrawText16</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawText16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawtext16'>
+<funcprototype>
+ <funcdef><function>XDrawText16</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XTextItem16<parameter> *items</parameter></paramdef>
+ <paramdef>int<parameter> nitems</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>items</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of text items.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nitems</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of text items in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawText16</function>
+function is similar to
+<function>XDrawText</function>
+except that it uses 2-byte or 16-bit characters.
+Both functions allow complex spacing and font shifts between counted strings.
+</para>
+<para>
+<!-- .LP -->
+Each text item is processed in turn.
+A font member other than
+<symbol>None</symbol>
+in an item causes the font to be stored in the GC
+and used for subsequent text.
+A text element delta specifies an additional change
+in the position along the x axis before the string is drawn.
+The delta is always added to the character origin
+and is not dependent on any characteristics of the font.
+Each character image, as defined by the font in the GC, is treated as an
+additional mask for a fill operation on the drawable.
+The drawable is modified only where the font character has a bit set to 1.
+If a text item generates a
+<errorname>BadFont</errorname>
+error, the previous text items may have been drawn.
+</para>
+<para>
+<!-- .LP -->
+For fonts defined with linear indexing rather than 2-byte matrix indexing,
+each
+<structname>XChar2b</structname>
+structure is interpreted as a 16-bit number with byte1 as the
+most significant byte.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, fill-style, font, subwindow-mode,
+clip-x-origin, clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+and tile-stipple-y-origin.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawText</function>
+and
+<function>XDrawText16</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadFont</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Drawing_Text_Characters">
+<title>Drawing Text Characters</title>
+<!-- .XS -->
+<!-- (SN Drawing Text Characters -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Strings</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>strings</secondary></indexterm>
+To draw 8-bit characters in a given drawable, use
+<function>XDrawString</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawstring'>
+<funcprototype>
+ <funcdef><function>XDrawString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>int<parameter> x</parameter></paramdef>
+ <paramdef>int<parameter> y</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw 2-byte characters in a given drawable, use
+<function>XDrawString16</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawString16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawstring16'>
+<funcprototype>
+ <funcdef><function>XDrawString16</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XChar2b<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Each character image, as defined by the font in the GC, is treated as an
+additional mask for a fill operation on the drawable.
+The drawable is modified only where the font character has a bit set to 1.
+For fonts defined with 2-byte matrix indexing
+and used with
+<function>XDrawString16</function>,
+each byte is used as a byte2 with a byte1 of zero.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+function, plane-mask, fill-style, font, subwindow-mode, clip-x-origin,
+clip-y-origin, and clip-mask.
+They also use these GC mode-dependent components:
+foreground, background, tile, stipple, tile-stipple-x-origin,
+and tile-stipple-y-origin.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawString</function>
+and
+<function>XDrawString16</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Drawing_Image_Text_Characters">
+<title>Drawing Image Text Characters</title>
+<!-- .XS -->
+<!-- (SN Drawing Image Text Characters -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Image text</primary><secondary>drawing</secondary></indexterm>
+<indexterm><primary>Drawing</primary><secondary>image text</secondary></indexterm>
+Some applications, in particular terminal emulators, need to
+print image text in which both the foreground and background bits of
+each character are painted.
+This prevents annoying flicker on many displays.
+<indexterm><primary>XDrawImageString</primary></indexterm>
+<indexterm><primary>XDrawImageString16</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To draw 8-bit image text characters in a given drawable, use
+<function>XDrawImageString</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawImageString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawimagestring'>
+<funcprototype>
+ <funcdef><function>XDrawImageString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw 2-byte image text characters in a given drawable, use
+<function>XDrawImageString16</function>.
+</para>
+<indexterm significance="preferred"><primary>XDrawImageString16</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdrawimagestring16'>
+<funcprototype>
+ <funcdef><function>XDrawImageString16</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XChar2b<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy , which are relative to the origin of the specified drawable \ -->
+and define the origin of the first character
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDrawImageString16</function>
+function is similar to
+<function>XDrawImageString</function>
+except that it uses 2-byte or 16-bit characters.
+Both functions also use both the foreground and background pixels
+of the GC in the destination.
+</para>
+<para>
+<!-- .LP -->
+The effect is first to fill a
+destination rectangle with the background pixel defined in the GC and then
+to paint the text with the foreground pixel.
+The upper-left corner of the filled rectangle is at:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+[x, y - font-ascent]
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The width is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+overall-width
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The height is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+font-ascent + font-descent
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The overall-width, font-ascent, and font-descent
+are as would be returned by
+<function>XQueryTextExtents</function>
+using gc and string.
+The function and fill-style defined in the GC are ignored for these functions.
+The effective function is
+<symbol>GXcopy</symbol>,
+and the effective fill-style is
+<symbol>FillSolid</symbol>.
+</para>
+<para>
+<!-- .LP -->
+For fonts defined with 2-byte matrix indexing
+and used with
+<function>XDrawImageString</function>,
+each byte is used as a byte2 with a byte1 of zero.
+</para>
+<para>
+<!-- .LP -->
+Both functions use these GC components:
+plane-mask, foreground, background, font, subwindow-mode, clip-x-origin,
+clip-y-origin, and clip-mask.
+</para>
+<para>
+<!-- .LP -->
+<function>XDrawImageString</function>
+and
+<function>XDrawImageString16</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect2>
+</sect1>
+<sect1 id="Transferring_Images_between_Client_and_Server">
+<title>Transferring Images between Client and Server</title>
+<!-- .XS -->
+<!-- (SN Transferring Images between Client and Server -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to transfer images between a client
+and the server.
+Because the server may require diverse data formats,
+Xlib provides an image object that fully describes the data in memory
+and that provides for basic operations on that data.
+You should reference the data
+through the image object rather than referencing the data directly.
+However, some implementations of the Xlib library may efficiently deal with
+frequently used data formats by replacing
+functions in the procedure vector with special case functions.
+Supported operations include destroying the image, getting a pixel,
+storing a pixel, extracting a subimage of an image, and adding a constant
+to an image (see <link linkend="Manipulating_Images">section 16.8</link>).
+</para>
+<para>
+<!-- .LP -->
+All the image manipulation functions discussed in this section make use of
+the
+<structname>XImage</structname>
+structure,
+which describes an image as it exists in the client's memory.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XImage</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1i 3i -->
+<!-- .ta .5i 1i 3i -->
+typedef struct _XImage {
+ int width, height; /* size of image */
+ int xoffset; /* number of pixels offset in X direction */
+ int format; /* XYBitmap, XYPixmap, ZPixmap */
+ char *data; /* pointer to image data */
+ int byte_order; /* data byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* quant. of scanline 8, 16, 32 */
+ int bitmap_bit_order; /* LSBFirst, MSBFirst */
+ int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */
+ int depth; /* depth of image */
+ int bytes_per_line; /* accelerator to next scanline */
+ int bits_per_pixel; /* bits per pixel (ZPixmap) */
+ unsigned long red_mask; /* bits in z arrangement */
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ XPointer obdata; /* hook for the object routines to hang on */
+ struct funcs { /* image manipulation routines */
+ struct _XImage *(*create_image)();
+ int (*destroy_image)();
+ unsigned long (*get_pixel)();
+ int (*put_pixel)();
+ struct _XImage *(*sub_image)();
+ int (*add_pixel)();
+ } f;
+} XImage;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To initialize the image manipulation routines of an image structure, use
+<function>XInitImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XInitImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinitimage'>
+<funcprototype>
+ <funcdef>Status <function>XInitImage</function></funcdef>
+ <paramdef>XImage<parameter> *image</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInitImage</function>
+function initializes the internal image manipulation routines of an
+image structure, based on the values of the various structure members.
+All fields other than the manipulation routines must already be initialized.
+If the bytes_per_line member is zero,
+<function>XInitImage</function>
+will assume the image data is contiguous in memory and set the
+bytes_per_line member to an appropriate value based on the other
+members; otherwise, the value of bytes_per_line is not changed.
+All of the manipulation routines are initialized to functions
+that other Xlib image manipulation functions need to operate on the
+type of image specified by the rest of the structure.
+</para>
+<para>
+<!-- .LP -->
+This function must be called for any image constructed by the client
+before passing it to any other Xlib function.
+Image structures created or returned by Xlib do not need to be
+initialized in this fashion.
+</para>
+<para>
+<!-- .LP -->
+This function returns a nonzero status if initialization of the
+structure is successful. It returns zero if it detected some error
+or inconsistency in the structure, in which case the image is not changed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To combine an image with a rectangle of a drawable on the display,
+use
+<function>XPutImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XPutImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xputimage'>
+<funcprototype>
+ <funcdef><function>XPutImage</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>XImage<parameter> *image</parameter></paramdef>
+ <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef>
+ <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>image</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image you want combined with the rectangle.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the offset in X from the left edge of the image defined
+by the
+<structname>XImage</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the offset in Y from the top edge of the image defined
+by the
+<structname>XImage</structname>
+structure.
+<!-- .ds Dx , which are relative to the origin of the drawable \ -->
+and are the coordinates of the subimage
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Dx.
+<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPutImage</function>
+function
+combines an image with a rectangle of the specified drawable.
+The section of the image defined by the src_x, src_y, width, and height
+arguments is drawn on the specified part of the drawable.
+If
+<symbol>XYBitmap</symbol>
+format is used, the depth of the image must be one,
+or a
+<errorname>BadMatch</errorname>
+error results.
+The foreground pixel in the GC defines the source for the one bits in the image,
+and the background pixel defines the source for the zero bits.
+For
+<symbol>XYPixmap</symbol>
+and
+<symbol>ZPixmap</symbol>,
+the depth of the image must match the depth of the drawable,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If the characteristics of the image (for example, byte_order and bitmap_unit)
+differ from what the server requires,
+<function>XPutImage</function>
+automatically makes the appropriate
+conversions.
+</para>
+<para>
+<!-- .LP -->
+This function uses these GC components:
+function, plane-mask, subwindow-mode, clip-x-origin, clip-y-origin,
+and clip-mask.
+It also uses these GC mode-dependent components:
+foreground and background.
+</para>
+<para>
+<!-- .LP -->
+<function>XPutImage</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return the contents of a rectangle in a given drawable on the display,
+use
+<function>XGetImage</function>.
+This function specifically supports rudimentary screen dumps.
+</para>
+<indexterm significance="preferred"><primary>XGetImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetimage'>
+<funcprototype>
+ <funcdef>XImage *<function>XGetImage</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef>
+ <paramdef>int<parameter> format</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+<!-- .ds Xy , which are relative to the origin of the drawable \ -->
+and define the upper-left corner of the rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the plane mask.
+<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the format for the image.
+You can pass
+<symbol>XYPixmap</symbol>
+or
+<symbol>ZPixmap</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetImage</function>
+function returns a pointer to an
+<structname>XImage</structname>
+structure.
+This structure provides you with the contents of the specified rectangle of
+the drawable in the format you specify.
+If the format argument is
+<symbol>XYPixmap</symbol>,
+the image contains only the bit planes you passed to the plane_mask argument.
+If the plane_mask argument only requests a subset of the planes of the
+display, the depth of the returned image will be the number of planes
+requested.
+If the format argument is
+<symbol>ZPixmap</symbol>,
+<function>XGetImage</function>
+returns as zero the bits in all planes not
+specified in the plane_mask argument.
+The function performs no range checking on the values in plane_mask and ignores
+extraneous bits.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetImage</function>
+returns the depth of the image to the depth member of the
+<structname>XImage</structname>
+structure.
+The depth of the image is as specified when the drawable was created,
+except when getting a subset of the planes in
+<symbol>XYPixmap</symbol>
+format, when the depth is given by the number of bits set to 1 in plane_mask.
+</para>
+<para>
+<!-- .LP -->
+If the drawable is a pixmap,
+the given rectangle must be wholly contained within the pixmap,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If the drawable is a window,
+the window must be viewable,
+and it must be the case that if there were no inferiors or overlapping windows,
+the specified rectangle of the window would be fully visible on the screen
+and wholly contained within the outside edges of the window,
+or a
+<errorname>BadMatch</errorname>
+error results.
+Note that the borders of the window can be included and read with
+this request.
+If the window has backing-store, the backing-store contents are
+returned for regions of the window that are obscured by noninferior
+windows.
+If the window does not have backing-store,
+the returned contents of such obscured regions are undefined.
+The returned contents of visible regions of inferiors
+of a different depth than the specified window's depth are also undefined.
+The pointer cursor image is not included in the returned contents.
+If a problem occurs,
+<function>XGetImage</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetImage</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To copy the contents of a rectangle on the display
+to a location within a preexisting image structure, use
+<function>XGetSubImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetSubImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetsubimage'>
+<funcprototype>
+ <funcdef>XImage *<function>XGetSubImage</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> plane_mask</parameter></paramdef>
+ <paramdef>int<parameter> format</parameter></paramdef>
+ <paramdef>XImage<parameter> *dest_image</parameter></paramdef>
+ <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+<!-- .ds Xy , which are relative to the origin of the drawable \ -->
+and define the upper-left corner of the rectangle
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh \ of the subimage, which define the dimensions of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>plane_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the plane mask.
+<!-- .\" *** JIM: NEED MORE INFO FOR THIS. *** -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the format for the image.
+You can pass
+<symbol>XYPixmap</symbol>
+or
+<symbol>ZPixmap</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_image</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the destination image.
+<!-- .ds Dx , which are relative to the origin of the destination rectangle, \ -->
+specify its upper-left corner, and determine where the subimage \
+is placed in the destination image
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Dx.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetSubImage</function>
+function updates dest_image with the specified subimage in the same manner as
+<function>XGetImage</function>.
+If the format argument is
+<symbol>XYPixmap</symbol>,
+the image contains only the bit planes you passed to the plane_mask argument.
+If the format argument is
+<symbol>ZPixmap</symbol>,
+<function>XGetSubImage</function>
+returns as zero the bits in all planes not
+specified in the plane_mask argument.
+The function performs no range checking on the values in plane_mask and ignores
+extraneous bits.
+As a convenience,
+<function>XGetSubImage</function>
+returns a pointer to the same
+<structname>XImage</structname>
+structure specified by dest_image.
+</para>
+<para>
+<!-- .LP -->
+The depth of the destination
+<structname>XImage</structname>
+structure must be the same as that of the drawable.
+If the specified subimage does not fit at the specified location
+on the destination image, the right and bottom edges are clipped.
+If the drawable is a pixmap,
+the given rectangle must be wholly contained within the pixmap,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If the drawable is a window,
+the window must be viewable,
+and it must be the case that if there were no inferiors or overlapping windows,
+the specified rectangle of the window would be fully visible on the screen
+and wholly contained within the outside edges of the window,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If the window has backing-store,
+then the backing-store contents are returned for regions of the window
+that are obscured by noninferior windows.
+If the window does not have backing-store,
+the returned contents of such obscured regions are undefined.
+The returned contents of visible regions of inferiors
+of a different depth than the specified window's depth are also undefined.
+If a problem occurs,
+<function>XGetSubImage</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetSubImage</function>
+can generate
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadMatch</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+<!-- .bp -->
+
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH09.xml b/libX11/specs/libX11/CH09.xml index d37e0863a..50e29e070 100644 --- a/libX11/specs/libX11/CH09.xml +++ b/libX11/specs/libX11/CH09.xml @@ -1,2016 +1,2016 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="window_and_session_manager_functions"> -<title>Window and Session Manager Functions</title> - -<para> -Although it is difficult to categorize functions as exclusively for an application, -a window manager, or a session manager, the functions in this chapter are most -often used by window managers and session managers. It is not expected that -these functions will be used by most application programs. Xlib provides -management functions to: -</para> - -<itemizedlist> - <listitem><para>Change the parent of a window</para></listitem> - <listitem><para>Control the lifetime of a window</para></listitem> - <listitem><para>Manage installed colormaps</para></listitem> - <listitem><para>Set and retrieve the font search path</para></listitem> - <listitem><para>Grab the server</para></listitem> - <listitem><para>Kill a client</para></listitem> - <listitem><para>Control the screen saver</para></listitem> - <listitem><para>Control host access</para></listitem> -</itemizedlist> - -<sect1 id="Changing_the_Parent_of_a_Window"> -<title>Changing the Parent of a Window</title> -<!-- .XS --> -<!-- (SN Changing the Parent of a Window --> -<!-- .XE --> -<para> -<!-- .LP --> -To change a window's parent to another window on the same screen, use -<function>XReparentWindow</function>. -There is no way to move a window between screens. -</para> -<indexterm significance="preferred"><primary>XReparentWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xreparentwindow'> -<funcprototype> - <funcdef><function>XReparentWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> parent</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>parent</emphasis> - </term> - <listitem> - <para> -Specifies the parent window. -<!-- .ds Xy \ of the position in the new parent window --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the specified window is mapped, -<function>XReparentWindow</function> -automatically performs an -<systemitem>UnmapWindow</systemitem> -request on it, removes it from its current position in the hierarchy, -and inserts it as the child of the specified parent. -The window is placed in the stacking order on top with respect to -sibling windows. -</para> -<para> -<!-- .LP --> -After reparenting the specified window, -<function>XReparentWindow</function> -causes the X server to generate a -<symbol>ReparentNotify</symbol> -event. -The override_redirect member returned in this event is -set to the window's corresponding attribute. -Window manager clients usually should ignore this window if this member -is set to -<symbol>True</symbol>. -Finally, if the specified window was originally mapped, -the X server automatically performs a -<systemitem>MapWindow</systemitem> -request on it. -</para> -<para> -<!-- .LP --> -The X server performs normal exposure processing on formerly obscured -windows. -The X server might not generate -<symbol>Expose</symbol> -events for regions from the initial -<systemitem>UnmapWindow</systemitem> -request that are immediately obscured by the final -<systemitem>MapWindow</systemitem> -request. -A -<errorname>BadMatch</errorname> -error results if: -</para> -<itemizedlist> - <listitem> - <para> -The new parent window is not on the same screen as -the old parent window. - </para> - </listitem> - <listitem> - <para> -The new parent window is the specified window or an inferior of the -specified window. - </para> - </listitem> - <listitem> - <para> -The new parent is -<symbol>InputOnly</symbol>, -and the window is not. - </para> - </listitem> - <listitem> - <para> -The specified window has a -<symbol>ParentRelative</symbol> -background, and the new parent window is not the same depth as the -specified window. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<function>XReparentWindow</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Controlling_the_Lifetime_of_a_Window"> -<title>Controlling the Lifetime of a Window</title> -<!-- .XS --> -<!-- (SN Controlling the Lifetime of a Window --> -<!-- .XE --> -<para> -<!-- .LP --> -The save-set of a client is a list of other clients' windows that, -if they are inferiors of one of the client's windows at connection close, -should not be destroyed and should be remapped if they are unmapped. -For further information about close-connection processing, -see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>. -To allow an application's window to survive when a window manager that -has reparented a window fails, -Xlib provides the save-set functions that you can -use to control the longevity of subwindows -that are normally destroyed when the parent is destroyed. -For example, a window manager that wants to add decoration -to a window by adding a frame might reparent an application's -window. -When the frame is destroyed, -the application's window should not be destroyed -but be returned to its previous place in the window hierarchy. -</para> -<para> -<!-- .LP --> -The X server automatically removes windows from the save-set -when they are destroyed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add or remove a window from the client's save-set, use -<function>XChangeSaveSet</function>. -</para> -<indexterm significance="preferred"><primary>XChangeSaveSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangesaveset'> -<funcprototype> - <funcdef><function>XChangeSaveSet</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> change_mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi that you want to add to or delete from the client's save-set --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>change_mode</emphasis> - </term> - <listitem> - <para> -Specifies the mode. -You can pass -<symbol>SetModeInsert</symbol> -or -<symbol>SetModeDelete</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Depending on the specified mode, -<function>XChangeSaveSet</function> -either inserts or deletes the specified window from the client's save-set. -The specified window must have been created by some other client, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XChangeSaveSet</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a window to the client's save-set, use -<function>XAddToSaveSet</function>. -</para> -<indexterm significance="preferred"><primary>XAddToSaveSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddtosaveset'> -<funcprototype> - <funcdef><function>XAddToSaveSet</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi that you want to add to the client's save-set --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAddToSaveSet</function> -function adds the specified window to the client's save-set. -The specified window must have been created by some other client, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XAddToSaveSet</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove a window from the client's save-set, use -<function>XRemoveFromSaveSet</function>. -</para> -<indexterm significance="preferred"><primary>XRemoveFromSaveSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xremovefromsaveset'> -<funcprototype> - <funcdef><function>XRemoveFromSaveSet</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi that you want to delete from the client's save-set --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRemoveFromSaveSet</function> -function removes the specified window from the client's save-set. -The specified window must have been created by some other client, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XRemoveFromSaveSet</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Managing_Installed_Colormaps"> -<title>Managing Installed Colormaps</title> -<!-- .XS --> -<!-- (SN Managing Installed Colormaps --> -<!-- .XE --> -<para> -<!-- .LP --> -The X server maintains a list of installed colormaps. -Windows using these colormaps are guaranteed to display with -correct colors; windows using other colormaps may or may not display -with correct colors. -Xlib provides functions that you can use to install a colormap, -uninstall a colormap, and obtain a list of installed colormaps. -</para> -<para> -<!-- .LP --> -At any time, -there is a subset of the installed maps that is viewed as an ordered list -and is called the required list. -The length of the required list is at most M, -where M is the minimum number of installed colormaps specified for the screen -in the connection setup. -The required list is maintained as follows. -When a colormap is specified to -<function>XInstallColormap</function>, -it is added to the head of the list; -the list is truncated at the tail, if necessary, to keep its length to -at most M. -When a colormap is specified to -<function>XUninstallColormap</function> -and it is in the required list, -it is removed from the list. -A colormap is not added to the required list when it is implicitly installed -by the X server, -and the X server cannot implicitly uninstall a colormap that is in the -required list. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To install a colormap, use -<function>XInstallColormap</function>. -</para> -<indexterm significance="preferred"><primary>XInstallColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinstallcolormap'> -<funcprototype> - <funcdef><function>XInstallColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInstallColormap</function> -function installs the specified colormap for its associated screen. -All windows associated with this colormap immediately display with -true colors. -You associated the windows with this colormap when you created them by calling -<function>XCreateWindow</function>, -<function>XCreateSimpleWindow</function>, -<function>XChangeWindowAttributes</function>, -or -<function>XSetWindowColormap</function>. -</para> -<para> -<!-- .LP --> -If the specified colormap is not already an installed colormap, -the X server generates a -<symbol>ColormapNotify</symbol> -event on each window that has that colormap. -In addition, for every other colormap that is installed as -a result of a call to -<function>XInstallColormap</function>, -the X server generates a -<symbol>ColormapNotify</symbol> -event on each window that has that colormap. -</para> -<para> -<!-- .LP --> -<function>XInstallColormap</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To uninstall a colormap, use -<function>XUninstallColormap</function>. -</para> -<indexterm significance="preferred"><primary>XUninstallColormap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xuninstallcolormap'> -<funcprototype> - <funcdef><function>XUninstallColormap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Colormap<parameter> colormap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap</emphasis> - </term> - <listitem> - <para> -Specifies the colormap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUninstallColormap</function> -function removes the specified colormap from the required -list for its screen. -As a result, -the specified colormap might be uninstalled, -and the X server might implicitly install or uninstall additional colormaps. -Which colormaps get installed or uninstalled is server dependent -except that the required list must remain installed. -</para> -<para> -<!-- .LP --> -If the specified colormap becomes uninstalled, -the X server generates a -<symbol>ColormapNotify</symbol> -event on each window that has that colormap. -In addition, for every other colormap that is installed or uninstalled as a -result of a call to -<function>XUninstallColormap</function>, -the X server generates a -<symbol>ColormapNotify</symbol> -event on each window that has that colormap. -</para> -<para> -<!-- .LP --> -<function>XUninstallColormap</function> -can generate a -<errorname>BadColor</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a list of the currently installed colormaps for a given screen, use -<function>XListInstalledColormaps</function>. -</para> -<indexterm significance="preferred"><primary>XListInstalledColormaps</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlistinstalledcolormaps'> -<funcprototype> - <funcdef>Colormap *<function>XListInstalledColormaps</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> *num_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi that determines the screen --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_return</emphasis> - </term> - <listitem> - <para> -Returns the number of currently installed colormaps. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListInstalledColormaps</function> -function returns a list of the currently installed colormaps for the screen -of the specified window. -The order of the colormaps in the list is not significant -and is no explicit indication of the required list. -When the allocated list is no longer needed, -free it by using -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XListInstalledColormaps</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Setting_and_Retrieving_the_Font_Search_Path"> -<title>Setting and Retrieving the Font Search Path</title> -<!-- .XS --> -<!-- (SN Setting and Retrieving the Font Search Path --> -<!-- .XE --> -<para> -<!-- .LP --> -The set of fonts available from a server depends on a font -search path. Xlib provides functions to set and retrieve the -search path for a server. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the font search path, use -<function>XSetFontPath</function>. -</para> -<indexterm significance="preferred"><primary>XSetFontPath</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetfontpath'> -<funcprototype> - <funcdef><function>XSetFontPath</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> **directories</parameter></paramdef> - <paramdef>int<parameter> ndirs</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>directories</emphasis> - </term> - <listitem> - <para> -Specifies the directory path used to look for a font. -Setting the path to the empty list restores the default path defined -for the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ndirs</emphasis> - </term> - <listitem> - <para> -Specifies the number of directories in the path. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetFontPath</function> -function defines the directory search path for font lookup. -There is only one search path per X server, not one per client. -The encoding and interpretation of the strings are implementation-dependent, -but typically they specify directories or font servers to be searched -in the order listed. -An X server is permitted to cache font information internally; -for example, it might cache an entire font from a file and not -check on subsequent opens of that font to see if the underlying -font file has changed. -However, -when the font path is changed, -the X server is guaranteed to flush all cached information about fonts -for which there currently are no explicit resource IDs allocated. -The meaning of an error from this request is implementation-dependent. -</para> -<para> -<!-- .LP --> -<function>XSetFontPath</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the current font search path, use -<function>XGetFontPath</function>. -</para> -<indexterm significance="preferred"><primary>XGetFontPath</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetfontpath'> -<funcprototype> - <funcdef>char **<function>XGetFontPath</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *npaths_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>npaths_return</emphasis> - </term> - <listitem> - <para> -Returns the number of strings in the font path array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetFontPath</function> -function allocates and returns an array of strings containing the search path. -The contents of these strings are implementation-dependent -and are not intended to be interpreted by client applications. -When it is no longer needed, -the data in the font path should be freed by using -<function>XFreeFontPath</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To free data returned by -<function>XGetFontPath</function>, -use -<function>XFreeFontPath</function>. -</para> -<indexterm significance="preferred"><primary>XFreeFontPath</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreefontpath'> -<funcprototype> - <funcdef><function>XFreeFontPath</function></funcdef> - <paramdef>char<parameter> **list</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the array of strings you want to free. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeFontPath</function> -function -frees the data allocated by -<function>XGetFontPath</function>. -</para> -</sect1> -<sect1 id="Grabbing_the_Server_"> -<title>Grabbing the Server </title> -<!-- .XS --> -<!-- (SN Grabbing the Server --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to grab and ungrab the server. -These functions can be used to control processing of output on other -connections by the window system server. -While the server is grabbed, -no processing of requests or close downs on any other connection will occur. -A client closing its connection automatically ungrabs the server. -<indexterm><primary>Menus</primary></indexterm> -<indexterm><primary>Window</primary><secondary>managers</secondary></indexterm> -Although grabbing the server is highly discouraged, it is sometimes necessary. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To grab the server, use -<function>XGrabServer</function>. -</para> -<indexterm><primary>Server</primary><secondary>grabbing</secondary></indexterm> -<indexterm><primary>Grabbing</primary><secondary>server</secondary></indexterm> -<indexterm significance="preferred"><primary>XGrabServer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgrabserver'> -<funcprototype> - <funcdef><function>XGrabServer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGrabServer</function> -function disables processing of requests and close downs on all other -connections than the one this request arrived on. -You should not grab the X server any more than is absolutely necessary. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ungrab the server, use -<function>XUngrabServer</function>. -</para> -<indexterm significance="preferred"><primary>XUngrabServer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xungrabserver'> -<funcprototype> - <funcdef><function>XUngrabServer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUngrabServer</function> -function restarts processing of requests and close downs on other connections. -You should avoid grabbing the X server as much as possible. -</para> -</sect1> -<sect1 id="Killing_Clients"> -<title>Killing Clients</title> -<!-- .XS --> -<!-- (SN Killing Clients --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides a function to cause the connection to -a client to be closed and its resources to be destroyed. -To destroy a client, use -<function>XKillClient</function>. -</para> -<indexterm significance="preferred"><primary>XKillClient</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xkillclient'> -<funcprototype> - <funcdef><function>XKillClient</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> resource</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>resource</emphasis> - </term> - <listitem> - <para> -Specifies any resource associated with the client that you want to destroy or -<symbol>AllTemporary</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XKillClient</function> -function -forces a close down of the client -that created the resource -if a valid resource is specified. -If the client has already terminated in -either -<symbol>RetainPermanent</symbol> -or -<symbol>RetainTemporary</symbol> -mode, all of the client's -resources are destroyed. -If -<symbol>AllTemporary</symbol> -is specified, the resources of all clients that have terminated in -<symbol>RetainTemporary</symbol> -are destroyed (see <link linkend="Closing_the_Display">section 2.5</link>). -This permits implementation of window manager facilities that aid debugging. -A client can set its close-down mode to -<symbol>RetainTemporary</symbol>. -If the client then crashes, -its windows would not be destroyed. -The programmer can then inspect the application's window tree -and use the window manager to destroy the zombie windows. -</para> -<para> -<!-- .LP --> -<function>XKillClient</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -</sect1> -<sect1 id="Controlling_the_Screen_Saver_"> -<title>Controlling the Screen Saver </title> -<!-- .XS --> -<!-- (SN Controlling the Screen Saver --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set or reset the mode -of the screen saver, to force or activate the screen saver, -or to obtain the current screen saver values. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the screen saver mode, use -<function>XSetScreenSaver</function>. -</para> -<indexterm significance="preferred"><primary>XSetScreenSaver</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetscreensaver'> -<funcprototype> - <funcdef><function>XSetScreenSaver</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>inttimeout,<parameter> interval</parameter></paramdef> - <paramdef>int<parameter> prefer_blanking</parameter></paramdef> - <paramdef>int<parameter> allow_exposures</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>timeout</emphasis> - </term> - <listitem> - <para> -Specifies the timeout, in seconds, until the screen saver turns on. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>interval</emphasis> - </term> - <listitem> - <para> -Specifies the interval, in seconds, between screen saver alterations. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>prefer_blanking</emphasis> - </term> - <listitem> - <para> -Specifies how to enable screen blanking. -You can pass -<symbol>DontPreferBlanking</symbol>, -<symbol>PreferBlanking</symbol>, -or -<symbol>DefaultBlanking</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>allow_exposures</emphasis> - </term> - <listitem> - <para> -Specifies the screen save control values. -You can pass -<symbol>DontAllowExposures</symbol>, -<symbol>AllowExposures</symbol>, -or -<symbol>DefaultExposures</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Timeout and interval are specified in seconds. -A timeout of 0 disables the screen saver -(but an activated screen saver is not deactivated), -and a timeout of −1 restores the default. -Other negative values generate a -<errorname>BadValue</errorname> -error. -If the timeout value is nonzero, -<function>XSetScreenSaver</function> -enables the screen saver. -An interval of 0 disables the random-pattern motion. -If no input from devices (keyboard, mouse, and so on) is generated -for the specified number of timeout seconds once the screen saver is enabled, -the screen saver is activated. -</para> -<para> -<!-- .LP --> -For each screen, -if blanking is preferred and the hardware supports video blanking, -the screen simply goes blank. -Otherwise, if either exposures are allowed or the screen can be regenerated -without sending -<symbol>Expose</symbol> -events to clients, -the screen is tiled with the root window background tile randomly -re-origined each interval seconds. -Otherwise, the screens' state do not change, -and the screen saver is not activated. -The screen saver is deactivated, -and all screen states are restored at the next -keyboard or pointer input or at the next call to -<function>XForceScreenSaver</function> -with mode -<symbol>ScreenSaverReset</symbol>. -</para> -<para> -<!-- .LP --> -If the server-dependent screen saver method supports periodic change, -the interval argument serves as a hint about how long the change period -should be, and zero hints that no periodic change should be made. -Examples of ways to change the screen include scrambling the colormap -periodically, moving an icon image around the screen periodically, or tiling -the screen with the root window background tile, randomly re-origined -periodically. -</para> -<para> -<!-- .LP --> -<function>XSetScreenSaver</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To force the screen saver on or off, use -<function>XForceScreenSaver</function>. -</para> -<indexterm significance="preferred"><primary>XForceScreenSaver</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xforcescreensaver'> -<funcprototype> - <funcdef><function>XForceScreenSaver</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the mode that is to be applied. -You can pass -<symbol>ScreenSaverActive</symbol> -or -<symbol>ScreenSaverReset</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the specified mode is -<symbol>ScreenSaverActive</symbol> -and the screen saver currently is deactivated, -<function>XForceScreenSaver</function> -activates the screen saver even if the screen saver had been disabled -with a timeout of zero. -If the specified mode is -<symbol>ScreenSaverReset</symbol> -and the screen saver currently is enabled, -<function>XForceScreenSaver</function> -deactivates the screen saver if it was activated, -and the activation timer is reset to its initial state -(as if device input had been received). -</para> -<para> -<!-- .LP --> -<function>XForceScreenSaver</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To activate the screen saver, use -<function>XActivateScreenSaver</function>. -</para> -<indexterm significance="preferred"><primary>XActivateScreenSaver</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xactivatescreensaver'> -<funcprototype> - <funcdef><function>XActivateScreenSaver</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To reset the screen saver, use -<function>XResetScreenSaver</function>. -</para> -<indexterm significance="preferred"><primary>XResetScreenSaver</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xresetscreensaver'> -<funcprototype> - <funcdef><function>XResetScreenSaver</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To get the current screen saver values, use -<function>XGetScreenSaver</function>. -</para> -<indexterm significance="preferred"><primary>XGetScreenSaver</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetscreensaver'> -<funcprototype> - <funcdef><function>XGetScreenSaver</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int*timeout_return,<parameter> *interval_return</parameter></paramdef> - <paramdef>int<parameter> *prefer_blanking_return</parameter></paramdef> - <paramdef>int<parameter> *allow_exposures_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>timeout_return</emphasis> - </term> - <listitem> - <para> -Returns the timeout, in seconds, until the screen saver turns on. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>interval_return</emphasis> - </term> - <listitem> - <para> -Returns the interval between screen saver invocations. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>prefer_blanking_return</emphasis> - </term> - <listitem> - <para> -Returns the current screen blanking preference -(<symbol>DontPreferBlanking</symbol>, -<symbol>PreferBlanking</symbol>, -or -<symbol>DefaultBlanking</symbol>). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>allow_exposures_return</emphasis> - </term> - <listitem> - <para> -Returns the current screen save control value -(<symbol>DontAllowExposures</symbol>, -<symbol>AllowExposures</symbol>, -or -<symbol>DefaultExposures</symbol>). - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect1> -<sect1 id="Controlling_Host_Access"> -<title>Controlling Host Access</title> -<!-- .XS --> -<!-- (SN Controlling Host Access --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Add, get, or remove hosts from the access control list - </para> - </listitem> - <listitem> - <para> -Change, enable, or disable access - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<indexterm><primary>Access control list</primary></indexterm> -<indexterm><primary>Authentication</primary></indexterm> -X does not provide any protection on a per-window basis. -If you find out the resource ID of a resource, you can manipulate it. -To provide some minimal level of protection, however, -connections are permitted only from machines you trust. -This is adequate on single-user workstations but obviously -breaks down on timesharing machines. -Although provisions exist in the X protocol for proper connection -authentication, the lack of a standard authentication server -leaves host-level access control as the only common mechanism. -</para> -<para> -<!-- .LP --> -<indexterm><primary>Default Protection</primary></indexterm> -The initial set of hosts allowed to open connections typically consists of: -</para> -<itemizedlist> - <listitem> - <para> -The host the window system is running on. - </para> - </listitem> - <listitem> - <para> -On <acronym>POSIX</acronym>-conformant systems, each host listed in the -<filename>/etc/X<replaceable>?</replaceable>.hosts</filename> -file. -The ? indicates the number of the -display. -<indexterm><primary>Files</primary><secondary><filename>/etc/X<replaceable>?</replaceable>.hosts</filename></secondary></indexterm> -This file should consist of host names separated by newlines. -DECnet nodes must terminate in :: to distinguish them from Internet hosts. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -If a host is not in the access control list when the access control -mechanism is enabled and if the host attempts to establish a connection, -the server refuses the connection. -To change the access list, -the client must reside on the same host as the server and/or must -have been granted permission in the initial authorization at connection -setup. -</para> -<para> -<!-- .LP --> -Servers also can implement other access control policies in addition to -or in place of this host access facility. -For further information about other access control implementations, -see ``X Window System Protocol.'' -</para> -<sect2 id="Adding_Getting_or_Removing_Hosts"> -<title>Adding, Getting, or Removing Hosts</title> -<!-- .XS --> -<!-- (SN Adding, Getting, or Removing Hosts --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to add, get, or remove hosts -from the access control list. -All the host access control functions use the -<structname>XHostAddress</structname> -structure, which contains: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XHostAddress</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - int family; /* for example FamilyInternet */ - int length; /* length of address, in bytes */ - char *address; /* pointer to where to find the address */ -} XHostAddress; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The family member specifies which protocol address family to use -(for example, <acronym>TCP</acronym>/<acronym>IP</acronym> or DECnet) and can be -<symbol>FamilyInternet</symbol>, -<symbol>FamilyInternet6</symbol>, -<symbol>FamilyServerInterpreted</symbol>, -<symbol>FamilyDECnet</symbol>, -or -<symbol>FamilyChaos</symbol>. -The length member specifies the length of the address in bytes. -The address member specifies a pointer to the address. -</para> -<para> -<!-- .LP --> -For <acronym>TCP</acronym>/<acronym>IP</acronym>, the address should be in network byte order. -For <acronym>IP</acronym> version 4 addresses, the family should be FamilyInternet -and the length should be 4 bytes. For <acronym>IP</acronym> version 6 addresses, the -family should be FamilyInternet6 and the length should be 16 bytes. -</para> -<para> -<!-- .LP --> -For the DECnet family, -the server performs no automatic swapping on the address bytes. -A Phase IV address is 2 bytes long. -The first byte contains the least significant 8 bits of the node number. -The second byte contains the most significant 2 bits of the -node number in the least significant 2 bits of the byte -and the area in the most significant 6 bits of the byte. -</para> -<para> -<!-- .LP --> -For the ServerInterpreted family, the length is ignored and the address -member is a pointer to a -<structname>XServerInterpretedAddress</structname> -structure, which contains: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XServerInterpretedAddress</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - int typelength; /* length of type string, in bytes */ - int valuelength; /* length of value string, in bytes */ - char *type; /* pointer to where to find the type string */ - char *value; /* pointer to where to find the address */ -} XServerInterpretedAddress; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The type and value members point to strings representing the type and value of -the server interpreted entry. These strings may not be NULL-terminated so care -should be used when accessing them. The typelength and valuelength members -specify the length in byte of the type and value strings. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a single host, use -<function>XAddHost</function>. -</para> -<indexterm significance="preferred"><primary>XAddHost</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddhost'> -<funcprototype> - <funcdef><function>XAddHost</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XHostAddress<parameter> *host</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Ho added --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>host</emphasis> - </term> - <listitem> - <para> -Specifies the host that is to be (Ho. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAddHost</function> -function adds the specified host to the access control list for that display. -The server must be on the same host as the client issuing the command, or a -<errorname>BadAccess</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XAddHost</function> -can generate -<errorname>BadAccess</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add multiple hosts at one time, use -<function>XAddHosts</function>. -</para> -<indexterm significance="preferred"><primary>XAddHosts</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddhosts'> -<funcprototype> - <funcdef><function>XAddHosts</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XHostAddress<parameter> *hosts</parameter></paramdef> - <paramdef>int<parameter> num_hosts</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Ho added --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hosts</emphasis> - </term> - <listitem> - <para> -Specifies each host that is to be (Ho. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_hosts</emphasis> - </term> - <listitem> - <para> -Specifies the number of hosts. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAddHosts</function> -function adds each specified host to the access control list for that display. -The server must be on the same host as the client issuing the command, or a -<errorname>BadAccess</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XAddHosts</function> -can generate -<errorname>BadAccess</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a host list, use -<function>XListHosts</function>. -</para> -<indexterm significance="preferred"><primary>XListHosts</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlisthosts'> -<funcprototype> - <funcdef>XHostAddress *<function>XListHosts</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *nhosts_return</parameter></paramdef> - <paramdef>Bool<parameter> *state_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nhosts_return</emphasis> - </term> - <listitem> - <para> -Returns the number of hosts currently in the access control list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>state_return</emphasis> - </term> - <listitem> - <para> -Returns the state of the access control. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XListHosts</function> -function returns the current access control list as well as whether the use -of the list at connection setup was enabled or disabled. -<function>XListHosts</function> -allows a program to find out what machines can make connections. -It also returns a pointer to a list of host structures that -were allocated by the function. -When no longer needed, -this memory should be freed by calling -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove a single host, use -<function>XRemoveHost</function>. -</para> -<indexterm significance="preferred"><primary>XRemoveHost</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xremovehost'> -<funcprototype> - <funcdef><function>XRemoveHost</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XHostAddress<parameter> *host</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Ho removed --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>host</emphasis> - </term> - <listitem> - <para> -Specifies the host that is to be (Ho. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRemoveHost</function> -function removes the specified host from the access control list -for that display. -The server must be on the same host as the client process, or a -<errorname>BadAccess</errorname> -error results. -If you remove your machine from the access list, -you can no longer connect to that server, -and this operation cannot be reversed unless you reset the server. -</para> -<para> -<!-- .LP --> -<function>XRemoveHost</function> -can generate -<errorname>BadAccess</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove multiple hosts at one time, use -<function>XRemoveHosts</function>. -</para> -<indexterm significance="preferred"><primary>XRemoveHosts</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xremovehosts'> -<funcprototype> - <funcdef><function>XRemoveHosts</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XHostAddress<parameter> *hosts</parameter></paramdef> - <paramdef>int<parameter> num_hosts</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Ho removed --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hosts</emphasis> - </term> - <listitem> - <para> -Specifies each host that is to be (Ho. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_hosts</emphasis> - </term> - <listitem> - <para> -Specifies the number of hosts. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRemoveHosts</function> -function removes each specified host from the access control list for that -display. -The X server must be on the same host as the client process, or a -<errorname>BadAccess</errorname> -error results. -If you remove your machine from the access list, -you can no longer connect to that server, -and this operation cannot be reversed unless you reset the server. -</para> -<para> -<!-- .LP --> -<function>XRemoveHosts</function> -can generate -<errorname>BadAccess</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -</sect2> -<sect2 id="Changing_Enabling_or_Disabling_Access_Control"> -<title>Changing, Enabling, or Disabling Access Control</title> -<!-- .XS --> -<!-- (SN Changing, Enabling, or Disabling Access Control --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to enable, disable, -or change access control. -</para> -<para> -<!-- .LP --> -For these functions to execute successfully, -the client application must reside on the same host as the X server -and/or have been given permission in the initial authorization -at connection setup. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change access control, use -<function>XSetAccessControl</function>. -</para> -<indexterm significance="preferred"><primary>XSetAccessControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetaccesscontrol'> -<funcprototype> - <funcdef><function>XSetAccessControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the mode. -You can pass -<symbol>EnableAccess</symbol> -or -<symbol>DisableAccess</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetAccessControl</function> -function either enables or disables the use of the access control list -at each connection setup. -</para> -<para> -<!-- .LP --> -<function>XSetAccessControl</function> -can generate -<errorname>BadAccess</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To enable access control, use -<function>XEnableAccessControl</function>. -</para> -<indexterm significance="preferred"><primary>XEnableAccessControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xenableaccesscontrol'> -<funcprototype> - <funcdef><function>XEnableAccessControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XEnableAccessControl</function> -function enables the use of the access control list at each connection setup. -</para> -<para> -<!-- .LP --> -<function>XEnableAccessControl</function> -can generate a -<errorname>BadAccess</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To disable access control, use -<function>XDisableAccessControl</function>. -</para> -<indexterm significance="preferred"><primary>XDisableAccessControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisableaccesscontrol'> -<funcprototype> - <funcdef><function>XDisableAccessControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDisableAccessControl</function> -function disables the use of the access control list at each connection setup. -</para> -<para> -<!-- .LP --> -<function>XDisableAccessControl</function> -can generate a -<errorname>BadAccess</errorname> -error. -<!-- .bp --> - -</para> -</sect2> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="window_and_session_manager_functions">
+<title>Window and Session Manager Functions</title>
+
+<para>
+Although it is difficult to categorize functions as exclusively for an application,
+a window manager, or a session manager, the functions in this chapter are most
+often used by window managers and session managers. It is not expected that
+these functions will be used by most application programs. Xlib provides
+management functions to:
+</para>
+
+<itemizedlist>
+ <listitem><para>Change the parent of a window</para></listitem>
+ <listitem><para>Control the lifetime of a window</para></listitem>
+ <listitem><para>Manage installed colormaps</para></listitem>
+ <listitem><para>Set and retrieve the font search path</para></listitem>
+ <listitem><para>Grab the server</para></listitem>
+ <listitem><para>Kill a client</para></listitem>
+ <listitem><para>Control the screen saver</para></listitem>
+ <listitem><para>Control host access</para></listitem>
+</itemizedlist>
+
+<sect1 id="Changing_the_Parent_of_a_Window">
+<title>Changing the Parent of a Window</title>
+<!-- .XS -->
+<!-- (SN Changing the Parent of a Window -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To change a window's parent to another window on the same screen, use
+<function>XReparentWindow</function>.
+There is no way to move a window between screens.
+</para>
+<indexterm significance="preferred"><primary>XReparentWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xreparentwindow'>
+<funcprototype>
+ <funcdef><function>XReparentWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> parent</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>parent</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the parent window.
+<!-- .ds Xy \ of the position in the new parent window -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the specified window is mapped,
+<function>XReparentWindow</function>
+automatically performs an
+<systemitem>UnmapWindow</systemitem>
+request on it, removes it from its current position in the hierarchy,
+and inserts it as the child of the specified parent.
+The window is placed in the stacking order on top with respect to
+sibling windows.
+</para>
+<para>
+<!-- .LP -->
+After reparenting the specified window,
+<function>XReparentWindow</function>
+causes the X server to generate a
+<symbol>ReparentNotify</symbol>
+event.
+The override_redirect member returned in this event is
+set to the window's corresponding attribute.
+Window manager clients usually should ignore this window if this member
+is set to
+<symbol>True</symbol>.
+Finally, if the specified window was originally mapped,
+the X server automatically performs a
+<systemitem>MapWindow</systemitem>
+request on it.
+</para>
+<para>
+<!-- .LP -->
+The X server performs normal exposure processing on formerly obscured
+windows.
+The X server might not generate
+<symbol>Expose</symbol>
+events for regions from the initial
+<systemitem>UnmapWindow</systemitem>
+request that are immediately obscured by the final
+<systemitem>MapWindow</systemitem>
+request.
+A
+<errorname>BadMatch</errorname>
+error results if:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The new parent window is not on the same screen as
+the old parent window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The new parent window is the specified window or an inferior of the
+specified window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The new parent is
+<symbol>InputOnly</symbol>,
+and the window is not.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The specified window has a
+<symbol>ParentRelative</symbol>
+background, and the new parent window is not the same depth as the
+specified window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XReparentWindow</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Controlling_the_Lifetime_of_a_Window">
+<title>Controlling the Lifetime of a Window</title>
+<!-- .XS -->
+<!-- (SN Controlling the Lifetime of a Window -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The save-set of a client is a list of other clients' windows that,
+if they are inferiors of one of the client's windows at connection close,
+should not be destroyed and should be remapped if they are unmapped.
+For further information about close-connection processing,
+see <link linkend="Using_X_Server_Connection_Close_Operations_">section 2.6</link>.
+To allow an application's window to survive when a window manager that
+has reparented a window fails,
+Xlib provides the save-set functions that you can
+use to control the longevity of subwindows
+that are normally destroyed when the parent is destroyed.
+For example, a window manager that wants to add decoration
+to a window by adding a frame might reparent an application's
+window.
+When the frame is destroyed,
+the application's window should not be destroyed
+but be returned to its previous place in the window hierarchy.
+</para>
+<para>
+<!-- .LP -->
+The X server automatically removes windows from the save-set
+when they are destroyed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add or remove a window from the client's save-set, use
+<function>XChangeSaveSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XChangeSaveSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangesaveset'>
+<funcprototype>
+ <funcdef><function>XChangeSaveSet</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> change_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi that you want to add to or delete from the client's save-set -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>change_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode.
+You can pass
+<symbol>SetModeInsert</symbol>
+or
+<symbol>SetModeDelete</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Depending on the specified mode,
+<function>XChangeSaveSet</function>
+either inserts or deletes the specified window from the client's save-set.
+The specified window must have been created by some other client,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeSaveSet</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a window to the client's save-set, use
+<function>XAddToSaveSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XAddToSaveSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddtosaveset'>
+<funcprototype>
+ <funcdef><function>XAddToSaveSet</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi that you want to add to the client's save-set -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAddToSaveSet</function>
+function adds the specified window to the client's save-set.
+The specified window must have been created by some other client,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XAddToSaveSet</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove a window from the client's save-set, use
+<function>XRemoveFromSaveSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XRemoveFromSaveSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xremovefromsaveset'>
+<funcprototype>
+ <funcdef><function>XRemoveFromSaveSet</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi that you want to delete from the client's save-set -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRemoveFromSaveSet</function>
+function removes the specified window from the client's save-set.
+The specified window must have been created by some other client,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XRemoveFromSaveSet</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Managing_Installed_Colormaps">
+<title>Managing Installed Colormaps</title>
+<!-- .XS -->
+<!-- (SN Managing Installed Colormaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The X server maintains a list of installed colormaps.
+Windows using these colormaps are guaranteed to display with
+correct colors; windows using other colormaps may or may not display
+with correct colors.
+Xlib provides functions that you can use to install a colormap,
+uninstall a colormap, and obtain a list of installed colormaps.
+</para>
+<para>
+<!-- .LP -->
+At any time,
+there is a subset of the installed maps that is viewed as an ordered list
+and is called the required list.
+The length of the required list is at most M,
+where M is the minimum number of installed colormaps specified for the screen
+in the connection setup.
+The required list is maintained as follows.
+When a colormap is specified to
+<function>XInstallColormap</function>,
+it is added to the head of the list;
+the list is truncated at the tail, if necessary, to keep its length to
+at most M.
+When a colormap is specified to
+<function>XUninstallColormap</function>
+and it is in the required list,
+it is removed from the list.
+A colormap is not added to the required list when it is implicitly installed
+by the X server,
+and the X server cannot implicitly uninstall a colormap that is in the
+required list.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To install a colormap, use
+<function>XInstallColormap</function>.
+</para>
+<indexterm significance="preferred"><primary>XInstallColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinstallcolormap'>
+<funcprototype>
+ <funcdef><function>XInstallColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInstallColormap</function>
+function installs the specified colormap for its associated screen.
+All windows associated with this colormap immediately display with
+true colors.
+You associated the windows with this colormap when you created them by calling
+<function>XCreateWindow</function>,
+<function>XCreateSimpleWindow</function>,
+<function>XChangeWindowAttributes</function>,
+or
+<function>XSetWindowColormap</function>.
+</para>
+<para>
+<!-- .LP -->
+If the specified colormap is not already an installed colormap,
+the X server generates a
+<symbol>ColormapNotify</symbol>
+event on each window that has that colormap.
+In addition, for every other colormap that is installed as
+a result of a call to
+<function>XInstallColormap</function>,
+the X server generates a
+<symbol>ColormapNotify</symbol>
+event on each window that has that colormap.
+</para>
+<para>
+<!-- .LP -->
+<function>XInstallColormap</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To uninstall a colormap, use
+<function>XUninstallColormap</function>.
+</para>
+<indexterm significance="preferred"><primary>XUninstallColormap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xuninstallcolormap'>
+<funcprototype>
+ <funcdef><function>XUninstallColormap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Colormap<parameter> colormap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the colormap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUninstallColormap</function>
+function removes the specified colormap from the required
+list for its screen.
+As a result,
+the specified colormap might be uninstalled,
+and the X server might implicitly install or uninstall additional colormaps.
+Which colormaps get installed or uninstalled is server dependent
+except that the required list must remain installed.
+</para>
+<para>
+<!-- .LP -->
+If the specified colormap becomes uninstalled,
+the X server generates a
+<symbol>ColormapNotify</symbol>
+event on each window that has that colormap.
+In addition, for every other colormap that is installed or uninstalled as a
+result of a call to
+<function>XUninstallColormap</function>,
+the X server generates a
+<symbol>ColormapNotify</symbol>
+event on each window that has that colormap.
+</para>
+<para>
+<!-- .LP -->
+<function>XUninstallColormap</function>
+can generate a
+<errorname>BadColor</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a list of the currently installed colormaps for a given screen, use
+<function>XListInstalledColormaps</function>.
+</para>
+<indexterm significance="preferred"><primary>XListInstalledColormaps</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlistinstalledcolormaps'>
+<funcprototype>
+ <funcdef>Colormap *<function>XListInstalledColormaps</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> *num_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi that determines the screen -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of currently installed colormaps.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListInstalledColormaps</function>
+function returns a list of the currently installed colormaps for the screen
+of the specified window.
+The order of the colormaps in the list is not significant
+and is no explicit indication of the required list.
+When the allocated list is no longer needed,
+free it by using
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XListInstalledColormaps</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Setting_and_Retrieving_the_Font_Search_Path">
+<title>Setting and Retrieving the Font Search Path</title>
+<!-- .XS -->
+<!-- (SN Setting and Retrieving the Font Search Path -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The set of fonts available from a server depends on a font
+search path. Xlib provides functions to set and retrieve the
+search path for a server.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the font search path, use
+<function>XSetFontPath</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetFontPath</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetfontpath'>
+<funcprototype>
+ <funcdef><function>XSetFontPath</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> **directories</parameter></paramdef>
+ <paramdef>int<parameter> ndirs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>directories</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the directory path used to look for a font.
+Setting the path to the empty list restores the default path defined
+for the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ndirs</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of directories in the path.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetFontPath</function>
+function defines the directory search path for font lookup.
+There is only one search path per X server, not one per client.
+The encoding and interpretation of the strings are implementation-dependent,
+but typically they specify directories or font servers to be searched
+in the order listed.
+An X server is permitted to cache font information internally;
+for example, it might cache an entire font from a file and not
+check on subsequent opens of that font to see if the underlying
+font file has changed.
+However,
+when the font path is changed,
+the X server is guaranteed to flush all cached information about fonts
+for which there currently are no explicit resource IDs allocated.
+The meaning of an error from this request is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetFontPath</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the current font search path, use
+<function>XGetFontPath</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetFontPath</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetfontpath'>
+<funcprototype>
+ <funcdef>char **<function>XGetFontPath</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *npaths_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>npaths_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of strings in the font path array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetFontPath</function>
+function allocates and returns an array of strings containing the search path.
+The contents of these strings are implementation-dependent
+and are not intended to be interpreted by client applications.
+When it is no longer needed,
+the data in the font path should be freed by using
+<function>XFreeFontPath</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To free data returned by
+<function>XGetFontPath</function>,
+use
+<function>XFreeFontPath</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeFontPath</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreefontpath'>
+<funcprototype>
+ <funcdef><function>XFreeFontPath</function></funcdef>
+ <paramdef>char<parameter> **list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the array of strings you want to free.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeFontPath</function>
+function
+frees the data allocated by
+<function>XGetFontPath</function>.
+</para>
+</sect1>
+<sect1 id="Grabbing_the_Server_">
+<title>Grabbing the Server </title>
+<!-- .XS -->
+<!-- (SN Grabbing the Server -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to grab and ungrab the server.
+These functions can be used to control processing of output on other
+connections by the window system server.
+While the server is grabbed,
+no processing of requests or close downs on any other connection will occur.
+A client closing its connection automatically ungrabs the server.
+<indexterm><primary>Menus</primary></indexterm>
+<indexterm><primary>Window</primary><secondary>managers</secondary></indexterm>
+Although grabbing the server is highly discouraged, it is sometimes necessary.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To grab the server, use
+<function>XGrabServer</function>.
+</para>
+<indexterm><primary>Server</primary><secondary>grabbing</secondary></indexterm>
+<indexterm><primary>Grabbing</primary><secondary>server</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGrabServer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgrabserver'>
+<funcprototype>
+ <funcdef><function>XGrabServer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGrabServer</function>
+function disables processing of requests and close downs on all other
+connections than the one this request arrived on.
+You should not grab the X server any more than is absolutely necessary.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ungrab the server, use
+<function>XUngrabServer</function>.
+</para>
+<indexterm significance="preferred"><primary>XUngrabServer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xungrabserver'>
+<funcprototype>
+ <funcdef><function>XUngrabServer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUngrabServer</function>
+function restarts processing of requests and close downs on other connections.
+You should avoid grabbing the X server as much as possible.
+</para>
+</sect1>
+<sect1 id="Killing_Clients">
+<title>Killing Clients</title>
+<!-- .XS -->
+<!-- (SN Killing Clients -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides a function to cause the connection to
+a client to be closed and its resources to be destroyed.
+To destroy a client, use
+<function>XKillClient</function>.
+</para>
+<indexterm significance="preferred"><primary>XKillClient</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xkillclient'>
+<funcprototype>
+ <funcdef><function>XKillClient</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> resource</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>resource</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies any resource associated with the client that you want to destroy or
+<symbol>AllTemporary</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XKillClient</function>
+function
+forces a close down of the client
+that created the resource
+if a valid resource is specified.
+If the client has already terminated in
+either
+<symbol>RetainPermanent</symbol>
+or
+<symbol>RetainTemporary</symbol>
+mode, all of the client's
+resources are destroyed.
+If
+<symbol>AllTemporary</symbol>
+is specified, the resources of all clients that have terminated in
+<symbol>RetainTemporary</symbol>
+are destroyed (see <link linkend="Closing_the_Display">section 2.5</link>).
+This permits implementation of window manager facilities that aid debugging.
+A client can set its close-down mode to
+<symbol>RetainTemporary</symbol>.
+If the client then crashes,
+its windows would not be destroyed.
+The programmer can then inspect the application's window tree
+and use the window manager to destroy the zombie windows.
+</para>
+<para>
+<!-- .LP -->
+<function>XKillClient</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Controlling_the_Screen_Saver_">
+<title>Controlling the Screen Saver </title>
+<!-- .XS -->
+<!-- (SN Controlling the Screen Saver -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set or reset the mode
+of the screen saver, to force or activate the screen saver,
+or to obtain the current screen saver values.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the screen saver mode, use
+<function>XSetScreenSaver</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetScreenSaver</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetscreensaver'>
+<funcprototype>
+ <funcdef><function>XSetScreenSaver</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>inttimeout,<parameter> interval</parameter></paramdef>
+ <paramdef>int<parameter> prefer_blanking</parameter></paramdef>
+ <paramdef>int<parameter> allow_exposures</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>timeout</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the timeout, in seconds, until the screen saver turns on.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>interval</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the interval, in seconds, between screen saver alterations.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prefer_blanking</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies how to enable screen blanking.
+You can pass
+<symbol>DontPreferBlanking</symbol>,
+<symbol>PreferBlanking</symbol>,
+or
+<symbol>DefaultBlanking</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>allow_exposures</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen save control values.
+You can pass
+<symbol>DontAllowExposures</symbol>,
+<symbol>AllowExposures</symbol>,
+or
+<symbol>DefaultExposures</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Timeout and interval are specified in seconds.
+A timeout of 0 disables the screen saver
+(but an activated screen saver is not deactivated),
+and a timeout of −1 restores the default.
+Other negative values generate a
+<errorname>BadValue</errorname>
+error.
+If the timeout value is nonzero,
+<function>XSetScreenSaver</function>
+enables the screen saver.
+An interval of 0 disables the random-pattern motion.
+If no input from devices (keyboard, mouse, and so on) is generated
+for the specified number of timeout seconds once the screen saver is enabled,
+the screen saver is activated.
+</para>
+<para>
+<!-- .LP -->
+For each screen,
+if blanking is preferred and the hardware supports video blanking,
+the screen simply goes blank.
+Otherwise, if either exposures are allowed or the screen can be regenerated
+without sending
+<symbol>Expose</symbol>
+events to clients,
+the screen is tiled with the root window background tile randomly
+re-origined each interval seconds.
+Otherwise, the screens' state do not change,
+and the screen saver is not activated.
+The screen saver is deactivated,
+and all screen states are restored at the next
+keyboard or pointer input or at the next call to
+<function>XForceScreenSaver</function>
+with mode
+<symbol>ScreenSaverReset</symbol>.
+</para>
+<para>
+<!-- .LP -->
+If the server-dependent screen saver method supports periodic change,
+the interval argument serves as a hint about how long the change period
+should be, and zero hints that no periodic change should be made.
+Examples of ways to change the screen include scrambling the colormap
+periodically, moving an icon image around the screen periodically, or tiling
+the screen with the root window background tile, randomly re-origined
+periodically.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetScreenSaver</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To force the screen saver on or off, use
+<function>XForceScreenSaver</function>.
+</para>
+<indexterm significance="preferred"><primary>XForceScreenSaver</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xforcescreensaver'>
+<funcprototype>
+ <funcdef><function>XForceScreenSaver</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode that is to be applied.
+You can pass
+<symbol>ScreenSaverActive</symbol>
+or
+<symbol>ScreenSaverReset</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the specified mode is
+<symbol>ScreenSaverActive</symbol>
+and the screen saver currently is deactivated,
+<function>XForceScreenSaver</function>
+activates the screen saver even if the screen saver had been disabled
+with a timeout of zero.
+If the specified mode is
+<symbol>ScreenSaverReset</symbol>
+and the screen saver currently is enabled,
+<function>XForceScreenSaver</function>
+deactivates the screen saver if it was activated,
+and the activation timer is reset to its initial state
+(as if device input had been received).
+</para>
+<para>
+<!-- .LP -->
+<function>XForceScreenSaver</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To activate the screen saver, use
+<function>XActivateScreenSaver</function>.
+</para>
+<indexterm significance="preferred"><primary>XActivateScreenSaver</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xactivatescreensaver'>
+<funcprototype>
+ <funcdef><function>XActivateScreenSaver</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To reset the screen saver, use
+<function>XResetScreenSaver</function>.
+</para>
+<indexterm significance="preferred"><primary>XResetScreenSaver</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xresetscreensaver'>
+<funcprototype>
+ <funcdef><function>XResetScreenSaver</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To get the current screen saver values, use
+<function>XGetScreenSaver</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetScreenSaver</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetscreensaver'>
+<funcprototype>
+ <funcdef><function>XGetScreenSaver</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int*timeout_return,<parameter> *interval_return</parameter></paramdef>
+ <paramdef>int<parameter> *prefer_blanking_return</parameter></paramdef>
+ <paramdef>int<parameter> *allow_exposures_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>timeout_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the timeout, in seconds, until the screen saver turns on.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>interval_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the interval between screen saver invocations.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prefer_blanking_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the current screen blanking preference
+(<symbol>DontPreferBlanking</symbol>,
+<symbol>PreferBlanking</symbol>,
+or
+<symbol>DefaultBlanking</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>allow_exposures_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the current screen save control value
+(<symbol>DontAllowExposures</symbol>,
+<symbol>AllowExposures</symbol>,
+or
+<symbol>DefaultExposures</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect1>
+<sect1 id="Controlling_Host_Access">
+<title>Controlling Host Access</title>
+<!-- .XS -->
+<!-- (SN Controlling Host Access -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Add, get, or remove hosts from the access control list
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Change, enable, or disable access
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<indexterm><primary>Access control list</primary></indexterm>
+<indexterm><primary>Authentication</primary></indexterm>
+X does not provide any protection on a per-window basis.
+If you find out the resource ID of a resource, you can manipulate it.
+To provide some minimal level of protection, however,
+connections are permitted only from machines you trust.
+This is adequate on single-user workstations but obviously
+breaks down on timesharing machines.
+Although provisions exist in the X protocol for proper connection
+authentication, the lack of a standard authentication server
+leaves host-level access control as the only common mechanism.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Default Protection</primary></indexterm>
+The initial set of hosts allowed to open connections typically consists of:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The host the window system is running on.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+On <acronym>POSIX</acronym>-conformant systems, each host listed in the
+<filename>/etc/X<replaceable>?</replaceable>.hosts</filename>
+file.
+The ? indicates the number of the
+display.
+<indexterm><primary>Files</primary><secondary><filename>/etc/X<replaceable>?</replaceable>.hosts</filename></secondary></indexterm>
+This file should consist of host names separated by newlines.
+DECnet nodes must terminate in :: to distinguish them from Internet hosts.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+If a host is not in the access control list when the access control
+mechanism is enabled and if the host attempts to establish a connection,
+the server refuses the connection.
+To change the access list,
+the client must reside on the same host as the server and/or must
+have been granted permission in the initial authorization at connection
+setup.
+</para>
+<para>
+<!-- .LP -->
+Servers also can implement other access control policies in addition to
+or in place of this host access facility.
+For further information about other access control implementations,
+see ``X Window System Protocol.''
+</para>
+<sect2 id="Adding_Getting_or_Removing_Hosts">
+<title>Adding, Getting, or Removing Hosts</title>
+<!-- .XS -->
+<!-- (SN Adding, Getting, or Removing Hosts -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to add, get, or remove hosts
+from the access control list.
+All the host access control functions use the
+<structname>XHostAddress</structname>
+structure, which contains:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XHostAddress</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int family; /* for example FamilyInternet */
+ int length; /* length of address, in bytes */
+ char *address; /* pointer to where to find the address */
+} XHostAddress;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The family member specifies which protocol address family to use
+(for example, <acronym>TCP</acronym>/<acronym>IP</acronym> or DECnet) and can be
+<symbol>FamilyInternet</symbol>,
+<symbol>FamilyInternet6</symbol>,
+<symbol>FamilyServerInterpreted</symbol>,
+<symbol>FamilyDECnet</symbol>,
+or
+<symbol>FamilyChaos</symbol>.
+The length member specifies the length of the address in bytes.
+The address member specifies a pointer to the address.
+</para>
+<para>
+<!-- .LP -->
+For <acronym>TCP</acronym>/<acronym>IP</acronym>, the address should be in network byte order.
+For <acronym>IP</acronym> version 4 addresses, the family should be FamilyInternet
+and the length should be 4 bytes. For <acronym>IP</acronym> version 6 addresses, the
+family should be FamilyInternet6 and the length should be 16 bytes.
+</para>
+<para>
+<!-- .LP -->
+For the DECnet family,
+the server performs no automatic swapping on the address bytes.
+A Phase IV address is 2 bytes long.
+The first byte contains the least significant 8 bits of the node number.
+The second byte contains the most significant 2 bits of the
+node number in the least significant 2 bits of the byte
+and the area in the most significant 6 bits of the byte.
+</para>
+<para>
+<!-- .LP -->
+For the ServerInterpreted family, the length is ignored and the address
+member is a pointer to a
+<structname>XServerInterpretedAddress</structname>
+structure, which contains:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XServerInterpretedAddress</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ int typelength; /* length of type string, in bytes */
+ int valuelength; /* length of value string, in bytes */
+ char *type; /* pointer to where to find the type string */
+ char *value; /* pointer to where to find the address */
+} XServerInterpretedAddress;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The type and value members point to strings representing the type and value of
+the server interpreted entry. These strings may not be NULL-terminated so care
+should be used when accessing them. The typelength and valuelength members
+specify the length in byte of the type and value strings.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a single host, use
+<function>XAddHost</function>.
+</para>
+<indexterm significance="preferred"><primary>XAddHost</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddhost'>
+<funcprototype>
+ <funcdef><function>XAddHost</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XHostAddress<parameter> *host</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Ho added -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>host</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the host that is to be (Ho.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAddHost</function>
+function adds the specified host to the access control list for that display.
+The server must be on the same host as the client issuing the command, or a
+<errorname>BadAccess</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XAddHost</function>
+can generate
+<errorname>BadAccess</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add multiple hosts at one time, use
+<function>XAddHosts</function>.
+</para>
+<indexterm significance="preferred"><primary>XAddHosts</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddhosts'>
+<funcprototype>
+ <funcdef><function>XAddHosts</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XHostAddress<parameter> *hosts</parameter></paramdef>
+ <paramdef>int<parameter> num_hosts</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Ho added -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hosts</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies each host that is to be (Ho.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_hosts</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of hosts.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAddHosts</function>
+function adds each specified host to the access control list for that display.
+The server must be on the same host as the client issuing the command, or a
+<errorname>BadAccess</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XAddHosts</function>
+can generate
+<errorname>BadAccess</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a host list, use
+<function>XListHosts</function>.
+</para>
+<indexterm significance="preferred"><primary>XListHosts</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlisthosts'>
+<funcprototype>
+ <funcdef>XHostAddress *<function>XListHosts</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *nhosts_return</parameter></paramdef>
+ <paramdef>Bool<parameter> *state_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nhosts_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of hosts currently in the access control list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>state_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the state of the access control.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XListHosts</function>
+function returns the current access control list as well as whether the use
+of the list at connection setup was enabled or disabled.
+<function>XListHosts</function>
+allows a program to find out what machines can make connections.
+It also returns a pointer to a list of host structures that
+were allocated by the function.
+When no longer needed,
+this memory should be freed by calling
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove a single host, use
+<function>XRemoveHost</function>.
+</para>
+<indexterm significance="preferred"><primary>XRemoveHost</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xremovehost'>
+<funcprototype>
+ <funcdef><function>XRemoveHost</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XHostAddress<parameter> *host</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Ho removed -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>host</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the host that is to be (Ho.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRemoveHost</function>
+function removes the specified host from the access control list
+for that display.
+The server must be on the same host as the client process, or a
+<errorname>BadAccess</errorname>
+error results.
+If you remove your machine from the access list,
+you can no longer connect to that server,
+and this operation cannot be reversed unless you reset the server.
+</para>
+<para>
+<!-- .LP -->
+<function>XRemoveHost</function>
+can generate
+<errorname>BadAccess</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove multiple hosts at one time, use
+<function>XRemoveHosts</function>.
+</para>
+<indexterm significance="preferred"><primary>XRemoveHosts</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xremovehosts'>
+<funcprototype>
+ <funcdef><function>XRemoveHosts</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XHostAddress<parameter> *hosts</parameter></paramdef>
+ <paramdef>int<parameter> num_hosts</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Ho removed -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hosts</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies each host that is to be (Ho.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_hosts</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of hosts.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRemoveHosts</function>
+function removes each specified host from the access control list for that
+display.
+The X server must be on the same host as the client process, or a
+<errorname>BadAccess</errorname>
+error results.
+If you remove your machine from the access list,
+you can no longer connect to that server,
+and this operation cannot be reversed unless you reset the server.
+</para>
+<para>
+<!-- .LP -->
+<function>XRemoveHosts</function>
+can generate
+<errorname>BadAccess</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Changing_Enabling_or_Disabling_Access_Control">
+<title>Changing, Enabling, or Disabling Access Control</title>
+<!-- .XS -->
+<!-- (SN Changing, Enabling, or Disabling Access Control -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to enable, disable,
+or change access control.
+</para>
+<para>
+<!-- .LP -->
+For these functions to execute successfully,
+the client application must reside on the same host as the X server
+and/or have been given permission in the initial authorization
+at connection setup.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change access control, use
+<function>XSetAccessControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetAccessControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetaccesscontrol'>
+<funcprototype>
+ <funcdef><function>XSetAccessControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode.
+You can pass
+<symbol>EnableAccess</symbol>
+or
+<symbol>DisableAccess</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetAccessControl</function>
+function either enables or disables the use of the access control list
+at each connection setup.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetAccessControl</function>
+can generate
+<errorname>BadAccess</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To enable access control, use
+<function>XEnableAccessControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XEnableAccessControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xenableaccesscontrol'>
+<funcprototype>
+ <funcdef><function>XEnableAccessControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XEnableAccessControl</function>
+function enables the use of the access control list at each connection setup.
+</para>
+<para>
+<!-- .LP -->
+<function>XEnableAccessControl</function>
+can generate a
+<errorname>BadAccess</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To disable access control, use
+<function>XDisableAccessControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisableAccessControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisableaccesscontrol'>
+<funcprototype>
+ <funcdef><function>XDisableAccessControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDisableAccessControl</function>
+function disables the use of the access control list at each connection setup.
+</para>
+<para>
+<!-- .LP -->
+<function>XDisableAccessControl</function>
+can generate a
+<errorname>BadAccess</errorname>
+error.
+<!-- .bp -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH11.xml b/libX11/specs/libX11/CH11.xml index f203f6f10..39140bbf6 100644 --- a/libX11/specs/libX11/CH11.xml +++ b/libX11/specs/libX11/CH11.xml @@ -1,2521 +1,2521 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="event_handling_functions"> -<title>Event Handling Functions</title> - -<para> -This chapter discusses the Xlib functions you can use to: -</para> -<itemizedlist> - <listitem><para>Select events</para></listitem> - <listitem><para>Handle the output buffer and the event queue</para></listitem> - <listitem><para>Select events from the event queue</para></listitem> - <listitem><para>Send and get events</para></listitem> - <listitem><para>Handle protocol errors</para></listitem> -</itemizedlist> -<note><para> -Some toolkits use their own event-handling functions and do not allow you to -interchange these event-handling functions with those in Xlib. For further -information, see the documentation supplied with the toolkit. -</para></note> - -<para> -Most applications simply are event loops: they wait for an event, decide what to do with it, -execute some amount of code that results in changes to the display, and then wait for the next -event. -</para> - -<sect1 id="Selecting_Events"> -<title>Selecting Events</title> -<!-- .XS --> -<!-- (SN Selecting Events --> -<!-- .XE --> -<para> -<!-- .LP --> -There are two ways to select the events you want reported to your client -application. -One way is to set the event_mask member of the -<structname>XSetWindowAttributes</structname> -structure when you call -<function>XCreateWindow</function> -and -<function>XChangeWindowAttributes</function>. -Another way is to use -<function>XSelectInput</function>. -</para> -<indexterm significance="preferred"><primary>XSelectInput</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xselectinput'> -<funcprototype> - <funcdef><function>XSelectInput</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose events you are interested in --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSelectInput</function> -function requests that the X server report the events associated with the -specified event mask. -Initially, X will not report any of these events. -Events are reported relative to a window. -If a window is not interested in a device event, it usually propagates to -the closest ancestor that is interested, -unless the do_not_propagate mask prohibits it. -<indexterm><primary>Event</primary><secondary>propagation</secondary></indexterm> -</para> -<para> -<!-- .LP --> -Setting the event-mask attribute of a window overrides any previous call -for the same window but not for other clients. -Multiple clients can select for the same events on the same window -with the following restrictions: -</para> -<itemizedlist> - <listitem> - <para> -Multiple clients can select events on the same window because their event masks -are disjoint. -When the X server generates an event, it reports it -to all interested clients. - </para> - </listitem> - <listitem> - <para> -Only one client at a time can select -<symbol>CirculateRequest</symbol>, -<symbol>ConfigureRequest</symbol>, -or -<symbol>MapRequest</symbol> -events, which are associated with -the event mask -<symbol>SubstructureRedirectMask</symbol>. - </para> - </listitem> - <listitem> - <para> -Only one client at a time can select -a -<symbol>ResizeRequest</symbol> -event, which is associated with -the event mask -<symbol>ResizeRedirectMask</symbol>. - </para> - </listitem> - <listitem> - <para> -Only one client at a time can select a -<symbol>ButtonPress</symbol> -event, which is associated with -the event mask -<symbol>ButtonPressMask</symbol>. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The server reports the event to all interested clients. -</para> -<para> -<!-- .LP --> -<function>XSelectInput</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Handling_the_Output_Buffer"> -<title>Handling the Output Buffer</title> -<!-- .XS --> -<!-- (SN Handling the Output Buffer --> -<!-- .XE --> -<para> -<!-- .LP --> -The output buffer is an area used by Xlib to store requests. -The functions described in this section flush the output buffer -if the function would block or not return an event. -That is, all requests residing in the output buffer that -have not yet been sent are transmitted to the X server. -These functions differ in the additional tasks they might perform. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To flush the output buffer, use -<function>XFlush</function>. -</para> -<indexterm significance="preferred"><primary>XFlush</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xflush'> -<funcprototype> - <funcdef><function>XFlush</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFlush</function> -function -flushes the output buffer. -Most client applications need not use this function because the output -buffer is automatically flushed as needed by calls to -<function>XPending</function>, -<function>XNextEvent</function>, -and -<function>XWindowEvent</function>. -<indexterm><primary>XPending</primary></indexterm> -<indexterm><primary>XNextEvent</primary></indexterm> -<indexterm><primary>XWindowEvent</primary></indexterm> -Events generated by the server may be enqueued into the library's event queue. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To flush the output buffer and then wait until all requests have been processed, -use -<function>XSync</function>. -</para> -<indexterm significance="preferred"><primary>XSync</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsync'> -<funcprototype> - <funcdef><function>XSync</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Bool<parameter> discard</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>discard</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether -<function>XSync</function> -discards all events on the event queue. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSync</function> -function -flushes the output buffer and then waits until all requests have been received -and processed by the X server. -Any errors generated must be handled by the error handler. -For each protocol error received by Xlib, -<function>XSync</function> -calls the client application's error handling routine -(see <link linkend="Using_the_Default_Error_Handlers">section 11.8.2</link>). -Any events generated by the server are enqueued into the library's -event queue. -</para> -<para> -<!-- .LP --> -Finally, if you passed -<symbol>False</symbol>, -<function>XSync</function> -does not discard the events in the queue. -If you passed -<symbol>True</symbol>, -<function>XSync</function> -discards all events in the queue, -including those events that were on the queue before -<function>XSync</function> -was called. -Client applications seldom need to call -<function>XSync</function>. -</para> -</sect1> -<sect1 id="Event_Queue_Management"> -<title>Event Queue Management</title> -<!-- .XS --> -<!-- (SN Event Queue Management --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib maintains an event queue. -However, the operating system also may be buffering data -in its network connection that is not yet read into the event queue. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To check the number of events in the event queue, use -<function>XEventsQueued</function>. -</para> -<indexterm significance="preferred"><primary>XEventsQueued</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xeventsqueued'> -<funcprototype> - <funcdef>int <function>XEventsQueued</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the mode. -You can pass -<symbol>QueuedAlready</symbol>, -<symbol>QueuedAfterFlush</symbol>, -or -<symbol>QueuedAfterReading</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If mode is -<symbol>QueuedAlready</symbol>, -<function>XEventsQueued</function> -returns the number of events -already in the event queue (and never performs a system call). -If mode is -<symbol>QueuedAfterFlush</symbol>, -<function>XEventsQueued</function> -returns the number of events already in the queue if the number is nonzero. -If there are no events in the queue, -<function>XEventsQueued</function> -flushes the output buffer, -attempts to read more events out of the application's connection, -and returns the number read. -If mode is -<symbol>QueuedAfterReading</symbol>, -<function>XEventsQueued</function> -returns the number of events already in the queue if the number is nonzero. -If there are no events in the queue, -<function>XEventsQueued</function> -attempts to read more events out of the application's connection -without flushing the output buffer and returns the number read. -</para> -<para> -<!-- .LP --> -<function>XEventsQueued</function> -always returns immediately without I/O if there are events already in the -queue. -<function>XEventsQueued</function> -with mode -<symbol>QueuedAfterFlush</symbol> -is identical in behavior to -<function>XPending</function>. -<function>XEventsQueued</function> -with mode -<symbol>QueuedAlready</symbol> -is identical to the -<function>XQLength</function> -function. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return the number of events that are pending, use -<function>XPending</function>. -</para> -<indexterm significance="preferred"><primary>XPending</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpending'> -<funcprototype> - <funcdef>int <function>XPending</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPending</function> -function returns the number of events that have been received from the -X server but have not been removed from the event queue. -<function>XPending</function> -is identical to -<function>XEventsQueued</function> -with the mode -<symbol>QueuedAfterFlush</symbol> -specified. -</para> -</sect1> -<sect1 id="Manipulating_the_Event_Queue"> -<title>Manipulating the Event Queue</title> -<!-- .XS --> -<!-- (SN Manipulating the Event Queue --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that let you manipulate the event queue. -This section discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Obtain events, in order, and remove them from the queue - </para> - </listitem> - <listitem> - <para> -Peek at events in the queue without removing them - </para> - </listitem> - <listitem> - <para> -Obtain events that match the event mask or the arbitrary -predicate procedures that you provide - </para> - </listitem> -</itemizedlist> -<sect2 id="Returning_the_Next_Event"> -<title>Returning the Next Event</title> -<!-- .XS --> -<!-- (SN Returning the Next Event --> -<!-- .XE --> -<para> -<!-- .LP --> -To get the next event and remove it from the queue, use -<function>XNextEvent</function>. -</para> -<indexterm significance="preferred"><primary>XNextEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xnextevent'> -<funcprototype> - <funcdef><function>XNextEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the next event in the queue. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XNextEvent</function> -function copies the first event from the event queue into the specified -<structname>XEvent</structname> -structure and then removes it from the queue. -If the event queue is empty, -<function>XNextEvent</function> -flushes the output buffer and blocks until an event is received. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To peek at the event queue, use -<function>XPeekEvent</function>. -</para> -<indexterm significance="preferred"><primary>XPeekEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpeekevent'> -<funcprototype> - <funcdef><function>XPeekEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns a copy of the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPeekEvent</function> -function returns the first event from the event queue, -but it does not remove the event from the queue. -If the queue is empty, -<function>XPeekEvent</function> -flushes the output buffer and blocks until an event is received. -It then copies the event into the client-supplied -<structname>XEvent</structname> -structure without removing it from the event queue. -</para> -</sect2> -<sect2 id="Selecting_Events_Using_a_Predicate_Procedure"> -<title>Selecting Events Using a Predicate Procedure</title> -<!-- .XS --> -<!-- (SN Selecting Events Using a Predicate Procedure --> -<!-- .XE --> -<para> -<!-- .LP --> -Each of the functions discussed in this section requires you to -pass a predicate procedure that determines if an event matches -what you want. -Your predicate procedure must decide if the event is useful -without calling any Xlib functions. -If the predicate directly or indirectly causes the state of the event queue -to change, the result is not defined. -If Xlib has been initialized for threads, the predicate is called with -the display locked and the result of a call by the predicate to any -Xlib function that locks the display is not defined unless the caller -has first called -<function>XLockDisplay</function>. -</para> -<para> -<!-- .LP --> -The predicate procedure and its associated arguments are: -</para> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef><type>Bool</type></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event</parameter></paramdef> - <paramdef>XPointer<parameter> arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XEvent</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arg</emphasis> - </term> - <listitem> - <para> -Specifies the argument passed in from the -<function>XIfEvent</function>, -<function>XCheckIfEvent</function>, -or -<function>XPeekIfEvent</function> -function. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The predicate procedure is called once for each -event in the queue until it finds a match. -After finding a match, the predicate procedure must return -<symbol>True</symbol>. -If it did not find a match, it must return -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To check the event queue for a matching event -and, if found, remove the event from the queue, use -<function>XIfEvent</function>. -</para> -<indexterm significance="preferred"><primary>XIfEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xifevent'> -<funcprototype> - <funcdef><function>XIfEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> - <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef> - <paramdef>XPointer<parameter> arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate</emphasis> - </term> - <listitem> - <para> -Specifies the procedure that is to be called to determine -if the next event in the queue matches what you want. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arg</emphasis> - </term> - <listitem> - <para> -Specifies the user-supplied argument that will be passed to the predicate procedure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XIfEvent</function> -function completes only when the specified predicate -procedure returns -<symbol>True</symbol> -for an event, -which indicates an event in the queue matches. -<function>XIfEvent</function> -flushes the output buffer if it blocks waiting for additional events. -<function>XIfEvent</function> -removes the matching event from the queue -and copies the structure into the client-supplied -<structname>XEvent</structname> -structure. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To check the event queue for a matching event without blocking, use -<function>XCheckIfEvent</function>. -</para> -<indexterm significance="preferred"><primary>XCheckIfEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcheckifevent'> -<funcprototype> - <funcdef>Bool <function>XCheckIfEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> - <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef> - <paramdef>XPointer<parameter> arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns a copy of the matched event's associated structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate</emphasis> - </term> - <listitem> - <para> -Specifies the procedure that is to be called to determine -if the next event in the queue matches what you want. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arg</emphasis> - </term> - <listitem> - <para> -Specifies the user-supplied argument that will be passed to the predicate procedure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -When the predicate procedure finds a match, -<function>XCheckIfEvent</function> -copies the matched event into the client-supplied -<structname>XEvent</structname> -structure and returns -<symbol>True</symbol>. -(This event is removed from the queue.) -If the predicate procedure finds no match, -<function>XCheckIfEvent</function> -returns -<symbol>False</symbol>, -and the output buffer will have been flushed. -All earlier events stored in the queue are not discarded. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To check the event queue for a matching event -without removing the event from the queue, use -<function>XPeekIfEvent</function>. -</para> -<indexterm significance="preferred"><primary>XPeekIfEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpeekifevent'> -<funcprototype> - <funcdef><function>XPeekIfEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> - <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef> - <paramdef>XPointer<parameter> arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns a copy of the matched event's associated structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>predicate</emphasis> - </term> - <listitem> - <para> -Specifies the procedure that is to be called to determine -if the next event in the queue matches what you want. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arg</emphasis> - </term> - <listitem> - <para> -Specifies the user-supplied argument that will be passed to the predicate procedure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPeekIfEvent</function> -function returns only when the specified predicate -procedure returns -<symbol>True</symbol> -for an event. -After the predicate procedure finds a match, -<function>XPeekIfEvent</function> -copies the matched event into the client-supplied -<structname>XEvent</structname> -structure without removing the event from the queue. -<function>XPeekIfEvent</function> -flushes the output buffer if it blocks waiting for additional events. -</para> -</sect2> -<sect2 id="Selecting_Events_Using_a_Window_or_Event_Mask"> -<title>Selecting Events Using a Window or Event Mask</title> -<!-- .XS --> -<!-- (SN Selecting Events Using a Window or Event Mask --> -<!-- .XE --> -<para> -<!-- .LP --> -The functions discussed in this section let you select events by window -or event types, allowing you to process events out of order. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove the next event that matches both a window and an event mask, use -<function>XWindowEvent</function>. -</para> -<indexterm significance="preferred"><primary>XWindowEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwindowevent'> -<funcprototype> - <funcdef><function>XWindowEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose events you are interested in --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XWindowEvent</function> -function searches the event queue for an event that matches both the specified -window and event mask. -When it finds a match, -<function>XWindowEvent</function> -removes that event from the queue and copies it into the specified -<structname>XEvent</structname> -structure. -The other events stored in the queue are not discarded. -If a matching event is not in the queue, -<function>XWindowEvent</function> -flushes the output buffer and blocks until one is received. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove the next event that matches both a window and an event mask (if any), -use -<function>XCheckWindowEvent</function>. -<indexterm><primary>XCheckWindowEvent</primary></indexterm> -This function is similar to -<function>XWindowEvent</function> -except that it never blocks and it returns a -<type>Bool</type> -indicating if the event was returned. -</para> -<indexterm significance="preferred"><primary>XCheckWindowEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcheckwindowevent'> -<funcprototype> - <funcdef>Bool <function>XCheckWindowEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Wi whose events you are interested in --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCheckWindowEvent</function> -function searches the event queue and then the events available -on the server connection for the first event that matches the specified window -and event mask. -If it finds a match, -<function>XCheckWindowEvent</function> -removes that event, copies it into the specified -<structname>XEvent</structname> -structure, and returns -<symbol>True</symbol>. -The other events stored in the queue are not discarded. -If the event you requested is not available, -<function>XCheckWindowEvent</function> -returns -<symbol>False</symbol>, -and the output buffer will have been flushed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To remove the next event that matches an event mask, use -<function>XMaskEvent</function>. -</para> -<indexterm significance="preferred"><primary>XMaskEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmaskevent'> -<funcprototype> - <funcdef><function>XMaskEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMaskEvent</function> -function searches the event queue for the events associated with the -specified mask. -When it finds a match, -<function>XMaskEvent</function> -removes that event and copies it into the specified -<structname>XEvent</structname> -structure. -The other events stored in the queue are not discarded. -If the event you requested is not in the queue, -<function>XMaskEvent</function> -flushes the output buffer and blocks until one is received. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return and remove the next event that matches an event mask (if any), use -<function>XCheckMaskEvent</function>. -This function is similar to -<function>XMaskEvent</function> -except that it never blocks and it returns a -<type>Bool</type> -indicating if the event was returned. -</para> -<indexterm significance="preferred"><primary>XCheckMaskEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcheckmaskevent'> -<funcprototype> - <funcdef>Bool <function>XCheckMaskEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCheckMaskEvent</function> -function searches the event queue and then any events available on the -server connection for the first event that matches the specified mask. -If it finds a match, -<function>XCheckMaskEvent</function> -removes that event, copies it into the specified -<structname>XEvent</structname> -structure, and returns -<symbol>True</symbol>. -The other events stored in the queue are not discarded. -If the event you requested is not available, -<function>XCheckMaskEvent</function> -returns -<symbol>False</symbol>, -and the output buffer will have been flushed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return and remove the next event in the queue that matches an event type, use -<function>XCheckTypedEvent</function>. -</para> -<indexterm significance="preferred"><primary>XCheckTypedEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchecktypedevent'> -<funcprototype> - <funcdef>Bool <function>XCheckTypedEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> event_type</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_type</emphasis> - </term> - <listitem> - <para> -Specifies the event type to be compared. - - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCheckTypedEvent</function> -function searches the event queue and then any events available -on the server connection for the first event that matches the specified type. -If it finds a match, -<function>XCheckTypedEvent</function> -removes that event, copies it into the specified -<structname>XEvent</structname> -structure, and returns -<symbol>True</symbol>. -The other events in the queue are not discarded. -If the event is not available, -<function>XCheckTypedEvent</function> -returns -<symbol>False</symbol>, -and the output buffer will have been flushed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return and remove the next event in the queue that matches an event type -and a window, use -<function>XCheckTypedWindowEvent</function>. -</para> -<indexterm significance="preferred"><primary>XCheckTypedWindowEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchecktypedwindowevent'> -<funcprototype> - <funcdef>Bool <function>XCheckTypedWindowEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> event_type</parameter></paramdef> - <paramdef>XEvent<parameter> *event_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_type</emphasis> - </term> - <listitem> - <para> -Specifies the event type to be compared. - - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_return</emphasis> - </term> - <listitem> - <para> -Returns the matched event's associated structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCheckTypedWindowEvent</function> -function searches the event queue and then any events available -on the server connection for the first event that matches the specified -type and window. -If it finds a match, -<function>XCheckTypedWindowEvent</function> -removes the event from the queue, copies it into the specified -<structname>XEvent</structname> -structure, and returns -<symbol>True</symbol>. -The other events in the queue are not discarded. -If the event is not available, -<function>XCheckTypedWindowEvent</function> -returns -<symbol>False</symbol>, -and the output buffer will have been flushed. -</para> -</sect2> -</sect1> -<sect1 id="Putting_an_Event_Back_into_the_Queue"> -<title>Putting an Event Back into the Queue</title> -<!-- .XS --> -<!-- (SN Putting an Event Back into the Queue --> -<!-- .XE --> -<para> -<!-- .LP --> -To push an event back into the event queue, use -<function>XPutBackEvent</function>. -</para> -<indexterm significance="preferred"><primary>XPutBackEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xputbackevent'> -<funcprototype> - <funcdef><function>XPutBackEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XEvent<parameter> *event</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event</emphasis> - </term> - <listitem> - <para> -Specifies the event. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPutBackEvent</function> -function pushes an event back onto the head of the display's event queue -by copying the event into the queue. -This can be useful if you read an event and then decide that you -would rather deal with it later. -There is no limit to the number of times in succession that you can call -<function>XPutBackEvent</function>. -</para> -</sect1> -<sect1 id="Sending_Events_to_Other_Applications"> -<title>Sending Events to Other Applications</title> -<!-- .XS --> -<!-- (SN Sending Events to Other Applications --> -<!-- .XE --> -<para> -<!-- .LP --> -To send an event to a specified window, use -<function>XSendEvent</function>. -<indexterm><primary>XSendEvent</primary></indexterm> -This function is often used in selection processing. -For example, the owner of a selection should use -<function>XSendEvent</function> -to send a -<symbol>SelectionNotify</symbol> -event to a requestor when a selection has been converted -and stored as a property. -</para> -<indexterm significance="preferred"><primary>XSendEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsendevent'> -<funcprototype> - <funcdef>Status <function>XSendEvent</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Bool<parameter> propagate</parameter></paramdef> - <paramdef>long<parameter> event_mask</parameter></paramdef> - <paramdef>XEvent<parameter> *event_send</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window the event is to be sent to, or -<symbol>PointerWindow</symbol>, -or -<symbol>InputFocus</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>propagate</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_send</emphasis> - </term> - <listitem> - <para> -Specifies the event that is to be sent. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSendEvent</function> -function identifies the destination window, -determines which clients should receive the specified events, -and ignores any active grabs. -This function requires you to pass an event mask. -For a discussion of the valid event mask names, -see <link linkend="Event_Masks">section 10.3</link>. -This function uses the w argument to identify the destination window as follows: -</para> -<itemizedlist> - <listitem> - <para> -If w is -<symbol>PointerWindow</symbol>, -the destination window is the window that contains the pointer. - </para> - </listitem> - <listitem> - <para> -If w is -<symbol>InputFocus</symbol> -and if the focus window contains the pointer, -the destination window is the window that contains the pointer; -otherwise, the destination window is the focus window. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -To determine which clients should receive the specified events, -<function>XSendEvent</function> -uses the propagate argument as follows: -</para> -<itemizedlist> - <listitem> - <para> -If event_mask is the empty set, -the event is sent to the client that created the destination window. -If that client no longer exists, -no event is sent. - </para> - </listitem> - <listitem> - <para> -If propagate is -<symbol>False</symbol>, -the event is sent to every client selecting on destination any of the event -types in the event_mask argument. - </para> - </listitem> - <listitem> - <para> -If propagate is -<symbol>True</symbol> -and no clients have selected on destination any of -the event types in event-mask, the destination is replaced with the -closest ancestor of destination for which some client has selected a -type in event-mask and for which no intervening window has that type in its -do-not-propagate-mask. -If no such window exists or if the window is -an ancestor of the focus window and -<symbol>InputFocus</symbol> -was originally specified -as the destination, the event is not sent to any clients. -Otherwise, the event is reported to every client selecting on the final -destination any of the types specified in event_mask. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The event in the -<structname>XEvent</structname> -structure must be one of the core events or one of the events -defined by an extension (or a -<errorname>BadValue</errorname> -error results) so that the X server can correctly byte-swap -the contents as necessary. -The contents of the event are -otherwise unaltered and unchecked by the X server except to force send_event to -<symbol>True</symbol> -in the forwarded event and to set the serial number in the event correctly; -therefore these fields -and the display field are ignored by -<function>XSendEvent</function>. -</para> -<para> -<!-- .LP --> -<function>XSendEvent</function> -returns zero if the conversion to wire protocol format failed -and returns nonzero otherwise. -</para> -<para> -<!-- .LP --> -<function>XSendEvent</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Getting_Pointer_Motion_History"> -<title>Getting Pointer Motion History</title> -<!-- .XS --> -<!-- (SN Getting Pointer Motion History --> -<!-- .XE --> -<para> -<!-- .LP --> -Some X server implementations will maintain a more complete -history of pointer motion than is reported by event notification. -The pointer position at each pointer hardware interrupt may be -stored in a buffer for later retrieval. -This buffer is called the motion history buffer. -For example, a few applications, such as paint programs, -want to have a precise history of where the pointer -traveled. -However, this historical information is highly excessive for most applications. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To determine the approximate maximum number of elements in the motion buffer, -use -<function>XDisplayMotionBufferSize</function>. -</para> -<indexterm significance="preferred"><primary>XDisplayMotionBufferSize</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisplaymotionbuffersize'> -<funcprototype> - <funcdef>unsigned <type>long</type></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The server may retain the recent history of the pointer motion -and do so to a finer granularity than is reported by -<symbol>MotionNotify</symbol> -events. -The -<function>XGetMotionEvents</function> -function makes this history available. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the motion history for a specified window and time, use -<function>XGetMotionEvents</function>. -</para> -<indexterm significance="preferred"><primary>XGetMotionEvents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetmotionevents'> -<funcprototype> - <funcdef>XTimeCoord *<function>XGetMotionEvents</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Timestart,<parameter> stop</parameter></paramdef> - <paramdef>int<parameter> *nevents_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>start</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>stop</emphasis> - </term> - <listitem> - <para> -Specify the time interval in which the events are returned from the motion -history buffer. -You can pass a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nevents_return</emphasis> - </term> - <listitem> - <para> -Returns the number of events from the motion history buffer. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetMotionEvents</function> -function returns all events in the motion history buffer that fall between the -specified start and stop times, inclusive, and that have coordinates -that lie within the specified window (including its borders) at its present -placement. -If the server does not support motion history, -if the start time is later than the stop time, -or if the start time is in the future, -no events are returned; -<function>XGetMotionEvents</function> -returns NULL. -If the stop time is in the future, it is equivalent to specifying -<symbol>CurrentTime</symbol>. -The return type for this function is a structure defined as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XTimeCoord</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - Time time; - short x, y; -} XTimeCoord; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The time member is set to the time, in milliseconds. -The x and y members are set to the coordinates of the pointer and -are reported relative to the origin -of the specified window. -To free the data returned from this call, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetMotionEvents</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Handling_Protocol_Errors"> -<title>Handling Protocol Errors</title> -<!-- .XS --> -<!-- (SN Handling Protocol Errors --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to enable or disable synchronization -and to use the default error handlers. -</para> -<sect2 id="Enabling_or_Disabling_Synchronization"> -<title>Enabling or Disabling Synchronization</title> -<!-- .XS --> -<!-- (SN Enabling or Disabling Synchronization --> -<!-- .XE --> -<para> -<!-- .LP --> -When debugging X applications, -it often is very convenient to require Xlib to behave synchronously -so that errors are reported as they occur. -The following function lets you disable or enable synchronous behavior. -Note that graphics may occur 30 or more times more slowly when -synchronization is enabled. -<indexterm><primary>_Xdebug</primary></indexterm> -On <acronym>POSIX</acronym>-conformant systems, -there is also a global variable -<varname>_Xdebug</varname> -that, if set to nonzero before starting a program under a debugger, will force -synchronous library behavior. -</para> -<para> -<!-- .LP --> -After completing their work, -all Xlib functions that generate protocol requests call what is known as -an after function. -<function>XSetAfterFunction</function> -sets which function is to be called. -</para> -<indexterm significance="preferred"><primary>XSetAfterFunction</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetafterfunction'> -<funcprototype> - <funcdef><type>int</type></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> (*procedure)()</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>procedure</emphasis> - </term> - <listitem> - <para> -Specifies the procedure to be called. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The specified procedure is called with only a display pointer. -<function>XSetAfterFunction</function> -returns the previous after function. -</para> -<para> -<!-- .LP --> -To enable or disable synchronization, use -<function>XSynchronize</function>. -</para> -<indexterm><primary>Debugging</primary><secondary>synchronous mode</secondary></indexterm> -<indexterm significance="preferred"><primary>XSynchronize</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsynchronize'> -<funcprototype> - <funcdef><type>int</type></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Bool<parameter> onoff</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>onoff</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether to enable -or disable synchronization. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSynchronize</function> -function returns -the previous after function. -If onoff is -<symbol>True</symbol>, -<function>XSynchronize</function> -turns on synchronous behavior. -If onoff is -<symbol>False</symbol>, -<function>XSynchronize</function> -turns off synchronous behavior. -</para> -</sect2> -<sect2 id="Using_the_Default_Error_Handlers"> -<title>Using the Default Error Handlers</title> -<!-- .XS --> -<!-- (SN Using the Default Error Handlers --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Debugging</primary><secondary>error handlers</secondary></indexterm> -<indexterm><primary>Error</primary><secondary>handlers</secondary></indexterm> -There are two default error handlers in Xlib: -one to handle typically fatal conditions (for example, -the connection to a display server dying because a machine crashed) -and one to handle protocol errors from the X server. -These error handlers can be changed to user-supplied routines if you -prefer your own error handling and can be changed as often as you like. -If either function is passed a NULL pointer, it will -reinvoke the default handler. -The action of the default handlers is to print an explanatory -message and exit. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the error handler, use -<function>XSetErrorHandler</function>. -</para> -<indexterm significance="preferred"><primary>XSetErrorHandler</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xseterrorhandler'> -<funcprototype> - <funcdef>int *<function>XSetErrorHandler</function></funcdef> - <paramdef>int <parameter> *handler</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>handler</emphasis> - </term> - <listitem> - <para> -Specifies the program's supplied error handler. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Xlib generally calls the program's -supplied error handler whenever an error is received. -It is not called on -<errorname>BadName</errorname> -errors from -<systemitem>OpenFont</systemitem>, -<systemitem>LookupColor</systemitem>, -or -<systemitem>AllocNamedColor</systemitem> -protocol requests or on -<errorname>BadFont</errorname> -errors from a -<systemitem>QueryFont</systemitem> -protocol request. -These errors generally are reflected back to the program through the -procedural interface. -Because this condition is not assumed to be fatal, -it is acceptable for your error handler to return; -the returned value is ignored. -However, the error handler should not -call any functions (directly or indirectly) on the display -that will generate protocol requests or that will look for input events. -The previous error handler is returned. -</para> -<para> -<!-- .LP --> -The -<structname>XErrorEvent</structname> -structure contains: -<indexterm><primary>Debugging</primary><secondary>error event</secondary></indexterm> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XErrorEvent</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int type; - Display *display; /* Display the event was read from */ - unsigned long serial; /* serial number of failed request */ - unsigned char error_code; /* error code of failed request */ - unsigned char request_code; /* Major op-code of failed request */ - unsigned char minor_code; /* Minor op-code of failed request */ - XID resourceid; /* resource id */ -} XErrorEvent; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm><primary>Serial Number</primary></indexterm> -The serial member is the number of requests, starting from one, -sent over the network connection since it was opened. -It is the number that was the value of -<function>NextRequest</function> -immediately before the failing call was made. -The request_code member is a protocol request -of the procedure that failed, as defined in -<filename class="headerfile"><X11/Xproto.h></filename>. -The following error codes can be returned by the functions described in this -chapter: -</para> -<!-- .br --> -<!-- .ne 13 --> -<indexterm><primary>Debugging</primary><secondary>error numbers</secondary></indexterm> -<indexterm><primary>Error</primary><secondary>codes</secondary></indexterm> -<!-- .\".CP T 3 --> -<!-- .\"Error Codes --> -<indexterm significance="preferred"><primary>BadAccess</primary></indexterm> -<indexterm significance="preferred"><primary>BadAlloc</primary></indexterm> -<indexterm significance="preferred"><primary>BadAtom</primary></indexterm> -<indexterm significance="preferred"><primary>BadColor</primary></indexterm> -<indexterm significance="preferred"><primary>BadCursor</primary></indexterm> -<indexterm significance="preferred"><primary>BadDrawable</primary></indexterm> -<indexterm significance="preferred"><primary>BadFont</primary></indexterm> -<indexterm significance="preferred"><primary>BadGC</primary></indexterm> -<indexterm significance="preferred"><primary>BadIDChoice</primary></indexterm> -<informaltable frame='none'> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'>Error Code</entry> - <entry align='left'>Description</entry> - </row> - </thead> - <tbody> - <row> - <entry><errorname id='BadAccess'>BadAccess</errorname></entry> - <entry> - <para>A client attempts to grab a key/button combination already grabbed - by another client.</para> - <para>A client attempts to free a colormap entry that it had not already allocated - or to free an entry in a colormap that was created with all entries writable.</para> - <para>A client attempts to store into a read-only or unallocated colormap entry.</para> - <para>A client attempts to modify the access control list from other than the local - (or otherwise authorized) host.</para> - <para>A client attempts to select an event type that another client - has already selected.</para> - </entry> - </row> - <row> - <entry><errorname id='BadAlloc'>BadAlloc</errorname></entry> - <entry>The server fails to allocate the requested resource. - Note that the explicit listing of - <errorname>BadAlloc</errorname> - errors in requests only covers allocation errors at a very coarse level - and is not intended to (nor can it in practice hope to) cover all cases of - a server running out of allocation space in the middle of service. - The semantics when a server runs out of allocation space are left unspecified, - but a server may generate a - <errorname>BadAlloc</errorname> - error on any request for this reason, - and clients should be prepared to receive such errors and handle or discard - them.</entry> - </row> - <row> - <entry><errorname id='BadAtom'>BadAtom</errorname></entry> - <entry>A value for an atom argument does not name a defined atom.</entry> - </row> - <row> - <entry><errorname id='BadColor'>BadColor</errorname></entry> - <entry>A value for a colormap argument does not name a defined colormap.</entry> - </row> - <row> - <entry><errorname id='BadCursor'>BadCursor</errorname></entry> - <entry>A value for a cursor argument does not name a defined cursor.</entry> - </row> - <row> - <entry><errorname id='BadDrawable'>BadDrawable</errorname></entry> - <entry>A value for a drawable argument does not name a defined window or pixmap.</entry> - </row> - <row> - <entry><errorname id='BadFont'>BadFont</errorname></entry> - <entry>A value for a font argument does not name a defined font (or, in some cases, - <type>GContext</type>).</entry> - </row> - <row> - <entry><errorname id='BadGC'>BadGC</errorname></entry> - <entry>A value for a - <type>GContext</type> - argument does not name a defined - <type>GContext</type>.</entry> - </row> - <row> - <entry><errorname id='BadIDChoice'>BadIDChoice</errorname></entry> - <entry>The value chosen for a resource identifier either is not included in the - range assigned to the client or is already in use. - Under normal circumstances, - this cannot occur and should be considered a server or Xlib error.</entry> - </row> - <row> - <entry><errorname id='BadImplementation'>BadImplementation</errorname></entry> - <entry>The server does not implement some aspect of the request. - A server that generates this error for a core request is deficient. - As such, this error is not listed for any of the requests, - but clients should be prepared to receive such errors - and handle or discard them.</entry> - </row> - <row> - <entry><errorname id='BadLength'>BadLength</errorname></entry> - <entry><para>The length of a request is shorter or longer than that required to - contain the arguments. - This is an internal Xlib or server error.</para> - <para>The length of a request exceeds the maximum length accepted by the server.</para> - </entry> - </row> - <row> - <entry><errorname id='BadMatch'>BadMatch</errorname></entry> - <entry><para>In a graphics request, - the root and depth of the graphics context do not match those of the drawable.</para> - <para>An <symbol>InputOnly</symbol> window is used as a drawable.</para> - <para>Some argument or pair of arguments has the correct type and range, - but it fails to match in some other way required by the request.</para> - <para>An <symbol>InputOnly</symbol> - window lacks this attribute.</para> - </entry> - </row> - <row> - <entry><errorname id='BadName'>BadName</errorname></entry> - <entry>A font or color of the specified name does not exist.</entry> - </row> - <row> - <entry><errorname id='BadPixmap'>BadPixmap</errorname></entry> - <entry>A value for a pixmap argument does not name a defined pixmap.</entry> - </row> - <row> - <entry><errorname id='BadRequest'>BadRequest</errorname></entry> - <entry>The major or minor opcode does not specify a valid request. - This usually is an Xlib or server error.</entry> - </row> - <row> - <entry><errorname id='BadValue'>BadValue</errorname></entry> - <entry>Some numeric value falls outside of the range of values accepted - by the request. - Unless a specific range is specified for an argument, - the full range defined by the argument's type is accepted. - Any argument defined as a set of alternatives typically can generate - this error (due to the encoding).</entry> - </row> - <row> - <entry><errorname id='BadWindow'>BadWindow</errorname></entry> - <entry>A value for a window argument does not name a defined window.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<indexterm significance="preferred"><primary>BadImplementation</primary></indexterm> -<indexterm significance="preferred"><primary>BadLength</primary></indexterm> -<indexterm significance="preferred"><primary>BadMatch</primary></indexterm> -<indexterm significance="preferred"><primary>BadName</primary></indexterm> -<indexterm significance="preferred"><primary>BadPixmap</primary></indexterm> -<indexterm significance="preferred"><primary>BadRequest</primary></indexterm> -<indexterm significance="preferred"><primary>BadValue</primary></indexterm> -<indexterm significance="preferred"><primary>BadWindow</primary></indexterm> -<!-- .NT Note --> - -<note> -<para> -The -<errorname>BadAtom</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadCursor</errorname>, -<errorname>BadDrawable</errorname>, -<errorname>BadFont</errorname>, -<errorname>BadGC</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadWindow</errorname> -errors are also used when the argument type is extended by a set of -fixed alternatives. -</para> -</note> - -<!-- .NE --> -<!-- .sp --> -<para> -<!-- .LP --> -To obtain textual descriptions of the specified error code, use -<function>XGetErrorText</function>. -</para> -<indexterm significance="preferred"><primary>XGetErrorText</primary></indexterm> -<indexterm><primary>Debugging</primary><secondary>error message strings</secondary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeterrortext'> -<funcprototype> - <funcdef><function>XGetErrorText</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> code</parameter></paramdef> - <paramdef>char<parameter> *buffer_return</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>code</emphasis> - </term> - <listitem> - <para> -Specifies the error code for which you want to obtain a description. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer_return</emphasis> - </term> - <listitem> - <para> -Returns the error description. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the size of the buffer. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetErrorText</function> -function copies a null-terminated string describing the specified error code -into the specified buffer. -The returned text is in the encoding of the current locale. -It is recommended that you use this function to obtain an error description -because extensions to Xlib may define their own error codes -and error strings. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain error messages from the error database, use -<function>XGetErrorDatabaseText</function>. -</para> -<indexterm significance="preferred"><primary>XGetErrorDatabaseText</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeterrordatabasetext'> -<funcprototype> - <funcdef><function>XGetErrorDatabaseText</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char*name,<parameter> *message</parameter></paramdef> - <paramdef>char<parameter> *default_string</parameter></paramdef> - <paramdef>char<parameter> *buffer_return</parameter></paramdef> - <paramdef>int<parameter> length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>message</emphasis> - </term> - <listitem> - <para> -Specifies the type of the error message. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>default_string</emphasis> - </term> - <listitem> - <para> -Specifies the default error message if none is found in the database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer_return</emphasis> - </term> - <listitem> - <para> -Returns the error description. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>length</emphasis> - </term> - <listitem> - <para> -Specifies the size of the buffer. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetErrorDatabaseText</function> -function returns a null-terminated message -(or the default message) from the error message -database. -Xlib uses this function internally to look up its error messages. -The text in the default_string argument is assumed -to be in the encoding of the current locale, -and the text stored in the buffer_return argument -is in the encoding of the current locale. -</para> -<para> -<!-- .LP --> -The name argument should generally be the name of your application. -The message argument should indicate which type of error message you want. -If the name and message are not in the Host Portable Character Encoding, -the result is implementation-dependent. -Xlib uses three predefined ``application names'' to report errors. -In these names, -uppercase and lowercase matter. -<variablelist> - <varlistentry> - <term> - XProtoError - </term> - <listitem> - <para> -The protocol error number is used as a string for the message argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - XlibMessage - </term> - <listitem> - <para> -These are the message strings that are used internally by the library. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - XRequest - </term> - <listitem> - <para> -For a core protocol request, -the major request protocol number is used for the message argument. -For an extension request, -the extension name (as given by -<function>InitExtension</function>) -followed by a period (.) and the minor request protocol number -is used for the message argument. -If no string is found in the error database, -the default_string is returned to the buffer argument. - </para> - </listitem> - </varlistentry> -</variablelist> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To report an error to the user when the requested display does not exist, use -<function>XDisplayName</function>. -</para> -<indexterm significance="preferred"><primary>XDisplayName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisplayname'> -<funcprototype> - <funcdef>char *<function>XDisplayName</function></funcdef> - <paramdef>char<parameter> *string</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDisplayName</function> -function returns the name of the display that -<function>XOpenDisplay</function> -would attempt to use. -If a NULL string is specified, -<function>XDisplayName</function> -looks in the environment for the display and returns the display name that -<function>XOpenDisplay</function> -would attempt to use. -This makes it easier to report to the user precisely which display the -program attempted to open when the initial connection attempt failed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To handle fatal I/O errors, use -<function>XSetIOErrorHandler</function>. -</para> -<indexterm significance="preferred"><primary>XSetIOErrorHandler</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetioerrorhandler'> -<funcprototype> - <funcdef><type>int</type></funcdef> - <paramdef>int(*handler)(Display<parameter> *)</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>handler</emphasis> - </term> - <listitem> - <para> -Specifies the program's supplied error handler. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetIOErrorHandler</function> -sets the fatal I/O error handler. -Xlib calls the program's supplied error handler if any sort of system call -error occurs (for example, the connection to the server was lost). -This is assumed to be a fatal condition, -and the called routine should not return. -If the I/O error handler does return, -the client process exits. -</para> -<para> -<!-- .LP --> -Note that the previous error handler is returned. -<!-- .bp --> - -</para> -</sect2> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="event_handling_functions">
+<title>Event Handling Functions</title>
+
+<para>
+This chapter discusses the Xlib functions you can use to:
+</para>
+<itemizedlist>
+ <listitem><para>Select events</para></listitem>
+ <listitem><para>Handle the output buffer and the event queue</para></listitem>
+ <listitem><para>Select events from the event queue</para></listitem>
+ <listitem><para>Send and get events</para></listitem>
+ <listitem><para>Handle protocol errors</para></listitem>
+</itemizedlist>
+<note><para>
+Some toolkits use their own event-handling functions and do not allow you to
+interchange these event-handling functions with those in Xlib. For further
+information, see the documentation supplied with the toolkit.
+</para></note>
+
+<para>
+Most applications simply are event loops: they wait for an event, decide what to do with it,
+execute some amount of code that results in changes to the display, and then wait for the next
+event.
+</para>
+
+<sect1 id="Selecting_Events">
+<title>Selecting Events</title>
+<!-- .XS -->
+<!-- (SN Selecting Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+There are two ways to select the events you want reported to your client
+application.
+One way is to set the event_mask member of the
+<structname>XSetWindowAttributes</structname>
+structure when you call
+<function>XCreateWindow</function>
+and
+<function>XChangeWindowAttributes</function>.
+Another way is to use
+<function>XSelectInput</function>.
+</para>
+<indexterm significance="preferred"><primary>XSelectInput</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xselectinput'>
+<funcprototype>
+ <funcdef><function>XSelectInput</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose events you are interested in -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSelectInput</function>
+function requests that the X server report the events associated with the
+specified event mask.
+Initially, X will not report any of these events.
+Events are reported relative to a window.
+If a window is not interested in a device event, it usually propagates to
+the closest ancestor that is interested,
+unless the do_not_propagate mask prohibits it.
+<indexterm><primary>Event</primary><secondary>propagation</secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+Setting the event-mask attribute of a window overrides any previous call
+for the same window but not for other clients.
+Multiple clients can select for the same events on the same window
+with the following restrictions:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Multiple clients can select events on the same window because their event masks
+are disjoint.
+When the X server generates an event, it reports it
+to all interested clients.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Only one client at a time can select
+<symbol>CirculateRequest</symbol>,
+<symbol>ConfigureRequest</symbol>,
+or
+<symbol>MapRequest</symbol>
+events, which are associated with
+the event mask
+<symbol>SubstructureRedirectMask</symbol>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Only one client at a time can select
+a
+<symbol>ResizeRequest</symbol>
+event, which is associated with
+the event mask
+<symbol>ResizeRedirectMask</symbol>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Only one client at a time can select a
+<symbol>ButtonPress</symbol>
+event, which is associated with
+the event mask
+<symbol>ButtonPressMask</symbol>.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The server reports the event to all interested clients.
+</para>
+<para>
+<!-- .LP -->
+<function>XSelectInput</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Handling_the_Output_Buffer">
+<title>Handling the Output Buffer</title>
+<!-- .XS -->
+<!-- (SN Handling the Output Buffer -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The output buffer is an area used by Xlib to store requests.
+The functions described in this section flush the output buffer
+if the function would block or not return an event.
+That is, all requests residing in the output buffer that
+have not yet been sent are transmitted to the X server.
+These functions differ in the additional tasks they might perform.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To flush the output buffer, use
+<function>XFlush</function>.
+</para>
+<indexterm significance="preferred"><primary>XFlush</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xflush'>
+<funcprototype>
+ <funcdef><function>XFlush</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFlush</function>
+function
+flushes the output buffer.
+Most client applications need not use this function because the output
+buffer is automatically flushed as needed by calls to
+<function>XPending</function>,
+<function>XNextEvent</function>,
+and
+<function>XWindowEvent</function>.
+<indexterm><primary>XPending</primary></indexterm>
+<indexterm><primary>XNextEvent</primary></indexterm>
+<indexterm><primary>XWindowEvent</primary></indexterm>
+Events generated by the server may be enqueued into the library's event queue.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To flush the output buffer and then wait until all requests have been processed,
+use
+<function>XSync</function>.
+</para>
+<indexterm significance="preferred"><primary>XSync</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsync'>
+<funcprototype>
+ <funcdef><function>XSync</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Bool<parameter> discard</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>discard</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether
+<function>XSync</function>
+discards all events on the event queue.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSync</function>
+function
+flushes the output buffer and then waits until all requests have been received
+and processed by the X server.
+Any errors generated must be handled by the error handler.
+For each protocol error received by Xlib,
+<function>XSync</function>
+calls the client application's error handling routine
+(see <link linkend="Using_the_Default_Error_Handlers">section 11.8.2</link>).
+Any events generated by the server are enqueued into the library's
+event queue.
+</para>
+<para>
+<!-- .LP -->
+Finally, if you passed
+<symbol>False</symbol>,
+<function>XSync</function>
+does not discard the events in the queue.
+If you passed
+<symbol>True</symbol>,
+<function>XSync</function>
+discards all events in the queue,
+including those events that were on the queue before
+<function>XSync</function>
+was called.
+Client applications seldom need to call
+<function>XSync</function>.
+</para>
+</sect1>
+<sect1 id="Event_Queue_Management">
+<title>Event Queue Management</title>
+<!-- .XS -->
+<!-- (SN Event Queue Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib maintains an event queue.
+However, the operating system also may be buffering data
+in its network connection that is not yet read into the event queue.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To check the number of events in the event queue, use
+<function>XEventsQueued</function>.
+</para>
+<indexterm significance="preferred"><primary>XEventsQueued</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xeventsqueued'>
+<funcprototype>
+ <funcdef>int <function>XEventsQueued</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mode.
+You can pass
+<symbol>QueuedAlready</symbol>,
+<symbol>QueuedAfterFlush</symbol>,
+or
+<symbol>QueuedAfterReading</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If mode is
+<symbol>QueuedAlready</symbol>,
+<function>XEventsQueued</function>
+returns the number of events
+already in the event queue (and never performs a system call).
+If mode is
+<symbol>QueuedAfterFlush</symbol>,
+<function>XEventsQueued</function>
+returns the number of events already in the queue if the number is nonzero.
+If there are no events in the queue,
+<function>XEventsQueued</function>
+flushes the output buffer,
+attempts to read more events out of the application's connection,
+and returns the number read.
+If mode is
+<symbol>QueuedAfterReading</symbol>,
+<function>XEventsQueued</function>
+returns the number of events already in the queue if the number is nonzero.
+If there are no events in the queue,
+<function>XEventsQueued</function>
+attempts to read more events out of the application's connection
+without flushing the output buffer and returns the number read.
+</para>
+<para>
+<!-- .LP -->
+<function>XEventsQueued</function>
+always returns immediately without I/O if there are events already in the
+queue.
+<function>XEventsQueued</function>
+with mode
+<symbol>QueuedAfterFlush</symbol>
+is identical in behavior to
+<function>XPending</function>.
+<function>XEventsQueued</function>
+with mode
+<symbol>QueuedAlready</symbol>
+is identical to the
+<function>XQLength</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return the number of events that are pending, use
+<function>XPending</function>.
+</para>
+<indexterm significance="preferred"><primary>XPending</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpending'>
+<funcprototype>
+ <funcdef>int <function>XPending</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPending</function>
+function returns the number of events that have been received from the
+X server but have not been removed from the event queue.
+<function>XPending</function>
+is identical to
+<function>XEventsQueued</function>
+with the mode
+<symbol>QueuedAfterFlush</symbol>
+specified.
+</para>
+</sect1>
+<sect1 id="Manipulating_the_Event_Queue">
+<title>Manipulating the Event Queue</title>
+<!-- .XS -->
+<!-- (SN Manipulating the Event Queue -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that let you manipulate the event queue.
+This section discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Obtain events, in order, and remove them from the queue
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Peek at events in the queue without removing them
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtain events that match the event mask or the arbitrary
+predicate procedures that you provide
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Returning_the_Next_Event">
+<title>Returning the Next Event</title>
+<!-- .XS -->
+<!-- (SN Returning the Next Event -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To get the next event and remove it from the queue, use
+<function>XNextEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XNextEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xnextevent'>
+<funcprototype>
+ <funcdef><function>XNextEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the next event in the queue.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XNextEvent</function>
+function copies the first event from the event queue into the specified
+<structname>XEvent</structname>
+structure and then removes it from the queue.
+If the event queue is empty,
+<function>XNextEvent</function>
+flushes the output buffer and blocks until an event is received.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To peek at the event queue, use
+<function>XPeekEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XPeekEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpeekevent'>
+<funcprototype>
+ <funcdef><function>XPeekEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a copy of the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPeekEvent</function>
+function returns the first event from the event queue,
+but it does not remove the event from the queue.
+If the queue is empty,
+<function>XPeekEvent</function>
+flushes the output buffer and blocks until an event is received.
+It then copies the event into the client-supplied
+<structname>XEvent</structname>
+structure without removing it from the event queue.
+</para>
+</sect2>
+<sect2 id="Selecting_Events_Using_a_Predicate_Procedure">
+<title>Selecting Events Using a Predicate Procedure</title>
+<!-- .XS -->
+<!-- (SN Selecting Events Using a Predicate Procedure -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Each of the functions discussed in this section requires you to
+pass a predicate procedure that determines if an event matches
+what you want.
+Your predicate procedure must decide if the event is useful
+without calling any Xlib functions.
+If the predicate directly or indirectly causes the state of the event queue
+to change, the result is not defined.
+If Xlib has been initialized for threads, the predicate is called with
+the display locked and the result of a call by the predicate to any
+Xlib function that locks the display is not defined unless the caller
+has first called
+<function>XLockDisplay</function>.
+</para>
+<para>
+<!-- .LP -->
+The predicate procedure and its associated arguments are:
+</para>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef><type>Bool</type></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event</parameter></paramdef>
+ <paramdef>XPointer<parameter> arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XEvent</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the argument passed in from the
+<function>XIfEvent</function>,
+<function>XCheckIfEvent</function>,
+or
+<function>XPeekIfEvent</function>
+function.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The predicate procedure is called once for each
+event in the queue until it finds a match.
+After finding a match, the predicate procedure must return
+<symbol>True</symbol>.
+If it did not find a match, it must return
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To check the event queue for a matching event
+and, if found, remove the event from the queue, use
+<function>XIfEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XIfEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xifevent'>
+<funcprototype>
+ <funcdef><function>XIfEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+ <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure that is to be called to determine
+if the next event in the queue matches what you want.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the user-supplied argument that will be passed to the predicate procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XIfEvent</function>
+function completes only when the specified predicate
+procedure returns
+<symbol>True</symbol>
+for an event,
+which indicates an event in the queue matches.
+<function>XIfEvent</function>
+flushes the output buffer if it blocks waiting for additional events.
+<function>XIfEvent</function>
+removes the matching event from the queue
+and copies the structure into the client-supplied
+<structname>XEvent</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To check the event queue for a matching event without blocking, use
+<function>XCheckIfEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XCheckIfEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcheckifevent'>
+<funcprototype>
+ <funcdef>Bool <function>XCheckIfEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+ <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a copy of the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure that is to be called to determine
+if the next event in the queue matches what you want.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the user-supplied argument that will be passed to the predicate procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When the predicate procedure finds a match,
+<function>XCheckIfEvent</function>
+copies the matched event into the client-supplied
+<structname>XEvent</structname>
+structure and returns
+<symbol>True</symbol>.
+(This event is removed from the queue.)
+If the predicate procedure finds no match,
+<function>XCheckIfEvent</function>
+returns
+<symbol>False</symbol>,
+and the output buffer will have been flushed.
+All earlier events stored in the queue are not discarded.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To check the event queue for a matching event
+without removing the event from the queue, use
+<function>XPeekIfEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XPeekIfEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpeekifevent'>
+<funcprototype>
+ <funcdef><function>XPeekIfEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+ <paramdef>Bool<parameter> (*predicate)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a copy of the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>predicate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure that is to be called to determine
+if the next event in the queue matches what you want.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the user-supplied argument that will be passed to the predicate procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPeekIfEvent</function>
+function returns only when the specified predicate
+procedure returns
+<symbol>True</symbol>
+for an event.
+After the predicate procedure finds a match,
+<function>XPeekIfEvent</function>
+copies the matched event into the client-supplied
+<structname>XEvent</structname>
+structure without removing the event from the queue.
+<function>XPeekIfEvent</function>
+flushes the output buffer if it blocks waiting for additional events.
+</para>
+</sect2>
+<sect2 id="Selecting_Events_Using_a_Window_or_Event_Mask">
+<title>Selecting Events Using a Window or Event Mask</title>
+<!-- .XS -->
+<!-- (SN Selecting Events Using a Window or Event Mask -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The functions discussed in this section let you select events by window
+or event types, allowing you to process events out of order.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove the next event that matches both a window and an event mask, use
+<function>XWindowEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XWindowEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwindowevent'>
+<funcprototype>
+ <funcdef><function>XWindowEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose events you are interested in -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XWindowEvent</function>
+function searches the event queue for an event that matches both the specified
+window and event mask.
+When it finds a match,
+<function>XWindowEvent</function>
+removes that event from the queue and copies it into the specified
+<structname>XEvent</structname>
+structure.
+The other events stored in the queue are not discarded.
+If a matching event is not in the queue,
+<function>XWindowEvent</function>
+flushes the output buffer and blocks until one is received.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove the next event that matches both a window and an event mask (if any),
+use
+<function>XCheckWindowEvent</function>.
+<indexterm><primary>XCheckWindowEvent</primary></indexterm>
+This function is similar to
+<function>XWindowEvent</function>
+except that it never blocks and it returns a
+<type>Bool</type>
+indicating if the event was returned.
+</para>
+<indexterm significance="preferred"><primary>XCheckWindowEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcheckwindowevent'>
+<funcprototype>
+ <funcdef>Bool <function>XCheckWindowEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Wi whose events you are interested in -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCheckWindowEvent</function>
+function searches the event queue and then the events available
+on the server connection for the first event that matches the specified window
+and event mask.
+If it finds a match,
+<function>XCheckWindowEvent</function>
+removes that event, copies it into the specified
+<structname>XEvent</structname>
+structure, and returns
+<symbol>True</symbol>.
+The other events stored in the queue are not discarded.
+If the event you requested is not available,
+<function>XCheckWindowEvent</function>
+returns
+<symbol>False</symbol>,
+and the output buffer will have been flushed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To remove the next event that matches an event mask, use
+<function>XMaskEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XMaskEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmaskevent'>
+<funcprototype>
+ <funcdef><function>XMaskEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMaskEvent</function>
+function searches the event queue for the events associated with the
+specified mask.
+When it finds a match,
+<function>XMaskEvent</function>
+removes that event and copies it into the specified
+<structname>XEvent</structname>
+structure.
+The other events stored in the queue are not discarded.
+If the event you requested is not in the queue,
+<function>XMaskEvent</function>
+flushes the output buffer and blocks until one is received.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return and remove the next event that matches an event mask (if any), use
+<function>XCheckMaskEvent</function>.
+This function is similar to
+<function>XMaskEvent</function>
+except that it never blocks and it returns a
+<type>Bool</type>
+indicating if the event was returned.
+</para>
+<indexterm significance="preferred"><primary>XCheckMaskEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcheckmaskevent'>
+<funcprototype>
+ <funcdef>Bool <function>XCheckMaskEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCheckMaskEvent</function>
+function searches the event queue and then any events available on the
+server connection for the first event that matches the specified mask.
+If it finds a match,
+<function>XCheckMaskEvent</function>
+removes that event, copies it into the specified
+<structname>XEvent</structname>
+structure, and returns
+<symbol>True</symbol>.
+The other events stored in the queue are not discarded.
+If the event you requested is not available,
+<function>XCheckMaskEvent</function>
+returns
+<symbol>False</symbol>,
+and the output buffer will have been flushed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return and remove the next event in the queue that matches an event type, use
+<function>XCheckTypedEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XCheckTypedEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchecktypedevent'>
+<funcprototype>
+ <funcdef>Bool <function>XCheckTypedEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> event_type</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event type to be compared.
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCheckTypedEvent</function>
+function searches the event queue and then any events available
+on the server connection for the first event that matches the specified type.
+If it finds a match,
+<function>XCheckTypedEvent</function>
+removes that event, copies it into the specified
+<structname>XEvent</structname>
+structure, and returns
+<symbol>True</symbol>.
+The other events in the queue are not discarded.
+If the event is not available,
+<function>XCheckTypedEvent</function>
+returns
+<symbol>False</symbol>,
+and the output buffer will have been flushed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return and remove the next event in the queue that matches an event type
+and a window, use
+<function>XCheckTypedWindowEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XCheckTypedWindowEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchecktypedwindowevent'>
+<funcprototype>
+ <funcdef>Bool <function>XCheckTypedWindowEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> event_type</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event type to be compared.
+
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched event's associated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCheckTypedWindowEvent</function>
+function searches the event queue and then any events available
+on the server connection for the first event that matches the specified
+type and window.
+If it finds a match,
+<function>XCheckTypedWindowEvent</function>
+removes the event from the queue, copies it into the specified
+<structname>XEvent</structname>
+structure, and returns
+<symbol>True</symbol>.
+The other events in the queue are not discarded.
+If the event is not available,
+<function>XCheckTypedWindowEvent</function>
+returns
+<symbol>False</symbol>,
+and the output buffer will have been flushed.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Putting_an_Event_Back_into_the_Queue">
+<title>Putting an Event Back into the Queue</title>
+<!-- .XS -->
+<!-- (SN Putting an Event Back into the Queue -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To push an event back into the event queue, use
+<function>XPutBackEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XPutBackEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xputbackevent'>
+<funcprototype>
+ <funcdef><function>XPutBackEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPutBackEvent</function>
+function pushes an event back onto the head of the display's event queue
+by copying the event into the queue.
+This can be useful if you read an event and then decide that you
+would rather deal with it later.
+There is no limit to the number of times in succession that you can call
+<function>XPutBackEvent</function>.
+</para>
+</sect1>
+<sect1 id="Sending_Events_to_Other_Applications">
+<title>Sending Events to Other Applications</title>
+<!-- .XS -->
+<!-- (SN Sending Events to Other Applications -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To send an event to a specified window, use
+<function>XSendEvent</function>.
+<indexterm><primary>XSendEvent</primary></indexterm>
+This function is often used in selection processing.
+For example, the owner of a selection should use
+<function>XSendEvent</function>
+to send a
+<symbol>SelectionNotify</symbol>
+event to a requestor when a selection has been converted
+and stored as a property.
+</para>
+<indexterm significance="preferred"><primary>XSendEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsendevent'>
+<funcprototype>
+ <funcdef>Status <function>XSendEvent</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Bool<parameter> propagate</parameter></paramdef>
+ <paramdef>long<parameter> event_mask</parameter></paramdef>
+ <paramdef>XEvent<parameter> *event_send</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window the event is to be sent to, or
+<symbol>PointerWindow</symbol>,
+or
+<symbol>InputFocus</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>propagate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_send</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event that is to be sent.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSendEvent</function>
+function identifies the destination window,
+determines which clients should receive the specified events,
+and ignores any active grabs.
+This function requires you to pass an event mask.
+For a discussion of the valid event mask names,
+see <link linkend="Event_Masks">section 10.3</link>.
+This function uses the w argument to identify the destination window as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If w is
+<symbol>PointerWindow</symbol>,
+the destination window is the window that contains the pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If w is
+<symbol>InputFocus</symbol>
+and if the focus window contains the pointer,
+the destination window is the window that contains the pointer;
+otherwise, the destination window is the focus window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+To determine which clients should receive the specified events,
+<function>XSendEvent</function>
+uses the propagate argument as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If event_mask is the empty set,
+the event is sent to the client that created the destination window.
+If that client no longer exists,
+no event is sent.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If propagate is
+<symbol>False</symbol>,
+the event is sent to every client selecting on destination any of the event
+types in the event_mask argument.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If propagate is
+<symbol>True</symbol>
+and no clients have selected on destination any of
+the event types in event-mask, the destination is replaced with the
+closest ancestor of destination for which some client has selected a
+type in event-mask and for which no intervening window has that type in its
+do-not-propagate-mask.
+If no such window exists or if the window is
+an ancestor of the focus window and
+<symbol>InputFocus</symbol>
+was originally specified
+as the destination, the event is not sent to any clients.
+Otherwise, the event is reported to every client selecting on the final
+destination any of the types specified in event_mask.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The event in the
+<structname>XEvent</structname>
+structure must be one of the core events or one of the events
+defined by an extension (or a
+<errorname>BadValue</errorname>
+error results) so that the X server can correctly byte-swap
+the contents as necessary.
+The contents of the event are
+otherwise unaltered and unchecked by the X server except to force send_event to
+<symbol>True</symbol>
+in the forwarded event and to set the serial number in the event correctly;
+therefore these fields
+and the display field are ignored by
+<function>XSendEvent</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XSendEvent</function>
+returns zero if the conversion to wire protocol format failed
+and returns nonzero otherwise.
+</para>
+<para>
+<!-- .LP -->
+<function>XSendEvent</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Getting_Pointer_Motion_History">
+<title>Getting Pointer Motion History</title>
+<!-- .XS -->
+<!-- (SN Getting Pointer Motion History -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some X server implementations will maintain a more complete
+history of pointer motion than is reported by event notification.
+The pointer position at each pointer hardware interrupt may be
+stored in a buffer for later retrieval.
+This buffer is called the motion history buffer.
+For example, a few applications, such as paint programs,
+want to have a precise history of where the pointer
+traveled.
+However, this historical information is highly excessive for most applications.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To determine the approximate maximum number of elements in the motion buffer,
+use
+<function>XDisplayMotionBufferSize</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisplayMotionBufferSize</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisplaymotionbuffersize'>
+<funcprototype>
+ <funcdef>unsigned <type>long</type></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The server may retain the recent history of the pointer motion
+and do so to a finer granularity than is reported by
+<symbol>MotionNotify</symbol>
+events.
+The
+<function>XGetMotionEvents</function>
+function makes this history available.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the motion history for a specified window and time, use
+<function>XGetMotionEvents</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetMotionEvents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetmotionevents'>
+<funcprototype>
+ <funcdef>XTimeCoord *<function>XGetMotionEvents</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Timestart,<parameter> stop</parameter></paramdef>
+ <paramdef>int<parameter> *nevents_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>start</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>stop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the time interval in which the events are returned from the motion
+history buffer.
+You can pass a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nevents_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of events from the motion history buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetMotionEvents</function>
+function returns all events in the motion history buffer that fall between the
+specified start and stop times, inclusive, and that have coordinates
+that lie within the specified window (including its borders) at its present
+placement.
+If the server does not support motion history,
+if the start time is later than the stop time,
+or if the start time is in the future,
+no events are returned;
+<function>XGetMotionEvents</function>
+returns NULL.
+If the stop time is in the future, it is equivalent to specifying
+<symbol>CurrentTime</symbol>.
+The return type for this function is a structure defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XTimeCoord</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ Time time;
+ short x, y;
+} XTimeCoord;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The time member is set to the time, in milliseconds.
+The x and y members are set to the coordinates of the pointer and
+are reported relative to the origin
+of the specified window.
+To free the data returned from this call, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetMotionEvents</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Handling_Protocol_Errors">
+<title>Handling Protocol Errors</title>
+<!-- .XS -->
+<!-- (SN Handling Protocol Errors -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to enable or disable synchronization
+and to use the default error handlers.
+</para>
+<sect2 id="Enabling_or_Disabling_Synchronization">
+<title>Enabling or Disabling Synchronization</title>
+<!-- .XS -->
+<!-- (SN Enabling or Disabling Synchronization -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When debugging X applications,
+it often is very convenient to require Xlib to behave synchronously
+so that errors are reported as they occur.
+The following function lets you disable or enable synchronous behavior.
+Note that graphics may occur 30 or more times more slowly when
+synchronization is enabled.
+<indexterm><primary>_Xdebug</primary></indexterm>
+On <acronym>POSIX</acronym>-conformant systems,
+there is also a global variable
+<varname>_Xdebug</varname>
+that, if set to nonzero before starting a program under a debugger, will force
+synchronous library behavior.
+</para>
+<para>
+<!-- .LP -->
+After completing their work,
+all Xlib functions that generate protocol requests call what is known as
+an after function.
+<function>XSetAfterFunction</function>
+sets which function is to be called.
+</para>
+<indexterm significance="preferred"><primary>XSetAfterFunction</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetafterfunction'>
+<funcprototype>
+ <funcdef><type>int</type></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> (*procedure)()</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>procedure</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure to be called.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The specified procedure is called with only a display pointer.
+<function>XSetAfterFunction</function>
+returns the previous after function.
+</para>
+<para>
+<!-- .LP -->
+To enable or disable synchronization, use
+<function>XSynchronize</function>.
+</para>
+<indexterm><primary>Debugging</primary><secondary>synchronous mode</secondary></indexterm>
+<indexterm significance="preferred"><primary>XSynchronize</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsynchronize'>
+<funcprototype>
+ <funcdef><type>int</type></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Bool<parameter> onoff</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>onoff</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether to enable
+or disable synchronization.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSynchronize</function>
+function returns
+the previous after function.
+If onoff is
+<symbol>True</symbol>,
+<function>XSynchronize</function>
+turns on synchronous behavior.
+If onoff is
+<symbol>False</symbol>,
+<function>XSynchronize</function>
+turns off synchronous behavior.
+</para>
+</sect2>
+<sect2 id="Using_the_Default_Error_Handlers">
+<title>Using the Default Error Handlers</title>
+<!-- .XS -->
+<!-- (SN Using the Default Error Handlers -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Debugging</primary><secondary>error handlers</secondary></indexterm>
+<indexterm><primary>Error</primary><secondary>handlers</secondary></indexterm>
+There are two default error handlers in Xlib:
+one to handle typically fatal conditions (for example,
+the connection to a display server dying because a machine crashed)
+and one to handle protocol errors from the X server.
+These error handlers can be changed to user-supplied routines if you
+prefer your own error handling and can be changed as often as you like.
+If either function is passed a NULL pointer, it will
+reinvoke the default handler.
+The action of the default handlers is to print an explanatory
+message and exit.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the error handler, use
+<function>XSetErrorHandler</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetErrorHandler</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xseterrorhandler'>
+<funcprototype>
+ <funcdef>int *<function>XSetErrorHandler</function></funcdef>
+ <paramdef>int <parameter> *handler</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>handler</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the program's supplied error handler.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Xlib generally calls the program's
+supplied error handler whenever an error is received.
+It is not called on
+<errorname>BadName</errorname>
+errors from
+<systemitem>OpenFont</systemitem>,
+<systemitem>LookupColor</systemitem>,
+or
+<systemitem>AllocNamedColor</systemitem>
+protocol requests or on
+<errorname>BadFont</errorname>
+errors from a
+<systemitem>QueryFont</systemitem>
+protocol request.
+These errors generally are reflected back to the program through the
+procedural interface.
+Because this condition is not assumed to be fatal,
+it is acceptable for your error handler to return;
+the returned value is ignored.
+However, the error handler should not
+call any functions (directly or indirectly) on the display
+that will generate protocol requests or that will look for input events.
+The previous error handler is returned.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XErrorEvent</structname>
+structure contains:
+<indexterm><primary>Debugging</primary><secondary>error event</secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XErrorEvent</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int type;
+ Display *display; /* Display the event was read from */
+ unsigned long serial; /* serial number of failed request */
+ unsigned char error_code; /* error code of failed request */
+ unsigned char request_code; /* Major op-code of failed request */
+ unsigned char minor_code; /* Minor op-code of failed request */
+ XID resourceid; /* resource id */
+} XErrorEvent;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Serial Number</primary></indexterm>
+The serial member is the number of requests, starting from one,
+sent over the network connection since it was opened.
+It is the number that was the value of
+<function>NextRequest</function>
+immediately before the failing call was made.
+The request_code member is a protocol request
+of the procedure that failed, as defined in
+<filename class="headerfile"><X11/Xproto.h></filename>.
+The following error codes can be returned by the functions described in this
+chapter:
+</para>
+<!-- .br -->
+<!-- .ne 13 -->
+<indexterm><primary>Debugging</primary><secondary>error numbers</secondary></indexterm>
+<indexterm><primary>Error</primary><secondary>codes</secondary></indexterm>
+<!-- .\".CP T 3 -->
+<!-- .\"Error Codes -->
+<indexterm significance="preferred"><primary>BadAccess</primary></indexterm>
+<indexterm significance="preferred"><primary>BadAlloc</primary></indexterm>
+<indexterm significance="preferred"><primary>BadAtom</primary></indexterm>
+<indexterm significance="preferred"><primary>BadColor</primary></indexterm>
+<indexterm significance="preferred"><primary>BadCursor</primary></indexterm>
+<indexterm significance="preferred"><primary>BadDrawable</primary></indexterm>
+<indexterm significance="preferred"><primary>BadFont</primary></indexterm>
+<indexterm significance="preferred"><primary>BadGC</primary></indexterm>
+<indexterm significance="preferred"><primary>BadIDChoice</primary></indexterm>
+<informaltable frame='none'>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'>Error Code</entry>
+ <entry align='left'>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><errorname id='BadAccess'>BadAccess</errorname></entry>
+ <entry>
+ <para>A client attempts to grab a key/button combination already grabbed
+ by another client.</para>
+ <para>A client attempts to free a colormap entry that it had not already allocated
+ or to free an entry in a colormap that was created with all entries writable.</para>
+ <para>A client attempts to store into a read-only or unallocated colormap entry.</para>
+ <para>A client attempts to modify the access control list from other than the local
+ (or otherwise authorized) host.</para>
+ <para>A client attempts to select an event type that another client
+ has already selected.</para>
+ </entry>
+ </row>
+ <row>
+ <entry><errorname id='BadAlloc'>BadAlloc</errorname></entry>
+ <entry>The server fails to allocate the requested resource.
+ Note that the explicit listing of
+ <errorname>BadAlloc</errorname>
+ errors in requests only covers allocation errors at a very coarse level
+ and is not intended to (nor can it in practice hope to) cover all cases of
+ a server running out of allocation space in the middle of service.
+ The semantics when a server runs out of allocation space are left unspecified,
+ but a server may generate a
+ <errorname>BadAlloc</errorname>
+ error on any request for this reason,
+ and clients should be prepared to receive such errors and handle or discard
+ them.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadAtom'>BadAtom</errorname></entry>
+ <entry>A value for an atom argument does not name a defined atom.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadColor'>BadColor</errorname></entry>
+ <entry>A value for a colormap argument does not name a defined colormap.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadCursor'>BadCursor</errorname></entry>
+ <entry>A value for a cursor argument does not name a defined cursor.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadDrawable'>BadDrawable</errorname></entry>
+ <entry>A value for a drawable argument does not name a defined window or pixmap.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadFont'>BadFont</errorname></entry>
+ <entry>A value for a font argument does not name a defined font (or, in some cases,
+ <type>GContext</type>).</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadGC'>BadGC</errorname></entry>
+ <entry>A value for a
+ <type>GContext</type>
+ argument does not name a defined
+ <type>GContext</type>.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadIDChoice'>BadIDChoice</errorname></entry>
+ <entry>The value chosen for a resource identifier either is not included in the
+ range assigned to the client or is already in use.
+ Under normal circumstances,
+ this cannot occur and should be considered a server or Xlib error.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadImplementation'>BadImplementation</errorname></entry>
+ <entry>The server does not implement some aspect of the request.
+ A server that generates this error for a core request is deficient.
+ As such, this error is not listed for any of the requests,
+ but clients should be prepared to receive such errors
+ and handle or discard them.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadLength'>BadLength</errorname></entry>
+ <entry><para>The length of a request is shorter or longer than that required to
+ contain the arguments.
+ This is an internal Xlib or server error.</para>
+ <para>The length of a request exceeds the maximum length accepted by the server.</para>
+ </entry>
+ </row>
+ <row>
+ <entry><errorname id='BadMatch'>BadMatch</errorname></entry>
+ <entry><para>In a graphics request,
+ the root and depth of the graphics context do not match those of the drawable.</para>
+ <para>An <symbol>InputOnly</symbol> window is used as a drawable.</para>
+ <para>Some argument or pair of arguments has the correct type and range,
+ but it fails to match in some other way required by the request.</para>
+ <para>An <symbol>InputOnly</symbol>
+ window lacks this attribute.</para>
+ </entry>
+ </row>
+ <row>
+ <entry><errorname id='BadName'>BadName</errorname></entry>
+ <entry>A font or color of the specified name does not exist.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadPixmap'>BadPixmap</errorname></entry>
+ <entry>A value for a pixmap argument does not name a defined pixmap.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadRequest'>BadRequest</errorname></entry>
+ <entry>The major or minor opcode does not specify a valid request.
+ This usually is an Xlib or server error.</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadValue'>BadValue</errorname></entry>
+ <entry>Some numeric value falls outside of the range of values accepted
+ by the request.
+ Unless a specific range is specified for an argument,
+ the full range defined by the argument's type is accepted.
+ Any argument defined as a set of alternatives typically can generate
+ this error (due to the encoding).</entry>
+ </row>
+ <row>
+ <entry><errorname id='BadWindow'>BadWindow</errorname></entry>
+ <entry>A value for a window argument does not name a defined window.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<indexterm significance="preferred"><primary>BadImplementation</primary></indexterm>
+<indexterm significance="preferred"><primary>BadLength</primary></indexterm>
+<indexterm significance="preferred"><primary>BadMatch</primary></indexterm>
+<indexterm significance="preferred"><primary>BadName</primary></indexterm>
+<indexterm significance="preferred"><primary>BadPixmap</primary></indexterm>
+<indexterm significance="preferred"><primary>BadRequest</primary></indexterm>
+<indexterm significance="preferred"><primary>BadValue</primary></indexterm>
+<indexterm significance="preferred"><primary>BadWindow</primary></indexterm>
+<!-- .NT Note -->
+
+<note>
+<para>
+The
+<errorname>BadAtom</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadCursor</errorname>,
+<errorname>BadDrawable</errorname>,
+<errorname>BadFont</errorname>,
+<errorname>BadGC</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors are also used when the argument type is extended by a set of
+fixed alternatives.
+</para>
+</note>
+
+<!-- .NE -->
+<!-- .sp -->
+<para>
+<!-- .LP -->
+To obtain textual descriptions of the specified error code, use
+<function>XGetErrorText</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetErrorText</primary></indexterm>
+<indexterm><primary>Debugging</primary><secondary>error message strings</secondary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeterrortext'>
+<funcprototype>
+ <funcdef><function>XGetErrorText</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> code</parameter></paramdef>
+ <paramdef>char<parameter> *buffer_return</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>code</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the error code for which you want to obtain a description.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the error description.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetErrorText</function>
+function copies a null-terminated string describing the specified error code
+into the specified buffer.
+The returned text is in the encoding of the current locale.
+It is recommended that you use this function to obtain an error description
+because extensions to Xlib may define their own error codes
+and error strings.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain error messages from the error database, use
+<function>XGetErrorDatabaseText</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetErrorDatabaseText</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeterrordatabasetext'>
+<funcprototype>
+ <funcdef><function>XGetErrorDatabaseText</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char*name,<parameter> *message</parameter></paramdef>
+ <paramdef>char<parameter> *default_string</parameter></paramdef>
+ <paramdef>char<parameter> *buffer_return</parameter></paramdef>
+ <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>message</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the type of the error message.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>default_string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the default error message if none is found in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the error description.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetErrorDatabaseText</function>
+function returns a null-terminated message
+(or the default message) from the error message
+database.
+Xlib uses this function internally to look up its error messages.
+The text in the default_string argument is assumed
+to be in the encoding of the current locale,
+and the text stored in the buffer_return argument
+is in the encoding of the current locale.
+</para>
+<para>
+<!-- .LP -->
+The name argument should generally be the name of your application.
+The message argument should indicate which type of error message you want.
+If the name and message are not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Xlib uses three predefined ``application names'' to report errors.
+In these names,
+uppercase and lowercase matter.
+<variablelist>
+ <varlistentry>
+ <term>
+ XProtoError
+ </term>
+ <listitem>
+ <para>
+The protocol error number is used as a string for the message argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ XlibMessage
+ </term>
+ <listitem>
+ <para>
+These are the message strings that are used internally by the library.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ XRequest
+ </term>
+ <listitem>
+ <para>
+For a core protocol request,
+the major request protocol number is used for the message argument.
+For an extension request,
+the extension name (as given by
+<function>InitExtension</function>)
+followed by a period (.) and the minor request protocol number
+is used for the message argument.
+If no string is found in the error database,
+the default_string is returned to the buffer argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To report an error to the user when the requested display does not exist, use
+<function>XDisplayName</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisplayName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisplayname'>
+<funcprototype>
+ <funcdef>char *<function>XDisplayName</function></funcdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDisplayName</function>
+function returns the name of the display that
+<function>XOpenDisplay</function>
+would attempt to use.
+If a NULL string is specified,
+<function>XDisplayName</function>
+looks in the environment for the display and returns the display name that
+<function>XOpenDisplay</function>
+would attempt to use.
+This makes it easier to report to the user precisely which display the
+program attempted to open when the initial connection attempt failed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To handle fatal I/O errors, use
+<function>XSetIOErrorHandler</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetIOErrorHandler</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetioerrorhandler'>
+<funcprototype>
+ <funcdef><type>int</type></funcdef>
+ <paramdef>int(*handler)(Display<parameter> *)</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>handler</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the program's supplied error handler.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetIOErrorHandler</function>
+sets the fatal I/O error handler.
+Xlib calls the program's supplied error handler if any sort of system call
+error occurs (for example, the connection to the server was lost).
+This is assumed to be a fatal condition,
+and the called routine should not return.
+If the I/O error handler does return,
+the client process exits.
+</para>
+<para>
+<!-- .LP -->
+Note that the previous error handler is returned.
+<!-- .bp -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH12.xml b/libX11/specs/libX11/CH12.xml index 8334e9eb9..687f575cb 100644 --- a/libX11/specs/libX11/CH12.xml +++ b/libX11/specs/libX11/CH12.xml @@ -1,3937 +1,3937 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="input_device_functions"> -<title>Input Device Functions</title> - -<para> -You can use the Xlib input device functions to: -</para> - -<itemizedlist> - <listitem><para>Grab the pointer and individual buttons on the pointer</para></listitem> - <listitem><para>Grab the keyboard and individual keys on the keyboard</para></listitem> - <listitem><para>Resume event processing</para></listitem> - <listitem><para>Move the pointer</para></listitem> - <listitem><para>Set the input focus</para></listitem> - <listitem><para>Manipulate the keyboard and pointer settings</para></listitem> - <listitem><para>Manipulate the keyboard encoding</para></listitem> -</itemizedlist> - -<sect1 id="Pointer_Grabbing_"> -<title>Pointer Grabbing </title> -<!-- .XS --> -<!-- (SN Pointer Grabbing --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to control input from the pointer, -which usually is a mouse. -Usually, as soon as keyboard and mouse events occur, -the X server delivers them to the appropriate client, -which is determined by the window and input focus. -The X server provides sufficient control over event delivery to -allow window managers to support mouse ahead and various other -styles of user interface. -Many of these user interfaces depend on synchronous delivery of events. -The delivery of pointer and keyboard events can be controlled -independently. -</para> -<para> -<!-- .LP --> -When mouse buttons or keyboard keys are grabbed, events -will be sent to the grabbing client rather than the normal -client who would have received the event. -If the keyboard or pointer is in asynchronous mode, -further mouse and keyboard events will continue to be processed. -If the keyboard or pointer is in synchronous mode, no -further events are processed until the grabbing client -allows them (see -<function>XAllowEvents</function>). -The keyboard or pointer is considered frozen during this -interval. -The event that triggered the grab can also be replayed. -</para> -<para> -<!-- .LP --> -Note that the logical state of a device (as seen by client applications) -may lag the physical state if device event processing is frozen. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>Active grab</primary></indexterm> -There are two kinds of grabs: -active and passive. -An active grab occurs when a single client grabs the keyboard and/or pointer -explicitly (see -<function>XGrabPointer</function> -and -<function>XGrabKeyboard</function>). -<indexterm><primary>Passive grab</primary></indexterm> -A passive grab occurs when clients grab a particular keyboard key -or pointer button in a window, -and the grab will activate when the key or button is actually pressed. -Passive grabs are convenient for implementing reliable pop-up menus. -For example, you can guarantee that the pop-up is mapped -before the up pointer button event occurs by -grabbing a button requesting synchronous behavior. -The down event will trigger the grab and freeze further -processing of pointer events until you have the chance to -map the pop-up window. -You can then allow further event processing. -The up event will then be correctly processed relative to the -pop-up window. -</para> -<para> -<!-- .LP --> -For many operations, -there are functions that take a time argument. -The X server includes a timestamp in various events. -One special time, called -<indexterm significance="preferred"><primary>CurrentTime</primary></indexterm> -<indexterm significance="preferred"><primary>Time</primary></indexterm> -<symbol>CurrentTime</symbol>, -represents the current server time. -The X server maintains the time when the input focus was last changed, -when the keyboard was last grabbed, -when the pointer was last grabbed, -or when a selection was last changed. -Your -application may be slow reacting to an event. -You often need some way to specify that your -request should not occur if another application has in the meanwhile -taken control of the keyboard, pointer, or selection. -By providing the timestamp from the event in the request, -you can arrange that the operation not take effect -if someone else has performed an operation in the meanwhile. -</para> -<para> -<!-- .LP --> -A timestamp is a time value, expressed in milliseconds. -It typically is the time since the last server reset. -Timestamp values wrap around (after about 49.7 days). -The server, given its current time is represented by timestamp T, -always interprets timestamps from clients by treating half of the timestamp -space as being later in time than T. -One timestamp value, named -<symbol>CurrentTime</symbol>, -is never generated by the server. -This value is reserved for use in requests to represent the current server time. -</para> -<para> -<!-- .LP --> -For many functions in this section, -you pass pointer event mask bits. -The valid pointer event mask bits are: -<symbol>ButtonPressMask</symbol>, -<symbol>ButtonReleaseMask</symbol>, -<symbol>EnterWindowMask</symbol>, -<symbol>LeaveWindowMask</symbol>, -<symbol>PointerMotionMask</symbol>, -<symbol>PointerMotionHintMask</symbol>, -<symbol>Button1MotionMask</symbol>, -<symbol>Button2MotionMask</symbol>, -<symbol>Button3MotionMask</symbol>, -<symbol>Button4MotionMask</symbol>, -<symbol>Button5MotionMask</symbol>, -<symbol>ButtonMotionMask</symbol>, -and -<symbol>KeymapStateMask</symbol>. -For other functions in this section, -you pass keymask bits. -The valid keymask bits are: -<symbol>ShiftMask</symbol>, -<symbol>LockMask</symbol>, -<symbol>ControlMask</symbol>, -<symbol>Mod1Mask</symbol>, -<symbol>Mod2Mask</symbol>, -<symbol>Mod3Mask</symbol>, -<symbol>Mod4Mask</symbol>, -and -<symbol>Mod5Mask</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To grab the pointer, use -<function>XGrabPointer</function>. -</para> -<indexterm><primary>Grabbing</primary><secondary>pointer</secondary></indexterm> -<indexterm><primary>Pointer</primary><secondary>grabbing</secondary></indexterm> -<indexterm significance="preferred"><primary>XGrabPointer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgrabpointer'> -<funcprototype> - <funcdef>int <function>XGrabPointer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> - <paramdef>Bool<parameter> owner_events</parameter></paramdef> - <paramdef>unsignedint<parameter> event_mask</parameter></paramdef> - <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef> - <paramdef>Window<parameter> confine_to</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>owner_events</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the pointer -events are to be reported as usual or reported with respect to the grab window -if selected by the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies which pointer events are reported to the client. -The mask is the bitwise inclusive OR of the valid pointer event mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pointer_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of pointer events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keyboard_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of keyboard events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>confine_to</emphasis> - </term> - <listitem> - <para> -Specifies the window to confine the pointer in or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor that is to be displayed during the grab or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGrabPointer</function> -function actively grabs control of the pointer and returns -<symbol>GrabSuccess</symbol> -if the grab was successful. -Further pointer events are reported only to the grabbing client. -<function>XGrabPointer</function> -overrides any active pointer grab by this client. -If owner_events is -<symbol>False</symbol>, -all generated pointer events -are reported with respect to grab_window and are reported only if -selected by event_mask. -If owner_events is -<symbol>True</symbol> -and if a generated -pointer event would normally be reported to this client, -it is reported as usual. -Otherwise, the event is reported with respect to the -grab_window and is reported only if selected by event_mask. -For either value of owner_events, unreported events are discarded. -</para> -<para> -<!-- .LP --> -If the pointer_mode is -<symbol>GrabModeAsync</symbol>, -pointer event processing continues as usual. -If the pointer is currently frozen by this client, -the processing of events for the pointer is resumed. -If the pointer_mode is -<symbol>GrabModeSync</symbol>, -the state of the pointer, as seen by -client applications, -appears to freeze, and the X server generates no further pointer events -until the grabbing client calls -<function>XAllowEvents</function> -or until the pointer grab is released. -Actual pointer changes are not lost while the pointer is frozen; -they are simply queued in the server for later processing. -</para> -<para> -<!-- .LP --> -If the keyboard_mode is -<symbol>GrabModeAsync</symbol>, -keyboard event processing is unaffected by activation of the grab. -If the keyboard_mode is -<symbol>GrabModeSync</symbol>, -the state of the keyboard, as seen by -client applications, -appears to freeze, and the X server generates no further keyboard events -until the grabbing client calls -<function>XAllowEvents</function> -or until the pointer grab is released. -Actual keyboard changes are not lost while the pointer is frozen; -they are simply queued in the server for later processing. -</para> -<para> -<!-- .LP --> -If a cursor is specified, it is displayed regardless of what -window the pointer is in. -If -<symbol>None</symbol> -is specified, -the normal cursor for that window is displayed -when the pointer is in grab_window or one of its subwindows; -otherwise, the cursor for grab_window is displayed. -</para> -<para> -<!-- .LP --> -If a confine_to window is specified, -the pointer is restricted to stay contained in that window. -The confine_to window need have no relationship to the grab_window. -If the pointer is not initially in the confine_to window, -it is warped automatically to the closest edge -just before the grab activates and enter/leave events are generated as usual. -If the confine_to window is subsequently reconfigured, -the pointer is warped automatically, as necessary, -to keep it contained in the window. -</para> -<para> -<!-- .LP --> -The time argument allows you to avoid certain circumstances that come up -if applications take a long time to respond or if there are long network -delays. -Consider a situation where you have two applications, both -of which normally grab the pointer when clicked on. -If both applications specify the timestamp from the event, -the second application may wake up faster and successfully grab the pointer -before the first application. -The first application then will get an indication that the other application -grabbed the pointer before its request was processed. -</para> -<para> -<!-- .LP --> -<function>XGrabPointer</function> -generates -<symbol>EnterNotify</symbol> -and -<symbol>LeaveNotify</symbol> -events. -</para> -<para> -<!-- .LP --> -Either if grab_window or confine_to window is not viewable -or if the confine_to window lies completely outside the boundaries of the root -window, -<function>XGrabPointer</function> -fails and returns -<symbol>GrabNotViewable</symbol>. -If the pointer is actively grabbed by some other client, -it fails and returns -<symbol>AlreadyGrabbed</symbol>. -If the pointer is frozen by an active grab of another client, -it fails and returns -<symbol>GrabFrozen</symbol>. -If the specified time is earlier than the last-pointer-grab time or later -than the current X server time, it fails and returns -<symbol>GrabInvalidTime</symbol>. -Otherwise, the last-pointer-grab time is set to the specified time -(<symbol>CurrentTime</symbol> -is replaced by the current X server time). -</para> -<para> -<!-- .LP --> -<function>XGrabPointer</function> -can generate -<errorname>BadCursor</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ungrab the pointer, use -<function>XUngrabPointer</function>. -</para> -<indexterm><primary>Ungrabbing</primary><secondary>pointer</secondary></indexterm> -<indexterm><primary>Pointer</primary><secondary>ungrabbing</secondary></indexterm> -<indexterm significance="preferred"><primary>XUngrabPointer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xungrabpointer'> -<funcprototype> - <funcdef><function>XUngrabPointer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUngrabPointer</function> -function releases the pointer and any queued events -if this client has actively grabbed the pointer from -<function>XGrabPointer</function>, -<function>XGrabButton</function>, -or from a normal button press. -<function>XUngrabPointer</function> -does not release the pointer if the specified -time is earlier than the last-pointer-grab time or is later than the -current X server time. -It also generates -<symbol>EnterNotify</symbol> -and -<symbol>LeaveNotify</symbol> -events. -The X server performs an -<systemitem>UngrabPointer</systemitem> -request automatically if the event window or confine_to window -for an active pointer grab becomes not viewable -or if window reconfiguration causes the confine_to window to lie completely -outside the boundaries of the root window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change an active pointer grab, use -<function>XChangeActivePointerGrab</function>. -</para> -<indexterm><primary>Pointer</primary><secondary>grabbing</secondary></indexterm> -<indexterm ><primary>Changing</primary><secondary>pointer grab</secondary></indexterm> -<indexterm significance="preferred"><primary>XChangeActivePointerGrab</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangeactivepointergrab'> -<funcprototype> - <funcdef><function>XChangeActivePointerGrab</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedint<parameter> event_mask</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies which pointer events are reported to the client. -The mask is the bitwise inclusive OR of the valid pointer event mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor that is to be displayed or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangeActivePointerGrab</function> -function changes the specified dynamic parameters if the pointer is actively -grabbed by the client and if the specified time is no earlier than the -last-pointer-grab time and no later than the current X server time. -This function has no effect on the passive parameters of an -<function>XGrabButton</function>. -The interpretation of event_mask and cursor is the same as described in -<function>XGrabPointer</function>. -</para> -<para> -<!-- .LP --> -<function>XChangeActivePointerGrab</function> -can generate -<errorname>BadCursor</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To grab a pointer button, use -<function>XGrabButton</function>. -</para> -<indexterm><primary>Grabbing</primary><secondary>buttons</secondary></indexterm> -<indexterm><primary>Button</primary><secondary>grabbing</secondary></indexterm> -<indexterm significance="preferred"><primary>XGrabButton</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgrabbutton'> -<funcprototype> - <funcdef><function>XGrabButton</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedint<parameter> button</parameter></paramdef> - <paramdef>unsignedint<parameter> modifiers</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> - <paramdef>Bool<parameter> owner_events</parameter></paramdef> - <paramdef>unsignedint<parameter> event_mask</parameter></paramdef> - <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef> - <paramdef>Window<parameter> confine_to</parameter></paramdef> - <paramdef>Cursor<parameter> cursor</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Bu grabbed --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>button</emphasis> - </term> - <listitem> - <para> -Specifies the pointer button that is to be (Bu or -<symbol>AnyButton</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifiers</emphasis> - </term> - <listitem> - <para> -Specifies the set of keymasks or -<symbol>AnyModifier</symbol>. -The mask is the bitwise inclusive OR of the valid keymask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>owner_events</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the pointer -events are to be reported as usual or reported with respect to the grab window -if selected by the event mask. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mask</emphasis> - </term> - <listitem> - <para> -Specifies which pointer events are reported to the client. -The mask is the bitwise inclusive OR of the valid pointer event mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pointer_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of pointer events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keyboard_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of keyboard events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>confine_to</emphasis> - </term> - <listitem> - <para> -Specifies the window to confine the pointer in or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>cursor</emphasis> - </term> - <listitem> - <para> -Specifies the cursor that is to be displayed or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGrabButton</function> -function establishes a passive grab. -In the future, -the pointer is actively grabbed (as for -<function>XGrabPointer</function>), -the last-pointer-grab time is set to the time at which the button was pressed -(as transmitted in the -<symbol>ButtonPress</symbol> -event), and the -<symbol>ButtonPress</symbol> -event is reported if all of the following conditions are true: -</para> -<itemizedlist> - <listitem> - <para> -The pointer is not grabbed, and the specified button is logically pressed -when the specified modifier keys are logically down, -and no other buttons or modifier keys are logically down. - </para> - </listitem> - <listitem> - <para> -The grab_window contains the pointer. - </para> - </listitem> - <listitem> - <para> -The confine_to window (if any) is viewable. - </para> - </listitem> - <listitem> - <para> -A passive grab on the same button/key combination does not exist -on any ancestor of grab_window. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The interpretation of the remaining arguments is as for -<function>XGrabPointer</function>. -The active grab is terminated automatically when the logical state of the -pointer has all buttons released -(independent of the state of the logical modifier keys). -</para> -<para> -<!-- .LP --> -Note that the logical state of a device (as seen by client applications) -may lag the physical state if device event processing is frozen. -</para> -<para> -<!-- .LP --> -This request overrides all previous grabs by the same client on the same -button/key combinations on the same window. -A modifiers of -<symbol>AnyModifier</symbol> -is equivalent to issuing the grab request for all -possible modifier combinations (including the combination of no modifiers). -It is not required that all modifiers specified have currently assigned -KeyCodes. -A button of -<symbol>AnyButton</symbol> -is equivalent to -issuing the request for all possible buttons. -Otherwise, it is not required that the specified button currently be assigned -to a physical button. -</para> -<para> -<!-- .LP --> -If some other client has already issued an -<function>XGrabButton</function> -with the same button/key combination on the same window, a -<errorname>BadAccess</errorname> -error results. -When using -<symbol>AnyModifier</symbol> -or -<symbol>AnyButton</symbol>, -the request fails completely, -and a -<errorname>BadAccess</errorname> -error results (no grabs are -established) if there is a conflicting grab for any combination. -<function>XGrabButton</function> -has no effect on an active grab. -</para> -<para> -<!-- .LP --> -<function>XGrabButton</function> -can generate -<errorname>BadCursor</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ungrab a pointer button, use -<function>XUngrabButton</function>. -</para> -<indexterm><primary>Ungrabbing</primary><secondary>buttons</secondary></indexterm> -<indexterm><primary>Button</primary><secondary>ungrabbing</secondary></indexterm> -<indexterm significance="preferred"><primary>XUngrabButton</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xungrabbutton'> -<funcprototype> - <funcdef><function>XUngrabButton</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedint<parameter> button</parameter></paramdef> - <paramdef>unsignedint<parameter> modifiers</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Bu released --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>button</emphasis> - </term> - <listitem> - <para> -Specifies the pointer button that is to be (Bu or -<symbol>AnyButton</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifiers</emphasis> - </term> - <listitem> - <para> -Specifies the set of keymasks or -<symbol>AnyModifier</symbol>. -The mask is the bitwise inclusive OR of the valid keymask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUngrabButton</function> -function releases the passive button/key combination on the specified window if -it was grabbed by this client. -A modifiers of -<symbol>AnyModifier</symbol> -is -equivalent to issuing -the ungrab request for all possible modifier combinations, including -the combination of no modifiers. -A button of -<symbol>AnyButton</symbol> -is equivalent to issuing the -request for all possible buttons. -<function>XUngrabButton</function> -has no effect on an active grab. -</para> -<para> -<!-- .LP --> -<function>XUngrabButton</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Keyboard_Grabbing_"> -<title>Keyboard Grabbing </title> -<!-- .XS --> -<!-- (SN Keyboard Grabbing --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to grab or ungrab the keyboard -as well as allow events. -</para> -<para> -<!-- .LP --> -For many functions in this section, -you pass keymask bits. -The valid keymask bits are: -<symbol>ShiftMask</symbol>, -<symbol>LockMask</symbol>, -<symbol>ControlMask</symbol>, -<symbol>Mod1Mask</symbol>, -<symbol>Mod2Mask</symbol>, -<symbol>Mod3Mask</symbol>, -<symbol>Mod4Mask</symbol>, -and -<symbol>Mod5Mask</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To grab the keyboard, use -<function>XGrabKeyboard</function>. -</para> -<indexterm><primary>Keyboard</primary><secondary>grabbing</secondary></indexterm> -<indexterm><primary>Grabbing</primary><secondary>keyboard</secondary></indexterm> -<indexterm significance="preferred"><primary>XGrabKeyboard</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgrabkeyboard'> -<funcprototype> - <funcdef>int <function>XGrabKeyboard</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> - <paramdef>Bool<parameter> owner_events</parameter></paramdef> - <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>owner_events</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the keyboard events -are to be reported as usual. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pointer_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of pointer events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keyboard_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of keyboard events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGrabKeyboard</function> -function actively grabs control of the keyboard and generates -<symbol>FocusIn</symbol> -and -<symbol>FocusOut</symbol> -events. -Further key events are reported only to the -grabbing client. -<function>XGrabKeyboard</function> -overrides any active keyboard grab by this client. -If owner_events is -<symbol>False</symbol>, -all generated key events are reported with -respect to grab_window. -If owner_events is -<symbol>True</symbol> -and if a generated -key event would normally be reported to this client, it is reported -normally; otherwise, the event is reported with respect to the -grab_window. -Both -<symbol>KeyPress</symbol> -and -<symbol>KeyRelease</symbol> -events are always reported, -independent of any event selection made by the client. -</para> -<para> -<!-- .LP --> -If the keyboard_mode argument is -<symbol>GrabModeAsync</symbol>, -keyboard event processing continues -as usual. -If the keyboard is currently frozen by this client, -then processing of keyboard events is resumed. -If the keyboard_mode argument is -<symbol>GrabModeSync</symbol>, -the state of the keyboard (as seen by client applications) appears to freeze, -and the X server generates no further keyboard events until the -grabbing client issues a releasing -<function>XAllowEvents</function> -call or until the keyboard grab is released. -Actual keyboard changes are not lost while the keyboard is frozen; -they are simply queued in the server for later processing. -</para> -<para> -<!-- .LP --> -If pointer_mode is -<symbol>GrabModeAsync</symbol>, -pointer event processing is unaffected -by activation of the grab. -If pointer_mode is -<symbol>GrabModeSync</symbol>, -the state of the pointer (as seen by client applications) appears to freeze, -and the X server generates no further pointer events -until the grabbing client issues a releasing -<function>XAllowEvents</function> -call or until the keyboard grab is released. -Actual pointer changes are not lost while the pointer is frozen; -they are simply queued in the server for later processing. -</para> -<para> -<!-- .LP --> -If the keyboard is actively grabbed by some other client, -<function>XGrabKeyboard</function> -fails and returns -<symbol>AlreadyGrabbed</symbol>. -If grab_window is not viewable, -it fails and returns -<symbol>GrabNotViewable</symbol>. -If the keyboard is frozen by an active grab of another client, -it fails and returns -<symbol>GrabFrozen</symbol>. -If the specified time is earlier than the last-keyboard-grab time -or later than the current X server time, -it fails and returns -<symbol>GrabInvalidTime</symbol>. -Otherwise, the last-keyboard-grab time is set to the specified time -(<symbol>CurrentTime</symbol> -is replaced by the current X server time). -</para> -<para> -<!-- .LP --> -<function>XGrabKeyboard</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ungrab the keyboard, use -<function>XUngrabKeyboard</function>. -</para> -<indexterm><primary>Keyboard</primary><secondary>ungrabbing</secondary></indexterm> -<indexterm><primary>Ungrabbing</primary><secondary>keyboard</secondary></indexterm> -<indexterm significance="preferred"><primary>XUngrabKeyboard</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xungrabkeyboard'> -<funcprototype> - <funcdef><function>XUngrabKeyboard</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUngrabKeyboard</function> -function -releases the keyboard and any queued events if this client has it actively grabbed from -either -<function>XGrabKeyboard</function> -or -<function>XGrabKey</function>. -<function>XUngrabKeyboard</function> -does not release the keyboard and any queued events -if the specified time is earlier than -the last-keyboard-grab time or is later than the current X server time. -It also generates -<symbol>FocusIn</symbol> -and -<symbol>FocusOut</symbol> -events. -The X server automatically performs an -<systemitem>UngrabKeyboard</systemitem> -request if the event window for an -active keyboard grab becomes not viewable. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To passively grab a single key of the keyboard, use -<function>XGrabKey</function>. -</para> -<indexterm><primary>Key</primary><secondary>grabbing</secondary></indexterm> -<indexterm><primary>Grabbing</primary><secondary>keys</secondary></indexterm> -<indexterm significance="preferred"><primary>XGrabKey</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgrabkey'> -<funcprototype> - <funcdef><function>XGrabKey</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> keycode</parameter></paramdef> - <paramdef>unsignedint<parameter> modifiers</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> - <paramdef>Bool<parameter> owner_events</parameter></paramdef> - <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode</emphasis> - </term> - <listitem> - <para> -Specifies the KeyCode or -<symbol>AnyKey</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifiers</emphasis> - </term> - <listitem> - <para> -Specifies the set of keymasks or -<symbol>AnyModifier</symbol>. -The mask is the bitwise inclusive OR of the valid keymask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>owner_events</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that indicates whether the keyboard events -are to be reported as usual. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pointer_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of pointer events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keyboard_mode</emphasis> - </term> - <listitem> - <para> -Specifies further processing of keyboard events. -You can pass -<symbol>GrabModeSync</symbol> -or -<symbol>GrabModeAsync</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGrabKey</function> -function establishes a passive grab on the keyboard. -In the future, -the keyboard is actively grabbed (as for -<function>XGrabKeyboard</function>), -the last-keyboard-grab time is set to the time at which the key was pressed -(as transmitted in the -<symbol>KeyPress</symbol> -event), and the -<symbol>KeyPress</symbol> -event is reported if all of the following conditions are true: -</para> -<itemizedlist> - <listitem> - <para> -The keyboard is not grabbed and the specified key -(which can itself be a modifier key) is logically pressed -when the specified modifier keys are logically down, -and no other modifier keys are logically down. - </para> - </listitem> - <listitem> - <para> -Either the grab_window is an ancestor of (or is) the focus window, -or the grab_window is a descendant of the focus window and contains the pointer. - </para> - </listitem> - <listitem> - <para> -A passive grab on the same key combination does not exist -on any ancestor of grab_window. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The interpretation of the remaining arguments is as for -<function>XGrabKeyboard</function>. -The active grab is terminated automatically when the logical state of the -keyboard has the specified key released -(independent of the logical state of the modifier keys). -</para> -<para> -<!-- .LP --> -Note that the logical state of a device (as seen by client applications) -may lag the physical state if device event processing is frozen. -</para> -<para> -<!-- .LP --> -A modifiers argument of -<symbol>AnyModifier</symbol> -is equivalent to issuing the request for all -possible modifier combinations (including the combination of no -modifiers). -It is not required that all modifiers specified have -currently assigned KeyCodes. -A keycode argument of -<symbol>AnyKey</symbol> -is equivalent to issuing -the request for all possible KeyCodes. -Otherwise, the specified keycode must be in -the range specified by min_keycode and max_keycode in the connection -setup, -or a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -If some other client has issued a -<function>XGrabKey</function> -with the same key combination on the same window, a -<errorname>BadAccess</errorname> -error results. -When using -<symbol>AnyModifier</symbol> -or -<symbol>AnyKey</symbol>, -the request fails completely, -and a -<errorname>BadAccess</errorname> -error results (no grabs are established) -if there is a conflicting grab for any combination. -</para> -<para> -<!-- .LP --> -<function>XGrabKey</function> -can generate -<errorname>BadAccess</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ungrab a key, use -<function>XUngrabKey</function>. -</para> -<indexterm><primary>Key</primary><secondary>ungrabbing</secondary></indexterm> -<indexterm><primary>Ungrabbing</primary><secondary>keys</secondary></indexterm> -<indexterm significance="preferred"><primary>XUngrabKey</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xungrabkey'> -<funcprototype> - <funcdef><function>XUngrabKey</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> keycode</parameter></paramdef> - <paramdef>unsignedint<parameter> modifiers</parameter></paramdef> - <paramdef>Window<parameter> grab_window</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode</emphasis> - </term> - <listitem> - <para> -Specifies the KeyCode or -<symbol>AnyKey</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifiers</emphasis> - </term> - <listitem> - <para> -Specifies the set of keymasks or -<symbol>AnyModifier</symbol>. -The mask is the bitwise inclusive OR of the valid keymask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>grab_window</emphasis> - </term> - <listitem> - <para> -Specifies the grab window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUngrabKey</function> -function releases the key combination on the specified window if it was grabbed -by this client. -It has no effect on an active grab. -A modifiers of -<symbol>AnyModifier</symbol> -is equivalent to issuing -the request for all possible modifier combinations -(including the combination of no modifiers). -A keycode argument of -<symbol>AnyKey</symbol> -is equivalent to issuing the request for all possible key codes. -</para> -<para> -<!-- .LP --> -<function>XUngrabKey</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect1> -<sect1 id="Resuming_Event_Processing"> -<title>Resuming Event Processing</title> -<!-- .XS --> -<!-- (SN Resuming Event Processing --> -<!-- .XE --> -<para> -<!-- .LP --> -The previous sections discussed grab mechanisms with which processing -of events by the server can be temporarily suspended. This section -describes the mechanism for resuming event processing. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allow further events to be processed when the device has been frozen, use -<function>XAllowEvents</function>. -</para> -<indexterm significance="preferred"><primary>XAllowEvents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xallowevents'> -<funcprototype> - <funcdef><function>XAllowEvents</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> event_mode</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event_mode</emphasis> - </term> - <listitem> - <para> -Specifies the event mode. -You can pass -<symbol>AsyncPointer</symbol>, -<symbol>SyncPointer</symbol>, -<symbol>AsyncKeyboard</symbol>, -<symbol>SyncKeyboard</symbol>, -<symbol>ReplayPointer</symbol>, -<symbol>ReplayKeyboard</symbol>, -<symbol>AsyncBoth</symbol>, -or -<symbol>SyncBoth</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllowEvents</function> -function releases some queued events if the client has caused a device -to freeze. -It has no effect if the specified time is earlier than the last-grab -time of the most recent active grab for the client or if the specified time -is later than the current X server time. -Depending on the event_mode argument, the following occurs: -</para> -<informaltable frame='none'> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>AsyncPointer</symbol></entry> - <entry>If the pointer is frozen by the client, - pointer event processing continues as usual. - If the pointer is frozen twice by the client on behalf of two separate grabs, - <symbol>AsyncPointer</symbol> - thaws for both. - <symbol>AsyncPointer</symbol> - has no effect if the pointer is not frozen by the client, - but the pointer need not be grabbed by the client.</entry> - </row> - <row> - <entry><symbol>SyncPointer</symbol></entry> - <entry>If the pointer is frozen and actively grabbed by the client, - pointer event processing continues as usual until the next - <symbol>ButtonPress</symbol> - or - <symbol>ButtonRelease</symbol> - event is reported to the client. - At this time, - the pointer again appears to freeze. - However, if the reported event causes the pointer grab to be released, - the pointer does not freeze. - <symbol>SyncPointer</symbol> - has no effect if the pointer is not frozen by the client - or if the pointer is not grabbed by the client.</entry> - </row> - <row> - <entry><symbol>ReplayPointer</symbol></entry> - <entry>If the pointer is actively grabbed by the client and is frozen as the result of - an event having been sent to the client (either from the activation of an - <function>XGrabButton</function> - or from a previous - <function>XAllowEvents</function> - with mode - <symbol>SyncPointer</symbol> - but not from an - <function>XGrabPointer</function>), - the pointer grab is released and that event is completely reprocessed. - This time, however, the function ignores any passive grabs at or above - (toward the root of) the grab_window of the grab just released. - The request has no effect if the pointer is not grabbed by the client - or if the pointer is not frozen as the result of an event.</entry> - </row> - <row> - <entry><symbol>AsyncKeyboard</symbol></entry> - <entry>If the keyboard is frozen by the client, - keyboard event processing continues as usual. - If the keyboard is frozen twice by the client on behalf of two separate grabs, - <symbol>AsyncKeyboard</symbol> - thaws for both. - <symbol>AsyncKeyboard</symbol> - has no effect if the keyboard is not frozen by the client, - but the keyboard need not be grabbed by the client.</entry> - </row> - <row> - <entry><symbol>SyncKeyboard</symbol></entry> - <entry>If the keyboard is frozen and actively grabbed by the client, - keyboard event processing continues as usual until the next - <symbol>KeyPress</symbol> - or - <symbol>KeyRelease</symbol> - event is reported to the client. - At this time, - the keyboard again appears to freeze. - However, if the reported event causes the keyboard grab to be released, - the keyboard does not freeze. - <symbol>SyncKeyboard</symbol> - has no effect if the keyboard is not frozen by the client - or if the keyboard is not grabbed by the client.</entry> - </row> - <row> - <entry><symbol>ReplayKeyboard</symbol></entry> - <entry>If the keyboard is actively grabbed by the client and is frozen - as the result of an event having been sent to the client (either from the - activation of an - <function>XGrabKey</function> - or from a previous - <function>XAllowEvents</function> - with mode - <symbol>SyncKeyboard</symbol> - but not from an - <function>XGrabKeyboard</function>), - the keyboard grab is released and that event is completely reprocessed. - This time, however, the function ignores any passive grabs at or above - (toward the root of) - the grab_window of the grab just released. - The request has no effect if the keyboard is not grabbed by the client - or if the keyboard is not frozen as the result of an event.</entry> - </row> - <row> - <entry><symbol>SyncBoth</symbol></entry> - <entry>If both pointer and keyboard are frozen by the client, - event processing for both devices continues as usual until the next - <symbol>ButtonPress</symbol>, - <symbol>ButtonRelease</symbol>, - <symbol>KeyPress</symbol>, - or - <symbol>KeyRelease</symbol> - event is reported to the client for a grabbed device - (button event for the pointer, key event for the keyboard), - at which time the devices again appear to freeze. - However, if the reported event causes the grab to be released, - then the devices do not freeze (but if the other device is still - grabbed, then a subsequent event for it will still cause both devices - to freeze). - <symbol>SyncBoth</symbol> - has no effect unless both pointer and keyboard - are frozen by the client. - If the pointer or keyboard is frozen twice - by the client on behalf of two separate grabs, - <symbol>SyncBoth</symbol> - thaws for both (but a subsequent freeze for - <symbol>SyncBoth</symbol> - will only freeze each device once).</entry> - </row> - <row> - <entry><symbol>AsyncBoth</symbol></entry> - <entry>If the pointer and the keyboard are frozen by the - client, event processing for both devices continues as usual. - If a device is frozen twice by the client on behalf of two separate grabs, - <symbol>AsyncBoth</symbol> - thaws for both. - <symbol>AsyncBoth</symbol> - has no effect unless both - pointer and keyboard are frozen by the client.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -<symbol>AsyncPointer</symbol>, -<symbol>SyncPointer</symbol>, -and -<symbol>ReplayPointer</symbol> -have no effect on the -processing of keyboard events. -<symbol>AsyncKeyboard</symbol>, -<symbol>SyncKeyboard</symbol>, -and -<symbol>ReplayKeyboard</symbol> -have no effect on the -processing of pointer events. -It is possible for both a pointer grab and a keyboard grab (by the same -or different clients) to be active simultaneously. -If a device is frozen on behalf of either grab, -no event processing is performed for the device. -It is possible for a single device to be frozen because of both grabs. -In this case, -the freeze must be released on behalf of both grabs before events can -again be processed. -If a device is frozen twice by a single client, -then a single -<function>XAllowEvents</function> -releases both. -</para> -<para> -<!-- .LP --> -<function>XAllowEvents</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -</sect1> -<sect1 id="Moving_the_Pointer"> -<title>Moving the Pointer</title> -<!-- .XS --> -<!-- (SN Moving the Pointer --> -<!-- .XE --> -<para> -<!-- .LP --> -Although movement of the pointer normally should be left to the -control of the end user, sometimes it is necessary to move the -pointer to a new position under program control. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To move the pointer to an arbitrary point in a window, use -<function>XWarpPointer</function>. -</para> -<indexterm significance="preferred"><primary>XWarpPointer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwarppointer'> -<funcprototype> - <funcdef><function>XWarpPointer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Windowsrc_w,<parameter> dest_w</parameter></paramdef> - <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef> - <paramdef>unsignedintsrc_width,<parameter> src_height</parameter></paramdef> - <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_w</emphasis> - </term> - <listitem> - <para> -Specifies the source window or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_w</emphasis> - </term> - <listitem> - <para> -Specifies the destination window or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_y</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_height</emphasis> - </term> - <listitem> - <para> -Specify a rectangle in the source window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates within the destination window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If dest_w is -<symbol>None</symbol>, -<function>XWarpPointer</function> -moves the pointer by the offsets (dest_x, dest_y) relative to the current -position of the pointer. -If dest_w is a window, -<function>XWarpPointer</function> -moves the pointer to the offsets (dest_x, dest_y) relative to the origin of -dest_w. -However, if src_w is a window, -the move only takes place if the window src_w contains the pointer -and if the specified rectangle of src_w contains the pointer. -</para> -<para> -<!-- .LP --> -The src_x and src_y coordinates are relative to the origin of src_w. -If src_height is zero, -it is replaced with the current height of src_w minus src_y. -If src_width is zero, -it is replaced with the current width of src_w minus src_x. -</para> -<para> -<!-- .LP --> -There is seldom any reason for calling this function. -The pointer should normally be left to the user. -If you do use this function, however, it generates events just as if the user -had instantaneously moved the pointer from one position to another. -Note that you cannot use -<function>XWarpPointer</function> -to move the pointer outside the confine_to window of an active pointer grab. -An attempt to do so will only move the pointer as far as the closest edge of the -confine_to window. -</para> -<para> -<!-- .LP --> -<function>XWarpPointer</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect1> -<sect1 id="Controlling_Input_Focus"> -<title>Controlling Input Focus</title> -<!-- .XS --> -<!-- (SN Controlling Input Focus --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and get the input focus. -The input focus is a shared resource, and cooperation among clients is -required for correct interaction. See the -<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis> -for input focus policy. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the input focus, use -<function>XSetInputFocus</function>. -</para> -<indexterm significance="preferred"><primary>XSetInputFocus</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetinputfocus'> -<funcprototype> - <funcdef><function>XSetInputFocus</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> focus</parameter></paramdef> - <paramdef>int<parameter> revert_to</parameter></paramdef> - <paramdef>Time<parameter> time</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>focus</emphasis> - </term> - <listitem> - <para> -Specifies the window, -<symbol>PointerRoot</symbol>, -or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>revert_to</emphasis> - </term> - <listitem> - <para> -Specifies where the input focus reverts to if the window becomes not -viewable. -You can pass -<symbol>RevertToParent</symbol>, -<symbol>RevertToPointerRoot</symbol>, -or -<symbol>RevertToNone</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>time</emphasis> - </term> - <listitem> - <para> -Specifies the time. -You can pass either a timestamp or -<symbol>CurrentTime</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetInputFocus</function> -function changes the input focus and the last-focus-change time. -It has no effect if the specified time is earlier than the current -last-focus-change time or is later than the current X server time. -Otherwise, the last-focus-change time is set to the specified time -(<symbol>CurrentTime</symbol> -is replaced by the current X server time). -<function>XSetInputFocus</function> -causes the X server to generate -<symbol>FocusIn</symbol> -and -<symbol>FocusOut</symbol> -events. -</para> -<para> -<!-- .LP --> -Depending on the focus argument, -the following occurs: -</para> -<itemizedlist> - <listitem> - <para> -If focus is -<symbol>None</symbol>, -all keyboard events are discarded until a new focus window is set, -and the revert_to argument is ignored. - </para> - </listitem> - <listitem> - <para> -If focus is a window, -it becomes the keyboard's focus window. -If a generated keyboard event would normally be reported to this window -or one of its inferiors, the event is reported as usual. -Otherwise, the event is reported relative to the focus window. - </para> - </listitem> - <listitem> - <para> -If focus is -<symbol>PointerRoot</symbol>, -the focus window is dynamically taken to be the root window of whatever screen -the pointer is on at each keyboard event. -In this case, the revert_to argument is ignored. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The specified focus window must be viewable at the time -<function>XSetInputFocus</function> -is called, -or a -<errorname>BadMatch</errorname> -error results. -If the focus window later becomes not viewable, -the X server -evaluates the revert_to argument to determine the new focus window as follows: -</para> -<itemizedlist> - <listitem> - <para> -If revert_to is -<symbol>RevertToParent</symbol>, -the focus reverts to the parent (or the closest viewable ancestor), -and the new revert_to value is taken to be -<symbol>RevertToNone</symbol>. - </para> - </listitem> - <listitem> - <para> -If revert_to is -<symbol>RevertToPointerRoot</symbol> -or -<symbol>RevertToNone</symbol>, -the focus reverts to -<symbol>PointerRoot</symbol> -or -<symbol>None</symbol>, -respectively. -When the focus reverts, -the X server generates -<symbol>FocusIn</symbol> -and -<symbol>FocusOut</symbol> -events, but the last-focus-change time is not affected. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<function>XSetInputFocus</function> -can generate -<errorname>BadMatch</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the current input focus, use -<function>XGetInputFocus</function>. -</para> -<indexterm significance="preferred"><primary>XGetInputFocus</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetinputfocus'> -<funcprototype> - <funcdef><function>XGetInputFocus</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> *focus_return</parameter></paramdef> - <paramdef>int<parameter> *revert_to_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>focus_return</emphasis> - </term> - <listitem> - <para> -Returns the focus window, -<symbol>PointerRoot</symbol>, -or -<symbol>None</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>revert_to_return</emphasis> - </term> - <listitem> - <para> -Returns the current focus state -(<symbol>RevertToParent</symbol>, -<symbol>RevertToPointerRoot</symbol>, -or -<symbol>RevertToNone</symbol>). - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetInputFocus</function> -function returns the focus window and the current focus state. -</para> -</sect1> -<sect1 id="Manipulating_the_Keyboard_and_Pointer_Settings"> -<title>Manipulating the Keyboard and Pointer Settings</title> -<!-- .XS --> -<!-- (SN Manipulating the Keyboard and Pointer Settings --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to -change the keyboard control, obtain a list of the auto-repeat keys, -turn keyboard auto-repeat on or off, ring the bell, -set or obtain the pointer button or keyboard mapping, -and obtain a bit vector for the keyboard. -</para> -<para> -<!-- .LP --> -<indexterm><primary>Keyboard</primary><secondary>bell volume</secondary></indexterm> -<indexterm><primary>Keyboard</primary><secondary>keyclick volume</secondary></indexterm> -<indexterm><primary>Keyboard</primary><secondary>bit vector</secondary></indexterm> -<indexterm><primary>Mouse</primary><secondary>programming</secondary></indexterm> -This section discusses -the user-preference options of bell, key click, -pointer behavior, and so on. -The default values for many of these options are server dependent. -Not all implementations will actually be able to control all of these -parameters. -</para> -<para> -<!-- .LP --> -The -<function>XChangeKeyboardControl</function> -function changes control of a keyboard and operates on a -<structname>XKeyboardControl</structname> -structure: -<!-- .sM --> -</para> - -<literallayout class="monospaced"> -/* Mask bits for ChangeKeyboardControl */ - - -#define KBBellPercent (1L<<0) -#define KBBellPitch (1L<<1) -#define KBBellDuration (1L<<2) -#define KBLed (1L<<3) -#define KBLedMode (1L<<4) -#define KBKey (1L<<5) -#define KBAutoRepeatMode (1L<<6) - - -/* Values */ - -typedef struct { -int key_click_percent; -int bell_percent; -int bell_pitch; -int bell_duration; -int led; -int led_mode; /* LedModeOn, LedModeOff */ -int key; -int auto_repeat_mode; /* AutoRepeatModeOff, AutoRepeatModeOn, - AutoRepeatModeDefault */ -} XKeyboardControl; - -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The key_click_percent member sets the volume for key clicks between 0 (off) -and 100 (loud) inclusive, if possible. -A setting of -1 restores the default. -Other negative values generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -The bell_percent sets the base volume for the bell between 0 (off) and 100 -(loud) inclusive, if possible. -A setting of -1 restores the default. -Other negative values generate a -<errorname>BadValue</errorname> -error. -The bell_pitch member sets the pitch (specified in Hz) of the bell, if possible. -A setting of -1 restores the default. -Other negative values generate a -<errorname>BadValue</errorname> -error. -The bell_duration member sets the duration of the -bell specified in milliseconds, if possible. -A setting of -1 restores the default. -Other negative values generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -If both the led_mode and led members are specified, -the state of that <acronym>LED</acronym> is changed, if possible. -The led_mode member can be set to -<symbol>LedModeOn</symbol> -or -<symbol>LedModeOff</symbol>. -If only led_mode is specified, the state of -all LEDs are changed, if possible. -At most 32 LEDs numbered from one are supported. -No standard interpretation of LEDs is defined. -If led is specified without led_mode, a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -If both the auto_repeat_mode and key members are specified, -the auto_repeat_mode of that key is changed (according to -<symbol>AutoRepeatModeOn</symbol>, -<symbol>AutoRepeatModeOff</symbol>, -or -<symbol>AutoRepeatModeDefault</symbol>), -if possible. -If only auto_repeat_mode is -specified, the global auto_repeat_mode for the entire keyboard is -changed, if possible, and does not affect the per-key settings. -If a key is specified without an auto_repeat_mode, a -<errorname>BadMatch</errorname> -error results. -Each key has an individual mode of whether or not it should auto-repeat -and a default setting for the mode. -In addition, -there is a global mode of whether auto-repeat should be enabled or not -and a default setting for that mode. -When global mode is -<symbol>AutoRepeatModeOn</symbol>, -keys should obey their individual auto-repeat modes. -When global mode is -<symbol>AutoRepeatModeOff</symbol>, -no keys should auto-repeat. -An auto-repeating key generates alternating -<symbol>KeyPress</symbol> -and -<symbol>KeyRelease</symbol> -events. -When a key is used as a modifier, -it is desirable for the key not to auto-repeat, -regardless of its auto-repeat setting. -</para> -<para> -<!-- .LP --> -A bell generator connected with the console but not directly on a -keyboard is treated as if it were part of the keyboard. -The order in which controls are verified and altered is server-dependent. -If an error is generated, a subset of the controls may have been altered. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -</para> -<indexterm significance="preferred"><primary>XChangeKeyboardControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangekeyboardcontrol'> -<funcprototype> - <funcdef><function>XChangeKeyboardControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedlong<parameter> value_mask</parameter></paramdef> - <paramdef>XKeyboardControl<parameter> *values</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_mask</emphasis> - </term> - <listitem> - <para> -Specifies which controls to change. -This mask is the bitwise inclusive OR of the valid control mask bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values</emphasis> - </term> - <listitem> - <para> -Specifies one value for each bit set to 1 in the mask. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangeKeyboardControl</function> -function controls the keyboard characteristics defined by the -<structname>XKeyboardControl</structname> -structure. -The value_mask argument specifies which values are to be changed. -</para> -<para> -<!-- .LP --> -<function>XChangeKeyboardControl</function> -can generate -<errorname>BadMatch</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the current control values for the keyboard, use -<function>XGetKeyboardControl</function>. -</para> -<indexterm significance="preferred"><primary>XGetKeyboardControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetkeyboardcontrol'> -<funcprototype> - <funcdef><function>XGetKeyboardControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XKeyboardState<parameter> *values_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values_return</emphasis> - </term> - <listitem> - <para> -Returns the current keyboard controls in the specified -<structname>XKeyboardState</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetKeyboardControl</function> -function returns the current control values for the keyboard to the -<structname>XKeyboardState</structname> -structure. -</para> -<para> -<!-- .LP --> -<indexterm><primary>XGetKeyboardControl</primary></indexterm> -<indexterm significance="preferred"><primary>XKeyboardState</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - int key_click_percent; - int bell_percent; - unsigned int bell_pitch, bell_duration; - unsigned long led_mask; - int global_auto_repeat; - char auto_repeats[32]; -} XKeyboardState; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -For the LEDs, -the least significant bit of led_mask corresponds to <acronym>LED</acronym> one, -and each bit set to 1 in led_mask indicates an <acronym>LED</acronym> that is lit. -The global_auto_repeat member can be set to -<symbol>AutoRepeatModeOn</symbol> -or -<symbol>AutoRepeatModeOff</symbol>. -The auto_repeats member is a bit vector. -Each bit set to 1 indicates that auto-repeat is enabled -for the corresponding key. -The vector is represented as 32 bytes. -Byte N (from 0) contains the bits for keys 8N to 8N + 7 -with the least significant bit in the byte representing key 8N. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To turn on keyboard auto-repeat, use -<function>XAutoRepeatOn</function>. -</para> -<indexterm significance="preferred"><primary>XAutoRepeatOn</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xautorepeaton'> -<funcprototype> - <funcdef><function>XAutoRepeatOn</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAutoRepeatOn</function> -function turns on auto-repeat for the keyboard on the specified display. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To turn off keyboard auto-repeat, use -<function>XAutoRepeatOff</function>. -</para> -<indexterm significance="preferred"><primary>XAutoRepeatOff</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xautorepeatoff'> -<funcprototype> - <funcdef><function>XAutoRepeatOff</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAutoRepeatOff</function> -function turns off auto-repeat for the keyboard on the specified display. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To ring the bell, use -<function>XBell</function>. -</para> -<indexterm significance="preferred"><primary>XBell</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xbell'> -<funcprototype> - <funcdef><function>XBell</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> percent</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>percent</emphasis> - </term> - <listitem> - <para> -Specifies the volume for the bell, -which can range from -100 to 100 inclusive. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XBell</function> -function rings the bell on the keyboard on the specified display, if possible. -The specified volume is relative to the base volume for the keyboard. -If the value for the percent argument is not in the range -100 to 100 -inclusive, a -<errorname>BadValue</errorname> -error results. -The volume at which the bell rings -when the percent argument is nonnegative is: -</para> -<itemizedlist> - <listitem> - <para> -base - [(base * percent) / 100] + percent - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The volume at which the bell rings -when the percent argument is negative is: -</para> -<itemizedlist> - <listitem> - <para> -base + [(base * percent) / 100] - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -To change the base volume of the bell, use -<function>XChangeKeyboardControl</function>. -</para> -<para> -<!-- .LP --> -<function>XBell</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a bit vector that describes the state of the keyboard, use -<function>XQueryKeymap</function>. -</para> -<indexterm significance="preferred"><primary>XQueryKeymap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xquerykeymap'> -<funcprototype> - <funcdef><function>XQueryKeymap</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> keys_return[32]</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keys_return</emphasis> - </term> - <listitem> - <para> -Returns an array of bytes that identifies which keys are pressed down. -Each bit represents one key of the keyboard. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XQueryKeymap</function> -function returns a bit vector for the logical state of the keyboard, -where each bit set to 1 indicates that the corresponding key is currently -pressed down. -The vector is represented as 32 bytes. -Byte N (from 0) contains the bits for keys 8N to 8N + 7 -with the least significant bit in the byte representing key 8N. -</para> -<para> -<!-- .LP --> -Note that the logical state of a device (as seen by client applications) -may lag the physical state if device event processing is frozen. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the mapping of the pointer buttons, use -<function>XSetPointerMapping</function>. -</para> -<indexterm significance="preferred"><primary>XSetPointerMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetpointermapping'> -<funcprototype> - <funcdef>int <function>XSetPointerMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedchar<parameter> map[]</parameter></paramdef> - <paramdef>int<parameter> nmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>map</emphasis> - </term> - <listitem> - <para> -Specifies the mapping list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nmap</emphasis> - </term> - <listitem> - <para> -Specifies the number of items in the mapping list. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetPointerMapping</function> -function sets the mapping of the pointer. -If it succeeds, the X server generates a -<symbol>MappingNotify</symbol> -event, and -<function>XSetPointerMapping</function> -returns -<symbol>MappingSuccess</symbol>. -Element map[i] defines the logical button number for the physical button -i+1. -The length of the list must be the same as -<function>XGetPointerMapping</function> -would return, -or a -<errorname>BadValue</errorname> -error results. -A zero element disables a button, and elements are not restricted in -value by the number of physical buttons. -However, no two elements can have the same nonzero value, -or a -<errorname>BadValue</errorname> -error results. -If any of the buttons to be altered are logically in the down state, -<function>XSetPointerMapping</function> -returns -<symbol>MappingBusy</symbol>, -and the mapping is not changed. -</para> -<para> -<!-- .LP --> -<function>XSetPointerMapping</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the pointer mapping, use -<function>XGetPointerMapping</function>. -</para> -<indexterm significance="preferred"><primary>XGetPointerMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetpointermapping'> -<funcprototype> - <funcdef>int <function>XGetPointerMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>unsignedchar<parameter> map_return[]</parameter></paramdef> - <paramdef>int<parameter> nmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>map_return</emphasis> - </term> - <listitem> - <para> -Returns the mapping list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nmap</emphasis> - </term> - <listitem> - <para> -Specifies the number of items in the mapping list. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetPointerMapping</function> -function returns the current mapping of the pointer. -Pointer buttons are numbered starting from one. -<function>XGetPointerMapping</function> -returns the number of physical buttons actually on the pointer. -The nominal mapping for a pointer is map[i]=i+1. -The nmap argument specifies the length of the array where the pointer -mapping is returned, and only the first nmap elements are returned -in map_return. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To control the pointer's interactive feel, use -<function>XChangePointerControl</function>. -</para> -<indexterm significance="preferred"><primary>XChangePointerControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangepointercontrol'> -<funcprototype> - <funcdef><function>XChangePointerControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Booldo_accel,<parameter> do_threshold</parameter></paramdef> - <paramdef>intaccel_numerator,<parameter> accel_denominator</parameter></paramdef> - <paramdef>int<parameter> threshold</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>do_accel</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that controls whether the values for -the accel_numerator or accel_denominator are used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>do_threshold</emphasis> - </term> - <listitem> - <para> -Specifies a Boolean value that controls whether the value for the -threshold is used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>accel_numerator</emphasis> - </term> - <listitem> - <para> -Specifies the numerator for the acceleration multiplier. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>accel_denominator</emphasis> - </term> - <listitem> - <para> -Specifies the denominator for the acceleration multiplier. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>threshold</emphasis> - </term> - <listitem> - <para> -Specifies the acceleration threshold. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangePointerControl</function> -function defines how the pointing device moves. -The acceleration, expressed as a fraction, is a -multiplier for movement. -For example, -specifying 3/1 means the pointer moves three times as fast as normal. -The fraction may be rounded arbitrarily by the X server. -Acceleration -only takes effect if the pointer moves more than threshold pixels at -once and only applies to the amount beyond the value in the threshold argument. -Setting a value to -1 restores the default. -The values of the do_accel and do_threshold arguments must be -<symbol>True</symbol> -for the pointer values to be set, -or the parameters are unchanged. -Negative values (other than -1) generate a -<errorname>BadValue</errorname> -error, as does a zero value -for the accel_denominator argument. -</para> -<para> -<!-- .LP --> -<function>XChangePointerControl</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the current pointer parameters, use -<function>XGetPointerControl</function>. -</para> -<indexterm significance="preferred"><primary>XGetPointerControl</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetpointercontrol'> -<funcprototype> - <funcdef><function>XGetPointerControl</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int*accel_numerator_return,<parameter> *accel_denominator_return</parameter></paramdef> - <paramdef>int<parameter> *threshold_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>accel_numerator_return</emphasis> - </term> - <listitem> - <para> -Returns the numerator for the acceleration multiplier. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>accel_denominator_return</emphasis> - </term> - <listitem> - <para> -Returns the denominator for the acceleration multiplier. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>threshold_return</emphasis> - </term> - <listitem> - <para> -Returns the acceleration threshold. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetPointerControl</function> -function returns the pointer's current acceleration multiplier -and acceleration threshold. -</para> -</sect1> -<sect1 id="Manipulating_the_Keyboard_Encoding"> -<title>Manipulating the Keyboard Encoding</title> -<!-- .XS --> -<!-- (SN Manipulating the Keyboard Encoding --> -<!-- .XE --> -<para> -<!-- .LP --> -A KeyCode represents a physical (or logical) key. -KeyCodes lie in the inclusive range [8,255]. -A KeyCode value carries no intrinsic information, -although server implementors may attempt to encode geometry -(for example, matrix) information in some fashion so that it can -be interpreted in a server-dependent fashion. -The mapping between keys and KeyCodes cannot be changed. -</para> -<para> -<!-- .LP --> -A KeySym is an encoding of a symbol on the cap of a key. -The set of defined KeySyms includes the ISO Latin character sets (1-4), -Katakana, Arabic, Cyrillic, Greek, Technical, -Special, Publishing, APL, Hebrew, Thai, Korean -and a miscellany of keys found -on keyboards (Return, Help, Tab, and so on). -To the extent possible, these sets are derived from international -standards. -In areas where no standards exist, -some of these sets are derived from Digital Equipment Corporation standards. -The list of defined symbols can be found in -<filename class="headerfile"><X11/keysymdef.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/keysymdef.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm> -Unfortunately, some C preprocessors have -limits on the number of defined symbols. -If you must use KeySyms not -in the Latin 1-4, Greek, and miscellaneous classes, -you may have to define a symbol for those sets. -Most applications usually only include -<filename class="headerfile"><X11/keysym.h></filename>, -<indexterm type="file"><primary><filename class="headerfile">X11/keysym.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysym.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysym.h></filename></secondary></indexterm> -which defines symbols for ISO Latin 1-4, Greek, and miscellaneous. -</para> -<para> -<!-- .LP --> -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 -<symbol>NoSymbol</symbol> -entries) is -a single KeySym ``<emphasis remap='I'>K</emphasis>'', -then the list is treated as if it were the list -``<emphasis remap='I'>K</emphasis> NoSymbol <emphasis remap='I'>K</emphasis> NoSymbol''. -If the list (ignoring trailing -<symbol>NoSymbol</symbol> -entries) is a pair of KeySyms ``<emphasis remap='I'>K1 K2</emphasis>'', -then the list is treated as if it were the list ``<emphasis remap='I'>K1 K2 K1 K2</emphasis>''. -If the list (ignoring trailing -<symbol>NoSymbol</symbol> -entries) is a triple of KeySyms ``<emphasis remap='I'>K1 K2 K3</emphasis>'', -then the list is treated as if it were the list ``<emphasis remap='I'>K1 K2 K3</emphasis> NoSymbol''. -When an explicit ``void'' element is desired in the list, -the value -<symbol>VoidSymbol</symbol> -can be used. -</para> -<para> -<!-- .LP --> -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 -<symbol>NoSymbol</symbol>, -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 ``<emphasis remap='I'>K</emphasis>'' -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 ``<emphasis remap='I'>K</emphasis>'' and the second element were -the uppercase form of ``<emphasis remap='I'>K</emphasis>''. -</para> -<para> -<!-- .LP --> -The standard rules for obtaining a KeySym from a -<symbol>KeyPress</symbol> -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 -<symbol>Mod1</symbol> -through -<symbol>Mod5</symbol>. -This modifier is called the <emphasis remap='I'>group modifier</emphasis>. -For any KeyCode, -Group 1 is used when the group modifier is off, -and Group 2 is used when the group modifier is on. -</para> -<para> -<!-- .LP --> -The -<symbol>Lock</symbol> -modifier is interpreted as CapsLock when the KeySym named XK_Caps_Lock -is attached to some KeyCode and that KeyCode is attached to the -<symbol>Lock</symbol> -modifier. The -<symbol>Lock</symbol> -modifier is interpreted as ShiftLock when the KeySym named XK_Shift_Lock -is attached to some KeyCode and that KeyCode is attached to the -<symbol>Lock</symbol> -modifier. If the -<symbol>Lock</symbol> -modifier could be interpreted as both -CapsLock and ShiftLock, the CapsLock interpretation is used. -</para> -<para> -<!-- .LP --> -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 -<symbol>Mod1</symbol> -through -<symbol>Mod5</symbol>. -This modifier is called the -<emphasis remap='I'>numlock modifier</emphasis>. 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. -</para> -<para> -<!-- .LP --> -Within a group, the choice of KeySym is determined by applying the first -rule that is satisfied from the following list: -</para> -<itemizedlist> - <listitem> - <para> -The numlock modifier is on and the second KeySym is a keypad KeySym. In -this case, if the -<symbol>Shift</symbol> -modifier is on, or if the -<symbol>Lock</symbol> -modifier is on and -is interpreted as ShiftLock, then the first KeySym is used, otherwise the -second KeySym is used. - </para> - </listitem> - <listitem> - <para> -The -<symbol>Shift</symbol> -and -<symbol>Lock</symbol> -modifiers are both off. In this case, the first -KeySym is used. - </para> - </listitem> - <listitem> - <para> -The -<symbol>Shift</symbol> -modifier is off, and the -<symbol>Lock</symbol> -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. - </para> - </listitem> - <listitem> - <para> -The -<symbol>Shift</symbol> -modifier is on, and the -<symbol>Lock</symbol> -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. - </para> - </listitem> - <listitem> - <para> -The -<symbol>Shift</symbol> -modifier is on, or the -<symbol>Lock</symbol> -modifier is on and is interpreted -as ShiftLock, or both. In this case, the second KeySym is used. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -No spatial geometry of the symbols on the key is defined by -their order in the KeySym list, -although a geometry might be defined on a -server-specific basis. -The X server does not use the mapping between KeyCodes and KeySyms. -Rather, it merely stores it for reading and writing by clients. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the legal KeyCodes for a display, use -<function>XDisplayKeycodes</function>. -</para> -<indexterm significance="preferred"><primary>XDisplayKeycodes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisplaykeycodes'> -<funcprototype> - <funcdef><function>XDisplayKeycodes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int*min_keycodes_return,<parameter> *max_keycodes_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>min_keycodes_return</emphasis> - </term> - <listitem> - <para> -Returns the minimum number of KeyCodes. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>max_keycodes_return</emphasis> - </term> - <listitem> - <para> -Returns the maximum number of KeyCodes. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDisplayKeycodes</function> -function returns the min-keycodes and max-keycodes supported by the -specified display. -The minimum number of KeyCodes returned is never less than 8, -and the maximum number of KeyCodes returned is never greater than 255. -Not all KeyCodes in this range are required to have corresponding keys. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the symbols for the specified KeyCodes, use -<function>XGetKeyboardMapping</function>. -</para> -<indexterm significance="preferred"><primary>XGetKeyboardMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetkeyboardmapping'> -<funcprototype> - <funcdef>KeySym *<function>XGetKeyboardMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>KeyCode<parameter> first_keycode</parameter></paramdef> - <paramdef>int<parameter> keycode_count</parameter></paramdef> - <paramdef>int<parameter> *keysyms_per_keycode_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Kc returned --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>first_keycode</emphasis> - </term> - <listitem> - <para> -Specifies the first KeyCode that is to be (Kc. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode_count</emphasis> - </term> - <listitem> - <para> -Specifies the number of KeyCodes that are to be returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysyms_per_keycode_return</emphasis> - </term> - <listitem> - <para> -Returns the number of KeySyms per KeyCode. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetKeyboardMapping</function> -function returns the symbols for the specified number of KeyCodes -starting with first_keycode. -The value specified in first_keycode must be greater than -or equal to min_keycode as returned by -<function>XDisplayKeycodes</function>, -or a -<errorname>BadValue</errorname> -error results. -In addition, the following expression must be less than or equal -to max_keycode as returned by -<function>XDisplayKeycodes</function>: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -first_keycode + keycode_count - 1 -</literallayout> -</para> -<para> -<!-- .LP --> -If this is not the case, a -<errorname>BadValue</errorname> -error results. -The number of elements in the KeySyms list is: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -keycode_count * keysyms_per_keycode_return -</literallayout> -</para> -<para> -<!-- .LP --> -KeySym number N, counting from zero, for KeyCode K has the following index -in the list, counting from zero: -<literallayout class="monospaced"> -(K - first_code) * keysyms_per_code_return + N -</literallayout> -</para> -<para> -<!-- .LP --> -The X server arbitrarily chooses the keysyms_per_keycode_return value -to be large enough to report all requested symbols. -A special KeySym value of -<symbol>NoSymbol</symbol> -is used to fill in unused elements for -individual KeyCodes. -To free the storage returned by -<function>XGetKeyboardMapping</function>, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetKeyboardMapping</function> -can generate a -<errorname>BadValue</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To change the keyboard mapping, use -<function>XChangeKeyboardMapping</function>. -</para> -<indexterm significance="preferred"><primary>XChangeKeyboardMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xchangekeyboardmapping'> -<funcprototype> - <funcdef><function>XChangeKeyboardMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> first_keycode</parameter></paramdef> - <paramdef>int<parameter> keysyms_per_keycode</parameter></paramdef> - <paramdef>KeySym<parameter> *keysyms</parameter></paramdef> - <paramdef>int<parameter> num_codes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Kc changed --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>first_keycode</emphasis> - </term> - <listitem> - <para> -Specifies the first KeyCode that is to be (Kc. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysyms_per_keycode</emphasis> - </term> - <listitem> - <para> -Specifies the number of KeySyms per KeyCode. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysyms</emphasis> - </term> - <listitem> - <para> -Specifies an array of KeySyms. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_codes</emphasis> - </term> - <listitem> - <para> -Specifies the number of KeyCodes that are to be changed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XChangeKeyboardMapping</function> -function defines the symbols for the specified number of KeyCodes -starting with first_keycode. -The symbols for KeyCodes outside this range remain unchanged. -The number of elements in keysyms must be: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -num_codes * keysyms_per_keycode -</literallayout> -</para> -<para> -<!-- .LP --> -The specified first_keycode must be greater than or equal to min_keycode -returned by -<function>XDisplayKeycodes</function>, -or a -<errorname>BadValue</errorname> -error results. -In addition, the following expression must be less than or equal to -max_keycode as returned by -<function>XDisplayKeycodes</function>, -or a -<errorname>BadValue</errorname> -error results: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -first_keycode + num_codes - 1 -</literallayout> -</para> -<para> -<!-- .LP --> -KeySym number N, counting from zero, for KeyCode K has the following index -in keysyms, counting from zero: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -(K - first_keycode) * keysyms_per_keycode + N -</literallayout> -</para> -<para> -<!-- .LP --> -The specified keysyms_per_keycode can be chosen arbitrarily by the client -to be large enough to hold all desired symbols. -A special KeySym value of -<symbol>NoSymbol</symbol> -should be used to fill in unused elements -for individual KeyCodes. -It is legal for -<symbol>NoSymbol</symbol> -to appear in nontrailing positions -of the effective list for a KeyCode. -<function>XChangeKeyboardMapping</function> -generates a -<symbol>MappingNotify</symbol> -event. -</para> -<para> -<!-- .LP --> -There is no requirement that the X server interpret this mapping. -It is merely stored for reading and writing by clients. -</para> -<para> -<!-- .LP --> -<function>XChangeKeyboardMapping</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -The next six functions make use of the -<structname>XModifierKeymap</structname> -data structure, which contains: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XModifierKeymap</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int max_keypermod; /* This server's max number of keys per modifier */ - KeyCode *modifiermap; /* An 8 by max_keypermod array of the modifiers */ -} XModifierKeymap; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -To create an -<structname>XModifierKeymap</structname> -structure, use -<function>XNewModifiermap</function>. -</para> -<indexterm significance="preferred"><primary>XNewModifiermap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xnewmodifiermap'> -<funcprototype> - <funcdef>XModifierKeymap *<function>XNewModifiermap</function></funcdef> - <paramdef>int<parameter> max_keys_per_mod</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>max_keys_per_mod</emphasis> - </term> - <listitem> - <para> -Specifies the number of KeyCode entries preallocated to the modifiers -in the map. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XNewModifiermap</function> -function returns a pointer to -<structname>XModifierKeymap</structname> -structure for later use. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a new entry to an -<structname>XModifierKeymap</structname> -structure, use -<function>XInsertModifiermapEntry</function>. -</para> -<indexterm significance="preferred"><primary>XInsertModifiermapEntry</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xinsertmodifiermapentry'> -<funcprototype> - <funcdef>XModifierKeymap *<function>XInsertModifiermapEntry</function></funcdef> - <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef> - <paramdef>KeyCode<parameter> keycode_entry</parameter></paramdef> - <paramdef>int<parameter> modifier</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>modmap</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XModifierKeymap</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode_entry</emphasis> - </term> - <listitem> - <para> -Specifies the KeyCode. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifier</emphasis> - </term> - <listitem> - <para> -Specifies the modifier. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XInsertModifiermapEntry</function> -function adds the specified KeyCode to the set that controls the specified -modifier and returns the resulting -<structname>XModifierKeymap</structname> -structure (expanded as needed). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To delete an entry from an -<structname>XModifierKeymap</structname> -structure, use -<function>XDeleteModifiermapEntry</function>. -</para> -<indexterm significance="preferred"><primary>XDeleteModifiermapEntry</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdeletemodifiermapentry'> -<funcprototype> - <funcdef>XModifierKeymap *<function>XDeleteModifiermapEntry</function></funcdef> - <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef> - <paramdef>KeyCode<parameter> keycode_entry</parameter></paramdef> - <paramdef>int<parameter> modifier</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>modmap</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XModifierKeymap</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode_entry</emphasis> - </term> - <listitem> - <para> -Specifies the KeyCode. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modifier</emphasis> - </term> - <listitem> - <para> -Specifies the modifier. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDeleteModifiermapEntry</function> -function deletes the specified KeyCode from the set that controls the -specified modifier and returns a pointer to the resulting -<structname>XModifierKeymap</structname> -structure. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy an -<structname>XModifierKeymap</structname> -structure, use -<function>XFreeModifiermap</function>. -</para> -<indexterm significance="preferred"><primary>XFreeModifiermap</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreemodifiermap'> -<funcprototype> - <funcdef><function>XFreeModifiermap</function></funcdef> - <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>modmap</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XModifierKeymap</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeModifiermap</function> -function frees the specified -<structname>XModifierKeymap</structname> -structure. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the KeyCodes to be used as modifiers, use -<function>XSetModifierMapping</function>. -</para> -<indexterm significance="preferred"><primary>XSetModifierMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetmodifiermapping'> -<funcprototype> - <funcdef>int <function>XSetModifierMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>modmap</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XModifierKeymap</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetModifierMapping</function> -function specifies the KeyCodes of the keys (if any) that are to be used -as modifiers. -If it succeeds, -the X server generates a -<symbol>MappingNotify</symbol> -event, and -<function>XSetModifierMapping</function> -returns -<symbol>MappingSuccess</symbol>. -X permits at most 8 modifier keys. -If more than 8 are specified in the -<structname>XModifierKeymap</structname> -structure, a -<errorname>BadLength</errorname> -error results. -</para> -<para> -<!-- .LP --> -The modifiermap member of the -<structname>XModifierKeymap</structname> -structure contains 8 sets of max_keypermod KeyCodes, -one for each modifier in the order -<symbol>Shift</symbol>, -<symbol>Lock</symbol>, -<symbol>Control</symbol>, -<symbol>Mod1</symbol>, -<symbol>Mod2</symbol>, -<symbol>Mod3</symbol>, -<symbol>Mod4</symbol>, -and -<symbol>Mod5</symbol>. -Only nonzero KeyCodes have meaning in each set, -and zero KeyCodes are ignored. -In addition, all of the nonzero KeyCodes must be in the range specified by -min_keycode and max_keycode in the -<type>Display</type> -structure, -or a -<errorname>BadValue</errorname> -error results. -</para> -<para> -<!-- .LP --> -An X server can impose restrictions on how modifiers can be changed, -for example, -if certain keys do not generate up transitions in hardware, -if auto-repeat cannot be disabled on certain keys, -or if multiple modifier keys are not supported. -If some such restriction is violated, -the status reply is -<symbol>MappingFailed</symbol>, -and none of the modifiers are changed. -If the new KeyCodes specified for a modifier differ from those -currently defined and any (current or new) keys for that modifier are -in the logically down state, -<function>XSetModifierMapping</function> -returns -<symbol>MappingBusy</symbol>, -and none of the modifiers is changed. -</para> -<para> -<!-- .LP --> -<function>XSetModifierMapping</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the KeyCodes used as modifiers, use -<function>XGetModifierMapping</function>. -</para> -<indexterm significance="preferred"><primary>XGetModifierMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetmodifiermapping'> -<funcprototype> - <funcdef>XModifierKeymap *<function>XGetModifierMapping</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetModifierMapping</function> -function returns a pointer to a newly created -<structname>XModifierKeymap</structname> -structure that contains the keys being used as modifiers. -The structure should be freed after use by calling -<function>XFreeModifiermap</function>. -If only zero values appear in the set for any modifier, -that modifier is disabled. -<!-- .bp --> - - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="input_device_functions">
+<title>Input Device Functions</title>
+
+<para>
+You can use the Xlib input device functions to:
+</para>
+
+<itemizedlist>
+ <listitem><para>Grab the pointer and individual buttons on the pointer</para></listitem>
+ <listitem><para>Grab the keyboard and individual keys on the keyboard</para></listitem>
+ <listitem><para>Resume event processing</para></listitem>
+ <listitem><para>Move the pointer</para></listitem>
+ <listitem><para>Set the input focus</para></listitem>
+ <listitem><para>Manipulate the keyboard and pointer settings</para></listitem>
+ <listitem><para>Manipulate the keyboard encoding</para></listitem>
+</itemizedlist>
+
+<sect1 id="Pointer_Grabbing_">
+<title>Pointer Grabbing </title>
+<!-- .XS -->
+<!-- (SN Pointer Grabbing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to control input from the pointer,
+which usually is a mouse.
+Usually, as soon as keyboard and mouse events occur,
+the X server delivers them to the appropriate client,
+which is determined by the window and input focus.
+The X server provides sufficient control over event delivery to
+allow window managers to support mouse ahead and various other
+styles of user interface.
+Many of these user interfaces depend on synchronous delivery of events.
+The delivery of pointer and keyboard events can be controlled
+independently.
+</para>
+<para>
+<!-- .LP -->
+When mouse buttons or keyboard keys are grabbed, events
+will be sent to the grabbing client rather than the normal
+client who would have received the event.
+If the keyboard or pointer is in asynchronous mode,
+further mouse and keyboard events will continue to be processed.
+If the keyboard or pointer is in synchronous mode, no
+further events are processed until the grabbing client
+allows them (see
+<function>XAllowEvents</function>).
+The keyboard or pointer is considered frozen during this
+interval.
+The event that triggered the grab can also be replayed.
+</para>
+<para>
+<!-- .LP -->
+Note that the logical state of a device (as seen by client applications)
+may lag the physical state if device event processing is frozen.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>Active grab</primary></indexterm>
+There are two kinds of grabs:
+active and passive.
+An active grab occurs when a single client grabs the keyboard and/or pointer
+explicitly (see
+<function>XGrabPointer</function>
+and
+<function>XGrabKeyboard</function>).
+<indexterm><primary>Passive grab</primary></indexterm>
+A passive grab occurs when clients grab a particular keyboard key
+or pointer button in a window,
+and the grab will activate when the key or button is actually pressed.
+Passive grabs are convenient for implementing reliable pop-up menus.
+For example, you can guarantee that the pop-up is mapped
+before the up pointer button event occurs by
+grabbing a button requesting synchronous behavior.
+The down event will trigger the grab and freeze further
+processing of pointer events until you have the chance to
+map the pop-up window.
+You can then allow further event processing.
+The up event will then be correctly processed relative to the
+pop-up window.
+</para>
+<para>
+<!-- .LP -->
+For many operations,
+there are functions that take a time argument.
+The X server includes a timestamp in various events.
+One special time, called
+<indexterm significance="preferred"><primary>CurrentTime</primary></indexterm>
+<indexterm significance="preferred"><primary>Time</primary></indexterm>
+<symbol>CurrentTime</symbol>,
+represents the current server time.
+The X server maintains the time when the input focus was last changed,
+when the keyboard was last grabbed,
+when the pointer was last grabbed,
+or when a selection was last changed.
+Your
+application may be slow reacting to an event.
+You often need some way to specify that your
+request should not occur if another application has in the meanwhile
+taken control of the keyboard, pointer, or selection.
+By providing the timestamp from the event in the request,
+you can arrange that the operation not take effect
+if someone else has performed an operation in the meanwhile.
+</para>
+<para>
+<!-- .LP -->
+A timestamp is a time value, expressed in milliseconds.
+It typically is the time since the last server reset.
+Timestamp values wrap around (after about 49.7 days).
+The server, given its current time is represented by timestamp T,
+always interprets timestamps from clients by treating half of the timestamp
+space as being later in time than T.
+One timestamp value, named
+<symbol>CurrentTime</symbol>,
+is never generated by the server.
+This value is reserved for use in requests to represent the current server time.
+</para>
+<para>
+<!-- .LP -->
+For many functions in this section,
+you pass pointer event mask bits.
+The valid pointer event mask bits are:
+<symbol>ButtonPressMask</symbol>,
+<symbol>ButtonReleaseMask</symbol>,
+<symbol>EnterWindowMask</symbol>,
+<symbol>LeaveWindowMask</symbol>,
+<symbol>PointerMotionMask</symbol>,
+<symbol>PointerMotionHintMask</symbol>,
+<symbol>Button1MotionMask</symbol>,
+<symbol>Button2MotionMask</symbol>,
+<symbol>Button3MotionMask</symbol>,
+<symbol>Button4MotionMask</symbol>,
+<symbol>Button5MotionMask</symbol>,
+<symbol>ButtonMotionMask</symbol>,
+and
+<symbol>KeymapStateMask</symbol>.
+For other functions in this section,
+you pass keymask bits.
+The valid keymask bits are:
+<symbol>ShiftMask</symbol>,
+<symbol>LockMask</symbol>,
+<symbol>ControlMask</symbol>,
+<symbol>Mod1Mask</symbol>,
+<symbol>Mod2Mask</symbol>,
+<symbol>Mod3Mask</symbol>,
+<symbol>Mod4Mask</symbol>,
+and
+<symbol>Mod5Mask</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To grab the pointer, use
+<function>XGrabPointer</function>.
+</para>
+<indexterm><primary>Grabbing</primary><secondary>pointer</secondary></indexterm>
+<indexterm><primary>Pointer</primary><secondary>grabbing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGrabPointer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgrabpointer'>
+<funcprototype>
+ <funcdef>int <function>XGrabPointer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>unsignedint<parameter> event_mask</parameter></paramdef>
+ <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef>
+ <paramdef>Window<parameter> confine_to</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the pointer
+events are to be reported as usual or reported with respect to the grab window
+if selected by the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which pointer events are reported to the client.
+The mask is the bitwise inclusive OR of the valid pointer event mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pointer_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of pointer events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keyboard_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of keyboard events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>confine_to</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window to confine the pointer in or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor that is to be displayed during the grab or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGrabPointer</function>
+function actively grabs control of the pointer and returns
+<symbol>GrabSuccess</symbol>
+if the grab was successful.
+Further pointer events are reported only to the grabbing client.
+<function>XGrabPointer</function>
+overrides any active pointer grab by this client.
+If owner_events is
+<symbol>False</symbol>,
+all generated pointer events
+are reported with respect to grab_window and are reported only if
+selected by event_mask.
+If owner_events is
+<symbol>True</symbol>
+and if a generated
+pointer event would normally be reported to this client,
+it is reported as usual.
+Otherwise, the event is reported with respect to the
+grab_window and is reported only if selected by event_mask.
+For either value of owner_events, unreported events are discarded.
+</para>
+<para>
+<!-- .LP -->
+If the pointer_mode is
+<symbol>GrabModeAsync</symbol>,
+pointer event processing continues as usual.
+If the pointer is currently frozen by this client,
+the processing of events for the pointer is resumed.
+If the pointer_mode is
+<symbol>GrabModeSync</symbol>,
+the state of the pointer, as seen by
+client applications,
+appears to freeze, and the X server generates no further pointer events
+until the grabbing client calls
+<function>XAllowEvents</function>
+or until the pointer grab is released.
+Actual pointer changes are not lost while the pointer is frozen;
+they are simply queued in the server for later processing.
+</para>
+<para>
+<!-- .LP -->
+If the keyboard_mode is
+<symbol>GrabModeAsync</symbol>,
+keyboard event processing is unaffected by activation of the grab.
+If the keyboard_mode is
+<symbol>GrabModeSync</symbol>,
+the state of the keyboard, as seen by
+client applications,
+appears to freeze, and the X server generates no further keyboard events
+until the grabbing client calls
+<function>XAllowEvents</function>
+or until the pointer grab is released.
+Actual keyboard changes are not lost while the pointer is frozen;
+they are simply queued in the server for later processing.
+</para>
+<para>
+<!-- .LP -->
+If a cursor is specified, it is displayed regardless of what
+window the pointer is in.
+If
+<symbol>None</symbol>
+is specified,
+the normal cursor for that window is displayed
+when the pointer is in grab_window or one of its subwindows;
+otherwise, the cursor for grab_window is displayed.
+</para>
+<para>
+<!-- .LP -->
+If a confine_to window is specified,
+the pointer is restricted to stay contained in that window.
+The confine_to window need have no relationship to the grab_window.
+If the pointer is not initially in the confine_to window,
+it is warped automatically to the closest edge
+just before the grab activates and enter/leave events are generated as usual.
+If the confine_to window is subsequently reconfigured,
+the pointer is warped automatically, as necessary,
+to keep it contained in the window.
+</para>
+<para>
+<!-- .LP -->
+The time argument allows you to avoid certain circumstances that come up
+if applications take a long time to respond or if there are long network
+delays.
+Consider a situation where you have two applications, both
+of which normally grab the pointer when clicked on.
+If both applications specify the timestamp from the event,
+the second application may wake up faster and successfully grab the pointer
+before the first application.
+The first application then will get an indication that the other application
+grabbed the pointer before its request was processed.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabPointer</function>
+generates
+<symbol>EnterNotify</symbol>
+and
+<symbol>LeaveNotify</symbol>
+events.
+</para>
+<para>
+<!-- .LP -->
+Either if grab_window or confine_to window is not viewable
+or if the confine_to window lies completely outside the boundaries of the root
+window,
+<function>XGrabPointer</function>
+fails and returns
+<symbol>GrabNotViewable</symbol>.
+If the pointer is actively grabbed by some other client,
+it fails and returns
+<symbol>AlreadyGrabbed</symbol>.
+If the pointer is frozen by an active grab of another client,
+it fails and returns
+<symbol>GrabFrozen</symbol>.
+If the specified time is earlier than the last-pointer-grab time or later
+than the current X server time, it fails and returns
+<symbol>GrabInvalidTime</symbol>.
+Otherwise, the last-pointer-grab time is set to the specified time
+(<symbol>CurrentTime</symbol>
+is replaced by the current X server time).
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabPointer</function>
+can generate
+<errorname>BadCursor</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ungrab the pointer, use
+<function>XUngrabPointer</function>.
+</para>
+<indexterm><primary>Ungrabbing</primary><secondary>pointer</secondary></indexterm>
+<indexterm><primary>Pointer</primary><secondary>ungrabbing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XUngrabPointer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xungrabpointer'>
+<funcprototype>
+ <funcdef><function>XUngrabPointer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUngrabPointer</function>
+function releases the pointer and any queued events
+if this client has actively grabbed the pointer from
+<function>XGrabPointer</function>,
+<function>XGrabButton</function>,
+or from a normal button press.
+<function>XUngrabPointer</function>
+does not release the pointer if the specified
+time is earlier than the last-pointer-grab time or is later than the
+current X server time.
+It also generates
+<symbol>EnterNotify</symbol>
+and
+<symbol>LeaveNotify</symbol>
+events.
+The X server performs an
+<systemitem>UngrabPointer</systemitem>
+request automatically if the event window or confine_to window
+for an active pointer grab becomes not viewable
+or if window reconfiguration causes the confine_to window to lie completely
+outside the boundaries of the root window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change an active pointer grab, use
+<function>XChangeActivePointerGrab</function>.
+</para>
+<indexterm><primary>Pointer</primary><secondary>grabbing</secondary></indexterm>
+<indexterm ><primary>Changing</primary><secondary>pointer grab</secondary></indexterm>
+<indexterm significance="preferred"><primary>XChangeActivePointerGrab</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangeactivepointergrab'>
+<funcprototype>
+ <funcdef><function>XChangeActivePointerGrab</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedint<parameter> event_mask</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which pointer events are reported to the client.
+The mask is the bitwise inclusive OR of the valid pointer event mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor that is to be displayed or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangeActivePointerGrab</function>
+function changes the specified dynamic parameters if the pointer is actively
+grabbed by the client and if the specified time is no earlier than the
+last-pointer-grab time and no later than the current X server time.
+This function has no effect on the passive parameters of an
+<function>XGrabButton</function>.
+The interpretation of event_mask and cursor is the same as described in
+<function>XGrabPointer</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeActivePointerGrab</function>
+can generate
+<errorname>BadCursor</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To grab a pointer button, use
+<function>XGrabButton</function>.
+</para>
+<indexterm><primary>Grabbing</primary><secondary>buttons</secondary></indexterm>
+<indexterm><primary>Button</primary><secondary>grabbing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGrabButton</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgrabbutton'>
+<funcprototype>
+ <funcdef><function>XGrabButton</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedint<parameter> button</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>unsignedint<parameter> event_mask</parameter></paramdef>
+ <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef>
+ <paramdef>Window<parameter> confine_to</parameter></paramdef>
+ <paramdef>Cursor<parameter> cursor</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Bu grabbed -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>button</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer button that is to be (Bu or
+<symbol>AnyButton</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks or
+<symbol>AnyModifier</symbol>.
+The mask is the bitwise inclusive OR of the valid keymask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the pointer
+events are to be reported as usual or reported with respect to the grab window
+if selected by the event mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which pointer events are reported to the client.
+The mask is the bitwise inclusive OR of the valid pointer event mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pointer_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of pointer events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keyboard_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of keyboard events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>confine_to</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window to confine the pointer in or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>cursor</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the cursor that is to be displayed or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGrabButton</function>
+function establishes a passive grab.
+In the future,
+the pointer is actively grabbed (as for
+<function>XGrabPointer</function>),
+the last-pointer-grab time is set to the time at which the button was pressed
+(as transmitted in the
+<symbol>ButtonPress</symbol>
+event), and the
+<symbol>ButtonPress</symbol>
+event is reported if all of the following conditions are true:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The pointer is not grabbed, and the specified button is logically pressed
+when the specified modifier keys are logically down,
+and no other buttons or modifier keys are logically down.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The grab_window contains the pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The confine_to window (if any) is viewable.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A passive grab on the same button/key combination does not exist
+on any ancestor of grab_window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The interpretation of the remaining arguments is as for
+<function>XGrabPointer</function>.
+The active grab is terminated automatically when the logical state of the
+pointer has all buttons released
+(independent of the state of the logical modifier keys).
+</para>
+<para>
+<!-- .LP -->
+Note that the logical state of a device (as seen by client applications)
+may lag the physical state if device event processing is frozen.
+</para>
+<para>
+<!-- .LP -->
+This request overrides all previous grabs by the same client on the same
+button/key combinations on the same window.
+A modifiers of
+<symbol>AnyModifier</symbol>
+is equivalent to issuing the grab request for all
+possible modifier combinations (including the combination of no modifiers).
+It is not required that all modifiers specified have currently assigned
+KeyCodes.
+A button of
+<symbol>AnyButton</symbol>
+is equivalent to
+issuing the request for all possible buttons.
+Otherwise, it is not required that the specified button currently be assigned
+to a physical button.
+</para>
+<para>
+<!-- .LP -->
+If some other client has already issued an
+<function>XGrabButton</function>
+with the same button/key combination on the same window, a
+<errorname>BadAccess</errorname>
+error results.
+When using
+<symbol>AnyModifier</symbol>
+or
+<symbol>AnyButton</symbol>,
+the request fails completely,
+and a
+<errorname>BadAccess</errorname>
+error results (no grabs are
+established) if there is a conflicting grab for any combination.
+<function>XGrabButton</function>
+has no effect on an active grab.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabButton</function>
+can generate
+<errorname>BadCursor</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ungrab a pointer button, use
+<function>XUngrabButton</function>.
+</para>
+<indexterm><primary>Ungrabbing</primary><secondary>buttons</secondary></indexterm>
+<indexterm><primary>Button</primary><secondary>ungrabbing</secondary></indexterm>
+<indexterm significance="preferred"><primary>XUngrabButton</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xungrabbutton'>
+<funcprototype>
+ <funcdef><function>XUngrabButton</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedint<parameter> button</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Bu released -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>button</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the pointer button that is to be (Bu or
+<symbol>AnyButton</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks or
+<symbol>AnyModifier</symbol>.
+The mask is the bitwise inclusive OR of the valid keymask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUngrabButton</function>
+function releases the passive button/key combination on the specified window if
+it was grabbed by this client.
+A modifiers of
+<symbol>AnyModifier</symbol>
+is
+equivalent to issuing
+the ungrab request for all possible modifier combinations, including
+the combination of no modifiers.
+A button of
+<symbol>AnyButton</symbol>
+is equivalent to issuing the
+request for all possible buttons.
+<function>XUngrabButton</function>
+has no effect on an active grab.
+</para>
+<para>
+<!-- .LP -->
+<function>XUngrabButton</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Keyboard_Grabbing_">
+<title>Keyboard Grabbing </title>
+<!-- .XS -->
+<!-- (SN Keyboard Grabbing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to grab or ungrab the keyboard
+as well as allow events.
+</para>
+<para>
+<!-- .LP -->
+For many functions in this section,
+you pass keymask bits.
+The valid keymask bits are:
+<symbol>ShiftMask</symbol>,
+<symbol>LockMask</symbol>,
+<symbol>ControlMask</symbol>,
+<symbol>Mod1Mask</symbol>,
+<symbol>Mod2Mask</symbol>,
+<symbol>Mod3Mask</symbol>,
+<symbol>Mod4Mask</symbol>,
+and
+<symbol>Mod5Mask</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To grab the keyboard, use
+<function>XGrabKeyboard</function>.
+</para>
+<indexterm><primary>Keyboard</primary><secondary>grabbing</secondary></indexterm>
+<indexterm><primary>Grabbing</primary><secondary>keyboard</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGrabKeyboard</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgrabkeyboard'>
+<funcprototype>
+ <funcdef>int <function>XGrabKeyboard</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the keyboard events
+are to be reported as usual.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pointer_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of pointer events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keyboard_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of keyboard events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGrabKeyboard</function>
+function actively grabs control of the keyboard and generates
+<symbol>FocusIn</symbol>
+and
+<symbol>FocusOut</symbol>
+events.
+Further key events are reported only to the
+grabbing client.
+<function>XGrabKeyboard</function>
+overrides any active keyboard grab by this client.
+If owner_events is
+<symbol>False</symbol>,
+all generated key events are reported with
+respect to grab_window.
+If owner_events is
+<symbol>True</symbol>
+and if a generated
+key event would normally be reported to this client, it is reported
+normally; otherwise, the event is reported with respect to the
+grab_window.
+Both
+<symbol>KeyPress</symbol>
+and
+<symbol>KeyRelease</symbol>
+events are always reported,
+independent of any event selection made by the client.
+</para>
+<para>
+<!-- .LP -->
+If the keyboard_mode argument is
+<symbol>GrabModeAsync</symbol>,
+keyboard event processing continues
+as usual.
+If the keyboard is currently frozen by this client,
+then processing of keyboard events is resumed.
+If the keyboard_mode argument is
+<symbol>GrabModeSync</symbol>,
+the state of the keyboard (as seen by client applications) appears to freeze,
+and the X server generates no further keyboard events until the
+grabbing client issues a releasing
+<function>XAllowEvents</function>
+call or until the keyboard grab is released.
+Actual keyboard changes are not lost while the keyboard is frozen;
+they are simply queued in the server for later processing.
+</para>
+<para>
+<!-- .LP -->
+If pointer_mode is
+<symbol>GrabModeAsync</symbol>,
+pointer event processing is unaffected
+by activation of the grab.
+If pointer_mode is
+<symbol>GrabModeSync</symbol>,
+the state of the pointer (as seen by client applications) appears to freeze,
+and the X server generates no further pointer events
+until the grabbing client issues a releasing
+<function>XAllowEvents</function>
+call or until the keyboard grab is released.
+Actual pointer changes are not lost while the pointer is frozen;
+they are simply queued in the server for later processing.
+</para>
+<para>
+<!-- .LP -->
+If the keyboard is actively grabbed by some other client,
+<function>XGrabKeyboard</function>
+fails and returns
+<symbol>AlreadyGrabbed</symbol>.
+If grab_window is not viewable,
+it fails and returns
+<symbol>GrabNotViewable</symbol>.
+If the keyboard is frozen by an active grab of another client,
+it fails and returns
+<symbol>GrabFrozen</symbol>.
+If the specified time is earlier than the last-keyboard-grab time
+or later than the current X server time,
+it fails and returns
+<symbol>GrabInvalidTime</symbol>.
+Otherwise, the last-keyboard-grab time is set to the specified time
+(<symbol>CurrentTime</symbol>
+is replaced by the current X server time).
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabKeyboard</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ungrab the keyboard, use
+<function>XUngrabKeyboard</function>.
+</para>
+<indexterm><primary>Keyboard</primary><secondary>ungrabbing</secondary></indexterm>
+<indexterm><primary>Ungrabbing</primary><secondary>keyboard</secondary></indexterm>
+<indexterm significance="preferred"><primary>XUngrabKeyboard</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xungrabkeyboard'>
+<funcprototype>
+ <funcdef><function>XUngrabKeyboard</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUngrabKeyboard</function>
+function
+releases the keyboard and any queued events if this client has it actively grabbed from
+either
+<function>XGrabKeyboard</function>
+or
+<function>XGrabKey</function>.
+<function>XUngrabKeyboard</function>
+does not release the keyboard and any queued events
+if the specified time is earlier than
+the last-keyboard-grab time or is later than the current X server time.
+It also generates
+<symbol>FocusIn</symbol>
+and
+<symbol>FocusOut</symbol>
+events.
+The X server automatically performs an
+<systemitem>UngrabKeyboard</systemitem>
+request if the event window for an
+active keyboard grab becomes not viewable.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To passively grab a single key of the keyboard, use
+<function>XGrabKey</function>.
+</para>
+<indexterm><primary>Key</primary><secondary>grabbing</secondary></indexterm>
+<indexterm><primary>Grabbing</primary><secondary>keys</secondary></indexterm>
+<indexterm significance="preferred"><primary>XGrabKey</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgrabkey'>
+<funcprototype>
+ <funcdef><function>XGrabKey</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> keycode</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+ <paramdef>Bool<parameter> owner_events</parameter></paramdef>
+ <paramdef>intpointer_mode,<parameter> keyboard_mode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeyCode or
+<symbol>AnyKey</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks or
+<symbol>AnyModifier</symbol>.
+The mask is the bitwise inclusive OR of the valid keymask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>owner_events</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that indicates whether the keyboard events
+are to be reported as usual.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pointer_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of pointer events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keyboard_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies further processing of keyboard events.
+You can pass
+<symbol>GrabModeSync</symbol>
+or
+<symbol>GrabModeAsync</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGrabKey</function>
+function establishes a passive grab on the keyboard.
+In the future,
+the keyboard is actively grabbed (as for
+<function>XGrabKeyboard</function>),
+the last-keyboard-grab time is set to the time at which the key was pressed
+(as transmitted in the
+<symbol>KeyPress</symbol>
+event), and the
+<symbol>KeyPress</symbol>
+event is reported if all of the following conditions are true:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The keyboard is not grabbed and the specified key
+(which can itself be a modifier key) is logically pressed
+when the specified modifier keys are logically down,
+and no other modifier keys are logically down.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Either the grab_window is an ancestor of (or is) the focus window,
+or the grab_window is a descendant of the focus window and contains the pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A passive grab on the same key combination does not exist
+on any ancestor of grab_window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The interpretation of the remaining arguments is as for
+<function>XGrabKeyboard</function>.
+The active grab is terminated automatically when the logical state of the
+keyboard has the specified key released
+(independent of the logical state of the modifier keys).
+</para>
+<para>
+<!-- .LP -->
+Note that the logical state of a device (as seen by client applications)
+may lag the physical state if device event processing is frozen.
+</para>
+<para>
+<!-- .LP -->
+A modifiers argument of
+<symbol>AnyModifier</symbol>
+is equivalent to issuing the request for all
+possible modifier combinations (including the combination of no
+modifiers).
+It is not required that all modifiers specified have
+currently assigned KeyCodes.
+A keycode argument of
+<symbol>AnyKey</symbol>
+is equivalent to issuing
+the request for all possible KeyCodes.
+Otherwise, the specified keycode must be in
+the range specified by min_keycode and max_keycode in the connection
+setup,
+or a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If some other client has issued a
+<function>XGrabKey</function>
+with the same key combination on the same window, a
+<errorname>BadAccess</errorname>
+error results.
+When using
+<symbol>AnyModifier</symbol>
+or
+<symbol>AnyKey</symbol>,
+the request fails completely,
+and a
+<errorname>BadAccess</errorname>
+error results (no grabs are established)
+if there is a conflicting grab for any combination.
+</para>
+<para>
+<!-- .LP -->
+<function>XGrabKey</function>
+can generate
+<errorname>BadAccess</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ungrab a key, use
+<function>XUngrabKey</function>.
+</para>
+<indexterm><primary>Key</primary><secondary>ungrabbing</secondary></indexterm>
+<indexterm><primary>Ungrabbing</primary><secondary>keys</secondary></indexterm>
+<indexterm significance="preferred"><primary>XUngrabKey</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xungrabkey'>
+<funcprototype>
+ <funcdef><function>XUngrabKey</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> keycode</parameter></paramdef>
+ <paramdef>unsignedint<parameter> modifiers</parameter></paramdef>
+ <paramdef>Window<parameter> grab_window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeyCode or
+<symbol>AnyKey</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifiers</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the set of keymasks or
+<symbol>AnyModifier</symbol>.
+The mask is the bitwise inclusive OR of the valid keymask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>grab_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the grab window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUngrabKey</function>
+function releases the key combination on the specified window if it was grabbed
+by this client.
+It has no effect on an active grab.
+A modifiers of
+<symbol>AnyModifier</symbol>
+is equivalent to issuing
+the request for all possible modifier combinations
+(including the combination of no modifiers).
+A keycode argument of
+<symbol>AnyKey</symbol>
+is equivalent to issuing the request for all possible key codes.
+</para>
+<para>
+<!-- .LP -->
+<function>XUngrabKey</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Resuming_Event_Processing">
+<title>Resuming Event Processing</title>
+<!-- .XS -->
+<!-- (SN Resuming Event Processing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The previous sections discussed grab mechanisms with which processing
+of events by the server can be temporarily suspended. This section
+describes the mechanism for resuming event processing.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allow further events to be processed when the device has been frozen, use
+<function>XAllowEvents</function>.
+</para>
+<indexterm significance="preferred"><primary>XAllowEvents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xallowevents'>
+<funcprototype>
+ <funcdef><function>XAllowEvents</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> event_mode</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the event mode.
+You can pass
+<symbol>AsyncPointer</symbol>,
+<symbol>SyncPointer</symbol>,
+<symbol>AsyncKeyboard</symbol>,
+<symbol>SyncKeyboard</symbol>,
+<symbol>ReplayPointer</symbol>,
+<symbol>ReplayKeyboard</symbol>,
+<symbol>AsyncBoth</symbol>,
+or
+<symbol>SyncBoth</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllowEvents</function>
+function releases some queued events if the client has caused a device
+to freeze.
+It has no effect if the specified time is earlier than the last-grab
+time of the most recent active grab for the client or if the specified time
+is later than the current X server time.
+Depending on the event_mode argument, the following occurs:
+</para>
+<informaltable frame='none'>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>AsyncPointer</symbol></entry>
+ <entry>If the pointer is frozen by the client,
+ pointer event processing continues as usual.
+ If the pointer is frozen twice by the client on behalf of two separate grabs,
+ <symbol>AsyncPointer</symbol>
+ thaws for both.
+ <symbol>AsyncPointer</symbol>
+ has no effect if the pointer is not frozen by the client,
+ but the pointer need not be grabbed by the client.</entry>
+ </row>
+ <row>
+ <entry><symbol>SyncPointer</symbol></entry>
+ <entry>If the pointer is frozen and actively grabbed by the client,
+ pointer event processing continues as usual until the next
+ <symbol>ButtonPress</symbol>
+ or
+ <symbol>ButtonRelease</symbol>
+ event is reported to the client.
+ At this time,
+ the pointer again appears to freeze.
+ However, if the reported event causes the pointer grab to be released,
+ the pointer does not freeze.
+ <symbol>SyncPointer</symbol>
+ has no effect if the pointer is not frozen by the client
+ or if the pointer is not grabbed by the client.</entry>
+ </row>
+ <row>
+ <entry><symbol>ReplayPointer</symbol></entry>
+ <entry>If the pointer is actively grabbed by the client and is frozen as the result of
+ an event having been sent to the client (either from the activation of an
+ <function>XGrabButton</function>
+ or from a previous
+ <function>XAllowEvents</function>
+ with mode
+ <symbol>SyncPointer</symbol>
+ but not from an
+ <function>XGrabPointer</function>),
+ the pointer grab is released and that event is completely reprocessed.
+ This time, however, the function ignores any passive grabs at or above
+ (toward the root of) the grab_window of the grab just released.
+ The request has no effect if the pointer is not grabbed by the client
+ or if the pointer is not frozen as the result of an event.</entry>
+ </row>
+ <row>
+ <entry><symbol>AsyncKeyboard</symbol></entry>
+ <entry>If the keyboard is frozen by the client,
+ keyboard event processing continues as usual.
+ If the keyboard is frozen twice by the client on behalf of two separate grabs,
+ <symbol>AsyncKeyboard</symbol>
+ thaws for both.
+ <symbol>AsyncKeyboard</symbol>
+ has no effect if the keyboard is not frozen by the client,
+ but the keyboard need not be grabbed by the client.</entry>
+ </row>
+ <row>
+ <entry><symbol>SyncKeyboard</symbol></entry>
+ <entry>If the keyboard is frozen and actively grabbed by the client,
+ keyboard event processing continues as usual until the next
+ <symbol>KeyPress</symbol>
+ or
+ <symbol>KeyRelease</symbol>
+ event is reported to the client.
+ At this time,
+ the keyboard again appears to freeze.
+ However, if the reported event causes the keyboard grab to be released,
+ the keyboard does not freeze.
+ <symbol>SyncKeyboard</symbol>
+ has no effect if the keyboard is not frozen by the client
+ or if the keyboard is not grabbed by the client.</entry>
+ </row>
+ <row>
+ <entry><symbol>ReplayKeyboard</symbol></entry>
+ <entry>If the keyboard is actively grabbed by the client and is frozen
+ as the result of an event having been sent to the client (either from the
+ activation of an
+ <function>XGrabKey</function>
+ or from a previous
+ <function>XAllowEvents</function>
+ with mode
+ <symbol>SyncKeyboard</symbol>
+ but not from an
+ <function>XGrabKeyboard</function>),
+ the keyboard grab is released and that event is completely reprocessed.
+ This time, however, the function ignores any passive grabs at or above
+ (toward the root of)
+ the grab_window of the grab just released.
+ The request has no effect if the keyboard is not grabbed by the client
+ or if the keyboard is not frozen as the result of an event.</entry>
+ </row>
+ <row>
+ <entry><symbol>SyncBoth</symbol></entry>
+ <entry>If both pointer and keyboard are frozen by the client,
+ event processing for both devices continues as usual until the next
+ <symbol>ButtonPress</symbol>,
+ <symbol>ButtonRelease</symbol>,
+ <symbol>KeyPress</symbol>,
+ or
+ <symbol>KeyRelease</symbol>
+ event is reported to the client for a grabbed device
+ (button event for the pointer, key event for the keyboard),
+ at which time the devices again appear to freeze.
+ However, if the reported event causes the grab to be released,
+ then the devices do not freeze (but if the other device is still
+ grabbed, then a subsequent event for it will still cause both devices
+ to freeze).
+ <symbol>SyncBoth</symbol>
+ has no effect unless both pointer and keyboard
+ are frozen by the client.
+ If the pointer or keyboard is frozen twice
+ by the client on behalf of two separate grabs,
+ <symbol>SyncBoth</symbol>
+ thaws for both (but a subsequent freeze for
+ <symbol>SyncBoth</symbol>
+ will only freeze each device once).</entry>
+ </row>
+ <row>
+ <entry><symbol>AsyncBoth</symbol></entry>
+ <entry>If the pointer and the keyboard are frozen by the
+ client, event processing for both devices continues as usual.
+ If a device is frozen twice by the client on behalf of two separate grabs,
+ <symbol>AsyncBoth</symbol>
+ thaws for both.
+ <symbol>AsyncBoth</symbol>
+ has no effect unless both
+ pointer and keyboard are frozen by the client.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+<symbol>AsyncPointer</symbol>,
+<symbol>SyncPointer</symbol>,
+and
+<symbol>ReplayPointer</symbol>
+have no effect on the
+processing of keyboard events.
+<symbol>AsyncKeyboard</symbol>,
+<symbol>SyncKeyboard</symbol>,
+and
+<symbol>ReplayKeyboard</symbol>
+have no effect on the
+processing of pointer events.
+It is possible for both a pointer grab and a keyboard grab (by the same
+or different clients) to be active simultaneously.
+If a device is frozen on behalf of either grab,
+no event processing is performed for the device.
+It is possible for a single device to be frozen because of both grabs.
+In this case,
+the freeze must be released on behalf of both grabs before events can
+again be processed.
+If a device is frozen twice by a single client,
+then a single
+<function>XAllowEvents</function>
+releases both.
+</para>
+<para>
+<!-- .LP -->
+<function>XAllowEvents</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Moving_the_Pointer">
+<title>Moving the Pointer</title>
+<!-- .XS -->
+<!-- (SN Moving the Pointer -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Although movement of the pointer normally should be left to the
+control of the end user, sometimes it is necessary to move the
+pointer to a new position under program control.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To move the pointer to an arbitrary point in a window, use
+<function>XWarpPointer</function>.
+</para>
+<indexterm significance="preferred"><primary>XWarpPointer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwarppointer'>
+<funcprototype>
+ <funcdef><function>XWarpPointer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Windowsrc_w,<parameter> dest_w</parameter></paramdef>
+ <paramdef>intsrc_x,<parameter> src_y</parameter></paramdef>
+ <paramdef>unsignedintsrc_width,<parameter> src_height</parameter></paramdef>
+ <paramdef>intdest_x,<parameter> dest_y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the source window or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the destination window or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify a rectangle in the source window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates within the destination window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If dest_w is
+<symbol>None</symbol>,
+<function>XWarpPointer</function>
+moves the pointer by the offsets (dest_x, dest_y) relative to the current
+position of the pointer.
+If dest_w is a window,
+<function>XWarpPointer</function>
+moves the pointer to the offsets (dest_x, dest_y) relative to the origin of
+dest_w.
+However, if src_w is a window,
+the move only takes place if the window src_w contains the pointer
+and if the specified rectangle of src_w contains the pointer.
+</para>
+<para>
+<!-- .LP -->
+The src_x and src_y coordinates are relative to the origin of src_w.
+If src_height is zero,
+it is replaced with the current height of src_w minus src_y.
+If src_width is zero,
+it is replaced with the current width of src_w minus src_x.
+</para>
+<para>
+<!-- .LP -->
+There is seldom any reason for calling this function.
+The pointer should normally be left to the user.
+If you do use this function, however, it generates events just as if the user
+had instantaneously moved the pointer from one position to another.
+Note that you cannot use
+<function>XWarpPointer</function>
+to move the pointer outside the confine_to window of an active pointer grab.
+An attempt to do so will only move the pointer as far as the closest edge of the
+confine_to window.
+</para>
+<para>
+<!-- .LP -->
+<function>XWarpPointer</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect1>
+<sect1 id="Controlling_Input_Focus">
+<title>Controlling Input Focus</title>
+<!-- .XS -->
+<!-- (SN Controlling Input Focus -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and get the input focus.
+The input focus is a shared resource, and cooperation among clients is
+required for correct interaction. See the
+<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>
+for input focus policy.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the input focus, use
+<function>XSetInputFocus</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetInputFocus</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetinputfocus'>
+<funcprototype>
+ <funcdef><function>XSetInputFocus</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> focus</parameter></paramdef>
+ <paramdef>int<parameter> revert_to</parameter></paramdef>
+ <paramdef>Time<parameter> time</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>focus</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window,
+<symbol>PointerRoot</symbol>,
+or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>revert_to</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies where the input focus reverts to if the window becomes not
+viewable.
+You can pass
+<symbol>RevertToParent</symbol>,
+<symbol>RevertToPointerRoot</symbol>,
+or
+<symbol>RevertToNone</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>time</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the time.
+You can pass either a timestamp or
+<symbol>CurrentTime</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetInputFocus</function>
+function changes the input focus and the last-focus-change time.
+It has no effect if the specified time is earlier than the current
+last-focus-change time or is later than the current X server time.
+Otherwise, the last-focus-change time is set to the specified time
+(<symbol>CurrentTime</symbol>
+is replaced by the current X server time).
+<function>XSetInputFocus</function>
+causes the X server to generate
+<symbol>FocusIn</symbol>
+and
+<symbol>FocusOut</symbol>
+events.
+</para>
+<para>
+<!-- .LP -->
+Depending on the focus argument,
+the following occurs:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If focus is
+<symbol>None</symbol>,
+all keyboard events are discarded until a new focus window is set,
+and the revert_to argument is ignored.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If focus is a window,
+it becomes the keyboard's focus window.
+If a generated keyboard event would normally be reported to this window
+or one of its inferiors, the event is reported as usual.
+Otherwise, the event is reported relative to the focus window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If focus is
+<symbol>PointerRoot</symbol>,
+the focus window is dynamically taken to be the root window of whatever screen
+the pointer is on at each keyboard event.
+In this case, the revert_to argument is ignored.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The specified focus window must be viewable at the time
+<function>XSetInputFocus</function>
+is called,
+or a
+<errorname>BadMatch</errorname>
+error results.
+If the focus window later becomes not viewable,
+the X server
+evaluates the revert_to argument to determine the new focus window as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+If revert_to is
+<symbol>RevertToParent</symbol>,
+the focus reverts to the parent (or the closest viewable ancestor),
+and the new revert_to value is taken to be
+<symbol>RevertToNone</symbol>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If revert_to is
+<symbol>RevertToPointerRoot</symbol>
+or
+<symbol>RevertToNone</symbol>,
+the focus reverts to
+<symbol>PointerRoot</symbol>
+or
+<symbol>None</symbol>,
+respectively.
+When the focus reverts,
+the X server generates
+<symbol>FocusIn</symbol>
+and
+<symbol>FocusOut</symbol>
+events, but the last-focus-change time is not affected.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XSetInputFocus</function>
+can generate
+<errorname>BadMatch</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the current input focus, use
+<function>XGetInputFocus</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetInputFocus</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetinputfocus'>
+<funcprototype>
+ <funcdef><function>XGetInputFocus</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> *focus_return</parameter></paramdef>
+ <paramdef>int<parameter> *revert_to_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>focus_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the focus window,
+<symbol>PointerRoot</symbol>,
+or
+<symbol>None</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>revert_to_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the current focus state
+(<symbol>RevertToParent</symbol>,
+<symbol>RevertToPointerRoot</symbol>,
+or
+<symbol>RevertToNone</symbol>).
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetInputFocus</function>
+function returns the focus window and the current focus state.
+</para>
+</sect1>
+<sect1 id="Manipulating_the_Keyboard_and_Pointer_Settings">
+<title>Manipulating the Keyboard and Pointer Settings</title>
+<!-- .XS -->
+<!-- (SN Manipulating the Keyboard and Pointer Settings -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to
+change the keyboard control, obtain a list of the auto-repeat keys,
+turn keyboard auto-repeat on or off, ring the bell,
+set or obtain the pointer button or keyboard mapping,
+and obtain a bit vector for the keyboard.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>Keyboard</primary><secondary>bell volume</secondary></indexterm>
+<indexterm><primary>Keyboard</primary><secondary>keyclick volume</secondary></indexterm>
+<indexterm><primary>Keyboard</primary><secondary>bit vector</secondary></indexterm>
+<indexterm><primary>Mouse</primary><secondary>programming</secondary></indexterm>
+This section discusses
+the user-preference options of bell, key click,
+pointer behavior, and so on.
+The default values for many of these options are server dependent.
+Not all implementations will actually be able to control all of these
+parameters.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XChangeKeyboardControl</function>
+function changes control of a keyboard and operates on a
+<structname>XKeyboardControl</structname>
+structure:
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+/* Mask bits for ChangeKeyboardControl */
+
+
+#define KBBellPercent (1L<<0)
+#define KBBellPitch (1L<<1)
+#define KBBellDuration (1L<<2)
+#define KBLed (1L<<3)
+#define KBLedMode (1L<<4)
+#define KBKey (1L<<5)
+#define KBAutoRepeatMode (1L<<6)
+
+
+/* Values */
+
+typedef struct {
+int key_click_percent;
+int bell_percent;
+int bell_pitch;
+int bell_duration;
+int led;
+int led_mode; /* LedModeOn, LedModeOff */
+int key;
+int auto_repeat_mode; /* AutoRepeatModeOff, AutoRepeatModeOn,
+ AutoRepeatModeDefault */
+} XKeyboardControl;
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The key_click_percent member sets the volume for key clicks between 0 (off)
+and 100 (loud) inclusive, if possible.
+A setting of -1 restores the default.
+Other negative values generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+The bell_percent sets the base volume for the bell between 0 (off) and 100
+(loud) inclusive, if possible.
+A setting of -1 restores the default.
+Other negative values generate a
+<errorname>BadValue</errorname>
+error.
+The bell_pitch member sets the pitch (specified in Hz) of the bell, if possible.
+A setting of -1 restores the default.
+Other negative values generate a
+<errorname>BadValue</errorname>
+error.
+The bell_duration member sets the duration of the
+bell specified in milliseconds, if possible.
+A setting of -1 restores the default.
+Other negative values generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+If both the led_mode and led members are specified,
+the state of that <acronym>LED</acronym> is changed, if possible.
+The led_mode member can be set to
+<symbol>LedModeOn</symbol>
+or
+<symbol>LedModeOff</symbol>.
+If only led_mode is specified, the state of
+all LEDs are changed, if possible.
+At most 32 LEDs numbered from one are supported.
+No standard interpretation of LEDs is defined.
+If led is specified without led_mode, a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+If both the auto_repeat_mode and key members are specified,
+the auto_repeat_mode of that key is changed (according to
+<symbol>AutoRepeatModeOn</symbol>,
+<symbol>AutoRepeatModeOff</symbol>,
+or
+<symbol>AutoRepeatModeDefault</symbol>),
+if possible.
+If only auto_repeat_mode is
+specified, the global auto_repeat_mode for the entire keyboard is
+changed, if possible, and does not affect the per-key settings.
+If a key is specified without an auto_repeat_mode, a
+<errorname>BadMatch</errorname>
+error results.
+Each key has an individual mode of whether or not it should auto-repeat
+and a default setting for the mode.
+In addition,
+there is a global mode of whether auto-repeat should be enabled or not
+and a default setting for that mode.
+When global mode is
+<symbol>AutoRepeatModeOn</symbol>,
+keys should obey their individual auto-repeat modes.
+When global mode is
+<symbol>AutoRepeatModeOff</symbol>,
+no keys should auto-repeat.
+An auto-repeating key generates alternating
+<symbol>KeyPress</symbol>
+and
+<symbol>KeyRelease</symbol>
+events.
+When a key is used as a modifier,
+it is desirable for the key not to auto-repeat,
+regardless of its auto-repeat setting.
+</para>
+<para>
+<!-- .LP -->
+A bell generator connected with the console but not directly on a
+keyboard is treated as if it were part of the keyboard.
+The order in which controls are verified and altered is server-dependent.
+If an error is generated, a subset of the controls may have been altered.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+</para>
+<indexterm significance="preferred"><primary>XChangeKeyboardControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangekeyboardcontrol'>
+<funcprototype>
+ <funcdef><function>XChangeKeyboardControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> value_mask</parameter></paramdef>
+ <paramdef>XKeyboardControl<parameter> *values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which controls to change.
+This mask is the bitwise inclusive OR of the valid control mask bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies one value for each bit set to 1 in the mask.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangeKeyboardControl</function>
+function controls the keyboard characteristics defined by the
+<structname>XKeyboardControl</structname>
+structure.
+The value_mask argument specifies which values are to be changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeKeyboardControl</function>
+can generate
+<errorname>BadMatch</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the current control values for the keyboard, use
+<function>XGetKeyboardControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetKeyboardControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetkeyboardcontrol'>
+<funcprototype>
+ <funcdef><function>XGetKeyboardControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XKeyboardState<parameter> *values_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the current keyboard controls in the specified
+<structname>XKeyboardState</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetKeyboardControl</function>
+function returns the current control values for the keyboard to the
+<structname>XKeyboardState</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<indexterm><primary>XGetKeyboardControl</primary></indexterm>
+<indexterm significance="preferred"><primary>XKeyboardState</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ int key_click_percent;
+ int bell_percent;
+ unsigned int bell_pitch, bell_duration;
+ unsigned long led_mask;
+ int global_auto_repeat;
+ char auto_repeats[32];
+} XKeyboardState;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+For the LEDs,
+the least significant bit of led_mask corresponds to <acronym>LED</acronym> one,
+and each bit set to 1 in led_mask indicates an <acronym>LED</acronym> that is lit.
+The global_auto_repeat member can be set to
+<symbol>AutoRepeatModeOn</symbol>
+or
+<symbol>AutoRepeatModeOff</symbol>.
+The auto_repeats member is a bit vector.
+Each bit set to 1 indicates that auto-repeat is enabled
+for the corresponding key.
+The vector is represented as 32 bytes.
+Byte N (from 0) contains the bits for keys 8N to 8N + 7
+with the least significant bit in the byte representing key 8N.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To turn on keyboard auto-repeat, use
+<function>XAutoRepeatOn</function>.
+</para>
+<indexterm significance="preferred"><primary>XAutoRepeatOn</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xautorepeaton'>
+<funcprototype>
+ <funcdef><function>XAutoRepeatOn</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAutoRepeatOn</function>
+function turns on auto-repeat for the keyboard on the specified display.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To turn off keyboard auto-repeat, use
+<function>XAutoRepeatOff</function>.
+</para>
+<indexterm significance="preferred"><primary>XAutoRepeatOff</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xautorepeatoff'>
+<funcprototype>
+ <funcdef><function>XAutoRepeatOff</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAutoRepeatOff</function>
+function turns off auto-repeat for the keyboard on the specified display.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To ring the bell, use
+<function>XBell</function>.
+</para>
+<indexterm significance="preferred"><primary>XBell</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xbell'>
+<funcprototype>
+ <funcdef><function>XBell</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> percent</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>percent</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the volume for the bell,
+which can range from -100 to 100 inclusive.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XBell</function>
+function rings the bell on the keyboard on the specified display, if possible.
+The specified volume is relative to the base volume for the keyboard.
+If the value for the percent argument is not in the range -100 to 100
+inclusive, a
+<errorname>BadValue</errorname>
+error results.
+The volume at which the bell rings
+when the percent argument is nonnegative is:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+base - [(base * percent) / 100] + percent
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The volume at which the bell rings
+when the percent argument is negative is:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+base + [(base * percent) / 100]
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+To change the base volume of the bell, use
+<function>XChangeKeyboardControl</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XBell</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a bit vector that describes the state of the keyboard, use
+<function>XQueryKeymap</function>.
+</para>
+<indexterm significance="preferred"><primary>XQueryKeymap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xquerykeymap'>
+<funcprototype>
+ <funcdef><function>XQueryKeymap</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> keys_return[32]</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keys_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns an array of bytes that identifies which keys are pressed down.
+Each bit represents one key of the keyboard.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XQueryKeymap</function>
+function returns a bit vector for the logical state of the keyboard,
+where each bit set to 1 indicates that the corresponding key is currently
+pressed down.
+The vector is represented as 32 bytes.
+Byte N (from 0) contains the bits for keys 8N to 8N + 7
+with the least significant bit in the byte representing key 8N.
+</para>
+<para>
+<!-- .LP -->
+Note that the logical state of a device (as seen by client applications)
+may lag the physical state if device event processing is frozen.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the mapping of the pointer buttons, use
+<function>XSetPointerMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetPointerMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetpointermapping'>
+<funcprototype>
+ <funcdef>int <function>XSetPointerMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> map[]</parameter></paramdef>
+ <paramdef>int<parameter> nmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>map</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of items in the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetPointerMapping</function>
+function sets the mapping of the pointer.
+If it succeeds, the X server generates a
+<symbol>MappingNotify</symbol>
+event, and
+<function>XSetPointerMapping</function>
+returns
+<symbol>MappingSuccess</symbol>.
+Element map[i] defines the logical button number for the physical button
+i+1.
+The length of the list must be the same as
+<function>XGetPointerMapping</function>
+would return,
+or a
+<errorname>BadValue</errorname>
+error results.
+A zero element disables a button, and elements are not restricted in
+value by the number of physical buttons.
+However, no two elements can have the same nonzero value,
+or a
+<errorname>BadValue</errorname>
+error results.
+If any of the buttons to be altered are logically in the down state,
+<function>XSetPointerMapping</function>
+returns
+<symbol>MappingBusy</symbol>,
+and the mapping is not changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetPointerMapping</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the pointer mapping, use
+<function>XGetPointerMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetPointerMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetpointermapping'>
+<funcprototype>
+ <funcdef>int <function>XGetPointerMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> map_return[]</parameter></paramdef>
+ <paramdef>int<parameter> nmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>map_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of items in the mapping list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetPointerMapping</function>
+function returns the current mapping of the pointer.
+Pointer buttons are numbered starting from one.
+<function>XGetPointerMapping</function>
+returns the number of physical buttons actually on the pointer.
+The nominal mapping for a pointer is map[i]=i+1.
+The nmap argument specifies the length of the array where the pointer
+mapping is returned, and only the first nmap elements are returned
+in map_return.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To control the pointer's interactive feel, use
+<function>XChangePointerControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XChangePointerControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangepointercontrol'>
+<funcprototype>
+ <funcdef><function>XChangePointerControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Booldo_accel,<parameter> do_threshold</parameter></paramdef>
+ <paramdef>intaccel_numerator,<parameter> accel_denominator</parameter></paramdef>
+ <paramdef>int<parameter> threshold</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>do_accel</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that controls whether the values for
+the accel_numerator or accel_denominator are used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>do_threshold</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a Boolean value that controls whether the value for the
+threshold is used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>accel_numerator</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the numerator for the acceleration multiplier.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>accel_denominator</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the denominator for the acceleration multiplier.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>threshold</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the acceleration threshold.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangePointerControl</function>
+function defines how the pointing device moves.
+The acceleration, expressed as a fraction, is a
+multiplier for movement.
+For example,
+specifying 3/1 means the pointer moves three times as fast as normal.
+The fraction may be rounded arbitrarily by the X server.
+Acceleration
+only takes effect if the pointer moves more than threshold pixels at
+once and only applies to the amount beyond the value in the threshold argument.
+Setting a value to -1 restores the default.
+The values of the do_accel and do_threshold arguments must be
+<symbol>True</symbol>
+for the pointer values to be set,
+or the parameters are unchanged.
+Negative values (other than -1) generate a
+<errorname>BadValue</errorname>
+error, as does a zero value
+for the accel_denominator argument.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangePointerControl</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the current pointer parameters, use
+<function>XGetPointerControl</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetPointerControl</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetpointercontrol'>
+<funcprototype>
+ <funcdef><function>XGetPointerControl</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int*accel_numerator_return,<parameter> *accel_denominator_return</parameter></paramdef>
+ <paramdef>int<parameter> *threshold_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>accel_numerator_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the numerator for the acceleration multiplier.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>accel_denominator_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the denominator for the acceleration multiplier.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>threshold_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the acceleration threshold.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetPointerControl</function>
+function returns the pointer's current acceleration multiplier
+and acceleration threshold.
+</para>
+</sect1>
+<sect1 id="Manipulating_the_Keyboard_Encoding">
+<title>Manipulating the Keyboard Encoding</title>
+<!-- .XS -->
+<!-- (SN Manipulating the Keyboard Encoding -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A KeyCode represents a physical (or logical) key.
+KeyCodes lie in the inclusive range [8,255].
+A KeyCode value carries no intrinsic information,
+although server implementors may attempt to encode geometry
+(for example, matrix) information in some fashion so that it can
+be interpreted in a server-dependent fashion.
+The mapping between keys and KeyCodes cannot be changed.
+</para>
+<para>
+<!-- .LP -->
+A KeySym is an encoding of a symbol on the cap of a key.
+The set of defined KeySyms includes the ISO Latin character sets (1-4),
+Katakana, Arabic, Cyrillic, Greek, Technical,
+Special, Publishing, APL, Hebrew, Thai, Korean
+and a miscellany of keys found
+on keyboards (Return, Help, Tab, and so on).
+To the extent possible, these sets are derived from international
+standards.
+In areas where no standards exist,
+some of these sets are derived from Digital Equipment Corporation standards.
+The list of defined symbols can be found in
+<filename class="headerfile"><X11/keysymdef.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/keysymdef.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm>
+Unfortunately, some C preprocessors have
+limits on the number of defined symbols.
+If you must use KeySyms not
+in the Latin 1-4, Greek, and miscellaneous classes,
+you may have to define a symbol for those sets.
+Most applications usually only include
+<filename class="headerfile"><X11/keysym.h></filename>,
+<indexterm type="file"><primary><filename class="headerfile">X11/keysym.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysym.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysym.h></filename></secondary></indexterm>
+which defines symbols for ISO Latin 1-4, Greek, and miscellaneous.
+</para>
+<para>
+<!-- .LP -->
+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
+<symbol>NoSymbol</symbol>
+entries) is
+a single KeySym ``<emphasis remap='I'>K</emphasis>'',
+then the list is treated as if it were the list
+``<emphasis remap='I'>K</emphasis> NoSymbol <emphasis remap='I'>K</emphasis> NoSymbol''.
+If the list (ignoring trailing
+<symbol>NoSymbol</symbol>
+entries) is a pair of KeySyms ``<emphasis remap='I'>K1 K2</emphasis>'',
+then the list is treated as if it were the list ``<emphasis remap='I'>K1 K2 K1 K2</emphasis>''.
+If the list (ignoring trailing
+<symbol>NoSymbol</symbol>
+entries) is a triple of KeySyms ``<emphasis remap='I'>K1 K2 K3</emphasis>'',
+then the list is treated as if it were the list ``<emphasis remap='I'>K1 K2 K3</emphasis> NoSymbol''.
+When an explicit ``void'' element is desired in the list,
+the value
+<symbol>VoidSymbol</symbol>
+can be used.
+</para>
+<para>
+<!-- .LP -->
+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
+<symbol>NoSymbol</symbol>,
+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 ``<emphasis remap='I'>K</emphasis>''
+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 ``<emphasis remap='I'>K</emphasis>'' and the second element were
+the uppercase form of ``<emphasis remap='I'>K</emphasis>''.
+</para>
+<para>
+<!-- .LP -->
+The standard rules for obtaining a KeySym from a
+<symbol>KeyPress</symbol>
+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
+<symbol>Mod1</symbol>
+through
+<symbol>Mod5</symbol>.
+This modifier is called the <emphasis remap='I'>group modifier</emphasis>.
+For any KeyCode,
+Group 1 is used when the group modifier is off,
+and Group 2 is used when the group modifier is on.
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>Lock</symbol>
+modifier is interpreted as CapsLock when the KeySym named XK_Caps_Lock
+is attached to some KeyCode and that KeyCode is attached to the
+<symbol>Lock</symbol>
+modifier. The
+<symbol>Lock</symbol>
+modifier is interpreted as ShiftLock when the KeySym named XK_Shift_Lock
+is attached to some KeyCode and that KeyCode is attached to the
+<symbol>Lock</symbol>
+modifier. If the
+<symbol>Lock</symbol>
+modifier could be interpreted as both
+CapsLock and ShiftLock, the CapsLock interpretation is used.
+</para>
+<para>
+<!-- .LP -->
+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
+<symbol>Mod1</symbol>
+through
+<symbol>Mod5</symbol>.
+This modifier is called the
+<emphasis remap='I'>numlock modifier</emphasis>. 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.
+</para>
+<para>
+<!-- .LP -->
+Within a group, the choice of KeySym is determined by applying the first
+rule that is satisfied from the following list:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The numlock modifier is on and the second KeySym is a keypad KeySym. In
+this case, if the
+<symbol>Shift</symbol>
+modifier is on, or if the
+<symbol>Lock</symbol>
+modifier is on and
+is interpreted as ShiftLock, then the first KeySym is used, otherwise the
+second KeySym is used.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The
+<symbol>Shift</symbol>
+and
+<symbol>Lock</symbol>
+modifiers are both off. In this case, the first
+KeySym is used.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The
+<symbol>Shift</symbol>
+modifier is off, and the
+<symbol>Lock</symbol>
+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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The
+<symbol>Shift</symbol>
+modifier is on, and the
+<symbol>Lock</symbol>
+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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The
+<symbol>Shift</symbol>
+modifier is on, or the
+<symbol>Lock</symbol>
+modifier is on and is interpreted
+as ShiftLock, or both. In this case, the second KeySym is used.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+No spatial geometry of the symbols on the key is defined by
+their order in the KeySym list,
+although a geometry might be defined on a
+server-specific basis.
+The X server does not use the mapping between KeyCodes and KeySyms.
+Rather, it merely stores it for reading and writing by clients.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the legal KeyCodes for a display, use
+<function>XDisplayKeycodes</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisplayKeycodes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisplaykeycodes'>
+<funcprototype>
+ <funcdef><function>XDisplayKeycodes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int*min_keycodes_return,<parameter> *max_keycodes_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>min_keycodes_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the minimum number of KeyCodes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>max_keycodes_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the maximum number of KeyCodes.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDisplayKeycodes</function>
+function returns the min-keycodes and max-keycodes supported by the
+specified display.
+The minimum number of KeyCodes returned is never less than 8,
+and the maximum number of KeyCodes returned is never greater than 255.
+Not all KeyCodes in this range are required to have corresponding keys.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the symbols for the specified KeyCodes, use
+<function>XGetKeyboardMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetKeyboardMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetkeyboardmapping'>
+<funcprototype>
+ <funcdef>KeySym *<function>XGetKeyboardMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>KeyCode<parameter> first_keycode</parameter></paramdef>
+ <paramdef>int<parameter> keycode_count</parameter></paramdef>
+ <paramdef>int<parameter> *keysyms_per_keycode_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Kc returned -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>first_keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the first KeyCode that is to be (Kc.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of KeyCodes that are to be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms_per_keycode_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of KeySyms per KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetKeyboardMapping</function>
+function returns the symbols for the specified number of KeyCodes
+starting with first_keycode.
+The value specified in first_keycode must be greater than
+or equal to min_keycode as returned by
+<function>XDisplayKeycodes</function>,
+or a
+<errorname>BadValue</errorname>
+error results.
+In addition, the following expression must be less than or equal
+to max_keycode as returned by
+<function>XDisplayKeycodes</function>:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+first_keycode + keycode_count - 1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If this is not the case, a
+<errorname>BadValue</errorname>
+error results.
+The number of elements in the KeySyms list is:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+keycode_count * keysyms_per_keycode_return
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+KeySym number N, counting from zero, for KeyCode K has the following index
+in the list, counting from zero:
+<literallayout class="monospaced">
+(K - first_code) * keysyms_per_code_return + N
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The X server arbitrarily chooses the keysyms_per_keycode_return value
+to be large enough to report all requested symbols.
+A special KeySym value of
+<symbol>NoSymbol</symbol>
+is used to fill in unused elements for
+individual KeyCodes.
+To free the storage returned by
+<function>XGetKeyboardMapping</function>,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetKeyboardMapping</function>
+can generate a
+<errorname>BadValue</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To change the keyboard mapping, use
+<function>XChangeKeyboardMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XChangeKeyboardMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xchangekeyboardmapping'>
+<funcprototype>
+ <funcdef><function>XChangeKeyboardMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> first_keycode</parameter></paramdef>
+ <paramdef>int<parameter> keysyms_per_keycode</parameter></paramdef>
+ <paramdef>KeySym<parameter> *keysyms</parameter></paramdef>
+ <paramdef>int<parameter> num_codes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Kc changed -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>first_keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the first KeyCode that is to be (Kc.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms_per_keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of KeySyms per KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysyms</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of KeySyms.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_codes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of KeyCodes that are to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XChangeKeyboardMapping</function>
+function defines the symbols for the specified number of KeyCodes
+starting with first_keycode.
+The symbols for KeyCodes outside this range remain unchanged.
+The number of elements in keysyms must be:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+num_codes * keysyms_per_keycode
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The specified first_keycode must be greater than or equal to min_keycode
+returned by
+<function>XDisplayKeycodes</function>,
+or a
+<errorname>BadValue</errorname>
+error results.
+In addition, the following expression must be less than or equal to
+max_keycode as returned by
+<function>XDisplayKeycodes</function>,
+or a
+<errorname>BadValue</errorname>
+error results:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+first_keycode + num_codes - 1
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+KeySym number N, counting from zero, for KeyCode K has the following index
+in keysyms, counting from zero:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+(K - first_keycode) * keysyms_per_keycode + N
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The specified keysyms_per_keycode can be chosen arbitrarily by the client
+to be large enough to hold all desired symbols.
+A special KeySym value of
+<symbol>NoSymbol</symbol>
+should be used to fill in unused elements
+for individual KeyCodes.
+It is legal for
+<symbol>NoSymbol</symbol>
+to appear in nontrailing positions
+of the effective list for a KeyCode.
+<function>XChangeKeyboardMapping</function>
+generates a
+<symbol>MappingNotify</symbol>
+event.
+</para>
+<para>
+<!-- .LP -->
+There is no requirement that the X server interpret this mapping.
+It is merely stored for reading and writing by clients.
+</para>
+<para>
+<!-- .LP -->
+<function>XChangeKeyboardMapping</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+The next six functions make use of the
+<structname>XModifierKeymap</structname>
+data structure, which contains:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XModifierKeymap</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int max_keypermod; /* This server's max number of keys per modifier */
+ KeyCode *modifiermap; /* An 8 by max_keypermod array of the modifiers */
+} XModifierKeymap;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+To create an
+<structname>XModifierKeymap</structname>
+structure, use
+<function>XNewModifiermap</function>.
+</para>
+<indexterm significance="preferred"><primary>XNewModifiermap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xnewmodifiermap'>
+<funcprototype>
+ <funcdef>XModifierKeymap *<function>XNewModifiermap</function></funcdef>
+ <paramdef>int<parameter> max_keys_per_mod</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>max_keys_per_mod</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of KeyCode entries preallocated to the modifiers
+in the map.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XNewModifiermap</function>
+function returns a pointer to
+<structname>XModifierKeymap</structname>
+structure for later use.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a new entry to an
+<structname>XModifierKeymap</structname>
+structure, use
+<function>XInsertModifiermapEntry</function>.
+</para>
+<indexterm significance="preferred"><primary>XInsertModifiermapEntry</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xinsertmodifiermapentry'>
+<funcprototype>
+ <funcdef>XModifierKeymap *<function>XInsertModifiermapEntry</function></funcdef>
+ <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef>
+ <paramdef>KeyCode<parameter> keycode_entry</parameter></paramdef>
+ <paramdef>int<parameter> modifier</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XModifierKeymap</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode_entry</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the modifier.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XInsertModifiermapEntry</function>
+function adds the specified KeyCode to the set that controls the specified
+modifier and returns the resulting
+<structname>XModifierKeymap</structname>
+structure (expanded as needed).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To delete an entry from an
+<structname>XModifierKeymap</structname>
+structure, use
+<function>XDeleteModifiermapEntry</function>.
+</para>
+<indexterm significance="preferred"><primary>XDeleteModifiermapEntry</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdeletemodifiermapentry'>
+<funcprototype>
+ <funcdef>XModifierKeymap *<function>XDeleteModifiermapEntry</function></funcdef>
+ <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef>
+ <paramdef>KeyCode<parameter> keycode_entry</parameter></paramdef>
+ <paramdef>int<parameter> modifier</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XModifierKeymap</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode_entry</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the modifier.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDeleteModifiermapEntry</function>
+function deletes the specified KeyCode from the set that controls the
+specified modifier and returns a pointer to the resulting
+<structname>XModifierKeymap</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy an
+<structname>XModifierKeymap</structname>
+structure, use
+<function>XFreeModifiermap</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeModifiermap</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreemodifiermap'>
+<funcprototype>
+ <funcdef><function>XFreeModifiermap</function></funcdef>
+ <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XModifierKeymap</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeModifiermap</function>
+function frees the specified
+<structname>XModifierKeymap</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the KeyCodes to be used as modifiers, use
+<function>XSetModifierMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetModifierMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetmodifiermapping'>
+<funcprototype>
+ <funcdef>int <function>XSetModifierMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XModifierKeymap<parameter> *modmap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XModifierKeymap</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetModifierMapping</function>
+function specifies the KeyCodes of the keys (if any) that are to be used
+as modifiers.
+If it succeeds,
+the X server generates a
+<symbol>MappingNotify</symbol>
+event, and
+<function>XSetModifierMapping</function>
+returns
+<symbol>MappingSuccess</symbol>.
+X permits at most 8 modifier keys.
+If more than 8 are specified in the
+<structname>XModifierKeymap</structname>
+structure, a
+<errorname>BadLength</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+The modifiermap member of the
+<structname>XModifierKeymap</structname>
+structure contains 8 sets of max_keypermod KeyCodes,
+one for each modifier in the order
+<symbol>Shift</symbol>,
+<symbol>Lock</symbol>,
+<symbol>Control</symbol>,
+<symbol>Mod1</symbol>,
+<symbol>Mod2</symbol>,
+<symbol>Mod3</symbol>,
+<symbol>Mod4</symbol>,
+and
+<symbol>Mod5</symbol>.
+Only nonzero KeyCodes have meaning in each set,
+and zero KeyCodes are ignored.
+In addition, all of the nonzero KeyCodes must be in the range specified by
+min_keycode and max_keycode in the
+<type>Display</type>
+structure,
+or a
+<errorname>BadValue</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+An X server can impose restrictions on how modifiers can be changed,
+for example,
+if certain keys do not generate up transitions in hardware,
+if auto-repeat cannot be disabled on certain keys,
+or if multiple modifier keys are not supported.
+If some such restriction is violated,
+the status reply is
+<symbol>MappingFailed</symbol>,
+and none of the modifiers are changed.
+If the new KeyCodes specified for a modifier differ from those
+currently defined and any (current or new) keys for that modifier are
+in the logically down state,
+<function>XSetModifierMapping</function>
+returns
+<symbol>MappingBusy</symbol>,
+and none of the modifiers is changed.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetModifierMapping</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the KeyCodes used as modifiers, use
+<function>XGetModifierMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetModifierMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetmodifiermapping'>
+<funcprototype>
+ <funcdef>XModifierKeymap *<function>XGetModifierMapping</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetModifierMapping</function>
+function returns a pointer to a newly created
+<structname>XModifierKeymap</structname>
+structure that contains the keys being used as modifiers.
+The structure should be freed after use by calling
+<function>XFreeModifiermap</function>.
+If only zero values appear in the set for any modifier,
+that modifier is disabled.
+<!-- .bp -->
+
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH13.xml b/libX11/specs/libX11/CH13.xml index 65a92e729..4ebe19c57 100644 --- a/libX11/specs/libX11/CH13.xml +++ b/libX11/specs/libX11/CH13.xml @@ -1,10326 +1,10326 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="locales_and_internationalized_text_functions"> -<title>Locales and Internationalized Text Functions</title> - -<para> -An internationalized application is one that is adaptable to the requirements of different native -languages, local customs, and character string encodings. The process of adapting the operation -to a particular native language, local custom, or string encoding is called localization. A goal of -internationalization is to permit localization without program source modifications or recompilation. -</para> -<para> -As one of the localization mechanisms, Xlib provides an X Input Method (<acronym>XIM</acronym>) -functional interface for internationalized text input and an X Output Method -(<acronym>XOM</acronym>) functional interface for internationalized text output. -</para> -<para> -Internationalization in X is based on the concept of a locale. A locale defines the localized -behavior of a program at run time. Locales affect Xlib in its: -</para> - -<itemizedlist> - <listitem><para>Encoding and processing of input method text</para></listitem> - <listitem><para>Encoding of resource files and values</para></listitem> - <listitem><para>Encoding and imaging of text strings</para></listitem> - <listitem><para>Encoding and decoding for inter-client text communication</para></listitem> -</itemizedlist> - - -<para> -• -Encoding and decoding for inter-client text communication -Characters from various languages are represented in a computer using an encoding. -Different languages have different encodings, and there are even different -encodings for the same characters in the same language. -</para> -<para> -This chapter defines support for localized text imaging and text input and describes the locale -mechanism that controls all locale-dependent Xlib functions. Sets of functions are provided for -multibyte (char *) text as well as wide character (wchar_t) text in the form supported by the host -C language environment. The multibyte and wide character functions are equivalent except for -the form of the text argument. -</para> -<para> -The Xlib internationalization functions are not meant to provide support for -multilingual applications (mixing multiple languages within a single piece of text), -but they make it possible to implement applications that work in limited -fashion with more than one language in independent contexts. -</para> -<para> -The remainder of this chapter discusses: -</para> - -<itemizedlist> - <listitem><para>X locale management</para></listitem> - <listitem><para>Locale and modifier dependencies</para></listitem> - <listitem><para>Variable argument lists</para></listitem> - <listitem><para>Output methods</para></listitem> - <listitem><para>Input methods</para></listitem> - <listitem><para>String constants</para></listitem> -</itemizedlist> - - -<sect1 id="X_Locale_Management"> -<title>X Locale Management</title> -<!-- .XS --> -<!-- (SN X Locale Management --> -<!-- .XE --> -<para> -<!-- .LP --> -X supports one or more of the locales defined by the host environment. -On implementations that conform to the ANSI C library, -the locale announcement method is -<function>setlocale</function>. -This function configures the locale operation of both -the host C library and Xlib. -The operation of Xlib is governed by the LC_CTYPE category; -this is called the <emphasis remap='I'>current locale</emphasis>. -An implementation is permitted to provide implementation-dependent -mechanisms for announcing the locale in addition to -<function>setlocale</function>. -</para> -<para> -<!-- .LP --> -On implementations that do not conform to the ANSI C library, -the locale announcement method is Xlib implementation-dependent. -</para> -<para> -<!-- .LP --> -The mechanism by which the semantic operation of Xlib is defined -for a specific locale is implementation-dependent. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -X is not required to support all the locales supported by the host. -To determine if the current locale is supported by X, use -<function>XSupportsLocale</function>. -</para> - -<para>Bool XSupportsLocale()</para> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSupportsLocale</function> -function returns -<symbol>True</symbol> -if Xlib functions are capable of operating under the current locale. -If it returns -<symbol>False</symbol>, -Xlib locale-dependent functions for which the -<symbol>XLocaleNotSupported</symbol> -return status is defined will return -<symbol>XLocaleNotSupported</symbol>. -Other Xlib locale-dependent routines will operate in the ``C'' locale. -</para> -<para> -<!-- .LP --> -The client is responsible for selecting its locale and X modifiers. -Clients should provide a means for the user to override the clients' -locale selection at client invocation. -Most single-display X clients operate in a single locale -for both X and the host processing environment. -They will configure the locale by calling three functions: -the host locale configuration function, -<function>XSupportsLocale</function>, -and -<function>XSetLocaleModifiers</function>. -</para> -<para> -<!-- .LP --> -The semantics of certain categories of X internationalization capabilities -can be configured by setting modifiers. -Modifiers are named by implementation-dependent and locale-specific strings. -The only standard use for this capability at present -is selecting one of several styles of keyboard input method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To configure Xlib locale modifiers for the current locale, use -<function>XSetLocaleModifiers</function>. -</para> -<indexterm significance="preferred"><primary>XSetLocaleModifiers</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetlocalemodifiers'> -<funcprototype> - <funcdef>char *<function>XSetLocaleModifiers</function></funcdef> - <paramdef>char<parameter> *modifier_list</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>modifier_list</emphasis> - </term> - <listitem> - <para> -Specifies the modifiers. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetLocaleModifiers</function> -function sets the X modifiers for the current locale setting. -The modifier_list argument is a null-terminated string of the form -``{@<emphasis remap='I'>category</emphasis>=<emphasis remap='I'>value</emphasis>}'', that is, -having zero or more concatenated ``@<emphasis remap='I'>category</emphasis>=<emphasis remap='I'>value</emphasis>'' -entries, where <emphasis remap='I'>category</emphasis> is a category name -and <emphasis remap='I'>value</emphasis> is the (possibly empty) setting for that category. -The values are encoded in the current locale. -Category names are restricted to the <acronym>POSIX</acronym> Portable Filename Character Set. -</para> -<para> -<!-- .LP --> -The local host X locale modifiers announcer (on <acronym>POSIX</acronym>-compliant systems, -the XMODIFIERS environment variable) is appended to the modifier_list to -provide default values on the local host. -If a given category appears more than once in the list, -the first setting in the list is used. -If a given category is not included in the full modifier list, -the category is set to an implementation-dependent default -for the current locale. -An empty value for a category explicitly specifies the -implementation-dependent default. -</para> -<para> -<!-- .LP --> -If the function is successful, it returns a pointer to a string. -The contents of the string are such that a subsequent call with that string -(in the same locale) will restore the modifiers to the same settings. -If modifier_list is a NULL pointer, -<function>XSetLocaleModifiers</function> -also returns a pointer to such a string, -and the current locale modifiers are not changed. -</para> -<para> -<!-- .LP --> -If invalid values are given for one or more modifier categories supported by -the locale, a NULL pointer is returned, and none of the -current modifiers are changed. -</para> -<para> -<!-- .LP --> -At program startup, -the modifiers that are in effect are unspecified until -the first successful call to set them. Whenever the locale is changed, the -modifiers that are in effect become unspecified until the next successful call -to set them. -Clients should always call -<function>XSetLocaleModifiers</function> -with a non-NULL modifier_list after setting the locale -before they call any locale-dependent Xlib routine. -</para> -<para> -<!-- .LP --> -The only standard modifier category currently defined is ``im'', -which identifies the desired input method. -The values for input method are not standardized. -A single locale may use multiple input methods, -switching input method under user control. -The modifier may specify the initial input method in effect -or an ordered list of input methods. -Multiple input methods may be specified in a single im value string -in an implementation-dependent manner. -</para> -<para> -<!-- .LP --> -The returned modifiers string is owned by Xlib and should not be modified or -freed by the client. -It may be freed by Xlib after the current locale or modifiers are changed. -Until freed, it will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -The recommended procedure for clients initializing their locale and modifiers -is to obtain locale and modifier announcers separately from -one of the following prioritized sources: -</para> -<itemizedlist> - <listitem> - <para> -A command line option - </para> - </listitem> - <listitem> - <para> -A resource - </para> - </listitem> - <listitem> - <para> -The empty string ("") - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The first of these that is defined should be used. -Note that when a locale command line option or locale resource is defined, -the effect should be to set all categories to the specified locale, -overriding any category-specific settings in the local host environment. -</para> -</sect1> -<sect1 id="Locale_and_Modifier_Dependencies"> -<title>Locale and Modifier Dependencies</title> -<!-- .XS --> -<!-- (SN Locale and Modifier Dependencies --> -<!-- .XE --> -<para> -<!-- .LP --> -The internationalized Xlib functions operate in the current locale -configured by the host environment and X locale modifiers set by -<function>XSetLocaleModifiers</function> -or in the locale and modifiers configured at the time -some object supplied to the function was created. -For each locale-dependent function, -the following table describes the locale (and modifiers) dependency: -</para> - -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <thead> - <row> - <entry align='center'>Locale from</entry> - <entry align='center'>Affects the Function</entry> - <entry align='center'>In</entry> - </row> - </thead> - <tbody> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Locale Query/Configuration:</emphasis></entry> - </row> - <row> - <entry morerows='1'><function>setlocale</function></entry> - <entry><function>XSupportsLocale</function></entry> - <entry>Locale queried</entry> - </row> - <row> - <entry><function>XSetLocaleModifiers</function></entry> - <entry>Locale modified</entry> - </row> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Resources:</emphasis></entry> - </row> - <row> - <entry><function>setlocale</function></entry> - <entry> - <para><function>XrmGetFileDatabase</function></para> - <para><function>XrmGetStringDatabase</function></para> - </entry> - <entry>Locale of <type>XrmDatabase</type></entry> - </row> - <row> - <entry><type>XrmDatabase</type></entry> - <entry> - <para><function>XrmPutFileDatabase</function></para> - <para><function>XrmLocaleOfDatabase</function></para> - </entry> - <entry>Locale of <type>XrmDatabase</type></entry> - </row> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Setting Standard Properties:</emphasis></entry> - </row> - <row> - <entry><function>setlocale</function></entry> - <entry><function>XmbSetWMProperties</function></entry> - <entry>Encoding of supplied/returned - text (some WM_ property - text in environment locale)</entry> - </row> - <row> - <entry><function>setlocale</function></entry> - <entry> - <para><function>XmbTextPropertyToTextList</function></para> - <para><function>XwcTextPropertyToTextList</function></para> - <para><function>XmbTextListToTextProperty</function></para> - <para><function>XwcTextListToTextProperty</function></para> - </entry> - <entry>Encoding of supplied/returned text</entry> - </row> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Text Input:</emphasis></entry> - </row> - <row> - <entry morerows='2'><function>setlocale</function></entry> - <entry><function>XOpenIM</function></entry> - <entry><acronym>XIM</acronym> input method selection</entry> - </row> - <row> - <entry><function>XRegisterIMInstantiateCallback</function></entry> - <entry><acronym>XIM</acronym> selection</entry> - </row> - <row> - <entry><function>XUnregisterIMInstantiateCallback</function></entry> - <entry><acronym>XIM</acronym> selection</entry> - </row> - <row> - <entry morerows='1'><type>XIM</type></entry> - <entry><function>XCreateIC</function></entry> - <entry><acronym>XIC</acronym> input method configuration</entry> - </row> - <row> - <entry><function>XLocaleOfIM</function>, and so on</entry> - <entry>Queried locale</entry> - </row> - <row> - <entry morerows='1'><type>XIC</type></entry> - <entry><function>XmbLookupString</function></entry> - <entry>Keyboard layout</entry> - </row> - <row> - <entry><function>XwcLookupString</function></entry> - <entry>Encoding of returned text</entry> - </row> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Text Drawing:</emphasis></entry> - </row> - <row> - <entry morerows='1'><function>setlocale</function></entry> - <entry><function>XOpenOM</function></entry> - <entry><acronym>XOM</acronym> output method selection</entry> - </row> - <row> - <entry><function>XCreateFontSet</function></entry> - <entry>Charsets of fonts in XFontSet</entry> - </row> - <row> - <entry morerows='1'><type>XOM</type></entry> - <entry><function>XCreateOC</function></entry> - <entry><acronym>XOC</acronym> output method configuration</entry> - </row> - <row> - <entry><function>XLocaleOfOM</function>, and so on</entry> - <entry>Queried locale</entry> - </row> - <row> - <entry morerows='2'><type>XFontSet</type></entry> - <entry><function>XmbDrawText</function>,</entry> - <entry>Locale of supplied text</entry> - </row> - <row> - <entry><function>XwcDrawText</function>, and so on</entry> - <entry>Locale of supplied text</entry> - </row> - <row> - <entry> - <para><function>XExtentsOfFontSet</function>, and so on</para> - <para><function>XmbTextExtents</function>,</para> - <para><function>XwcTextExtents</function>, and so on</para> - </entry> - <entry>Locale-dependent metrics</entry> - </row> - <row> - <entry nameend='c3' namest='c1'> - <emphasis role='bold'>Xlib Errors:</emphasis></entry> - </row> - <row> - <entry><function>setlocale</function></entry> - <entry> - <para><function>XGetErrorDatabaseText</function>,</para> - <para><function>XGetErrorText</function>, and so on</para> - </entry> - <entry>Locale of error message</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Clients may assume that a locale-encoded text string returned -by an X function can be passed to a C library routine, or vice versa, -if the locale is the same at the two calls. -</para> -<para> -<!-- .LP --> -All text strings processed by internationalized Xlib functions are assumed -to begin in the initial state of the encoding of the locale, if the encoding -is state-dependent. -</para> -<para> -<!-- .LP --> -All Xlib functions behave as if they do not change the current locale -or X modifier setting. -(This means that if they do change locale or call -<function>XSetLocaleModifiers</function> -with a non-NULL argument, they must save and restore the current state on -entry and exit.) -Also, Xlib functions on implementations that conform to the ANSI C library do -not alter the global state associated with the ANSI C functions -<function>mblen</function>, -<function>mbtowc</function>, -<function>wctomb</function>, -and -<function>strtok</function>. -</para> -</sect1> -<sect1 id="Variable_Argument_Lists"> -<title>Variable Argument Lists</title> -<!-- .XS --> -<!-- (SN Variable Argument Lists --> -<!-- .XE --> -<para> -<!-- .LP --> -Various functions in this chapter have arguments that conform -to the ANSI C variable argument list calling convention. -Each function denoted with an argument of the form ``...'' takes -a variable-length list of name and value pairs, -where each name is a string and each value is of type -<type>XPointer</type>. -A name argument that is NULL identifies the end of the list. -</para> -<para> -<!-- .LP --> -A variable-length argument list may contain a nested list. -If the name -<symbol>XNVaNestedList</symbol> -is specified in place of an argument name, -then the following value is interpreted as an -<type>XVaNestedList</type> -value that specifies a list of values logically inserted into the -original list at the point of declaration. -A NULL identifies the end of a nested list. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a nested variable argument list dynamically, use -<function>XVaCreateNestedList</function>. -</para> -<indexterm significance="preferred"><primary>XVaCreateNestedList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xvacreatenestedlist'> -<funcprototype> - <funcdef>XVaNestedList <function>XVaCreateNestedList</function></funcdef> - <paramdef>int<parameter> dummy</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>dummy</emphasis> - </term> - <listitem> - <para> -Specifies an unused argument (required by ANSI C). -<!-- .ds Al --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XVaCreateNestedList</function> -function allocates memory and copies its arguments into -a single list pointer, -which may be used as a value for arguments requiring a list value. -Any entries are copied as specified. -Data passed by reference is not copied; -the caller must ensure data remains valid for the lifetime -of the nested list. -The list should be freed using -<function>XFree</function> -when it is no longer needed. -</para> -</sect1> -<sect1 id="Output_Methods"> -<title>Output Methods</title> -<!-- .XS --> -<!-- (SN Output Methods --> -<!-- .XE --> -<para> -<!-- .LP --> -This section provides discussions of the following X Output Method -(<acronym>XOM</acronym>) topics: -</para> -<itemizedlist> - <listitem> - <para> -Output method overview - </para> - </listitem> - <listitem> - <para> -Output method functions - </para> - </listitem> - <listitem> - <para> -Output method values - </para> - </listitem> - <listitem> - <para> -Output context functions - </para> - </listitem> - <listitem> - <para> -Output context values - </para> - </listitem> - <listitem> - <para> -Creating and freeing a font set - </para> - </listitem> - <listitem> - <para> -Obtaining font set metrics - </para> - </listitem> - <listitem> - <para> -Drawing text using font sets - </para> - </listitem> -</itemizedlist> -<sect2 id="Output_Method_Overview"> -<title>Output Method Overview</title> -<!-- .XS --> -<!-- (SN Output Method Overview --> -<!-- .XE --> -<para> -<!-- .LP --> -Locale-dependent text may include one or more text components, each of -which may require different fonts and character set encodings. -In some languages, each component might have a different -drawing direction, and some components might contain -context-dependent characters that change shape based on -relationships with neighboring characters. -</para> -<para> -<!-- .LP --> -When drawing such locale-dependent text, some locale-specific -knowledge is required; -for example, what fonts are required to draw the text, -how the text can be separated into components, and which -fonts are selected to draw each component. -Further, when bidirectional text must be drawn, -the internal representation order of the text must be changed -into the visual representation order to be drawn. -</para> -<para> -<!-- .LP --> -An X Output Method provides a functional interface so that clients -do not have to deal directly with such locale-dependent details. -Output methods provide the following capabilities: -</para> -<itemizedlist> - <listitem> - <para> -Creating a set of fonts required to draw locale-dependent text. - </para> - </listitem> - <listitem> - <para> -Drawing locale-dependent text with a font set without the caller -needing to be aware of locale dependencies. - </para> - </listitem> - <listitem> - <para> -Obtaining the escapement and extents in pixels of locale-dependent text. - </para> - </listitem> - <listitem> - <para> -Determining if bidirectional or context-dependent drawing is required -in a specific locale with a specific font set. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Two different abstractions are used in the representation of -the output method for clients. -</para> -<para> -<!-- .LP --> -The abstraction used to communicate with an output method -is an opaque data structure represented by the -<type>XOM</type> -data type. -The abstraction for representing the state of a particular output thread -is called an <emphasis remap='I'>output context</emphasis>. -The Xlib representation of an output context is an -<type>XOC</type>, -which is compatible with -<type>XFontSet</type> -in terms of its functional interface, but is -a broader, more generalized abstraction. -</para> -</sect2> -<sect2 id="Output_Method_Functions"> -<title>Output Method Functions</title> -<!-- .XS --> -<!-- (SN Output Method Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -To open an output method, use -<function>XOpenOM</function>. -</para> -<indexterm significance="preferred"><primary>XOpenOM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xopenom'> -<funcprototype> - <funcdef>XOM <function>XOpenOM</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XrmDatabase<parameter> db</parameter></paramdef> - <paramdef>char<parameter> *res_name</parameter></paramdef> - <paramdef>char<parameter> *res_class</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>db</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_name</emphasis> - </term> - <listitem> - <para> -Specifies the full resource name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_class</emphasis> - </term> - <listitem> - <para> -Specifies the full class name of the application. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XOpenOM</function> -function opens an output method -matching the current locale and modifiers specification. -The current locale and modifiers are bound to the output method -when -<function>XOpenOM</function> -is called. -The locale associated with an output method cannot be changed. -</para> -<para> -<!-- .LP --> -The specific output method to which this call will be routed -is identified on the basis of the current locale and modifiers. -<function>XOpenOM</function> -will identify a default output method corresponding to the -current locale. -That default can be modified using -<function>XSetLocaleModifiers</function> -to set the output method modifier. -</para> -<para> -<!-- .LP --> -The db argument is the resource database to be used by the output method -for looking up resources that are private to the output method. -It is not intended that this database be used to look -up values that can be set as OC values in an output context. -If db is NULL, -no database is passed to the output method. -</para> -<para> -<!-- .LP --> -The res_name and res_class arguments specify the resource name -and class of the application. -They are intended to be used as prefixes by the output method -when looking up resources that are common to all output contexts -that may be created for this output method. -The characters used for resource names and classes must be in the -X Portable Character Set. -The resources looked up are not fully specified -if res_name or res_class is NULL. -</para> -<para> -<!-- .LP --> -The res_name and res_class arguments are not assumed to exist beyond -the call to -<function>XOpenOM</function>. -The specified resource database is assumed to exist for the lifetime -of the output method. -</para> -<para> -<!-- .LP --> -<function>XOpenOM</function> -returns NULL if no output method could be opened. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To close an output method, use -<function>XCloseOM</function>. -</para> -<indexterm significance="preferred"><primary>XCloseOM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcloseom'> -<funcprototype> - <funcdef>Status <function>XCloseOM</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCloseOM</function> -function closes the specified output method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set output method attributes, use -<function>XSetOMValues</function>. -</para> -<indexterm significance="preferred"><primary>XSetOMValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetomvalues'> -<funcprototype> - <funcdef>char *<function>XSetOMValues</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. -<!-- .ds Al \ to set <acronym>XOM</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetOMValues</function> -function presents a variable argument list programming interface -for setting properties or features of the specified output method. -This function returns NULL if it succeeds; -otherwise, -it returns the name of the first argument that could not be obtained. -</para> -<para> -<!-- .LP --> -No standard arguments are currently defined by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To query an output method, use -<function>XGetOMValues</function>. -</para> -<indexterm significance="preferred"><primary>XGetOMValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetomvalues'> -<funcprototype> - <funcdef>char *<function>XGetOMValues</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. -<!-- .ds Al \ to get XOM values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetOMValues</function> -function presents a variable argument list programming interface -for querying properties or features of the specified output method. -This function returns NULL if it succeeds; -otherwise, -it returns the name of the first argument that could not be obtained. -</para> -<para> -<!-- .LP --> -To obtain the display associated with an output method, use -<function>XDisplayOfOM</function>. -</para> -<indexterm significance="preferred"><primary>XDisplayOfOM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisplayofom'> -<funcprototype> - <funcdef>Display *<function>XDisplayOfOM</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDisplayOfOM</function> -function returns the display associated with the specified output method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the locale associated with an output method, use -<function>XLocaleOfOM</function>. -</para> -<indexterm significance="preferred"><primary>XLocaleOfOM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlocaleofom'> -<funcprototype> - <funcdef>char *<function>XLocaleOfOM</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLocaleOfOM</function> -returns the locale associated with the specified output method. -</para> -</sect2> -<sect2 id="X_Output_Method_Values"> -<title>X Output Method Values</title> -<!-- .XS --> -<!-- (SN X Output Method Values --> -<!-- .XE --> -<para> -<!-- .LP --> -The following table describes how <acronym>XOM</acronym> values are interpreted by an -output method. -The first column lists the <acronym>XOM</acronym> values. The second column indicates -how each of the <acronym>XOM</acronym> values are treated by a particular output style. -</para> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -The following key applies to this table. -</para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'>Key</entry> - <entry align='left'>Explanation</entry> - </row> - </thead> - <tbody> - <row> - <entry>G</entry> - <entry>This value may be read using <function>XGetOMValues</function>.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para></para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'><acronym>XOM</acronym> Value</entry> - <entry align='left'>Key</entry> - </row> - </thead> - <tbody> - <row> - <entry><symbol>XNRequiredCharSet</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNQueryOrientation</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNDirectionalDependentDrawing</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNContextualDrawing</symbol></entry> - <entry>G</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -</para> -<sect3 id="Required_Char_Set"> -<title>Required Char Set</title> -<!-- .XS --> -<!-- (SN Required Char Set --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNRequiredCharSet</symbol> -argument returns the list of charsets that are required for loading the fonts -needed for the locale. -The value of the argument is a pointer to a structure of type -<structname>XOMCharSetList</structname>. -</para> -<para> -<!-- .LP --> -The -<structname>XOMCharSetList</structname> -structure is defined as follows: -<indexterm significance="preferred"><primary>XOMCharSetList</primary></indexterm> -<!-- .sM --> -</para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int charset_count; - char **charset_list; -} XOMCharSetList; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The charset_list member is a list of one or more null-terminated -charset names, and the charset_count member is the number of -charset names. -</para> -<para> -<!-- .LP --> -The required charset list is owned by Xlib and should not be modified or -freed by the client. -It will be freed by a call to -<function>XCloseOM</function> -with the associated -<type>XOM</type>. -Until freed, its contents will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Query_Orientation"> -<title>Query Orientation</title> -<!-- .XS --> -<!-- (SN Query Orientation --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNQueryOrientation</symbol> -argument returns the global orientation of text when drawn. -Other than -<constant>XOMOrientation_LTR_TTB</constant>, -the set of orientations supported is locale-dependent. -The value of the argument is a pointer to a structure of type -<structname>XOMOrientation</structname>. -Clients are responsible for freeing the -<structname>XOMOrientation</structname> -structure by using -<function>XFree</function>; -this also frees the contents of the structure. -</para> - -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int num_orientation; - XOrientation *orientation; /* Input Text description */ -} XOMOrientation; - -typedef enum { - XOMOrientation_LTR_TTB, - XOMOrientation_RTL_TTB, - XOMOrientation_TTB_LTR, - XOMOrientation_TTB_RTL, - XOMOrientation_Context -} XOrientation; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The possible value for XOrientation may be: -</para> -<itemizedlist> - <listitem> - <para> -<constant>XOMOrientation_LTR_TTB</constant> -left-to-right, top-to-bottom global orientation - </para> - </listitem> - <listitem> - <para> -<constant>XOMOrientation_RTL_TTB</constant> -right-to-left, top-to-bottom global orientation - </para> - </listitem> - <listitem> - <para> -<constant>XOMOrientation_TTB_LTR</constant> -top-to-bottom, left-to-right global orientation - </para> - </listitem> - <listitem> - <para> -<constant>XOMOrientation_TTB_RTL</constant> -top-to-bottom, right-to-left global orientation - </para> - </listitem> - <listitem> - <para> -<constant>XOMOrientation_Context</constant> -contextual global orientation - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Directional_Dependent_Drawing"> -<title>Directional Dependent Drawing</title> -<!-- .XS --> -<!-- (SN Directional Dependent Drawing --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNDirectionalDependentDrawing</symbol> -argument indicates whether the text rendering functions -implement implicit handling of directional text. If this value -is -<symbol>True</symbol>, -the output method has knowledge of directional -dependencies and reorders text as necessary when -rendering text. If this value is -<symbol>False</symbol>, -the output method does not implement any directional text -handling, and all character directions are assumed to be left-to-right. -</para> -<para> -<!-- .LP --> -Regardless of the rendering order of characters, -the origins of all characters are on the primary draw direction side -of the drawing origin. -</para> -<para> -<!-- .LP --> -This OM value presents functionality identical to the -<function>XDirectionalDependentDrawing</function> -function. -</para> -</sect3> -<sect3 id="Context_Dependent_Drawing"> -<title>Context Dependent Drawing</title> -<!-- .XS --> -<!-- (SN Context Dependent Drawing --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNContextualDrawing</symbol> -argument indicates whether the text rendering functions -implement implicit context-dependent drawing. If this value is -<symbol>True</symbol>, -the output method has knowledge of context dependencies and -performs character shape editing, combining glyphs to present -a single character as necessary. The actual shape editing is -dependent on the locale implementation and the font set used. -</para> -<para> -<!-- .LP --> -This OM value presents functionality identical to the -<function>XContextualDrawing</function> -function. -</para> -</sect3> -</sect2> -<sect2 id="Output_Context_Functions"> -<title>Output Context Functions</title> -<!-- .XS --> -<!-- (SN Output Context Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -An output context is an abstraction that contains both the data -required by an output method and the information required -to display that data. -There can be multiple output contexts for one output method. -The programming interfaces for creating, reading, or modifying -an output context use a variable argument list. -The name elements of the argument lists are referred to as <acronym>XOC</acronym> values. -It is intended that output methods be controlled by these <acronym>XOC</acronym> values. -As new <acronym>XOC</acronym> values are created, -they should be registered with the X Consortium. -An -<type>XOC</type> -can be used anywhere an -<type>XFontSet</type> -can be used, and vice versa; -<type>XFontSet</type> -is retained for compatibility with previous releases. -The concepts of output methods and output contexts include broader, -more generalized abstraction than font set, -supporting complex and more intelligent text display, and dealing not only -with multiple fonts but also with context dependencies. -However, -<type>XFontSet</type> -is widely used in several interfaces, so -<type>XOC</type> -is defined as an upward compatible type of -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create an output context, use -<function>XCreateOC</function>. -</para> -<indexterm significance="preferred"><primary>XCreateOC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreateoc'> -<funcprototype> - <funcdef>XOC <function>XCreateOC</function></funcdef> - <paramdef>XOM<parameter> om</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>om</emphasis> - </term> - <listitem> - <para> -Specifies the output method. -<!-- .ds Al \ to set <acronym>XOC</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateOC</function> -function creates an output context within the specified output method. -</para> -<para> -<!-- .LP --> -The base font names argument is mandatory at creation time, and -the output context will not be created unless it is provided. -All other output context values can be set later. -</para> -<para> -<!-- .LP --> -<function>XCreateOC</function> -returns NULL if no output context could be created. -NULL can be returned for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -A required argument was not set. - </para> - </listitem> - <listitem> - <para> -A read-only argument was set. - </para> - </listitem> - <listitem> - <para> -An argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -The output method encountered an output method implementation-dependent error. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<function>XCreateOC</function> -can generate a -<errorname>BadAtom</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy an output context, use -<function>XDestroyOC</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyOC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroyoc'> -<funcprototype> - <funcdef>void <function>XDestroyOC</function></funcdef> - <paramdef>XOC<parameter> oc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>oc</emphasis> - </term> - <listitem> - <para> -Specifies the output context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDestroyOC</function> -function destroys the specified output context. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the output method associated with an output context, use -<function>XOMOfOC</function>. -</para> -<indexterm significance="preferred"><primary>XOMOfOC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xomofoc'> -<funcprototype> - <funcdef>XOM <function>XOMOfOC</function></funcdef> - <paramdef>XOC<parameter> oc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>oc</emphasis> - </term> - <listitem> - <para> -Specifies the output context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XOMOfOC</function> -function returns the output method associated with the -specified output context. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Xlib provides two functions for setting and reading output context values, -respectively, -<function>XSetOCValues</function> -and -<function>XGetOCValues</function>. -Both functions have a variable-length argument list. -In that argument list, any <acronym>XOC</acronym> value's name must be denoted -with a character string using the X Portable Character Set. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set <acronym>XOC</acronym> values, use -<function>XSetOCValues</function>. -</para> -<indexterm significance="preferred"><primary>XSetOCValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetocvalues'> -<funcprototype> - <funcdef>char *<function>XSetOCValues</function></funcdef> - <paramdef>XOC<parameter> oc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>oc</emphasis> - </term> - <listitem> - <para> -Specifies the output context. -<!-- .ds Al \ to set <acronym>XOC</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetOCValues</function> -function returns NULL if no error occurred; -otherwise, -it returns the name of the first argument that could not be set. -An argument might not be set for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -The argument is read-only. - </para> - </listitem> - <listitem> - <para> -The argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -An implementation-dependent error occurs. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Each value to be set must be an appropriate datum, -matching the data type imposed by the semantics of the argument. -</para> -<para> -<!-- .LP --> -<function>XSetOCValues</function> -can generate a -<errorname>BadAtom</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain <acronym>XOC</acronym> values, use -<function>XGetOCValues</function>. -</para> -<indexterm significance="preferred"><primary>XGetOCValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetocvalues'> -<funcprototype> - <funcdef>char *<function>XGetOCValues</function></funcdef> - <paramdef>XOC<parameter> oc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>oc</emphasis> - </term> - <listitem> - <para> -Specifies the output context. -<!-- .ds Al \ to get XOC values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetOCValues</function> -function returns NULL if no error occurred; otherwise, -it returns the name of the first argument that could not be obtained. -An argument might not be obtained for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -The argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -An implementation-dependent error occurs. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Each argument value -following a name must point to a location where the value is to be stored. -</para> -</sect2> - -<sect2 id="Output_Context_Values"> -<title>Output Context Values</title> -<!-- .XS --> -<!-- (SN Output Context Values --> -<!-- .XE --> -<para> -<!-- .LP --> -The following table describes how <acronym>XOC</acronym> values are interpreted -by an output method. -The first column lists the <acronym>XOC</acronym> values. -The second column indicates the alternative interfaces that function -identically and are provided for compatibility with previous releases. -The third column indicates how each of the <acronym>XOC</acronym> values is treated. -</para> -<!-- .LP --> -<para> -The following keys apply to this table. -</para> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'>Key</entry> - <entry align='left'>Explanation</entry> - </row> - </thead> - <tbody> - <row> - <entry>C</entry> - <entry>This value must be set with <function>XCreateOC</function>.</entry> - </row> - <row> - <entry>D</entry> - <entry>This value may be set using <function>XCreateOC</function>. - If it is not set,a default is provided.</entry> - </row> - <row> - <entry>G</entry> - <entry>This value may be read using <function>XGetOCValues</function>.</entry> - </row> - <row> - <entry>S</entry> - <entry>This value must be set using <function>XSetOCValues</function>.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para></para> - -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <thead> - <row> - <entry align='left'><acronym>XOC</acronym> Value</entry> - <entry align='left'>Alternative Interface</entry> - <entry align='left'>Key</entry> - </row> - </thead> - <tbody> - <row> - <entry>BaseFontName</entry> - <entry><function>XCreateFontSet</function></entry> - <entry>C-G</entry> - </row> - <row> - <entry>MissingCharSet</entry> - <entry><function>XCreateFontSet</function></entry> - <entry>G</entry> - </row> - <row> - <entry>DefaultString</entry> - <entry><function>XCreateFontSet</function></entry> - <entry>G</entry> - </row> - <row> - <entry>Orientation</entry> - <entry>-</entry> - <entry>D-S-G</entry> - </row> - <row> - <entry>ResourceName</entry> - <entry>-</entry> - <entry>S-G</entry> - </row> - <row> - <entry>ResourceClass</entry> - <entry>-</entry> - <entry>S-G</entry> - </row> - <row> - <entry>FontInfo</entry> - <entry><function>XFontsOfFontSet</function></entry> - <entry>G</entry> - </row> - <row> - <entry>OMAutomatic</entry> - <entry>-</entry> - <entry>G</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -</para> -<sect3 id="Base_Font_Name"> -<title>Base Font Name</title> -<!-- .XS --> -<!-- (SN Base Font Name --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNBaseFontName</symbol> -argument is a list of base font names that Xlib uses -to load the fonts needed for the locale. -The base font names are a comma-separated list. The string is null-terminated -and is assumed to be in the Host Portable Character Encoding; -otherwise, the result is implementation-dependent. -White space immediately on either side of a separating comma is ignored. -</para> -<para> -<!-- .LP --> -Use of <acronym>XLFD</acronym> font names permits Xlib to obtain the fonts needed for a -variety of locales from a single locale-independent base font name. -The single base font name should name a family of fonts whose members -are encoded in the various charsets needed by the locales of interest. -</para> -<para> -<!-- .LP --> -An <acronym>XLFD</acronym> base font name can explicitly name a charset needed for the locale. -This allows the user to specify an exact font for use with a charset required -by a locale, fully controlling the font selection. -</para> -<para> -<!-- .LP --> -If a base font name is not an <acronym>XLFD</acronym> name, -Xlib will attempt to obtain an <acronym>XLFD</acronym> name from the font properties -for the font. -If Xlib is successful, the -<function>XGetOCValues</function> -function will return this <acronym>XLFD</acronym> name instead of the client-supplied name. -</para> -<para> -<!-- .LP --> -This argument must be set at creation time -and cannot be changed. -If no fonts exist for any of the required charsets, -or if the locale definition in Xlib requires that a font exist -for a particular charset and a font is not found for that charset, -<function>XCreateOC</function> -returns NULL. -</para> -<para> -<!-- .LP --> -When querying for the -<symbol>XNBaseFontName</symbol> -<acronym>XOC</acronym> value, -<function>XGetOCValues</function> -returns a null-terminated string identifying the base font names that -Xlib used to load the fonts needed for the locale. -This string is owned by Xlib and should not be modified or freed by -the client. -The string will be freed by a call to -<function>XDestroyOC</function> -with the associated -<type>XOC</type>. -Until freed, the string contents will not be modified by Xlib. -</para> -</sect3> -<sect3 id="Missing_CharSet"> -<title>Missing CharSet</title> -<!-- .XS --> -<!-- (SN Missing CharSet --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNMissingCharSet</symbol> -argument returns the list of required charsets that are missing from the -font set. -The value of the argument is a pointer to a structure of type -<structname>XOMCharSetList</structname>. -</para> -<para> -<!-- .LP --> -If fonts exist for all of the charsets required by the current locale, -charset_list is set to NULL and charset_count is set to zero. -If no fonts exist for one or more of the required charsets, -charset_list is set to a list of one or more null-terminated charset names -for which no fonts exist, and charset_count is set to the number of -missing charsets. -The charsets are from the list of the required charsets for -the encoding of the locale and do not include any charsets to which Xlib -may be able to remap a required charset. -</para> -<para> -<!-- .LP --> -The missing charset list is owned by Xlib and should not be modified or -freed by the client. -It will be freed by a call to -<function>XDestroyOC</function> -with the associated -<type>XOC</type>. -Until freed, its contents will not be modified by Xlib. -</para> -</sect3> -<sect3 id="Default_String"> -<title>Default String</title> -<!-- .XS --> -<!-- (SN Default String --> -<!-- .XE --> -<para> -<!-- .LP --> -When a drawing or measuring function is called with an -<type>XOC</type> -that has missing charsets, some characters in the locale will not be -drawable. -The -<symbol>XNDefaultString</symbol> -argument returns a pointer to a string that represents the glyphs -that are drawn with this -<type>XOC</type> -when the charsets of the available fonts do not include all glyphs -required to draw a character. -The string does not necessarily consist of valid characters -in the current locale and is not necessarily drawn with -the fonts loaded for the font set, -but the client can draw or measure the default glyphs -by including this string in a string being drawn or measured with the -<type>XOC</type>. -</para> -<para> -<!-- .LP --> -If the -<symbol>XNDefaultString</symbol> -argument returned the empty string (""), -no glyphs are drawn and the escapement is zero. -The returned string is null-terminated. -It is owned by Xlib and should not be modified or freed by the client. -It will be freed by a call to -<function>XDestroyOC</function> -with the associated -<type>XOC</type>. -Until freed, its contents will not be modified by Xlib. -</para> -</sect3> -<sect3 id="Orientation"> -<title>Orientation</title> -<!-- .XS --> -<!-- (SN Orientation --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNOrientation</symbol> -argument specifies the current orientation of text when drawn. The value of -this argument is one of the values returned by the -<function>XGetOMValues</function> -function with the -<symbol>XNQueryOrientation</symbol> -argument specified in the -<type>XOrientation</type> -list. -The value of the argument is of type -<type>XOrientation</type>. -When -<symbol>XNOrientation</symbol> -is queried, the value specifies the current orientation. -When -<symbol>XNOrientation</symbol> -is set, a value is used to set the current orientation. -</para> -<para> -<!-- .LP --> -When -<constant>XOMOrientation_Context</constant> -is set, the text orientation of the -text is determined according to an implementation-defined method -(for example, ISO 6429 control sequences), and the initial text orientation for -locale-dependent Xlib functions is assumed to -be -<constant>XOMOrientation_LTR_TTB</constant>. -</para> -<para> -<!-- .LP --> -The -<symbol>XNOrientation</symbol> -value does not change the prime drawing direction -for Xlib drawing functions. -</para> -</sect3> -<sect3 id="Resource_Name_and_Class"> -<title>Resource Name and Class</title> -<!-- .XS --> -<!-- (SN Resource Name and Class --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNResourceName</symbol> -and -<symbol>XNResourceClass</symbol> -arguments are strings that specify the full name and class -used by the client to obtain resources for the display of the output context. -These values should be used as prefixes for name and class -when looking up resources that may vary according to the output context. -If these values are not set, -the resources will not be fully specified. -</para> -<para> -<!-- .LP --> -It is not intended that values that can be set as <acronym>XOM</acronym> values be -set as resources. -</para> -<para> -<!-- .LP --> -When querying for the -<symbol>XNResourceName</symbol> -or -<symbol>XNResourceClass</symbol> -<acronym>XOC</acronym> value, -<function>XGetOCValues</function> -returns a null-terminated string. -This string is owned by Xlib and should not be modified or freed by -the client. -The string will be freed by a call to -<function>XDestroyOC</function> -with the associated -<type>XOC</type> -or when the associated value is changed via -<function>XSetOCValues</function>. -Until freed, the string contents will not be modified by Xlib. -</para> -</sect3> -<sect3 id="Font_Info"> -<title>Font Info</title> -<!-- .XS --> -<!-- (SN Font Info --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNFontInfo</symbol> -argument specifies a list of one or more -<structname>XFontStruct</structname> -structures -and font names for the fonts used for drawing by the given output context. -The value of the argument is a pointer to a structure of type -<structname>XOMFontInfo</structname>. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int num_font; - XFontStruct **font_struct_list; - char **font_name_list; -} XOMFontInfo; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -A list of pointers to the -<structname>XFontStruct</structname> -structures is returned to font_struct_list. -A list of pointers to null-terminated, fully-specified font name strings -in the locale of the output context is returned to font_name_list. -The font_name_list order corresponds to the font_struct_list order. -The number of -<structname>XFontStruct</structname> -structures and font names is returned to num_font. -</para> -<para> -<!-- .LP --> -Because it is not guaranteed that a given character will be imaged using a -single font glyph, -there is no provision for mapping a character or default string -to the font properties, font ID, or direction hint for the font -for the character. -The client may access the -<structname>XFontStruct</structname> -list to obtain these values for all the fonts currently in use. -</para> -<para> -<!-- .LP --> -Xlib does not guarantee that fonts are loaded from the server -at the creation of an -<type>XOC</type>. -Xlib may choose to cache font data, loading it only as needed to draw text -or compute text dimensions. -Therefore, existence of the per_char metrics in the -<structname>XFontStruct</structname> -structures in the -<structname>XFontStructSet</structname> -is undefined. -Also, note that all properties in the -<structname>XFontStruct</structname> -structures are in the STRING encoding. -</para> -<para> -<!-- .LP --> -The client must not free the -<structname>XOMFontInfo</structname> -struct itself; it will be freed when the -<type>XOC</type> -is closed. -</para> -</sect3> -<sect3 id="OM_Automatic"> -<title>OM Automatic</title> -<!-- .XS --> -<!-- (SN OM Automatic --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNOMAutomatic</symbol> -argument returns whether the associated output context was created by -<function>XCreateFontSet</function> -or not. Because the -<function>XFreeFontSet</function> -function not only destroys the output context but also closes the implicit -output method associated with it, -<function>XFreeFontSet</function> -should be used with any output context created by -<function>XCreateFontSet</function>. -However, it is possible that a client does not know how the output context -was created. -Before a client destroys the output context, -it can query whether -<symbol>XNOMAutomatic</symbol> -is set to determine whether -<function>XFreeFontSet</function> -or -<function>XDestroyOC</function> -should be used to destroy the output context. -</para> -</sect3> -</sect2> -<sect2 id="Creating_and_Freeing_a_Font_Set"> -<title>Creating and Freeing a Font Set</title> -<!-- .XS --> -<!-- (SN Creating and Freeing a Font Set --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib international text drawing is done using a set of one or more fonts, -as needed for the locale of the text. -Fonts are loaded according to a list of base font names -supplied by the client and the charsets required by the locale. -The -<type>XFontSet</type> -is an opaque type representing the state of a particular output thread -and is equivalent to the type -<type>XOC</type>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -The -<function>XCreateFontSet</function> -function is a convenience function for creating an output context using -only default values. The returned -<type>XFontSet</type> -has an implicitly created -<type>XOM</type>. -This -<type>XOM</type> -has an OM value -<symbol>XNOMAutomatic</symbol> -automatically set to -<symbol>True</symbol> -so that the output context self indicates whether it was created by -<function>XCreateOC</function> -or -<function>XCreateFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XCreateFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatefontset'> -<funcprototype> - <funcdef>XFontSet <function>XCreateFontSet</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *base_font_name_list</parameter></paramdef> - <paramdef>char<parameter> ***missing_charset_list_return</parameter></paramdef> - <paramdef>int<parameter> *missing_charset_count_return</parameter></paramdef> - <paramdef>char<parameter> **def_string_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>base_font_name_list</emphasis> - </term> - <listitem> - <para> -Specifies the base font names. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>missing_charset_list_return</emphasis> - </term> - <listitem> - <para> -Returns the missing charsets. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>missing_charset_count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of missing charsets. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>def_string_return</emphasis> - </term> - <listitem> - <para> -Returns the string drawn for missing charsets. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateFontSet</function> -function creates a font set for the specified display. -The font set is bound to the current locale when -<function>XCreateFontSet</function> -is called. -The font set may be used in subsequent calls to obtain font -and character information and to image text in the locale of the font set. -</para> -<para> -<!-- .LP --> -The base_font_name_list argument is a list of base font names -that Xlib uses to load the fonts needed for the locale. -The base font names are a comma-separated list. -The string is null-terminated -and is assumed to be in the Host Portable Character Encoding; -otherwise, the result is implementation-dependent. -White space immediately on either side of a separating comma is ignored. -</para> -<para> -<!-- .LP --> -Use of <acronym>XLFD</acronym> font names permits Xlib to obtain the fonts needed for a -variety of locales from a single locale-independent base font name. -The single base font name should name a family of fonts whose members -are encoded in the various charsets needed by the locales of interest. -</para> -<para> -<!-- .LP --> -An <acronym>XLFD</acronym> base font name can explicitly name a charset needed for the locale. -This allows the user to specify an exact font for use with a charset required -by a locale, fully controlling the font selection. -</para> -<para> -<!-- .LP --> -If a base font name is not an <acronym>XLFD</acronym> name, -Xlib will attempt to obtain an <acronym>XLFD</acronym> name from the font properties -for the font. -If this action is successful in obtaining an <acronym>XLFD</acronym> name, the -<function>XBaseFontNameListOfFontSet</function> -function will return this <acronym>XLFD</acronym> name instead of the client-supplied name. -</para> -<para> -<!-- .LP --> -Xlib uses the following algorithm to select the fonts -that will be used to display text with the -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -For each font charset required by the locale, -the base font name list is searched for the first appearance of one -of the following cases that names a set of fonts that exist at the server: -</para> -<itemizedlist> - <listitem> - <para> -The first <acronym>XLFD</acronym>-conforming base font name that specifies the required -charset or a superset of the required charset in its -<structfield>CharSetRegistry</structfield> -and -<structfield>CharSetEncoding</structfield> -fields. -The implementation may use a base font name whose specified charset -is a superset of the required charset, for example, -an ISO8859-1 font for an ASCII charset. - </para> - </listitem> - <listitem> - <para> -The first set of one or more <acronym>XLFD</acronym>-conforming base font names -that specify one or more charsets that can be remapped to support the -required charset. -The Xlib implementation may recognize various mappings -from a required charset to one or more other charsets -and use the fonts for those charsets. -For example, JIS Roman is ASCII with tilde and backslash replaced -by yen and overbar; -Xlib may load an ISO8859-1 font to support this character set -if a JIS Roman font is not available. - </para> - </listitem> - <listitem> - <para> -The first <acronym>XLFD</acronym>-conforming font name or the first non-<acronym>XLFD</acronym> font name -for which an <acronym>XLFD</acronym> font name can be obtained, combined with the -required charset (replacing the -<structfield>CharSetRegistry</structfield> -and -<structfield>CharSetEncoding</structfield> -fields in the <acronym>XLFD</acronym> font name). -As in case 1, -the implementation may use a charset that is a superset -of the required charset. - </para> - </listitem> - <listitem> - <para> -The first font name that can be mapped in some implementation-dependent -manner to one or more fonts that support imaging text in the charset. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -For example, assume that a locale required the charsets: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -ISO8859-1 -JISX0208.1983 -JISX0201.1976 -GB2312-1980.0 -</literallayout> -</para> -<para> -<!-- .LP --> -The user could supply a base_font_name_list that explicitly specifies the -charsets, ensuring that specific fonts are used if they exist. -For example: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -"-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-240-JISX0208.1983-0,\\ --JIS-Fixed-Medium-R-Normal--26-180-100-100-C-120-JISX0201.1976-0,\\ --GB-Fixed-Medium-R-Normal--26-180-100-100-C-240-GB2312-1980.0,\\ --Adobe-Courier-Bold-R-Normal--25-180-75-75-M-150-ISO8859-1" -</literallayout> -</para> -<para> -<!-- .LP --> -Alternatively, the user could supply a base_font_name_list -that omits the charsets, -letting Xlib select font charsets required for the locale. -For example: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -"-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-240,\\ --JIS-Fixed-Medium-R-Normal--26-180-100-100-C-120,\\ --GB-Fixed-Medium-R-Normal--26-180-100-100-C-240,\\ --Adobe-Courier-Bold-R-Normal--25-180-100-100-M-150" -</literallayout> -</para> -<para> -<!-- .LP --> -Alternatively, the user could simply supply a single base font name -that allows Xlib to select from all available fonts -that meet certain minimum <acronym>XLFD</acronym> property requirements. -For example: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -"-*-*-*-R-Normal--*-180-100-100-*-*" -</literallayout> -</para> -<para> -<!-- .LP --> -If -<function>XCreateFontSet</function> -is unable to create the font set, -either because there is insufficient memory or because the current locale -is not supported, -<function>XCreateFontSet</function> -returns NULL, missing_charset_list_return is set to NULL, -and missing_charset_count_return -is set to zero. -If fonts exist for all of the charsets required by the current locale, -<function>XCreateFontSet</function> -returns a valid -<type>XFontSet</type>, -missing_charset_list_return is set to NULL, -and missing_charset_count_return is set to zero. -</para> -<para> -<!-- .LP --> -If no font exists for one or more of the required charsets, -<function>XCreateFontSet</function> -sets missing_charset_list_return to a -list of one or more null-terminated charset names for which no font exists -and sets missing_charset_count_return to the number of missing fonts. -The charsets are from the list of the required charsets for -the encoding of the locale and do not include any charsets to which Xlib -may be able to remap a required charset. -</para> -<para> -<!-- .LP --> -If no font exists for any of the required charsets -or if the locale definition in Xlib requires that a font exist -for a particular charset and a font is not found for that charset, -<function>XCreateFontSet</function> -returns NULL. -Otherwise, -<function>XCreateFontSet</function> -returns a valid -<type>XFontSet</type> -to font_set. -</para> -<para> -<!-- .LP --> -When an Xmb/wc drawing or measuring function is called with an -<type>XFontSet</type> -that has missing charsets, some characters in the locale will not be -drawable. -If def_string_return is non-NULL, -<function>XCreateFontSet</function> -returns a pointer to a string that represents the glyphs -that are drawn with this -<type>XFontSet</type> -when the charsets of the available fonts do not include all font glyphs -required to draw a codepoint. -The string does not necessarily consist of valid characters -in the current locale and is not necessarily drawn with -the fonts loaded for the font set, -but the client can draw and measure the default glyphs -by including this string in a string being drawn or measured with the -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -If the string returned to def_string_return is the empty string (""), -no glyphs are drawn, and the escapement is zero. -The returned string is null-terminated. -It is owned by Xlib and should not be modified or freed by the client. -It will be freed by a call to -<function>XFreeFontSet</function> -with the associated -<type>XFontSet</type>. -Until freed, its contents will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -The client is responsible for constructing an error message from the -missing charset and default string information and may choose to continue -operation in the case that some fonts did not exist. -</para> -<para> -<!-- .LP --> -The returned -<type>XFontSet</type> -and missing charset list should be freed with -<function>XFreeFontSet</function> -and -<function>XFreeStringList</function>, -respectively. -The client-supplied base_font_name_list may be freed -by the client after calling -<function>XCreateFontSet</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a list of -<structname>XFontStruct</structname> -structures and full font names given an -<type>XFontSet</type>, -use -<function>XFontsOfFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XFontsOfFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfontsoffontset'> -<funcprototype> - <funcdef>int <function>XFontsOfFontSet</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>XFontStruct<parameter> ***font_struct_list_return</parameter></paramdef> - <paramdef>char<parameter> ***font_name_list_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_struct_list_return</emphasis> - </term> - <listitem> - <para> -Returns the list of font structs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_name_list_return</emphasis> - </term> - <listitem> - <para> -Returns the list of font names. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFontsOfFontSet</function> -function returns a list of one or more -<structname>XFontStruct</structname>s -and font names for the fonts used by the Xmb and Xwc layers -for the given font set. -A list of pointers to the -<structname>XFontStruct</structname> -structures is returned to font_struct_list_return. -A list of pointers to null-terminated, fully specified font name strings -in the locale of the font set is returned to font_name_list_return. -The font_name_list order corresponds to the font_struct_list order. -The number of -<structname>XFontStruct</structname> -structures and font names is returned as the value of the function. -</para> -<para> -<!-- .LP --> -Because it is not guaranteed that a given character will be imaged using a -single font glyph, -there is no provision for mapping a character or default string -to the font properties, font ID, or direction hint for the font -for the character. -The client may access the -<structname>XFontStruct</structname> -list to obtain these values for all the fonts currently in use. -</para> -<para> -<!-- .LP --> -Xlib does not guarantee that fonts are loaded from the server -at the creation of an -<type>XFontSet</type>. -Xlib may choose to cache font data, loading it only as needed to draw text -or compute text dimensions. -Therefore, existence of the per_char metrics in the -<structname>XFontStruct</structname> -structures in the -<structname>XFontStructSet</structname> -is undefined. -Also, note that all properties in the -<structname>XFontStruct</structname> -structures are in the STRING encoding. -</para> -<para> -<!-- .LP --> -The -<structname>XFontStruct</structname> -and font name lists are owned by Xlib -and should not be modified or freed by the client. -They will be freed by a call to -<function>XFreeFontSet</function> -with the associated -<type>XFontSet</type>. -Until freed, their contents will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the base font name list and the selected font name list given an -<type>XFontSet</type>, -use -<function>XBaseFontNameListOfFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XBaseFontNameListOfFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xbasefontnamelistoffontset'> -<funcprototype> - <funcdef>char *<function>XBaseFontNameListOfFontSet</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XBaseFontNameListOfFontSet</function> -function returns the original base font name list supplied -by the client when the -<type>XFontSet</type> -was created. -A null-terminated string containing a list of -comma-separated font names is returned -as the value of the function. -White space may appear immediately on either side of separating commas. -</para> -<para> -<!-- .LP --> -If -<function>XCreateFontSet</function> -obtained an <acronym>XLFD</acronym> name from the font properties for the font specified -by a non-<acronym>XLFD</acronym> base name, the -<function>XBaseFontNameListOfFontSet</function> -function will return the <acronym>XLFD</acronym> name instead of the non-<acronym>XLFD</acronym> base name. -</para> -<para> -<!-- .LP --> -The base font name list is owned by Xlib and should not be modified or -freed by the client. -It will be freed by a call to -<function>XFreeFontSet</function> -with the associated -<type>XFontSet</type>. -Until freed, its contents will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the locale name given an -<type>XFontSet</type>, -use -<function>XLocaleOfFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XLocaleOfFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlocaleoffontset'> -<funcprototype> - <funcdef>char *<function>XLocaleOfFontSet</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLocaleOfFontSet</function> -function -returns the name of the locale bound to the specified -<type>XFontSet</type>, -as a null-terminated string. -</para> -<para> -<!-- .LP --> -The returned locale name string is owned by Xlib -and should not be modified or freed by the client. -It may be freed by a call to -<function>XFreeFontSet</function> -with the associated -<type>XFontSet</type>. -Until freed, it will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -The -<function>XFreeFontSet</function> -function is a convenience function for freeing an output context. -<function>XFreeFontSet</function> -also frees its associated -<type>XOM</type> -if the output context was created by -<function>XCreateFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XFreeFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreefontset'> -<funcprototype> - <funcdef>void <function>XFreeFontSet</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeFontSet</function> -function frees the specified font set. -The associated base font name list, font name list, -<structname>XFontStruct</structname> -list, and -<structname>XFontSetExtents</structname>, -if any, are freed. -</para> -</sect2> -<sect2 id="Obtaining_Font_Set_Metrics"> -<title>Obtaining Font Set Metrics</title> -<!-- .XS --> -<!-- (SN Obtaining Font Set Metrics --> -<!-- .XE --> -<para> -<!-- .LP --> -Metrics for the internationalized text drawing functions -are defined in terms of a primary draw direction, -which is the default direction in which the character origin advances -for each succeeding character in the string. -The Xlib interface is currently defined to support only a left-to-right -primary draw direction. -The drawing origin is the position passed to the drawing function -when the text is drawn. -The baseline is a line drawn through the drawing origin parallel -to the primary draw direction. -Character ink is the pixels painted in the foreground color -and does not include interline or intercharacter spacing -or image text background pixels. -</para> -<para> -<!-- .LP --> -The drawing functions are allowed to implement implicit text -directionality control, reversing the order in which characters are -rendered along the primary draw direction in response to locale-specific -lexical analysis of the string. -</para> -<para> -<!-- .LP --> -Regardless of the character rendering order, -the origins of all characters are on the primary draw direction side -of the drawing origin. -The screen location of a particular character image may be determined with -<function>XmbTextPerCharExtents</function> -or -<function>XwcTextPerCharExtents</function>. -</para> -<para> -<!-- .LP --> -The drawing functions are allowed to implement context-dependent -rendering, where the glyphs drawn for a string are not simply a -concatenation of the glyphs that represent each individual character. -A string of two characters drawn with -<function>XmbDrawString</function> -may render differently than if the two characters -were drawn with separate calls to -<function>XmbDrawString</function>. -If the client appends or inserts a character -in a previously drawn string, -the client may need to redraw some adjacent characters -to obtain proper rendering. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To find out about direction-dependent rendering, use -<function>XDirectionalDependentDrawing</function>. -</para> -<indexterm significance="preferred"><primary>XDirectionalDependentDrawing</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdirectionaldependentdrawing'> -<funcprototype> - <funcdef>Bool <function>XDirectionalDependentDrawing</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDirectionalDependentDrawing</function> -function returns -<symbol>True</symbol> -if the drawing functions implement implicit text directionality; -otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To find out about context-dependent rendering, use -<function>XContextualDrawing</function>. -</para> -<indexterm significance="preferred"><primary>XContextualDrawing</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcontextualdrawing'> -<funcprototype> - <funcdef>Bool <function>XContextualDrawing</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XContextualDrawing</function> -function returns -<symbol>True</symbol> -if text drawn with the font set might include context-dependent drawing; -otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To find out about context-dependent or direction-dependent rendering, use -<function>XContextDependentDrawing</function>. -</para> -<indexterm significance="preferred"><primary>XContextDependentDrawing</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcontextdependentdrawing'> -<funcprototype> - <funcdef>Bool <function>XContextDependentDrawing</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XContextDependentDrawing</function> -function returns -<symbol>True</symbol> -if the drawing functions implement implicit text directionality or -if text drawn with the font_set might include context-dependent drawing; -otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -The drawing functions do not interpret newline, tab, or other control -characters. -The behavior when nonprinting characters other than space are drawn -is implementation-dependent. -It is the client's responsibility to interpret control characters -in a text stream. -</para> -<para> -<!-- .LP --> -The maximum character extents for the fonts that are used by the text -drawing layers can be accessed by the -<structname>XFontSetExtents</structname> -structure: -<indexterm significance="preferred"><primary>XFontSetExtents</primary></indexterm> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - XRectangle max_ink_extent; /* over all drawable characters */ - XRectangle max_logical_extent; /* over all drawable characters */ -} XFontSetExtents; -</literallayout> -</para> -<para> -<!-- .LP --> -The -<structname>XRectangle</structname> -structures used to return font set metrics are the usual Xlib screen-oriented -rectangles -with x, y giving the upper left corner, and width and height always positive. -</para> -<para> -<!-- .LP --> -The max_ink_extent member gives the maximum extent, over all drawable characters, of -the rectangles that bound the character glyph image drawn in the -foreground color, relative to a constant origin. -See -<function>XmbTextExtents</function> -and -<function>XwcTextExtents</function> -for detailed semantics. -</para> -<para> -<!-- .LP --> -The max_logical_extent member gives the maximum extent, -over all drawable characters, of the rectangles -that specify minimum spacing to other graphical features, -relative to a constant origin. -Other graphical features drawn by the client, for example, -a border surrounding the text, should not intersect this rectangle. -The max_logical_extent member should be used to compute minimum -interline spacing and the minimum area that must be allowed -in a text field to draw a given number of arbitrary characters. -</para> -<para> -<!-- .LP --> -Due to context-dependent rendering, -appending a given character to a string may change -the string's extent by an amount other than that character's -individual extent. -</para> -<para> -<!-- .LP --> -The rectangles for a given character in a string can be obtained from -<function>XmbTextPerCharExtents</function> -or -<function>XwcTextPerCharExtents</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the maximum extents structure given an -<type>XFontSet</type>, -use -<function>XExtentsOfFontSet</function>. -</para> -<indexterm significance="preferred"><primary>XExtentsOfFontSet</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xextentsoffontset'> -<funcprototype> - <funcdef>XFontSetExtents *<function>XExtentsOfFontSet</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XExtentsOfFontSet</function> -function returns an -<structname>XFontSetExtents</structname> -structure for the fonts used by the Xmb and Xwc layers -for the given font set. -</para> -<para> -<!-- .LP --> -The -<structname>XFontSetExtents</structname> -structure is owned by Xlib and should not be modified -or freed by the client. -It will be freed by a call to -<function>XFreeFontSet</function> -with the associated -<type>XFontSet</type>. -Until freed, its contents will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the escapement in pixels of the specified text as a value, -use -<function>XmbTextEscapement</function> -or -<function>XwcTextEscapement</function>. -</para> -<indexterm significance="preferred"><primary>XmbTextEscapement</primary></indexterm> -<indexterm significance="preferred"><primary>XwcTextEscapement</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbtextescapement'> -<funcprototype> - <funcdef>int <function>XmbTextEscapement</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwctextescapement'> -<funcprototype> - <funcdef>int <function>XwcTextEscapement</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>wchar_t<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_wchars</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_wchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbTextEscapement</function> -and -<function>XwcTextEscapement</function> -functions return the escapement in pixels of the specified string as a value, -using the fonts loaded for the specified font set. -The escapement is the distance in pixels in the primary draw -direction from the drawing origin to the origin of the next character to -be drawn, assuming that the rendering of the next character is not -dependent on the supplied string. -</para> -<para> -<!-- .LP --> -Regardless of the character rendering order, -the escapement is always positive. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the overall_ink_return and overall_logical_return arguments, -the overall bounding box of the string's image, and a logical bounding box, -use -<function>XmbTextExtents</function> - or -<function>XwcTextExtents</function>. -</para> -<indexterm significance="preferred"><primary>XmbTextExtents</primary></indexterm> -<indexterm significance="preferred"><primary>XwcTextExtents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbtextextents'> -<funcprototype> - <funcdef>int <function>XmbTextExtents</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis> -<funcprototype id='xwctextextents'> - <funcdef>int <function>XwcTextExtents</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>wchar_t<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_wchars</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_wchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. -<!-- .ds Ov dimensions --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_ink_return</emphasis> - </term> - <listitem> - <para> -Returns the overall ink dimensions. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_logical_return</emphasis> - </term> - <listitem> - <para> -Returns the overall logical dimensions. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbTextExtents</function> -and -<function>XwcTextExtents</function> -functions set the components of the specified overall_ink_return and -overall_logical_return -arguments to the overall bounding box of the string's image -and a logical bounding box for spacing purposes, respectively. -They return the value returned by -<function>XmbTextEscapement</function> -or -<function>XwcTextEscapement</function>. -These metrics are relative to the drawing origin of the string, -using the fonts loaded for the specified font set. -</para> -<para> -<!-- .LP --> -If the overall_ink_return argument is non-NULL, -it is set to the bounding box of the string's character ink. -The overall_ink_return for a nondescending, horizontally drawn -Latin character is conventionally entirely above the baseline; -that is, overall_ink_return.height <= -overall_ink_return.y. -The overall_ink_return for a nonkerned character -is entirely at, and to the right of, the origin; -that is, overall_ink_return.x >= 0. -A character consisting of a single pixel at the origin would set -overall_ink_return fields y = 0, x = 0, width = 1, and height = 1. -</para> -<para> -<!-- .LP --> -If the overall_logical_return argument is non-NULL, -it is set to the bounding box that provides minimum spacing -to other graphical features for the string. -Other graphical features, for example, a border surrounding the text, -should not intersect this rectangle. -</para> -<para> -<!-- .LP --> -When the -<type>XFontSet</type> -has missing charsets, -metrics for each unavailable character are taken -from the default string returned by -<function>XCreateFontSet</function> -so that the metrics represent the text as it will actually be drawn. -The behavior for an invalid codepoint is undefined. -</para> -<para> -<!-- .LP --> -To determine the effective drawing origin for a character in a drawn string, -the client should call -<function>XmbTextPerCharExtents</function> -on the entire string, then on the character, -and subtract the x values of the returned -rectangles for the character. -This is useful to redraw portions of a line of text -or to justify words, but for context-dependent rendering, -the client should not assume that it can redraw the character by itself -and get the same rendering. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain per-character information for a text string, -use -<function>XmbTextPerCharExtents</function> -or -<function>XwcTextPerCharExtents</function>. -</para> -<indexterm significance="preferred"><primary>XmbTextPerCharExtents</primary></indexterm> -<indexterm significance="preferred"><primary>XwcTextPerCharExtents</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbtextpercharextents'> -<funcprototype> - <funcdef>Status <function>XmbTextPerCharExtents</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> - <paramdef>XRectangle<parameter> *ink_array_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *logical_array_return</parameter></paramdef> - <paramdef>int<parameter> array_size</parameter></paramdef> - <paramdef>int<parameter> *num_chars_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwctextpercharextents'> -<funcprototype> - <funcdef>Status <function>XwcTextPerCharExtents</function></funcdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>wchar_t<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_wchars</parameter></paramdef> - <paramdef>XRectangle<parameter> *ink_array_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *logical_array_return</parameter></paramdef> - <paramdef>int<parameter> array_size</parameter></paramdef> - <paramdef>int<parameter> *num_chars_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef> - <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_wchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>ink_array_return</emphasis> - </term> - <listitem> - <para> -Returns the ink dimensions for each character. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>logical_array_return</emphasis> - </term> - <listitem> - <para> -Returns the logical dimensions for each character. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>array_size</emphasis> - </term> - <listitem> - <para> -Specifies the size of ink_array_return and logical_array_return. -The caller must pass in arrays of this size. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_chars_return</emphasis> - </term> - <listitem> - <para> -Returns the number of characters in the string argument. -<!-- .ds Ov extents of the entire string --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_ink_return</emphasis> - </term> - <listitem> - <para> -Returns the overall ink dimensions. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>overall_logical_return</emphasis> - </term> - <listitem> - <para> -Returns the overall logical dimensions. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbTextPerCharExtents</function> -and -<function>XwcTextPerCharExtents</function> -functions return the text dimensions of each character of the specified text, -using the fonts loaded for the specified font set. -Each successive element of ink_array_return and logical_array_return -is set to the successive character's drawn metrics, -relative to the drawing origin of the string and one -rectangle -for each character in the supplied text string. -The number of elements of ink_array_return and logical_array_return -that have been set is returned to num_chars_return. -</para> -<para> -<!-- .LP --> -Each element of ink_array_return is set to the bounding box -of the corresponding character's drawn foreground color. -Each element of logical_array_return is set to the bounding box -that provides minimum spacing to other graphical features -for the corresponding character. -Other graphical features should not intersect any of the -logical_array_return rectangles. -</para> -<para> -<!-- .LP --> -Note that an -<structname>XRectangle</structname> -represents the effective drawing dimensions of the character, -regardless of the number of font glyphs that are used to draw -the character or the direction in which the character is drawn. -If multiple characters map to a single character glyph, -the dimensions of all the -<structname>XRectangle</structname>s -of those characters are the same. -</para> -<para> -<!-- .LP --> -When the -<type>XFontSet</type> -has missing charsets, metrics for each unavailable -character are taken from the default string returned by -<function>XCreateFontSet</function> -so that the metrics represent the text as it will actually be drawn. -The behavior for an invalid codepoint is undefined. -</para> -<para> -<!-- .LP --> -If the array_size is too small for the number of characters in the -supplied text, the functions return zero -and num_chars_return is set to the number of rectangles required. -Otherwise, the functions return a nonzero value. -</para> -<para> -<!-- .LP --> -If the overall_ink_return or overall_logical_return argument is non-NULL, -<function>XmbTextPerCharExtents</function> -and -<function>XwcTextPerCharExtents</function> -return the maximum extent of the string's metrics to overall_ink_return -or overall_logical_return, as returned by -<function>XmbTextExtents</function> -or -<function>XwcTextExtents</function>. -</para> -</sect2> -<sect2 id="Drawing_Text_Using_Font_Sets"> -<title>Drawing Text Using Font Sets</title> -<!-- .XS --> -<!-- (SN Drawing Text Using Font Sets --> -<!-- .XE --> -<para> -<!-- .LP --> -The functions defined in this section -draw text at a specified location in a drawable. -They are similar to the functions -<function>XDrawText</function>, -<function>XDrawString</function>, -and -<function>XDrawImageString</function> -except that they work with font sets instead of single fonts -and interpret the text based on the locale of the font set -instead of treating the bytes of the string as direct font indexes. -See <link linkend="Drawing_Text">section 8.6</link> for details -of the use of Graphics Contexts (GCs) -and possible protocol errors. -If a -<errorname>BadFont</errorname> -error is generated, -characters prior to the offending character may have been drawn. -</para> -<para> -<!-- .LP --> -The text is drawn using the fonts loaded for the specified font set; -the font in the GC is ignored and may be modified by the functions. -No validation that all fonts conform to some width rule is performed. -</para> -<para> -<!-- .LP --> -The text functions -<function>XmbDrawText</function> -and -<function>XwcDrawText</function> -use the following structures: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XmbTextItem</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - char *chars; /* pointer to string */ - int nchars; /* number of bytes */ - int delta; /* pixel delta between strings */ - XFontSet font_set; /* fonts, None means don't change */ -} XmbTextItem; -</literallayout> -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XwcTextItem</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - wchar_t *chars; /* pointer to wide char string */ - int nchars; /* number of wide characters */ - int delta; /* pixel delta between strings */ - XFontSet font_set; /* fonts, None means don't change */ -} XwcTextItem; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To draw text using multiple font sets in a given drawable, use -<function>XmbDrawText</function> -or -<function>XwcDrawText</function>. -</para> -<indexterm significance="preferred"><primary>XmbDrawText</primary></indexterm> -<indexterm significance="preferred"><primary>XwcDrawText</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbdrawtext'> -<funcprototype> - <funcdef>void <function>XmbDrawText</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XmbTextItem<parameter> *items</parameter></paramdef> - <paramdef>int<parameter> nitems</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwcdrawtext'> -<funcprototype> - <funcdef>void <function>XwcDrawText</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>XwcTextItem<parameter> *items</parameter></paramdef> - <paramdef>int<parameter> nitems</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>items</emphasis> - </term> - <listitem> - <para> -Specifies an array of text items. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nitems</emphasis> - </term> - <listitem> - <para> -Specifies the number of text items in the array. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbDrawText</function> -and -<function>XwcDrawText</function> -functions allow complex spacing and font set shifts between text strings. -Each text item is processed in turn, with the origin of a text -element advanced in the primary draw direction by the escapement of the -previous text item. -A text item delta specifies an additional escapement of the text item -drawing origin in the primary draw direction. -A font_set member other than -<symbol>None</symbol> -in an item causes the font set to be used for this and subsequent text items -in the text_items list. -Leading text items with a font_set member set to -<symbol>None</symbol> -will not be drawn. -</para> -<para> -<!-- .LP --> -<function>XmbDrawText</function> -and -<function>XwcDrawText</function> -do not perform any context-dependent rendering between text segments. -Clients may compute the drawing metrics by passing each text segment to -<function>XmbTextExtents</function> -and -<function>XwcTextExtents</function> -or -<function>XmbTextPerCharExtents</function> -and -<function>XwcTextPerCharExtents</function>. -When the -<type>XFontSet</type> -has missing charsets, each unavailable character is drawn -with the default string returned by -<function>XCreateFontSet</function>. -The behavior for an invalid codepoint is undefined. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To draw text using a single font set in a given drawable, use -<function>XmbDrawString</function> -or -<function>XwcDrawString</function>. -</para> -<indexterm significance="preferred"><primary>XmbDrawString</primary></indexterm> -<indexterm significance="preferred"><primary>XwcDrawString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbdrawstring'> -<funcprototype> - <funcdef>void <function>XmbDrawString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwcdrawstring'> -<funcprototype> - <funcdef>void <function>XwcDrawString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>wchar_t<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_wchars</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_wchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbDrawString</function> -and -<function>XwcDrawString</function> -functions draw the specified text with the foreground pixel. -When the -<type>XFontSet</type> -has missing charsets, each unavailable character is drawn -with the default string returned by -<function>XCreateFontSet</function>. -The behavior for an invalid codepoint is undefined. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To draw image text using a single font set in a given drawable, use -<function>XmbDrawImageString</function> -or -<function>XwcDrawImageString</function>. -</para> -<indexterm significance="preferred"><primary>XmbDrawImageString</primary></indexterm> -<indexterm significance="preferred"><primary>XwcDrawImageString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbdrawimagestring'> -<funcprototype> - <funcdef>void <function>XmbDrawImageString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwcdrawimagestring'> -<funcprototype> - <funcdef>void <function>XwcDrawImageString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>XFontSet<parameter> font_set</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>wchar_t<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_wchars</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>font_set</emphasis> - </term> - <listitem> - <para> -Specifies the font set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. -<!-- .ds Xy --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the character string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_wchars</emphasis> - </term> - <listitem> - <para> -Specifies the number of characters in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbDrawImageString</function> -and -<function>XwcDrawImageString</function> -functions fill a destination rectangle with the background pixel defined -in the GC and then paint the text with the foreground pixel. -The filled rectangle is the rectangle returned to overall_logical_return by -<function>XmbTextExtents</function> -or -<function>XwcTextExtents</function> -for the same text and -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -When the -<type>XFontSet</type> -has missing charsets, each unavailable character is drawn -with the default string returned by -<function>XCreateFontSet</function>. -The behavior for an invalid codepoint is undefined. -</para> -</sect2> -</sect1> -<sect1 id="Input_Methods"> -<title>Input Methods</title> -<!-- .XS --> -<!-- (SN Input Methods --> -<!-- .XE --> -<para> -<!-- .LP --> -This section provides discussions of the following X Input Method -(<acronym>XIM</acronym>) topics: -</para> -<itemizedlist> - <listitem> - <para> -Input method overview - </para> - </listitem> - <listitem> - <para> -Input method management - </para> - </listitem> - <listitem> - <para> -Input method functions - </para> - </listitem> - <listitem> - <para> -Input method values - </para> - </listitem> - <listitem> - <para> -Input context functions - </para> - </listitem> - <listitem> - <para> -Input context values - </para> - </listitem> - <listitem> - <para> -Input method callback semantics - </para> - </listitem> - <listitem> - <para> -Event filtering - </para> - </listitem> - <listitem> - <para> -Getting keyboard input - </para> - </listitem> - <listitem> - <para> -Input method conventions - </para> - </listitem> -</itemizedlist> -<sect2 id="Input_Method_Overview"> -<title>Input Method Overview</title> -<!-- .XS --> -<!-- (SN Input Method Overview --> -<!-- .XE --> -<para> -<!-- .LP --> -This section provides definitions for terms and concepts used -for internationalized text input and a brief overview of the -intended use of the mechanisms provided by Xlib. -</para> -<para> -<!-- .LP --> -A large number of languages in the world use alphabets -consisting of a small set of symbols (letters) to form words. -To enter text into a computer in an alphabetic language, -a user usually has a keyboard on which there exist key symbols corresponding -to the alphabet. -Sometimes, a few characters of an alphabetic language are missing -on the keyboard. -Many computer users who speak a Latin-alphabet-based language -only have an English-based keyboard. -They need to hit a combination of keystrokes -to enter a character that does not exist directly on the keyboard. -A number of algorithms have been developed for entering such characters. -These are known as European input methods, compose input methods, -or dead-key input methods. -</para> -<para> -<!-- .LP --> -Japanese is an example of a language with a phonetic symbol set, -where each symbol represents a specific sound. -There are two phonetic symbol sets in Japanese: Katakana and Hiragana. -In general, -Katakana is used for words that are of foreign origin, -and Hiragana is used for writing native Japanese words. -Collectively, the two systems are called Kana. -Each set consists of 48 characters. -</para> -<para> -<!-- .LP --> -Korean also has a phonetic symbol set, called Hangul. -Each of the 24 basic phonetic symbols (14 consonants and 10 vowels) -represents a specific sound. -A syllable is composed of two or three parts: -the initial consonants, the vowels, and the optional last consonants. -With Hangul, -syllables can be treated as the basic units on which text processing is done. -For example, -a delete operation may work on a phonetic symbol or a syllable. -Korean code sets include several thousands of these syllables. -A user types the phonetic symbols that make up the syllables of the words -to be entered. -The display may change as each phonetic symbol is entered. -For example, -when the second phonetic symbol of a syllable is entered, -the first phonetic symbol may change its shape and size. -Likewise, when the third phonetic symbol is entered, -the first two phonetic symbols may change their shape and size. -</para> -<para> -<!-- .LP --> -Not all languages rely solely on alphabetic or phonetic systems. -Some languages, including Japanese and Korean, employ an -ideographic writing system. -In an ideographic system, rather than taking a small set of -symbols and combining them in different ways to create words, -each word consists of one unique symbol (or, occasionally, several symbols). -The number of symbols can be very large: -approximately 50,000 have been identified in Hanzi, -the Chinese ideographic system. -</para> -<para> -<!-- .LP --> -Two major aspects of ideographic systems impact their use with computers. -First, the standard computer character sets in Japan, China, and Korea -include roughly 8,000 characters, -while sets in Taiwan have between 15,000 and 30,000 characters. -This makes it necessary to use more than one byte to represent a character. -Second, it obviously is impractical to have a keyboard that includes -all of a given language's ideographic symbols. -Therefore, a mechanism is required for entering characters -so that a keyboard with a reasonable number of keys can be used. -Those input methods are usually based on phonetics, -but there also exist methods based on the graphical properties of -characters. -</para> -<para> -<!-- .LP --> -In Japan, both Kana and the ideographic system Kanji are used. -In Korea, Hangul and sometimes the ideographic system Hanja are used. -Now consider entering ideographs in Japan, Korea, China, and Taiwan. -</para> -<para> -<!-- .LP --> -In Japan, either Kana or English characters are typed and then a region -is selected (sometimes automatically) for conversion to Kanji. -Several Kanji characters may have the same phonetic representation. -If that is the case with the string entered, -a menu of characters is presented and -the user must choose the appropriate one. -If no choice is necessary or a preference has been established, -the input method does the substitution directly. -When Latin characters are converted to Kana or Kanji, -it is called a romaji conversion. -</para> -<para> -<!-- .LP --> -In Korea, it is usually acceptable to keep Korean text in Hangul form, -but some people may choose to write Hanja-originated words in Hanja -rather than in Hangul. -To change Hangul to Hanja, -the user selects a region for conversion -and then follows the same basic method as that described for Japanese. -</para> -<para> -<!-- .LP --> -Probably because there are well-accepted phonetic writing systems -for Japanese and Korean, -computer input methods in these countries for entering ideographs -are fairly standard. -Keyboard keys have both English characters and phonetic symbols -engraved on them, and the user can switch between the two sets. -</para> -<para> -<!-- .LP --> -The situation is different for Chinese. -While there is a phonetic system called Pinyin promoted by authorities, -there is no consensus for entering Chinese text. -Some vendors use a phonetic decomposition (Pinyin or another), -others use ideographic decomposition of Chinese words, -with various implementations and keyboard layouts. -There are about 16 known methods, none of which is a clear standard. -</para> -<para> -<!-- .LP --> -Also, there are actually two ideographic sets used: -Traditional Chinese (the original written Chinese) -and Simplified Chinese. -Several years ago, -the People's Republic of China launched a campaign to simplify -some ideographic characters and eliminate redundancies altogether. -Under the plan, -characters would be streamlined every five years. -Characters have been revised several times now, -resulting in the smaller, simpler set that makes up Simplified Chinese. -</para> -<sect3 id="Input_Method_Architecture"> -<title>Input Method Architecture</title> -<!-- .XS --> -<!-- (SN Input Method Architecture --> -<!-- .XE --> -<para> -<!-- .LP --> -As shown in the previous section, -there are many different input methods in use today, -each varying with language, culture, and history. -A common feature of many input methods is that the user may type -multiple keystrokes to compose a single character (or set -of characters). -The process of composing characters from keystrokes is called -<emphasis remap='I'>preediting</emphasis>. -It may require complex algorithms and large dictionaries -involving substantial computer resources. -</para> -<para> -<!-- .LP --> -Input methods may require one or more areas in which to show the -feedback of the actual keystrokes, to propose disambiguation to the -user, to list dictionaries, and so on. -The input method areas of concern are as follows: -</para> -<itemizedlist> - <listitem> - <para> -The <emphasis remap='I'>status</emphasis> area is a logical extension of the -LEDs that exist on the physical keyboard. -It is a window that is intended to present the internal state -of the input method that is critical to the user. -The status area may consist of text data and bitmaps or some combination. - </para> - </listitem> - <listitem> - <para> -The <emphasis remap='I'>preedit</emphasis> area displays the -intermediate text for those languages that are composing prior to -the client handling the data. - </para> - </listitem> - <listitem> - <para> -The <emphasis remap='I'>auxiliary</emphasis> area is used for pop-up menus and customizing -dialogs that may be required for an input method. -There may be multiple auxiliary areas for an input method. -Auxiliary areas are managed by the input method independent of the client. -Auxiliary areas are assumed to be separate dialogs, -which are maintained by the input method. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -There are various user interaction styles used for preediting. -The ones supported by Xlib are as follows: -</para> -<itemizedlist> - <listitem> - <para> -For <emphasis remap='I'>on-the-spot</emphasis> input methods, -preediting data will be displayed directly in the application window. -Application data is moved to allow preedit data to appear -at the point of insertion. - </para> - </listitem> - <listitem> - <para> -<emphasis remap='I'>Over-the-spot</emphasis> preediting means that the data is displayed in -a preedit window that is placed over the point of insertion. - </para> - </listitem> - <listitem> - <para> -<emphasis remap='I'>Off-the-spot</emphasis> preediting means that the preedit window is -inside the application window but not at the point of insertion. -Often, this type of window is placed at the bottom of the application window. - </para> - </listitem> - <listitem> - <para> -<emphasis remap='I'>Root-window</emphasis> preediting refers to input methods that use a preedit -window that is the child of -<function>RootWindow</function>. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -It would require a lot of computing resources if portable applications -had to include input methods for all the languages in the world. -To avoid this, -a goal of the Xlib design is to allow an application -to communicate with an input method placed in a separate process. -Such a process is called an <emphasis remap='I'>input server</emphasis>. -The server to which the application should connect is dependent on -the environment when the application is started up, -that is, the user language and the actual encoding to be used for it. -The input method connection is said to be <emphasis remap='I'>locale-dependent</emphasis>. -It is also user-dependent. -For a given language, the user can choose, to some extent, -the user interface style of input method (if choice is possible among -several). -</para> -<para> -<!-- .LP --> -Using an input server implies communication overhead, -but applications can be migrated without relinking. -Input methods can be implemented either as a -stub communicating to an input server or as a local library. -</para> -<para> -<!-- .LP --> -An input method may be based on a <emphasis remap='I'>front-end</emphasis> or a <emphasis remap='I'>back-end</emphasis> -architecture. -In a front-end architecture, -there are two separate connections to the X server: -keystrokes go directly from the X server to the input method on -one connection and other events to the regular client connection. -The input method is then acting as a filter and sends composed strings -to the client. -A front-end architecture requires synchronization between the -two connections to avoid lost key events or locking issues. -</para> -<para> -<!-- .LP --> -In a back-end architecture, -a single X server connection is used. -A dispatching mechanism must decide on this channel to delegate appropriate -keystrokes to the input method. -For instance, -it may retain a Help keystroke for its own purpose. -In the case where the input method is a separate process (that is, a server), -there must be a special communication protocol between the back-end client -and the input server. -</para> -<para> -<!-- .LP --> -A front-end architecture introduces synchronization issues -and a filtering mechanism for noncharacter keystrokes -(Function keys, Help, and so on). -A back-end architecture sometimes implies more communication overhead -and more process switching. -If all three processes (X server, input server, client) -are running on a single workstation, -there are two process switches for each keystroke in a back-end -architecture, -but there is only one in a front-end architecture. -</para> -<para> -<!-- .LP --> -The abstraction used by a client to communicate with an input method -is an opaque data structure represented by the -<type>XIM</type> -data type. -This data structure is returned by the -<function>XOpenIM</function> -function, which opens an input method on a given display. -Subsequent operations on this data structure encapsulate all communication -between client and input method. -There is no need for an X client to use any networking library -or natural language package to use an input method. -</para> -<para> -<!-- .LP --> -A single input server may be used for one or more languages, -supporting one or more encoding schemes. -But the strings returned from an input method will always be encoded -in the (single) locale associated with the -<type>XIM</type> -object. -</para> -</sect3> -<sect3 id="Input_Contexts"> -<title>Input Contexts</title> -<!-- .XS --> -<!-- (SN Input Contexts --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides the ability to manage a multi-threaded state for text input. -A client may be using multiple windows, -each window with multiple text entry areas, -and the user possibly switching among them at any time. -The abstraction for representing the state of a particular input thread -is called an <emphasis remap='I'>input context</emphasis>. -The Xlib representation of an input context is an -<type>XIC</type>. -</para> -<para> -<!-- .LP --> -An input context is the abstraction retaining the state, properties, -and semantics of communication between a client and an input method. -An input context is a combination of an input method, a locale -specifying the encoding of the character strings to be returned, -a client window, internal state information, -and various layout or appearance characteristics. -The input context concept somewhat matches for input the graphics context -abstraction defined for graphics output. -</para> -<para> -<!-- .LP --> -One input context belongs to exactly one input method. -Different input contexts may be associated with the same input method, -possibly with the same client window. -An -<type>XIC</type> -is created with the -<function>XCreateIC</function> -function, providing an -<type>XIM</type> -argument and affiliating the input context to the input method -for its lifetime. -When an input method is closed with -<function>XCloseIM</function>, -all of its affiliated input contexts should not be used any more -(and should preferably be destroyed before closing the input method). -</para> -<para> -<!-- .LP --> -Considering the example of a client window with multiple text entry areas, -the application programmer could, for example, choose to implement as follows: -</para> -<itemizedlist> - <listitem> - <para> -As many input contexts are created as text entry areas, and the client -will get the input accumulated on each context each time it looks up -in that context. - </para> - </listitem> - <listitem> - <para> -A single context is created for a top-level window in the application. -If such a window contains several text entry areas, -each time the user moves to another text entry area, -the client has to indicate changes in the context. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -A range of choices can be made by application designers to use -either a single or multiple input contexts, -according to the needs of their application. -</para> -</sect3> -<sect3 id="Getting_Keyboard_Input"> -<title>Getting Keyboard Input</title> -<!-- .XS --> -<!-- (SN Getting Keyboard Input --> -<!-- .XE --> -<para> -<!-- .LP --> -To obtain characters from an input method, -a client must call the function -<function>XmbLookupString</function> -or -<function>XwcLookupString</function> -with an input context created from that input method. -Both a locale and display are bound to an input method when it is opened, -and an input context inherits this locale and display. -Any strings returned by -<function>XmbLookupString</function> -or -<function>XwcLookupString</function> -will be encoded in that locale. -</para> -</sect3> -<sect3 id="Focus_Management"> -<title>Focus Management</title> -<!-- .XS --> -<!-- (SN Focus Management --> -<!-- .XE --> -<para> -<!-- .LP --> -For each text entry area in which the -<function>XmbLookupString</function> -or -<function>XwcLookupString</function> -functions are used, -there will be an associated input context. -</para> -<para> -<!-- .LP --> -When the application focus moves to a text entry area, -the application must set the input context focus to the -input context associated with that area. -The input context focus is set by calling -<function>XSetICFocus</function> -with the appropriate input context. -</para> -<para> -<!-- .LP --> -Also, when the application focus moves out of a text entry area, the -application should unset the focus for the associated input context -by calling -<function>XUnsetICFocus</function>. -As an optimization, if -<function>XSetICFocus</function> -is called successively on two different input contexts, -setting the focus on the second -will automatically unset the focus on the first. -</para> -<para> -<!-- .LP --> -To set and unset the input context focus correctly, -it is necessary to track application-level focus changes. -Such focus changes do not necessarily correspond to X server focus changes. -</para> -<para> -<!-- .LP --> -If a single input context -is being used to do input for -multiple text entry areas, it will also be necessary -to set the focus window of the -input context whenever the focus window changes -(see <link linkend="Focus_Window">section 13.5.6.3</link>). -</para> -</sect3> -<sect3 id="Geometry_Management"> -<title>Geometry Management</title> -<!-- .XS --> -<!-- (SN Geometry Management --> -<!-- .XE --> -<para> -<!-- .LP --> -In most input method architectures -(on-the-spot being the notable exception), -the input method will perform the display of its own data. -To provide better visual locality, -it is often desirable to have the input method areas embedded within a client. -To do this, -the client may need to allocate space for an input method. -Xlib provides support that allows the size and position of input method -areas to be provided by a client. -The input method areas that are supported for geometry management -are the status area and the preedit area. -</para> -<para> -<!-- .LP --> -The fundamental concept on which geometry management for input method windows -is based is the proper division of responsibilities between the -client (or toolkit) and the input method. -The division of responsibilities is as follows: -</para> -<itemizedlist> - <listitem> - <para> -The client is responsible for the geometry of the input method window. - </para> - </listitem> - <listitem> - <para> -The input method is responsible for the contents of the input method window. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -An input method is able to suggest a size to the client, -but it cannot suggest a placement. -Also the input method can only suggest a size. -It does not determine the size, -and it must accept the size it is given. -</para> -<para> -<!-- .LP --> -Before a client provides geometry management for an input method, -it must determine if geometry management is needed. -The input method indicates the need for geometry management -by setting -<symbol>XIMPreeditArea</symbol> -or -<symbol>XIMStatusArea</symbol> -in its -<structname>XIMStyles</structname> -value returned by -<function>XGetIMValues</function>. -When a client has decided that it will provide geometry management -for an input method, -it indicates that decision by setting the -<symbol>XNInputStyle</symbol> -value in the -<type>XIC</type>. -</para> -<para> -<!-- .LP --> -After a client has established with the input method -that it will do geometry management, -the client must negotiate the geometry with the input method. -The geometry is negotiated by the following steps: -</para> -<itemizedlist> - <listitem> - <para> -The client suggests an area to the input method by setting the -<symbol>XNAreaNeeded</symbol> -value for that area. -If the client has no constraints for the input method, -it either will not suggest an area or will set the width and height to zero. -Otherwise, it will set one of the values. - </para> - </listitem> - <listitem> - <para> -The client will get the <acronym>XIC</acronym> value -<symbol>XNAreaNeeded</symbol>. -The input method will return its suggested size in this value. -The input method should pay attention to any constraints suggested -by the client. - </para> - </listitem> - <listitem> - <para> -The client sets the <acronym>XIC</acronym> value -<symbol>XNArea</symbol> -to inform the input method of the geometry of its window. -The client should try to honor the geometry requested by the input method. -The input method must accept this geometry. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Clients doing geometry management must be aware that setting other -<acronym>XIC</acronym> values may affect the geometry desired by an input method. -For example, -<symbol>XNFontSet</symbol> -and -<symbol>XNLineSpace</symbol> -may change the geometry desired by the input method. -</para> -<para> -<!-- .LP --> -The table of <acronym>XIC</acronym> values -(see <link linkend="Input_Context_Values">section 13.5.6</link>) -indicates the values that can cause the desired geometry to change -when they are set. -It is the responsibility of the client to renegotiate the geometry -of the input method window when it is needed. -</para> -<para> -<!-- .LP --> -In addition, -a geometry management callback is provided -by which an input method can initiate a geometry change. -</para> -</sect3> -<sect3 id="Event_Filtering"> -<title>Event Filtering</title> -<!-- .XS --> -<!-- (SN Event Filtering --> -<!-- .XE --> -<para> -<!-- .LP --> -A filtering mechanism is provided to allow input methods -to capture X events transparently to clients. -It is expected that toolkits (or clients) using -<function>XmbLookupString</function> -or -<function>XwcLookupString</function> -will call this filter at some point in the event processing mechanism -to make sure that events needed by an input method can be filtered -by that input method. -</para> -<para> -<!-- .LP --> -If there were no filter, -a client could receive and discard events that are necessary -for the proper functioning of an input method. -The following provides a few examples of such events: -</para> -<itemizedlist> - <listitem> - <para> -Expose events on preedit window in local mode. - </para> - </listitem> - <listitem> - <para> -Events may be used by an input method to communicate with an input server. -Such input server protocol-related events have to be intercepted -if one does not want to disturb client code. - </para> - </listitem> - <listitem> - <para> -Key events can be sent to a filter before they are bound -to translations such as those the X Toolkit Intrinsics library provides. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Clients are expected to get the <acronym>XIC</acronym> value -<symbol>XNFilterEvents</symbol> -and augment the event mask for the client window with that event mask. -This mask may be zero. -</para> -</sect3> -<sect3 id="Callbacks"> -<title>Callbacks</title> -<!-- .XS --> -<!-- (SN Callbacks --> -<!-- .XE --> -<para> -<!-- .LP --> -When an on-the-spot input method is implemented, -only the client can insert or delete preedit data in place -and possibly scroll existing text. -This means that the echo of the keystrokes has to be achieved -by the client itself, tightly coupled with the input method logic. -</para> -<para> -<!-- .LP --> -When the user enters a keystroke, -the client calls -<function>XmbLookupString</function> -or -<function>XwcLookupString</function>. -At this point, in the on-the-spot case, -the echo of the keystroke in the preedit has not yet been done. -Before returning to the client logic that handles the input characters, -the look-up function -must call the echoing logic to insert the new keystroke. -If the keystrokes entered so far make up a character, -the keystrokes entered need to be deleted, -and the composed character will be returned. -Hence, what happens is that, while being called by client code, -the input method logic has to call back to the client before it returns. -The client code, that is, a callback procedure, -is called from the input method logic. -</para> -<para> -<!-- .LP --> -There are a number of cases where the input method logic has to -call back the client. -Each of those cases is associated with a well-defined callback action. -It is possible for the client to specify, for each input context, -what callback is to be called for each action. -</para> -<para> -<!-- .LP --> -There are also callbacks provided for feedback of status information -and a callback to initiate a geometry request for an input method. -</para> -</sect3> -<sect3 id="Visible_Position_Feedback_Masks"> -<title>Visible Position Feedback Masks</title> -<!-- .XS --> -<!-- (SN Visible Position Feedback Masks --> -<!-- .XE --> -<para> -<!-- .LP --> -In the on-the-spot input style, there is a problem when -attempting to draw preedit strings that are longer than the -available space. Once the display area is exceeded, it is not -clear how best to display the preedit string. -The visible position feedback masks of -<structname>XIMText</structname> -help resolve this problem by allowing the input method to specify hints that -indicate the essential portions of the preedit string. -For example, such hints can help developers implement -scrolling of a long preedit string within a short preedit display area. -</para> -</sect3> -<sect3 id="Preedit_String_Management"> -<title>Preedit String Management</title> -<!-- .XS --> -<!-- (SN Preedit String Management --> -<!-- .XE --> -<para> -<!-- .LP --> -As highlighted before, the input method architecture provides -preediting, which supports a type of preprocessor input composition. -In this case, composition consists of interpreting a sequence -of key events and returning a committed string via -<function>XmbLookupString</function> -or -<function>XwcLookupString</function>. -This provides the basics for input methods. -</para> -<para> -<!-- .LP --> -In addition to preediting based on key events, a general framework -is provided to give a client that desires it more advanced preediting based -on the text within the client. This framework is called -<emphasis remap='I'>string conversion</emphasis> and is provided using <acronym>XIC</acronym> values. -The fundamental concept of string conversion -is to allow the input method to manipulate the client's -text independent of any user preediting operation. -</para> -<para> -<!-- .LP --> -The need for string conversion is based on -language needs and input method capabilities. -The following are some examples of string conversion: -</para> -<itemizedlist> - <listitem> - <para> -Transliteration conversion provides language-specific conversions -within the input method. -In the case of Korean input, users wish to convert a Hangul string -into a Hanja string while in preediting, after preediting, -or in other situations (for example, on a selected string). -The conversion is triggered when the user -presses a Hangul-to-Hanja key sequence (which may be input method specific). -Sometimes the user may want to invoke the conversion after finishing -preediting or on a user-selected string. -Thus, the string to be converted is in an application buffer, not in -the preedit area of the input method. The string conversion services -allow the client to request this transliteration conversion from the -input method. -There are many other transliteration conversions defined for -various languages, for example, Kana-to-Kanji conversion in Japanese. -<!-- .sp --> -The key to remember is that transliteration conversions are triggered -at the request of the user and returned to the client -immediately without affecting the preedit area of the input method. - </para> - </listitem> - <listitem> - <para> -Reconversion of a previously committed string or -a selected string is supported by many input methods as a -convenience to the user. -For example, a user tends to mistype the commit key while -preediting. In that case, some input methods provide a special -key sequence to request a ``reconvert'' operation on the -committed string, similiar to the undo facility provided by most -text editors. -Another example is where the user is proofreading a document -that has some misconversions from preediting and wants to correct -the misconverted text. Such reconversion is again triggered -by the user invoking some special action, but reconversions should -not affect the state of the preedit area. - </para> - </listitem> - <listitem> - <para> -Context-sensitive conversion is required for some languages -and input methods that need to retrieve text that surrounds the -current spot location (cursor position) of the client's buffer. -Such text is needed when the preediting operation depends on -some surrounding characters (usually preceding the spot location). -For example, -in Thai language input, certain character sequences may be invalid and -the input method may want to check whether characters constitute a -valid word. Input methods that do such context-dependent -checking need to retrieve the characters surrounding the current -cursor position to obtain complete words. -<!-- .sp --> -Unlike other conversions, this conversion is not explicitly -requested by the user. -Input methods that provide such context-sensitive conversion -continuously need to request context from the client, and any change -in the context of the spot location may affect such conversions. -The client's context would be needed if the user moves the cursor -and starts editing again. -<!-- .sp --> -For this reason, an input method supporting this type of conversion -should take notice of when the client calls -<function>XmbResetIC</function> -or -<function>XwcResetIC</function>, -which is usually an indication of a context change. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Context-sensitive conversions just need a copy of the client's text, -while other conversions replace the client's text with new text -to achieve the reconversion or transliteration. Yet in all -cases the result of a conversion, either immediately or via preediting, -is returned by the -<function>XmbLookupString</function> -and -<function>XwcLookupString</function> -functions. -</para> -<para> -<!-- .LP --> -String conversion support is dependent on the availability of the -<symbol>XNStringConversion</symbol> -or -<symbol>XNStringConversionCallback</symbol> -<acronym>XIC</acronym> values. -Because the input method may not support string conversions, -clients have to query the availability of string conversion -operations by checking the supported <acronym>XIC</acronym> values list by calling -<function>XGetIMValues</function> -with the -<symbol>XNQueryICValuesList</symbol> -IM value. -</para> -<para> -<!-- .LP --> -The difference between these two values is whether the -conversion is invoked by the client or the input method. -The -<symbol>XNStringConversion</symbol> -<acronym>XIC</acronym> value is used by clients to request -a string conversion from the input method. The client -is responsible for determining which events are used -to trigger the string conversion and whether the string to be -converted should be copied or deleted. The type of conversion -is determined by the input method; the client can only -pass the string to be converted. The client is guaranteed that -no -<symbol>XNStringConversionCallback</symbol> -will be issued when this value is set; thus, the client need -only set one of these values. -</para> -<para> -<!-- .LP --> -The -<symbol>XNStringConversionCallback</symbol> -<acronym>XIC</acronym> value is used by the client to notify the input method that -it will accept requests from the input method for string conversion. -If this value is set, -it is the input method's responsibility to determine which -events are used to trigger the string conversion. -When such events occur, the input method issues a call to the -client-supplied procedure to retrieve the string to be converted. The client's -callback procedure is notified whether to copy or delete the string and -is provided with hints as to the amount of text needed. -The -<structname>XIMStringConversionCallbackStruct</structname> -specifies which text should be passed back to the input method. -</para> -<para> -<!-- .LP --> -Finally, the input method may call the client's -<symbol>XNStringConversionCallback</symbol> -procedure multiple times if the string returned from the callback is -not sufficient to perform a successful conversion. The arguments -to the client's procedure allow the input method to define a -position (in character units) relative to the client's cursor position -and the size of the text needed. By varying the position and size of -the desired text in subsequent callbacks, the input method can retrieve -additional text. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -</sect2> -<sect2 id="Input_Method_Management"> -<title>Input Method Management</title> -<!-- .XS --> -<!-- (SN Input Method Management --> -<!-- .XE --> -<para> -<!-- .LP --> -The interface to input methods might appear to be simply creating -an input method -(<function>XOpenIM</function>) -and freeing an input method -(<function>XCloseIM</function>). -However, input methods may -require complex communication with input method servers (IM servers), -for example: -</para> - -<itemizedlist> - <listitem> - <para> -If the X server, IM server, and X clients are started asynchronously, -some clients may attempt to connect to the IM server before it is -fully operational, and fail. -Therefore, some mechanism is needed to allow clients to detect when an IM -server has started. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -It is up to clients to decide what should be done when an IM server is -not available (for example, wait, or use some other IM server). -</para> -<para> -<!-- .LP --> -</para> -<itemizedlist> - <listitem> - <para> -Some input methods may allow the underlying IM server to be switched. -Such customization may be desired without restarting the entire client. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -To support management of input methods in these cases, the following -functions are provided: -</para> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><function>XRegisterIMInstantiateCallback</function></entry> - <entry>This function allows clients to register a callback procedure - to be called when Xlib detects that an IM server is up and available.</entry> - </row> - <row> - <entry><function>XOpenIM</function></entry> - <entry>A client calls this function as a result of the callback procedure - being called.</entry> - </row> - <row> - <entry><function>XSetIMValues</function>, <function>XSetICValues</function></entry> - <entry>These functions use the <acronym>XIM</acronym> and <acronym>XIC</acronym> values, - <symbol>XNDestroyCallback</symbol>, - to allow a client - to register a callback procedure to be called when Xlib detects that - an IM server that was associated with an opened - input method is no longer available. - In addition, this function can be used to switch IM servers for those input - methods that support such functionality. The IM value for switching IM - servers is implementation-dependent; see the description below about - switching IM servers.</entry> - </row> - <row> - <entry><function>XUnregisterIMInstantiateCallback</function></entry> - <entry>This function removes a callback procedure registered by the client.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -Input methods that support switching of IM servers may exhibit some -side-effects: -</para> -<itemizedlist> - <listitem> - <para> -The input method will ensure that any new IM server supports any of the -input styles being used by input contexts already associated with the -input method. -However, the list of supported input styles may be different. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -</para> -<itemizedlist> - <listitem> - <para> -Geometry management requests on previously created input contexts -may be initiated by the new IM server. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -</para> -<sect3 id="Hot_Keys"> -<title>Hot Keys</title> -<!-- .XS --> -<!-- (SN Hot Keys --> -<!-- .XE --> -<para> -<!-- .LP --> -Some clients need to guarantee which keys can be used to escape from the -input method, regardless of the input method state; -for example, the client-specific Help key or the keys to move the -input focus. -The HotKey mechanism allows clients -to specify a set of keys for this purpose. However, the input -method might not allow clients to specify hot keys. -Therefore, clients have to query support of hot keys by checking the -supported <acronym>XIC</acronym> values list by calling -<function>XGetIMValues</function> -with the -<symbol>XNQueryICValuesList</symbol> -IM value. -When the hot keys specified conflict with the key bindings of the -input method, hot keys take precedence over the key bindings of the input -method. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Preedit_State_Operation"> -<title>Preedit State Operation</title> -<!-- .XS --> -<!-- (SN Preedit State Operation --> -<!-- .XE --> -<para> -<!-- .LP --> -An input method may have several internal states, depending on its -implementation and the locale. However, one state that is -independent of locale and implementation is whether the input method -is currently performing a preediting operation. -Xlib provides the ability for an application to manage the preedit state -programmatically. Two methods are provided for -retrieving the preedit state of an input context. -One method is to query the state by calling -<function>XGetICValues</function> -with the -<symbol>XNPreeditState</symbol> -<acronym>XIC</acronym> value. -Another method is to receive notification whenever -the preedit state is changed. To receive such notification, -an application needs to register a callback by calling -<function>XSetICValues</function> -with the -<symbol>XNPreeditStateNotifyCallback</symbol> -<acronym>XIC</acronym> value. -In order to change the preedit state programmatically, an application -needs to call -<function>XSetICValues</function> -with -<symbol>XNPreeditState</symbol>. -</para> -<para> -<!-- .LP --> -Availability of the preedit state is input method dependent. The input -method may not provide the ability to set the state or to -retrieve the state programmatically. Therefore, clients have to -query availability of preedit state operations by checking the -supported <acronym>XIC</acronym> values list by calling -<function>XGetIMValues</function> -with the -<symbol>XNQueryICValuesList</symbol> -IM value. -</para> -</sect3> -</sect2> -<sect2 id="Input_Method_Functions"> -<title>Input Method Functions</title> -<!-- .XS --> -<!-- (SN Input Method Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -To open a connection, use -<function>XOpenIM</function>. -</para> -<indexterm significance="preferred"><primary>XOpenIM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xopenim'> -<funcprototype> - <funcdef>XIM <function>XOpenIM</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XrmDatabase<parameter> db</parameter></paramdef> - <paramdef>char<parameter> *res_name</parameter></paramdef> - <paramdef>char<parameter> *res_class</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>db</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_name</emphasis> - </term> - <listitem> - <para> -Specifies the full resource name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_class</emphasis> - </term> - <listitem> - <para> -Specifies the full class name of the application. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XOpenIM</function> -function opens an input method, -matching the current locale and modifiers specification. -Current locale and modifiers are bound to the input method at opening time. -The locale associated with an input method cannot be changed dynamically. -This implies that the strings returned by -<function>XmbLookupString</function> -or -<function>XwcLookupString</function>, -for any input context affiliated with a given input method, -will be encoded in the locale current at the time the input method is opened. -</para> -<para> -<!-- .LP --> -The specific input method to which this call will be routed -is identified on the basis of the current locale. -<function>XOpenIM</function> -will identify a default input method corresponding to the -current locale. -That default can be modified using -<function>XSetLocaleModifiers</function> -for the input method modifier. -</para> -<para> -<!-- .LP --> -The db argument is the resource database to be used by the input method -for looking up resources that are private to the input method. -It is not intended that this database be used to look -up values that can be set as IC values in an input context. -If db is NULL, -no database is passed to the input method. -</para> -<para> -<!-- .LP --> -The res_name and res_class arguments specify the resource name -and class of the application. -They are intended to be used as prefixes by the input method -when looking up resources that are common to all input contexts -that may be created for this input method. -The characters used for resource names and classes must be in the -X Portable Character Set. -The resources looked up are not fully specified -if res_name or res_class is NULL. -</para> -<para> -<!-- .LP --> -The res_name and res_class arguments are not assumed to exist beyond -the call to -<function>XOpenIM</function>. -The specified resource database is assumed to exist for the lifetime -of the input method. -</para> -<para> -<!-- .LP --> -<function>XOpenIM</function> -returns NULL if no input method could be opened. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To close a connection, use -<function>XCloseIM</function>. -</para> -<indexterm significance="preferred"><primary>XCloseIM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcloseim'> -<funcprototype> - <funcdef>Status <function>XCloseIM</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCloseIM</function> -function closes the specified input method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set input method attributes, use -<function>XSetIMValues</function>. -</para> -<indexterm significance="preferred"><primary>XSetIMValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetimvalues'> -<funcprototype> - <funcdef>char *<function>XSetIMValues</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. -<!-- .ds Al \ to set <acronym>XIM</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable-length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetIMValues</function> -function presents a variable argument list programming interface -for setting attributes of the specified input method. -It returns NULL if it succeeds; -otherwise, -it returns the name of the first argument that could not be set. -Xlib does not attempt to set arguments from the supplied list that -follow the failed argument; -all arguments in the list preceding the failed argument have been set -correctly. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To query an input method, use -<function>XGetIMValues</function>. -</para> -<indexterm significance="preferred"><primary>XGetIMValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetimvalues'> -<funcprototype> - <funcdef>char *<function>XGetIMValues</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. -<!-- .ds Al \ to get XIM values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetIMValues</function> -function presents a variable argument list programming interface -for querying properties or features of the specified input method. -This function returns NULL if it succeeds; -otherwise, -it returns the name of the first argument that could not be obtained. -</para> -<para> -<!-- .LP --> -Each <acronym>XIM</acronym> value argument (following a name) must point to -a location where the <acronym>XIM</acronym> value is to be stored. -That is, if the <acronym>XIM</acronym> value is of type T, -the argument must be of type T*. -If T itself is a pointer type, -then -<function>XGetIMValues</function> -allocates memory to store the actual data, -and the client is responsible for freeing this data by calling -<function>XFree</function> -with the returned pointer. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the display associated with an input method, use -<function>XDisplayOfIM</function>. -</para> -<indexterm significance="preferred"><primary>XDisplayOfIM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdisplayofim'> -<funcprototype> - <funcdef>Display *<function>XDisplayOfIM</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDisplayOfIM</function> -function returns the display associated with the specified input method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the locale associated with an input method, use -<function>XLocaleOfIM</function>. -</para> -<indexterm significance="preferred"><primary>XLocaleOfIM</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlocaleofim'> -<funcprototype> - <funcdef>char *<function>XLocaleOfIM</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLocaleOfIM</function> -function returns the locale associated with the specified input method. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To register an input method instantiate callback, use -<function>XRegisterIMInstantiateCallback</function>. -</para> -<indexterm significance="preferred"><primary>XRegisterIMInstantiateCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xregisteriminstantiatecallback'> -<funcprototype> - <funcdef>Bool <function>XRegisterIMInstantiateCallback</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XrmDatabase<parameter> db</parameter></paramdef> - <paramdef>char<parameter> *res_name</parameter></paramdef> - <paramdef>char<parameter> *res_class</parameter></paramdef> - <paramdef>XIMProc<parameter> callback</parameter></paramdef> - <paramdef>XPointer<parameter> *client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>db</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_name</emphasis> - </term> - <listitem> - <para> -Specifies the full resource name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_class</emphasis> - </term> - <listitem> - <para> -Specifies the full class name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>callback</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the input method instantiate callback. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRegisterIMInstantiateCallback</function> -function registers a callback to be invoked whenever a new input method -becomes available for the specified display that matches the current -locale and modifiers. -</para> -<para> -<!-- .LP --> -The function returns -<symbol>True</symbol> - if it succeeds; otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -The generic prototype is as follows: -</para> -<indexterm significance="preferred"><primary>IMInstantiateCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='iminstantiatecallback'> -<funcprototype> - <funcdef>void <function><replaceable>IMInstantiateCallback</replaceable></function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -To unregister an input method instantiation callback, use -<function>XUnregisterIMInstantiateCallback</function>. -</para> -<indexterm significance="preferred"><primary>XUnregisterIMInstantiateCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunregisteriminstantiatecallback'> -<funcprototype> - <funcdef>Bool <function>XUnregisterIMInstantiateCallback</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XrmDatabase<parameter> db</parameter></paramdef> - <paramdef>char<parameter> *res_name</parameter></paramdef> - <paramdef>char<parameter> *res_class</parameter></paramdef> - <paramdef>XIMProc<parameter> callback</parameter></paramdef> - <paramdef>XPointer<parameter> *client_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>db</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_name</emphasis> - </term> - <listitem> - <para> -Specifies the full resource name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>res_class</emphasis> - </term> - <listitem> - <para> -Specifies the full class name of the application. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>callback</emphasis> - </term> - <listitem> - <para> -Specifies a pointer to the input method instantiate callback. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnregisterIMInstantiateCallback</function> -function removes an input method instantiation callback previously -registered. -The function returns -<symbol>True</symbol> -if it succeeds; otherwise, it returns -<symbol>False</symbol>. -</para> -</sect2> -<sect2 id="Input_Method_Values"> -<title>Input Method Values</title> -<!-- .XS --> -<!-- (SN Input Method Values --> -<!-- .XE --> -<para> -<!-- .LP --> -The following table describes how <acronym>XIM</acronym> values are interpreted -by an input method. -The first column lists the <acronym>XIM</acronym> values. -The second column indicates how each of the <acronym>XIM</acronym> values -are treated by that input style. -</para> -<para> -<!-- .LP --> -</para> -<para> -<!-- .LP --> -The following keys apply to this table. -</para> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'>Key</entry> - <entry align='left'>Explanation</entry> - </row> - </thead> - <tbody> - <row> - <entry>D</entry> - <entry>This value may be set using - <function>XSetIMValues</function>. - If it is not set, - a default is provided.</entry> - </row> - <row> - <entry>S</entry> - <entry>This value may be set using <function>XSetIMValues</function>.</entry> - </row> - <row> - <entry>G</entry> - <entry>This value may be read using <function>XGetIMValues</function>.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para></para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'><acronym>XIM</acronym> Value</entry> - <entry align='left'>Key</entry> - </row> - </thead> - <tbody> - <row> - <entry><symbol>XNQueryInputStyle</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNResourceName</symbol></entry> - <entry>D-S-G</entry> - </row> - <row> - <entry><symbol>XNResourceClass</symbol></entry> - <entry>D-S-G</entry> - </row> - <row> - <entry><symbol>XNDestroyCallback</symbol></entry> - <entry>D-S-G</entry> - </row> - <row> - <entry><symbol>XNQueryIMValuesList</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNQueryICValuesList</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNVisiblePosition</symbol></entry> - <entry>G</entry> - </row> - <row> - <entry><symbol>XNR6PreeditCallback</symbol></entry> - <entry>D-S-G</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -<symbol>XNR6PreeditCallback</symbol> -is obsolete and its use is not recommended -(see <link linkend="Preedit_Callback_Behavior">section 13.5.4.6</link>). -</para> - -<sect3 id="Query_Input_Style"> -<title>Query Input Style</title> -<!-- .XS --> -<!-- (SN Query Input Style --> -<!-- .XE --> -<para> -<!-- .LP --> -A client should always query the input method to determine which input -styles are supported. -The client should then find an input style it is capable of supporting. -</para> -<para> -<!-- .LP --> -If the client cannot find an input style that it can support, -it should negotiate with the user the continuation of the program -(exit, choose another input method, and so on). -</para> -<para> -<!-- .LP --> -The argument value must be a pointer to a location -where the returned value will be stored. -The returned value is a pointer to a structure of type -<structname>XIMStyles</structname>. -Clients are responsible for freeing the -<structname>XIMStyles</structname> -structure. -To do so, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XIMStyles</structname> -structure is defined as follows: -</para> - -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMStyle</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditArea</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditCallbacks</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditPosition</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditNothing</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditNone</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusArea</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusCallbacks</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusNothing</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusNone</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStyles</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -typedef unsigned long XIMStyle; - - -#define XIMPreeditArea 0x0001L -#define XIMPreeditCallbacks 0x0002L -#define XIMPreeditPosition 0x0004L -#define XIMPreeditNothing 0x0008L -#define XIMPreeditNone 0x0010L - -#define XIMStatusArea 0x0100L -#define XIMStatusCallbacks 0x0200L -#define XIMStatusNothing 0x0400L -#define XIMStatusNone 0x0800L - -typedef struct { - unsigned short count_styles; - XIMStyle * supported_styles; -} XIMStyles; - -</literallayout> - - -<para> -<!-- .LP --> -<!-- .eM --> -An -<structname>XIMStyles</structname> -structure contains the number of input styles supported -in its count_styles field. -This is also the size of the supported_styles array. -</para> -<para> -<!-- .LP --> -The supported styles is a list of bitmask combinations, -which indicate the combination of styles for each of the areas supported. -These areas are described later. -Each element in the list should select one of the bitmask values for -each area. -The list describes the complete set of combinations supported. -Only these combinations are supported by the input method. -</para> -<para> -<!-- .LP --> -The preedit category defines what type of support is provided -by the input method for preedit information. -</para> -<indexterm significance="preferred"><primary>XIMPreeditArea</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditPosition</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditCallbacks</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditNothing</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditNone</primary></indexterm> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>XIMPreeditArea</symbol></entry> - <entry>If chosen, - the input method would require the client to provide some area values - for it to do its preediting. - Refer to <acronym>XIC</acronym> values - <symbol>XNArea</symbol> - and - <symbol>XNAreaNeeded</symbol>.</entry> - </row> - <row> - <entry><symbol>XIMPreeditPosition</symbol></entry> - <entry>If chosen, - the input method would require the client to provide positional values. - Refer to <acronym>XIC</acronym> values - <symbol>XNSpotLocation</symbol> - and - <symbol>XNFocusWindow</symbol>.</entry> - </row> - <row> - <entry><symbol>XIMPreeditCallbacks</symbol></entry> - <entry>If chosen, - the input method would require the client to define the set of preedit callbacks. - Refer to <acronym>XIC</acronym> values - <symbol>XNPreeditStartCallback</symbol>, - <symbol>XNPreeditDoneCallback</symbol>, - <symbol>XNPreeditDrawCallback</symbol>, - and - <symbol>XNPreeditCaretCallback</symbol>.</entry> - </row> - <row> - <entry><symbol>XIMPreeditNothing</symbol></entry> - <entry>If chosen, the input method can function without any preedit values.</entry> - </row> - <row> - <entry><symbol>XIMPreeditNone</symbol></entry> - <entry>The input method does not provide any preedit feedback. - Any preedit value is ignored. - This style is mutually exclusive with the other preedit styles.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -The status category defines what type of support is provided -by the input method for status information. -</para> -<indexterm significance="preferred"><primary>XIMStatusArea</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusCallbacks</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusNothing</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusNone</primary></indexterm> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>XIMStatusArea</symbol></entry> - <entry>The input method requires the client to provide - some area values for it to do its status feedback. - See - <symbol>XNArea</symbol> - and - <symbol>XNAreaNeeded</symbol>.</entry> - </row> - <row> - <entry><symbol>XIMStatusCallbacks</symbol></entry> - <entry>The input method requires the client to define the set of status callbacks, - <symbol>XNStatusStartCallback</symbol>, - <symbol>XNStatusDoneCallback</symbol>, - and - <symbol>XNStatusDrawCallback</symbol>.</entry> - </row> - <row> - <entry><symbol>XIMStatusNothing</symbol></entry> - <entry>The input method can function without any status values.</entry> - </row> - <row> - <entry><symbol>XIMStatusNone</symbol></entry> - <entry>The input method does not provide any status feedback. - If chosen, any status value is ignored. - This style is mutually exclusive with the other status styles.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -</sect3> -<sect3 id="Resource_Name_and_Class_c"> -<title>Resource Name and Class</title> -<!-- .XS --> -<!-- (SN Resource Name and Class --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNResourceName</symbol> -and -<symbol>XNResourceClass</symbol> -arguments are strings that specify the full name and class -used by the input method. -These values should be used as prefixes for the name and class -when looking up resources that may vary according to the input method. -If these values are not set, -the resources will not be fully specified. -</para> -<para> -<!-- .LP --> -It is not intended that values that can be set as <acronym>XIM</acronym> values be -set as resources. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Destroy_Callback"> -<title>Destroy Callback</title> -<!-- .XS --> -<!-- (SN Destroy Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNDestroyCallback</symbol> -argument is a pointer to a structure of type -<structname>XIMCallback</structname>. -<symbol>XNDestroyCallback</symbol> -is triggered when an input method stops its service for any reason. -After the callback is invoked, the input method is closed and the -associated input context(s) are destroyed by Xlib. -Therefore, the client should not call -<function>XCloseIM</function> -or -<function>XDestroyIC</function>. -</para> -<para> -<!-- .LP --> -The generic prototype of this callback function is as follows: -</para> -<indexterm significance="preferred"><primary>DestroyCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='destroycallback'> -<funcprototype> - <funcdef>void <function><replaceable>DestroyCallback</replaceable></function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -A DestroyCallback is always called with a NULL call_data argument. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Query_IM_IC_Values_List"> -<title>Query IM/IC Values List</title> -<!-- .XS --> -<!-- (SN Query IM/IC Values List --> -<!-- .XE --> -<para> -<!-- .LP --> -<symbol>XNQueryIMValuesList</symbol> -and -<symbol>XNQueryICValuesList</symbol> -are used to query about <acronym>XIM</acronym> and <acronym>XIC</acronym> values supported by the input method. -</para> -<para> -<!-- .LP --> -The argument value must be a pointer to a location where the returned -value will be stored. The returned value is a pointer to a structure -of type -<structname>XIMValuesList</structname>. -Clients are responsible for freeing the -<structname>XIMValuesList</structname> -structure. -To do so, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XIMValuesList</structname> -structure is defined as follows: -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - unsigned short count_values; - char **supported_values; -} XIMValuesList; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect3> -<sect3 id="Visible_Position"> -<title>Visible Position</title> -<!-- .XS --> -<!-- (SN Visible Position --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNVisiblePosition</symbol> -argument indicates whether the visible position masks of -<type>XIMFeedback</type> -in -<structname>XIMText</structname> -are available. -</para> -<para> -<!-- .LP --> -The argument value must be a pointer to a location where the returned -value will be stored. The returned value is of type -<type>Bool</type>. -If the returned value is -<symbol>True</symbol>, -the input method uses the visible position masks of -<type>XIMFeedback</type> -in -<structname>XIMText</structname>; -otherwise, the input method does not use the masks. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIM</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryIMValuesList</symbol> -before using this argument. -If the -<symbol>XNVisiblePosition</symbol> -does not exist in the IM values list returned from -<symbol>XNQueryIMValuesList</symbol>, -the visible position masks of -<type>XIMFeedback</type> -in -<structname>XIMText</structname> -are not used to indicate the visible position. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Preedit_Callback_Behavior"> -<title>Preedit Callback Behavior</title> -<!-- .XS --> -<!-- (SN Preedit Callback Behavior --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNR6PreeditCallback</symbol> -argument originally included in the X11R6 specification has been -deprecated.\(dg -<!-- .\" If XNR6PreeditCallbackBehavior is not deprecated, then its type --> -<!-- .\" should be changed from *Bool to Bool. --> -<!-- .FS \(dg --> -During formulation of the X11R6 specification, the behavior of -the R6 PreeditDrawCallbacks was going to differ significantly from -that of the R5 callbacks. -Late changes to the specification converged the R5 and R6 behaviors, -eliminating the need for -<symbol>XNR6PreeditCallback</symbol>. -Unfortunately, this argument was not removed from the R6 specification -before it was published. -<!-- .FE --> -</para> -<para> -<!-- .LP --> -The -<symbol>XNR6PreeditCallback</symbol> -argument indicates whether the behavior of preedit callbacks regarding -<structname>XIMPreeditDrawCallbackStruct</structname> -values follows Release 5 or Release 6 semantics. -</para> -<para> -<!-- .LP --> -The value is of type -<type>Bool</type>. -When querying for -<symbol>XNR6PreeditCallback</symbol>, -if the returned value is -<symbol>True</symbol>, -the input method uses the Release 6 behavior; -otherwise, it uses the Release 5 behavior. -The default value is -<symbol>False</symbol>. -In order to use Release 6 semantics, the value of -<symbol>XNR6PreeditCallback</symbol> -must be set to -<symbol>True</symbol>. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIM</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryIMValuesList</symbol> -before using this argument. -If the -<symbol>XNR6PreeditCallback</symbol> -does not exist in the IM values list returned from -<symbol>XNQueryIMValuesList</symbol>, -the PreeditCallback behavior is Release 5 semantics. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -</sect2> -<sect2 id="Input_Context_Functions"> -<title>Input Context Functions</title> -<!-- .XS --> -<!-- (SN Input Context Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -An input context is an abstraction that is used to contain both the data -required (if any) by an input method and the information required -to display that data. -There may be multiple input contexts for one input method. -The programming interfaces for creating, reading, or modifying -an input context use a variable argument list. -The name elements of the argument lists are referred to as <acronym>XIC</acronym> values. -It is intended that input methods be controlled by these <acronym>XIC</acronym> values. -As new <acronym>XIC</acronym> values are created, -they should be registered with the X Consortium. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create an input context, use -<function>XCreateIC</function>. -</para> -<indexterm significance="preferred"><primary>XCreateIC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreateic'> -<funcprototype> - <funcdef>XIC <function>XCreateIC</function></funcdef> - <paramdef>XIM<parameter> im</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>im</emphasis> - </term> - <listitem> - <para> -Specifies the input method. -<!-- .ds Al \ to set <acronym>XIC</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateIC</function> -function creates a context within the specified input method. -</para> -<para> -<!-- .LP --> -Some of the arguments are mandatory at creation time, and -the input context will not be created if those arguments are not provided. -The mandatory arguments are the input style and the set of text callbacks -(if the input style selected requires callbacks). -All other input context values can be set later. -</para> -<para> -<!-- .LP --> -<function>XCreateIC</function> -returns a NULL value if no input context could be created. -A NULL value could be returned for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -A required argument was not set. - </para> - </listitem> - <listitem> - <para> -A read-only argument was set (for example, -<symbol>XNFilterEvents</symbol>). - </para> - </listitem> - <listitem> - <para> -The argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -The input method encountered an input method implementation-dependent error. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<function>XCreateIC</function> -can generate -<errorname>BadAtom</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy an input context, use -<function>XDestroyIC</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyIC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroyic'> -<funcprototype> - <funcdef>void <function>XDestroyIC</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<function>XDestroyIC</function> -destroys the specified input context. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To communicate to and synchronize with input method -for any changes in keyboard focus from the client side, -use -<function>XSetICFocus</function> -and -<function>XUnsetICFocus</function>. -</para> -<indexterm significance="preferred"><primary>XSetICFocus</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xseticfocus'> -<funcprototype> - <funcdef>void <function>XSetICFocus</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetICFocus</function> -function allows a client to notify an input method that the focus window -attached to the specified input context has received keyboard focus. -The input method should take action to provide appropriate feedback. -Complete feedback specification is a matter of user interface policy. -</para> -<para> -<!-- .LP --> -Calling -<function>XSetICFocus</function> -does not affect the focus window value. -</para> -<indexterm significance="preferred"><primary>XUnsetICFocus</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunseticfocus'> -<funcprototype> - <funcdef>void <function>XUnsetICFocus</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnsetICFocus</function> -function allows a client to notify an input method that the specified input context -has lost the keyboard focus and that no more input is expected on the focus window -attached to that input context. -The input method should take action to provide appropriate feedback. -Complete feedback specification is a matter of user interface policy. -</para> -<para> -<!-- .LP --> -Calling -<function>XUnsetICFocus</function> -does not affect the focus window value; -the client may still receive -events from the input method that are directed to the focus window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To reset the state of an input context to its initial state, use -<function>XmbResetIC</function> -or -<function>XwcResetIC</function>. -</para> -<indexterm significance="preferred"><primary>XmbResetIC</primary></indexterm> -<indexterm significance="preferred"><primary>XwcResetIC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbresetic'> -<funcprototype> - <funcdef>char *<function>XmbResetIC</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwcresetic'> -<funcprototype> - <funcdef>wchar_t *<function>XwcResetIC</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -When -<symbol>XNResetState</symbol> -is set to -<symbol>XIMInitialState</symbol>, -<function>XmbResetIC</function> -and -<function>XwcResetIC</function> -reset an input context to its initial state; -when -<symbol>XNResetState</symbol> -is set to -<symbol>XIMPreserveState</symbol>, -the current input context state is preserved. -In both cases, any input pending on that context is deleted. -The input method is required to clear the preedit area, if any, -and update the status accordingly. -Calling -<function>XmbResetIC</function> -or -<function>XwcResetIC</function> -does not change the focus. -</para> -<para> -<!-- .LP --> -The return value of -<function>XmbResetIC</function> -is its current preedit string as a multibyte string. -If there is any preedit text drawn or visible to the user, -then these procedures must return a non-NULL string. -If there is no visible preedit text, -then it is input method implementation-dependent -whether these procedures return a non-NULL string or NULL. -</para> -<para> -<!-- .LP --> -The client should free the returned string by calling -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the input method associated with an input context, use -<function>XIMOfIC</function>. -</para> -<indexterm significance="preferred"><primary>XIMOfIC</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='ximofic'> -<funcprototype> - <funcdef>XIM <function>XIMOfIC</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XIMOfIC</function> -function returns the input method associated with the specified input context. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Xlib provides two functions for setting and reading <acronym>XIC</acronym> values, respectively, -<function>XSetICValues</function> -and -<function>XGetICValues</function>. -Both functions have a variable-length argument list. -In that argument list, any <acronym>XIC</acronym> value's name must be denoted -with a character string using the X Portable Character Set. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set <acronym>XIC</acronym> values, use -<function>XSetICValues</function>. -</para> -<indexterm significance="preferred"><primary>XSetICValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xseticvalues'> -<funcprototype> - <funcdef>char *<function>XSetICValues</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. -<!-- .ds Al \ to set <acronym>XIC</acronym> values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetICValues</function> -function returns NULL if no error occurred; -otherwise, -it returns the name of the first argument that could not be set. -An argument might not be set for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -The argument is read-only (for example, -<symbol>XNFilterEvents</symbol>). - </para> - </listitem> - <listitem> - <para> -The argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -An implementation-dependent error occurs. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Each value to be set must be an appropriate datum, -matching the data type imposed by the semantics of the argument. -</para> -<para> -<!-- .LP --> -<function>XSetICValues</function> -can generate -<errorname>BadAtom</errorname>, -<errorname>BadColor</errorname>, -<errorname>BadCursor</errorname>, -<errorname>BadPixmap</errorname>, -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain <acronym>XIC</acronym> values, use -<function>XGetICValues</function>. -</para> -<indexterm significance="preferred"><primary>XGetICValues</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeticvalues'> -<funcprototype> - <funcdef>char *<function>XGetICValues</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. -<!-- .ds Al \ to get XIC values --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - ... - </term> - <listitem> - <para> -Specifies the variable length argument list(Al. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetICValues</function> -function returns NULL if no error occurred; otherwise, -it returns the name of the first argument that could not be obtained. -An argument could not be obtained for any of the following reasons: -</para> -<itemizedlist> - <listitem> - <para> -The argument name is not recognized. - </para> - </listitem> - <listitem> - <para> -The input method encountered an implementation-dependent error. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -Each IC attribute value argument (following a name) must point to -a location where the IC value is to be stored. -That is, if the IC value is of type T, -the argument must be of type T*. -If T itself is a pointer type, -then -<function>XGetICValues</function> -allocates memory to store the actual data, -and the client is responsible for freeing this data by calling -<function>XFree</function> -with the returned pointer. -The exception to this rule is for an IC value of type -<type>XVaNestedList</type> -(for preedit and status attributes). -In this case, the argument must also be of type -<type>XVaNestedList</type>. -Then, the rule of changing type T to T* and freeing the allocated data -applies to each element of the nested list. -</para> -</sect2> -<sect2 id="Input_Context_Values"> -<title>Input Context Values</title> -<!-- .XS --> -<!-- (SN Input Context Values --> -<!-- .XE --> -<para> -<!-- .LP --> -The following tables describe how <acronym>XIC</acronym> values are interpreted -by an input method depending on the input style chosen by the -user. -</para> -<para> -<!-- .LP --> -The first column lists the <acronym>XIC</acronym> values. -The second column indicates which values are involved in affecting, -negotiating, and setting the geometry of the input method windows. -The subentries under the third column indicate the different -input styles that are supported. -Each of these columns indicates how each of the <acronym>XIC</acronym> values -are treated by that input style. -</para> -<para> -<!-- .LP --> -The following keys apply to these tables. -</para> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <thead> - <row> - <entry align='left'>Key</entry> - <entry align='left'>Explanation</entry> - </row> - </thead> - <tbody> - <row> - <entry>C</entry> - <entry>This value must be set with <function>XCreateIC</function>.</entry> - </row> - <row> - <entry>D</entry> - <entry>This value may be set using - <function>XCreateIC</function>.> - If it is not set,> - a default is provided.</entry> - </row> - <row> - <entry>G</entry> - <entry>This value may be read using - <function>XGetICValues</function>.</entry> - </row> - <row> - <entry>GN</entry> - <entry>This value may cause geometry negotiation when its value is set by means of - <function>XCreateIC</function> - or - <function>XSetICValues</function>.</entry> - </row> - <row> - <entry>GR</entry> - <entry>This value will be the response of the input method when any - GN value is changed.</entry> - </row> - <row> - <entry>GS</entry> - <entry>This value will cause the geometry of the input method window to be set.</entry> - </row> - <row> - <entry>O</entry> - <entry>This value must be set once and only once. - It need not be set at create time.</entry> - </row> - <row> - <entry>S</entry> - <entry>This value may be set with - <function>XSetICValues</function>.</entry> - </row> - <row> - <entry>Ignored</entry> - <entry>This value is ignored by the input method for the given input style.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para></para> - -<!-- .LP --> -<informaltable> - <tgroup cols='7'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <colspec colname='c4'/> - <colspec colname='c5'/> - <colspec colname='c6'/> - <colspec colname='c7'/> - <thead> - <row> - <entry><acronym>XIC</acronym> Value</entry> - <entry>Geometry Mangement</entry> - <entry>Preedit Callback</entry> - <entry>Preedit Position</entry> - <entry>Input Style Preedit Area</entry> - <entry>Preedit Nothing</entry> - <entry>Preedit None</entry> - </row> - </thead> - <tbody> - <row> - <entry>Input Style</entry> - <entry></entry> - <entry>C-G</entry> - <entry>C-G</entry> - <entry>C-G</entry> - <entry>C-G</entry> - <entry>C-G</entry> - </row> - <row> - <entry>Client Window</entry> - <entry></entry> - <entry>O-G</entry> - <entry>O-G</entry> - <entry>O-G</entry> - <entry>O-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Focus Window</entry> - <entry>GN</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Resource Name</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Resource Class</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Geometry Callback</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Filter Events</entry> - <entry></entry> - <entry>G</entry> - <entry>G</entry> - <entry>G</entry> - <entry>G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Destroy Callback</entry> - <entry></entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - </row> - <row> - <entry>String Conversion Callback</entry> - <entry></entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - </row> - <row> - <entry>String Conversion</entry> - <entry></entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - </row> - <row> - <entry>Reset State</entry> - <entry></entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>HotKey</entry> - <entry></entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>HotKeyState</entry> - <entry></entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry><function>Preedit</function></entry> - </row> - <row> - <entry>Area</entry> - <entry>GS</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Area Needed</entry> - <entry>GN-GR</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Spot Location</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Colormap</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Foreground</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Background</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Background Pixmap</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Font Set</entry> - <entry>GN</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Line Spacing</entry> - <entry>GN</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Cursor</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Preedit State</entry> - <entry></entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Preedit State Notify Callback</entry> - <entry></entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Preedit Callbacks</entry> - <entry></entry> - <entry>C-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para></para> - -<!-- .LP --> -<informaltable> - <tgroup cols='6'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <colspec colname='c4'/> - <colspec colname='c5'/> - <colspec colname='c6'/> - <thead> - <row> - <entry><acronym>XIC</acronym> Value</entry> - <entry>Geomentry Management</entry> - <entry>Status Callback</entry> - <entry>Status Area</entry> - <entry>Status Nothing</entry> - <entry>Status None</entry> - </row> - </thead> - <tbody> - <row> - <entry>Input Style</entry> - <entry></entry> - <entry>C-G</entry> - <entry>C-G</entry> - <entry>C-G</entry> - <entry>C-G</entry> - </row> - <row> - <entry>Client Window</entry> - <entry></entry> - <entry>O-G</entry> - <entry>O-G</entry> - <entry>O-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Focus Window</entry> - <entry>GN</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Resource Name</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Resource Class</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Geometry Callback</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Filter Events</entry> - <entry></entry> - <entry>G</entry> - <entry>G</entry> - <entry>G</entry> - <entry>G</entry> - </row> - <row> - <entry><type>Status</type></entry> - </row> - <row> - <entry>Area</entry> - <entry>GS</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Area Needed</entry> - <entry>GN-GR</entry> - <entry>Ignored</entry> - <entry>S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Colormap</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Foreground</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Background</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Background Pixmap</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Font Set</entry> - <entry>GN</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Line Spacing</entry> - <entry>GN</entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Cursor</entry> - <entry></entry> - <entry>Ignored</entry> - <entry>D-S-G</entry> - <entry>D-S-G</entry> - <entry>Ignored</entry> - </row> - <row> - <entry>Status Callbacks</entry> - <entry></entry> - <entry>C-S-G</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - <entry>Ignored</entry> - </row> - </tbody> - </tgroup> -</informaltable> -<sect3 id="Input_Style"> -<title>Input Style</title> -<!-- .XS --> -<!-- (SN Input Style --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNInputStyle</symbol> -argument specifies the input style to be used. -The value of this argument must be one of the values returned by the -<function>XGetIMValues</function> -function with the -<symbol>XNQueryInputStyle</symbol> -argument specified in the supported_styles list. -</para> -<para> -<!-- .LP --> -Note that this argument must be set at creation time -and cannot be changed. -</para> -</sect3> -<sect3 id="Client_Window"> -<title>Client Window</title> -<!-- .XS --> -<!-- (SN Client Window --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNClientWindow</primary></indexterm> -The -<symbol>XNClientWindow</symbol> -argument specifies to the input method the client window in -which the input method -can display data or create subwindows. -Geometry values for input method areas are given with respect to the client -window. -Dynamic change of client window is not supported. -This argument may be set only once and -should be set before any input is done using this input context. -If it is not set, -the input method may not operate correctly. -</para> -<para> -<!-- .LP --> -If an attempt is made to set this value a second time with -<function>XSetICValues</function>, -the string -<symbol>XNClientWindow</symbol> -will be returned by -<function>XSetICValues</function>, -and the client window will not be changed. -</para> -<para> -<!-- .LP --> -If the client window is not a valid window ID on the display -attached to the input method, -a -<errorname>BadWindow</errorname> -error can be generated when this value is used by the input method. -</para> -</sect3> -<sect3 id="Focus_Window"> -<title>Focus Window</title> -<!-- .XS --> -<!-- (SN Focus Window --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNFocusWindow</primary></indexterm> -The -<symbol>XNFocusWindow</symbol> -argument specifies the focus window. -The primary purpose of the -<symbol>XNFocusWindow</symbol> -is to identify the window that will receive the key event when input -is composed. -In addition, the input method may possibly affect the focus window -as follows: -</para> -<itemizedlist> - <listitem> - <para> -Select events on it - </para> - </listitem> - <listitem> - <para> -Send events to it - </para> - </listitem> - <listitem> - <para> -Modify its properties - </para> - </listitem> - <listitem> - <para> -Grab the keyboard within that window - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The associated value must be of type -<type>Window</type>. -If the focus window is not a valid window ID on the display -attached to the input method, -a -<errorname>BadWindow</errorname> -error can be generated when this value is used by the input method. -</para> -<para> -<!-- .LP --> -When this <acronym>XIC</acronym> value is left unspecified, -the input method will use the client window as the default focus window. -</para> -</sect3> -<sect3 id="Resource_Name_and_Class_b"> -<title>Resource Name and Class</title> -<!-- .XS --> -<!-- (SN Resource Name and Class --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNResourceName</primary></indexterm> -<indexterm significance="preferred"><primary>XNResourceClass</primary></indexterm> -The -<symbol>XNResourceName</symbol> -and -<symbol>XNResourceClass</symbol> -arguments are strings that specify the full name and class -used by the client to obtain resources for the client window. -These values should be used as prefixes for name and class -when looking up resources that may vary according to the input context. -If these values are not set, -the resources will not be fully specified. -</para> -<para> -<!-- .LP --> -It is not intended that values that can be set as <acronym>XIC</acronym> values be -set as resources. -</para> -</sect3> -<sect3 id="Geometry_Callback"> -<title>Geometry Callback</title> -<!-- .XS --> -<!-- (SN Geometry Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNGeometryCallback</primary></indexterm> -The -<symbol>XNGeometryCallback</symbol> -argument is a structure of type -<structname>XIMCallback</structname> -(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>). -</para> -<para> -<!-- .LP --> -The -<symbol>XNGeometryCallback</symbol> -argument specifies the geometry callback that a client can set. -This callback is not required for correct operation of either -an input method or a client. -It can be set for a client whose user interface policy permits -an input method to request the dynamic change of that input -method's window. -An input method that does dynamic change will need to filter any -events that it uses to initiate the change. -</para> -</sect3> -<sect3 id="Filter_Events"> -<title>Filter Events</title> -<!-- .XS --> -<!-- (SN Filter Events --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNFilterEvents</primary></indexterm> -The -<symbol>XNFilterEvents</symbol> -argument returns the event mask that an input method needs -to have selected for. -The client is expected to augment its own event mask -for the client window with this one. -</para> -<para> -<!-- .LP --> -This argument is read-only, is set by the input method at create time, -and is never changed. -</para> -<para> -<!-- .LP --> -The type of this argument is -<type>unsigned</type> -<type>long</type>. -Setting this value will cause an error. -</para> -</sect3> -<sect3 id="Destroy_Callback_b"> -<title>Destroy Callback</title> -<!-- .XS --> -<!-- (SN Destroy Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNDestroyCallback</symbol> -argument is a pointer to a structure of type -<structname>XIMCallback</structname> -(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>). -This callback is triggered when the input method -stops its service for any reason; for example, when a connection to an IM -server is broken. After the destroy callback is called, -the input context is destroyed and the input method is closed. -Therefore, the client should not call -<function>XDestroyIC</function> -and -<function>XCloseIM</function>. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="String_Conversion_Callback"> -<title>String Conversion Callback</title> -<!-- .XS --> -<!-- (SN String Conversion Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNStringConversionCallback</symbol> -argument is a structure of type -<structname>XIMCallback</structname> -(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>). -</para> -<para> -<!-- .LP --> -The -<symbol>XNStringConversionCallback</symbol> -argument specifies a string conversion callback. This callback -is not required for correct operation of -either the input method or the client. It can be set by a client -to support string conversions that may be requested -by the input method. An input method that does string conversions -will filter any events that it uses to initiate the conversion. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this argument. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="String_Conversion_"> -<title>String Conversion </title> -<!-- .XS --> -<!-- (SN String Conversion --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNStringConversion</symbol> -argument is a structure of type -<structname>XIMStringConversionText</structname>. -</para> -<para> -<!-- .LP --> -The -<symbol>XNStringConversion</symbol> -argument specifies the string to be converted by an input method. -This argument is not required for correct operation of either -the input method or the client. -</para> -<para> -<!-- .LP --> -String conversion facilitates the manipulation of text independent -of preediting. -It is essential for some input methods and clients to manipulate -text by performing context-sensitive conversion, -reconversion, or transliteration conversion on it. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this argument. -</para> -<para> -<!-- .LP --> -The -<structname>XIMStringConversionText</structname> -structure is defined as follows: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> - -typedef struct _XIMStringConversionText { - unsigned short length; - XIMStringConversionFeedback *feedback; - Bool encoding_is_wchar; - union { - char *mbs; - wchar_t *wcs; - } string; -} XIMStringConversionText; - -typedef unsigned long XIMStringConversionFeedback; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The feedback member is reserved for future use. The text to be -converted is defined by the string and length members. The length -is indicated in characters. To prevent the library from freeing memory -pointed to by an uninitialized pointer, the client should set the feedback -element to NULL. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Reset_State"> -<title>Reset State</title> -<!-- .XS --> -<!-- (SN Reset State --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNResetState</symbol> -argument specifies the state the input context will return to after calling -<function>XmbResetIC</function> -or -<function>XwcResetIC</function>. -</para> -<para> -<!-- .LP --> -The <acronym>XIC</acronym> state may be set to its initial state, as specified by the -<symbol>XNPreeditState</symbol> -value when -<function>XCreateIC</function> -was called, or it may be set to preserve the current state. -</para> -<para> -<!-- .LP --> -The valid masks for -<type>XIMResetState</type> -are as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMInitialState</primary></indexterm> -<indexterm significance="preferred"><primary>XINPreserveState</primary></indexterm> -<!-- .sM --> -</para> -<literallayout class="monospaced"> -typedef unsigned long XIMResetState; - -#define XIMInitialState (1L) -#define XIMPreserveState (1L<<1) - -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -If -<symbol>XIMInitialState</symbol> -is set, then -<function>XmbResetIC</function> -and -<function>XwcResetIC</function> -will return to the initial -<symbol>XNPreeditState</symbol> -state of the <acronym>XIC</acronym>. -</para> -<para> -<!-- .LP --> -If -<symbol>XIMPreserveState</symbol> -is set, then -<function>XmbResetIC</function> -and -<function>XwcResetIC</function> -will preserve the current state of the <acronym>XIC</acronym>. -</para> -<para> -<!-- .LP --> -If -<symbol>XNResetState</symbol> -is left unspecified, the default is -<symbol>XIMInitialState</symbol>. -</para> -<para> -<!-- .LP --> -<type>XIMResetState</type> -values other than those specified above will default to -<symbol>XIMInitialState</symbol>. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this argument. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Hot_Keys_b"> -<title>Hot Keys</title> -<!-- .XS --> -<!-- (SN Hot Keys --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNHotKey</symbol> -argument specifies the hot key list to the <acronym>XIC</acronym>. -The hot key list is a pointer to the structure of type -<structname>XIMHotKeyTriggers</structname>, -which specifies the key events that must be received -without any interruption of the input method. -For the hot key list set with this argument to be utilized, the client -must also set -<symbol>XNHotKeyState</symbol> -to -<symbol>XIMHotKeyStateON</symbol>. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this functionality. -</para> -<para> -<!-- .LP --> -The value of the argument is a pointer to a structure of type -<structname>XIMHotKeyTriggers</structname>. -</para> -<para> -<!-- .LP --> -If an event for a key in the hot key list is found, then the process will -receive the event and it will be processed inside the client. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - KeySym keysym; - unsigned int modifier; - unsigned int modifier_mask; -} XIMHotKeyTrigger; - -typedef struct { - int num_hot_key; - XIMHotKeyTrigger *key; -} XIMHotKeyTriggers; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -<para> -<!-- .LP --> -The combination of modifier and modifier_mask are used to represent one of -three states for each modifier: -either the modifier must be on, or the modifier must be off, or the modifier -is a ``don't care'' - it may be on or off. -When a modifier_mask bit is set to 0, the state of the associated modifier -is ignored when evaluating whether the key is hot or not. -</para> - -<informaltable> - <tgroup cols='3'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <thead> - <row> - <entry>Modifier Bit</entry> - <entry>Mask Bit</entry> - <entry>Meaning</entry> - </row> - </thead> - <tbody> - <row> - <entry>0</entry> - <entry>1</entry> - <entry>The modifier must be off.</entry> - </row> - <row> - <entry>1</entry> - <entry>1</entry> - <entry>The modifier must be on.</entry> - </row> - <row> - <entry>n/a</entry> - <entry>0</entry> - <entry>Do not care if the modifier is on or off.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -</sect3> -<sect3 id="Hot_Key_State"> -<title>Hot Key State</title> -<!-- .XS --> -<!-- (SN Hot Key State --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNHotKeyState</symbol> -argument specifies the hot key state of the input method. -This is usually used to switch the input method between hot key -operation and normal input processing. -</para> -<para> -<!-- .LP --> -The value of the argument is a pointer to a structure of type -XIMHotKeyState . -</para> -<literallayout class="monospaced"> -typedef unsigned long XIMHotKeyState; - -#define XIMHotKeyStateON (0x0001L) -#define XIMHotKeyStateOFF (0x0002L) - -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -</para> -<para> -<!-- .LP --> -If not specified, the default is -<symbol>XIMHotKeyStateOFF</symbol>. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -<sect3 id="Preedit_and_Status_Attributes"> -<title>Preedit and Status Attributes</title> -<!-- .XS --> -<!-- (SN Preedit and Status Attributes --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNPreeditAttributes</primary></indexterm> -<indexterm significance="preferred"><primary>XNStatusAttributes</primary></indexterm> -The -<symbol>XNPreeditAttributes</symbol> -and -<symbol>XNStatusAttributes</symbol> -arguments specify to an input method the attributes to be used for the -preedit and status areas, -if any. -Those attributes are passed to -<function>XSetICValues</function> -or -<function>XGetICValues</function> -as a nested variable-length list. -The names to be used in these lists are described in the following sections. -</para> -<sect4 id="Area"> -<title>Area</title> -<!-- .XS --> -<!-- (SN Area --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNArea</primary></indexterm> -The value of the -<symbol>XNArea</symbol> -argument must be a pointer to a structure of type -<structname>XRectangle</structname>. -The interpretation of the -<symbol>XNArea</symbol> -argument is dependent on the input method style that has been set. -</para> -<para> -<!-- .LP --> -If the input method style is -<symbol>XIMPreeditPosition</symbol>, -<symbol>XNArea</symbol> -specifies the clipping region within which preediting will take place. -If the focus window has been set, -the coordinates are assumed to be relative to the focus window. -Otherwise, the coordinates are assumed to be relative to the client window. -If neither has been set, -the results are undefined. -</para> -<para> -<!-- .LP --> -If -<symbol>XNArea</symbol> -is not specified, is set to NULL, or is invalid, -the input method will default the clipping region -to the geometry of the -<symbol>XNFocusWindow</symbol>. -If the area specified is NULL or invalid, -the results are undefined. -</para> -<para> -<!-- .LP --> -If the input style is -<symbol>XIMPreeditArea</symbol> -or -<symbol>XIMStatusArea</symbol>, -<symbol>XNArea</symbol> -specifies the geometry provided by the client to the input method. -The input method may use this area to display its data, -either preedit or status depending on the area designated. -The input method may create a window as a child of the client window -with dimensions that fit the -<symbol>XNArea</symbol>. -The coordinates are relative to the client window. -If the client window has not been set yet, -the input method should save these values -and apply them when the client window is set. -If -<symbol>XNArea</symbol> -is not specified, is set to NULL, or is invalid, -the results are undefined. -</para> -</sect4> -<sect4 id="Area_Needed"> -<title>Area Needed</title> -<!-- .XS --> -<!-- (SN Area Needed --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNAreaNeeded</primary></indexterm> -When set, the -<symbol>XNAreaNeeded</symbol> -argument specifies the geometry suggested by the client for this area -(preedit or status). -The value associated with the argument must be a pointer to a -structure of type -<structname>XRectangle</structname>. -Note that the x, y values are not used -and that nonzero values for width or height are the constraints -that the client wishes the input method to respect. -</para> -<para> -<!-- .LP --> -When read, the -<symbol>XNAreaNeeded</symbol> -argument specifies the preferred geometry desired by the input method -for the area. -</para> -<para> -<!-- .LP --> -This argument is only valid if the input style is -<symbol>XIMPreeditArea</symbol> -or -<symbol>XIMStatusArea</symbol>. -It is used for geometry negotiation between the client and the input method -and has no other effect on the input method -(see <link linkend="Geometry_Management">section 13.5.1.5</link>). -</para> -</sect4> -<sect4 id="Spot_Location"> -<title>Spot Location</title> -<!-- .XS --> -<!-- (SN Spot Location --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNSpotLocation</primary></indexterm> -The -<symbol>XNSpotLocation</symbol> -argument specifies to the input method the coordinates of the spot -to be used by an input method executing with -<symbol>XNInputStyle</symbol> -set to -<symbol>XIMPreeditPosition</symbol>. -When specified to any input method other than -<symbol>XIMPreeditPosition</symbol>, -this <acronym>XIC</acronym> value is ignored. -</para> -<para> -<!-- .LP --> -The x coordinate specifies the position where the next character -would be inserted. -The y coordinate is the position of the baseline used -by the current text line in the focus window. -The x and y coordinates are relative to the focus window, if it has been set; -otherwise, they are relative to the client window. -If neither the focus window nor the client window has been set, -the results are undefined. -</para> -<para> -<!-- .LP --> -The value of the argument is a pointer to a structure of type -<structname>XPoint</structname>. -</para> -</sect4> -<sect4 id="Colormap"> -<title>Colormap</title> -<!-- .XS --> -<!-- (SN Colormap --> -<!-- .XE --> -<para> -<!-- .LP --> -Two different arguments can be used to indicate what colormap the input method -should use to allocate colors, a colormap ID, or a standard colormap name. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNColormap</primary></indexterm> -The -<symbol>XNColormap</symbol> -argument is used to specify a colormap ID. -The argument value is of type -<type>Colormap</type>. -An invalid argument may generate a -<errorname>BadColor</errorname> -error when it is used by the input method. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNStdColormap</primary></indexterm> -The -<symbol>XNStdColormap</symbol> -argument is used to indicate the name of the standard colormap -in which the input method should allocate colors. -The argument value is an -<type>Atom</type> -that should be a valid atom for calling -<function>XGetRGBColormaps</function>. -An invalid argument may generate a -<errorname>BadAtom</errorname> -error when it is used by the input method. -</para> -<para> -<!-- .LP --> -If the colormap is left unspecified, -the client window colormap becomes the default. -</para> -</sect4> -<sect4 id="Foreground_and_Background"> -<title>Foreground and Background</title> -<!-- .XS --> -<!-- (SN Foreground and Background --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNForeground</primary></indexterm> -<indexterm significance="preferred"><primary>XNBackground</primary></indexterm> -The -<symbol>XNForeground</symbol> -and -<symbol>XNBackground</symbol> -arguments specify the foreground and background pixel, respectively. -The argument value is of type -<type>unsigned</type> -<type>long</type>. -It must be a valid pixel in the input method colormap. -</para> -<para> -<!-- .LP --> -If these values are left unspecified, -the default is determined by the input method. -</para> -</sect4> -<sect4 id="Background_Pixmap"> -<title>Background Pixmap</title> -<!-- .XS --> -<!-- (SN Background Pixmap --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNBackgroundPixmap</symbol> -argument specifies a background pixmap to be used as the background of the -window. -The value must be of type -<type>Pixmap</type>. -An invalid argument may generate a -<errorname>BadPixmap</errorname> -error when it is used by the input method. -</para> -<para> -<!-- .LP --> -If this value is left unspecified, -the default is determined by the input method. -</para> -</sect4> -<sect4 id="Font_Set"> -<title>Font Set</title> -<!-- .XS --> -<!-- (SN Font Set --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNFontSet</primary></indexterm> -The -<symbol>XNFontSet</symbol> -argument specifies to the input method what font set is to be used. -The argument value is of type -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -If this value is left unspecified, -the default is determined by the input method. -</para> -</sect4> -<sect4 id="Line_Spacing"> -<title>Line Spacing</title> -<!-- .XS --> -<!-- (SN Line Spacing --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNLineSpace</symbol> -argument specifies to the input method what line spacing is to be used -in the preedit window if more than one line is to be used. -This argument is of type -<type>int</type>. -</para> -<para> -<!-- .LP --> -If this value is left unspecified, -the default is determined by the input method. -</para> -</sect4> -<sect4 id="Cursor"> -<title>Cursor</title> -<!-- .XS --> -<!-- (SN Cursor --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XNCursor</primary></indexterm> -The -<symbol>XNCursor</symbol> -argument specifies to the input method what cursor is to be used -in the specified window. -This argument is of type -<type>Cursor</type>. -</para> -<para> -<!-- .LP --> -An invalid argument may generate a -<errorname>BadCursor</errorname> -error when it is used by the input method. -If this value is left unspecified, -the default is determined by the input method. -</para> -</sect4> -<sect4 id="Preedit_State"> -<title>Preedit State</title> -<!-- .XS --> -<!-- (SN Preedit State --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<symbol>XNPreeditState</symbol> -argument specifies the state of input preediting for the input method. -Input preediting can be on or off. -</para> -<para> -<!-- .LP --> -The valid mask names for -<symbol>XNPreeditState</symbol> -are as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMPreeditUnknown</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditEnable</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreeditDisable</primary></indexterm> -<!-- .sM --> -</para> -<!-- .LP --> -<literallayout class="monospaced"> -typedef unsigned long XIMPreeditState; - -#define XIMPreeditUnknown 0L -#define XIMPreeditEnable 1L -#define XIMPreeditDisable (1L<<1) - -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -If a value of -<symbol>XIMPreeditEnable</symbol> -is set, then input preediting is turned on by the input method. -</para> -<para> -<!-- .LP --> -If a value of -<symbol>XIMPreeditDisable</symbol> -is set, then input preediting is turned off by the input method. -</para> -<para> -<!-- .LP --> -If -<symbol>XNPreeditState</symbol> -is left unspecified, then the state will be implementation-dependent. -</para> -<para> -<!-- .LP --> -When -<symbol>XNResetState</symbol> -is set to -<symbol>XIMInitialState</symbol>, -the -<symbol>XNPreeditState</symbol> -value specified at the creation time will be reflected as the initial state for -<function>XmbResetIC</function> -and -<function>XwcResetIC</function>. -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this argument. -</para> -</sect4> -<sect4 id="Preedit_State_Notify_Callback"> -<title>Preedit State Notify Callback</title> -<!-- .XS --> -<!-- (SN Preedit State Notify Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The preedit state notify callback is triggered by the input method -when the preediting state has changed. -The value of the -<symbol>XNPreeditStateNotifyCallback</symbol> -argument is a pointer to a structure of type -<structname>XIMCallback</structname>. -The generic prototype is as follows: -</para> -<indexterm significance="preferred"><primary>PreeditStateNotifyCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='preeditstatenotifycallback'> -<funcprototype> - <funcdef>void <function><replaceable>PreeditStateNotifyCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XIMPreeditStateNotifyCallbackStruct<parameter> *call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies the current preedit state. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<structname>XIMPreeditStateNotifyCallbackStruct</structname> -structure is defined as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMPreeditStateNotifyCallbackStruct</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct _XIMPreeditStateNotifyCallbackStruct { - XIMPreeditState state; -} XIMPreeditStateNotifyCallbackStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -<para> -<!-- .LP --> -Because this <acronym>XIC</acronym> value is optional, a client should call -<function>XGetIMValues</function> -with argument -<symbol>XNQueryICValuesList</symbol> -before using this argument. -</para> -</sect4> -<sect4 id="Preedit_and_Status_Callbacks"> -<title>Preedit and Status Callbacks</title> -<!-- .XS --> -<!-- (SN Preedit and Status Callbacks --> -<!-- .XE --> -<para> -<!-- .LP --> -A client that wants to support the input style -<symbol>XIMPreeditCallbacks</symbol> -must provide a set of preedit callbacks to the input method. -The set of preedit callbacks is as follows: -</para> -<indexterm significance="preferred"><primary>XNPreeditStartCallback</primary></indexterm> -<indexterm significance="preferred"><primary>XNPreeditDoneCallback</primary></indexterm> -<indexterm significance="preferred"><primary>XNPreeditDrawCallback</primary></indexterm> -<indexterm significance="preferred"><primary>XNPreeditCaretCallback</primary></indexterm> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>XNPreeditStartCallback</symbol></entry> - <entry>This is called when the input method starts preedit.</entry> - </row> - <row> - <entry><symbol>XNPreeditDoneCallback</symbol></entry> - <entry>This is called when the input method stops preedit.</entry> - </row> - <row> - <entry><symbol>XNPreeditDrawCallback</symbol></entry> - <entry>This is called when a number of preedit keystrokes should be echoed.</entry> - </row> - <row> - <entry><symbol>XNPreeditCaretCallback</symbol></entry> - <entry>This is called to move the text insertion point within the preedit string.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -A client that wants to support the input style -<symbol>XIMStatusCallbacks</symbol> -must provide a set of status callbacks to the input method. -The set of status callbacks is as follows: -</para> - -<indexterm significance="preferred"><primary>XNStatusStartCallback</primary></indexterm> -<indexterm significance="preferred"><primary>XNStatusDoneCallback</primary></indexterm> -<indexterm significance="preferred"><primary>XNStatusDrawCallback</primary></indexterm> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>XNStatusStartCallback</symbol></entry> - <entry>This is called when the input method initializes the status area.</entry> - </row> - <row> - <entry><symbol>XNStatusDoneCallback</symbol></entry> - <entry>This is called when the input method no longer needs the status area.</entry> - </row> - <row> - <entry><symbol>XNStatusDrawCallback</symbol></entry> - <entry>This is called when updating of the status area is required.</entry> - </row> - </tbody> - </tgroup> -</informaltable> -<para> -<!-- .LP --> -The value of any status or preedit argument is a pointer -to a structure of type -<structname>XIMCallback</structname>. -<indexterm significance="preferred"><primary>XIMProc</primary></indexterm> -<indexterm significance="preferred"><primary>XIMCallback</primary></indexterm> -<!-- .sM --> -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef void (*XIMProc)(); - -typedef struct { - XPointer client_data; - XIMProc callback; -} XIMCallback; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Each callback has some particular semantics and will carry the data -that expresses the environment necessary to the client -into a specific data structure. -This paragraph only describes the arguments to be used to set -the callback. -</para> -<para> -<!-- .LP --> -Setting any of these values while doing preedit -may cause unexpected results. -</para> -</sect4> -</sect3> -</sect2> -<sect2 id="Input_Method_Callback_Semantics"> -<title>Input Method Callback Semantics</title> -<!-- .XS --> -<!-- (SN Input Method Callback Semantics --> -<!-- .XE --> -<para> -<!-- .LP --> -<acronym>XIM</acronym> callbacks are procedures defined by clients or text drawing packages -that are to be called from the input method when selected events occur. -Most clients will use a text editing package or a toolkit -and, hence, will not need to define such callbacks. -This section defines the callback semantics, when they are triggered, -and what their arguments are. -This information is mostly useful for X toolkit implementors. -</para> -<para> -<!-- .LP --> -Callbacks are mostly provided so that clients (or text editing -packages) can implement on-the-spot preediting in their own window. -In that case, -the input method needs to communicate and synchronize with the client. -The input method needs to communicate changes in the preedit window -when it is under control of the client. -Those callbacks allow the client to initialize the preedit area, -display a new preedit string, -move the text insertion point during preedit, -terminate preedit, or update the status area. -</para> -<para> -<!-- .LP --> -All callback procedures follow the generic prototype: -</para> -<indexterm significance="preferred"><primary>CallbackPrototype</primary></indexterm> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef>void <function><replaceable>CallbackPrototype</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>SomeType<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies data specific to the callback. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The call_data argument is a structure that expresses the arguments needed -to achieve the semantics; -that is, -it is a specific data structure appropriate to the callback. -In cases where no data is needed in the callback, -this call_data argument is NULL. -The client_data argument is a closure that has been initially specified -by the client when specifying the callback and passed back. -It may serve, for example, to inherit application context in the callback. -</para> -<para> -<!-- .LP --> -The following paragraphs describe the programming semantics -and specific data structure associated with the different reasons. -</para> -<sect3 id="Geometry_Callback_b"> -<title>Geometry Callback</title> -<!-- .XS --> -<!-- (SN Geometry Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The geometry callback is triggered by the input method -to indicate that it wants the client to negotiate geometry. -The generic prototype is as follows: -</para> -<indexterm significance="preferred"><primary>GeometryCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis> -<funcprototype> - <funcdef>void <function><replaceable>GeometryCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback is called with a NULL call_data argument. -</para> -</sect3> -<sect3 id="Destroy_Callback_c"> -<title>Destroy Callback</title> -<!-- .XS --> -<!-- (SN Destroy Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The destroy callback is triggered by the input method -when it stops service for any reason. -After the callback is invoked, the input context will be freed by Xlib. -The generic prototype is as follows: -</para> -<indexterm significance="preferred"><primary>DestroyCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='destroycallback_xic'> -<funcprototype> - <funcdef>void <function><replaceable>DestroyCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback is called with a NULL call_data argument. -</para> -</sect3> -<sect3 id="String_Conversion_Callback_b"> -<title>String Conversion Callback</title> -<!-- .XS --> -<!-- (SN String Conversion Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -The string conversion callback is triggered by the input method -to request the client to return the string to be converted. The -returned string may be either a multibyte or wide character string, -with an encoding matching the locale bound to the input context. -The callback prototype is as follows: -</para> -<indexterm significance="preferred"><primary>StringConversionCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='stringconversioncallback'> -<funcprototype> - <funcdef>void <function><replaceable>StringConversionCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XIMStringConversionCallbackStruct<parameter> *call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input method. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies the amount of the string to be converted. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback is passed an -<structname>XIMStringConversionCallbackStruct</structname> -structure in the call_data argument. -The text member is an -<structname>XIMStringConversionText</structname> -structure (see <link linkend="String_Conversion_">section 13.5.6.9</link>) -to be filled in by the client -and describes the text to be sent to the input method. -The data pointed to by the -string and feedback elements of the -<structname>XIMStringConversionText</structname> -structure will be freed using -<function>XFree</function> -by the input method -after the callback returns. So the client should not point to -internal buffers that are critical to the client. -Similarly, because the feedback element is currently reserved for future -use, the client should set feedback to NULL to prevent the library from -freeing memory at some random location due to an uninitialized pointer. -</para> -<para> -<!-- .LP --> -The -<structname>XIMStringConversionCallbackStruct</structname> -structure is defined as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMStringConversionCallbackStruct</primary></indexterm> -<!-- .sM --> -</para> -<!-- .LP --> -<literallayout class="monospaced"> -typedef struct _XIMStringConversionCallbackStruct { - XIMStringConversionPosition position; - XIMCaretDirection direction; - short factor; - XIMStringConversionOperation operation; - XIMStringConversionText *text; -} XIMStringConversionCallbackStruct; - -typedef short XIMStringConversionPosition; - -typedef unsigned short XIMStringConversionOperation; - -#define XIMStringConversionSubstitution (0x0001) -#define XIMStringConversionRetrieval (0x0001) - -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -<type>XIMStringConversionPosition</type> -specifies the starting position of the string to be returned -in the -<structname>XIMStringConversionText</structname> -structure. The value identifies a position, in units of characters, -relative to the client's cursor position in the client's buffer. -</para> -<para> -<!-- .LP --> -The ending position of the text buffer is determined by -the direction and factor members. Specifically, it is the character position -relative to the starting point as defined by the -<structname>XIMCaretDirection</structname>. -The factor member of -<structname>XIMStringConversionCallbackStruct</structname> -specifies the number of -<structname>XIMCaretDirection</structname> -positions to be applied. For example, if the direction specifies -<constant>XIMLineEnd</constant> -and factor is 1, then all characters from the starting position to -the end of the current display line are returned. If the direction -specifies -<constant>XIMForwardChar</constant> -or -<constant>XIMBackwardChar</constant>, -then the factor specifies a relative position, indicated in characters, -from the starting position. -</para> -<para> -<!-- .LP --> -<type>XIMStringConversionOperation</type> -specifies whether the string to be converted should be -deleted (substitution) or copied (retrieval) from the client's -buffer. When the -<type>XIMStringConversionOperation</type> -is -<symbol>XIMStringConversionSubstitution</symbol>, -the client must delete the string to be converted from its own buffer. -When the -<type>XIMStringConversionOperation</type> -is -<symbol>XIMStringConversionRetrieval</symbol>, -the client must not delete the string to be converted from its buffer. -The substitute operation is typically used for reconversion and -transliteration conversion, -while the retrieval operation is typically used for context-sensitive -conversion. -</para> -</sect3> -<sect3 id="Preedit_State_Callbacks"> -<title>Preedit State Callbacks</title> -<!-- .XS --> -<!-- (SN Preedit State Callbacks --> -<!-- .XE --> -<para> -<!-- .LP --> -When the input method turns preediting on or off, a -<function><replaceable>PreeditStartCallback</replaceable></function> -or -<function><replaceable>PreeditDoneCallback</replaceable></function> -callback is triggered to let the toolkit do the setup -or the cleanup for the preedit region. -</para> -<indexterm significance="preferred"><primary>PreeditStartCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='preeditstartcallback'> -<funcprototype> - <funcdef>int <function><replaceable>PreeditStartCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -When preedit starts on the specified input context, -the callback is called with a NULL call_data argument. -<function><replaceable>PreeditStartCallback</replaceable></function> -will return the maximum size of the preedit string. -A positive number indicates the maximum number of bytes allowed -in the preedit string, -and a value of -1 indicates there is no limit. -</para> -<indexterm significance="preferred"><primary>PreeditDoneCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='preeditdonecallback'> -<funcprototype> - <funcdef>void <function><replaceable>PreeditDoneCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -When preedit stops on the specified input context, -the callback is called with a NULL call_data argument. -The client can release the data allocated by -<function><replaceable>PreeditStartCallback</replaceable></function>. -</para> -<para> -<!-- .LP --> -<function><replaceable>PreeditStartCallback</replaceable></function> -should initialize appropriate data needed for -displaying preedit information and for handling further -<function><replaceable>PreeditDrawCallback</replaceable></function> -calls. -Once -<function><replaceable>PreeditStartCallback</replaceable></function> -is called, it will not be called again before -<function><replaceable>PreeditDoneCallback</replaceable></function> -has been called. -</para> -</sect3> -<sect3 id="Preedit_Draw_Callback"> -<title>Preedit Draw Callback</title> -<!-- .XS --> -<!-- (SN Preedit Draw Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -This callback is triggered to draw and insert, delete or replace, -preedit text in the preedit region. -The preedit text may include unconverted input text such as Japanese Kana, -converted text such as Japanese Kanji characters, or characters of both kinds. -That string is either a multibyte or wide character string, -whose encoding matches the locale bound to the input context. -The callback prototype -is as follows: -</para> -<indexterm significance="preferred"><primary>PreeditDrawCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='preeditdrawcallback'> -<funcprototype> - <funcdef>void <function><replaceable>PreeditDrawCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XIMPreeditDrawCallbackStruct<parameter> *call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies the preedit drawing information. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback is passed an -<structname>XIMPreeditDrawCallbackStruct</structname> -structure in the call_data argument. -The text member of this structure contains the text to be drawn. -After the string has been drawn, -the caret should be moved to the specified location. -</para> -<para> -<!-- .LP --> -The -<structname>XIMPreeditDrawCallbackStruct</structname> -structure is defined as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMPreeditDrawCallbackStruct</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct _XIMPreeditDrawCallbackStruct { - int caret; /* Cursor offset within preedit string */ - int chg_first; /* Starting change position */ - int chg_length; /* Length of the change in character count */ - XIMText *text; -} XIMPreeditDrawCallbackStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The client must keep updating a buffer of the preedit text -and the callback arguments referring to indexes in that buffer. -The call_data fields have specific meanings according to the operation, -as follows: -</para> -<itemizedlist> - <listitem> - <para> -To indicate text deletion, -the call_data member specifies a NULL text field. -The text to be deleted is then the current text in the buffer -from position chg_first (starting at zero) on a character length -of chg_length. - </para> - </listitem> - <listitem> - <para> -When text is non-NULL, -it indicates insertion or replacement of text in the buffer. - </para> - </listitem> - <listitem> - <para> -The chg_length member -identifies the number of characters in the current preedit buffer -that are affected by this call. -A positive chg_length indicates that chg_length number of characters, starting -at chg_first, must be deleted or must be replaced by text, whose length is -specified in the -<structname>XIMText</structname> -structure. - </para> - </listitem> - <listitem> - <para> -A chg_length value of zero indicates that text must be inserted -right at the position specified by chg_first. -A value of zero for chg_first specifies the first character in the buffer. - </para> - </listitem> - <listitem> - <para> -chg_length and chg_first combine to identify the modification required to -the preedit buffer; beginning at chg_first, replace chg_length number of -characters with the text in the supplied -<structname>XIMText</structname> -structure. For example, suppose the preedit buffer contains the string "ABCDE". - </para> - </listitem> - <listitem> - <para> -<literallayout class="monospaced"> -<!-- .ft C --> -Text: A B C D E - ^ ^ ^ ^ ^ ^ -CharPos: 0 1 2 3 4 5 -<!-- .sp --> -<!-- .ft P --> -</literallayout> -The CharPos in the diagram shows the location of the character position -relative to the character. - </para> - </listitem> - <listitem> - <para> -If the value of chg_first is 1 and the value of chg_length is 3, this -says to replace 3 characters beginning at character position 1 with the -string in the -<structname>XIMText</structname> -structure. -Hence, <acronym>BCD</acronym> would be replaced by the value in the structure. - </para> - </listitem> - <listitem> - <para> -Though chg_length and chg_first are both signed integers they will -never have a negative value. - </para> - </listitem> - <listitem> - <para> -The caret member -identifies the character position before which the cursor should -be placed - after modification to the preedit buffer has been completed. -For example, if caret is zero, the cursor is at -the beginning of the buffer. If the caret is one, the cursor is between -the first and second character. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMText</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 1.5i 3i --> -typedef struct _XIMText { - unsigned short length; - XIMFeedback * feedback; - Bool encoding_is_wchar; - union { - char * multi_byte; - wchar_t * wide_char; - } string; -} XIMText; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The text string passed is actually a structure specifying as follows: -</para> -<itemizedlist> - <listitem> - <para> -The length member is the text length in characters. - </para> - </listitem> - <listitem> - <para> -The encoding_is_wchar member is a value that indicates -if the text string is encoded in wide character or multibyte format. -The text string may be passed either as multibyte or as wide character; -the input method controls in which form data is passed. -The client's -callback routine must be able to handle data passed in either form. - </para> - </listitem> - <listitem> - <para> -The string member is the text string. - </para> - </listitem> - <listitem> - <para> -The feedback member indicates rendering type for each character in the -string member. -If string is NULL (indicating that only highlighting of the existing -preedit buffer should be updated), feedback points to length highlight -elements that should be applied to the existing preedit buffer, beginning -at chg_first. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -The feedback member expresses the types of rendering feedback -the callback should apply when drawing text. -Rendering of the text to be drawn is specified either in generic ways -(for example, primary, secondary) or in specific ways (reverse, underline). -When generic indications are given, -the client is free to choose the rendering style. -It is necessary, however, that primary and secondary be mapped -to two distinct rendering styles. -</para> -<para> -<!-- .LP --> -If an input method wants to control display of the preedit string, an -input method can indicate the visibility hints using feedbacks in -a specific way. -The -<symbol>XIMVisibleToForward</symbol>, -<symbol>XIMVisibleToBackword</symbol>, -and -<symbol>XIMVisibleToCenter</symbol> -masks are exclusively used for these visibility hints. -The -<symbol>XIMVisibleToForward</symbol> -mask -indicates that the preedit text is preferably displayed in the -primary draw direction from the -caret position in the preedit area forward. -The -<symbol>XIMVisibleToBackword</symbol> -mask -indicates that the preedit text is preferably displayed from -the caret position in the preedit area backward, relative to the primary -draw direction. -The -<symbol>XIMVisibleToCenter</symbol> -mask -indicates that the preedit text is preferably displayed with -the caret position in the preedit area centered. -</para> -<para> -<!-- .LP --> -The insertion point of the preedit string could exist outside of -the visible area when visibility hints are used. -Only one of the -masks -is valid for the entire preedit string, and only one character -can hold one of these feedbacks for a given input context at one time. -This feedback may be OR'ed together with another highlight (such as -<symbol>XIMReverse</symbol>). -Only the most recently set feedback is valid, and any previous -feedback is automatically canceled. This is a hint to the client, and -the client is free to choose how to display the preedit string. -</para> -<para> -<!-- .LP --> -The feedback member also specifies how rendering of the text argument -should be performed. -If the feedback is NULL, -the callback should apply the same feedback as is used for the surrounding -characters in the preedit buffer; if chg_first is at a highlight boundary, -the client can choose which of the two highlights to use. -If feedback is not NULL, feedback specifies an array defining the -rendering for each -character of the string, and the length of the array is thus length. -</para> -<para> -<!-- .LP --> -If an input method wants to indicate that it is only updating the feedback of -the preedit text without changing the content of it, -the -<structname>XIMText</structname> -structure will contain a NULL value for the string field, -the number of characters affected (relative to chg_first) -will be in the length field, -and the feedback field will point to an array of -<type>XIMFeedback</type>. -</para> -<para> -<!-- .LP --> -Each element in the feedback array is a bitmask represented by a value of type -<type>XIMFeedback</type>. -The valid mask names are as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMReverse</primary></indexterm> -<indexterm significance="preferred"><primary>XIMUnderline</primary></indexterm> -<indexterm significance="preferred"><primary>XIMHighlight</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPrimary</primary></indexterm> -<indexterm significance="preferred"><primary>XIMSecondary</primary></indexterm> -<indexterm significance="preferred"><primary>XIMTertiary</primary></indexterm> -<indexterm significance="preferred"><primary>XIMVisibleToForward</primary></indexterm> -<indexterm significance="preferred"><primary>XIMVisibleToBackward</primary></indexterm> -<indexterm significance="preferred"><primary>XIMVisibleToCenter</primary></indexterm> -<!-- .sM --> -</para> -<literallayout class="monospaced"> -typedef unsigned long XIMFeedback; - -#define XIMReverse 1L -#define XIMUnderline (1L<<1) -#define XIMHighlight (1L<<2) -#define XIMPrimary (1L<<5)* -#define XIMSecondary (1L<<6)* -#define XIMTertiary (1L<<7)* -#define XIMVisibleToForward (1L<<8) -#define XIMVisibleToBackward (1L<<9) -#define XIMVisibleToCenter (1L<<10) - -*†The values for XIMPrimary, XIMSecondary, and XIMTertiary were incorrectly defined in -the R5 specification. The X Consortium’s X11R5 implementation correctly -implemented the values for these highlights. The value of these highlights has -been corrected in this specification to agree with the values in the -Consortium’s X11R5 and X11R6 implementations. - -</literallayout> - -<para> -<!-- .LP --> -Characters drawn with the -<symbol>XIMReverse</symbol> -highlight should be drawn by swapping the foreground and background colors -used to draw normal, unhighlighted characters. -Characters drawn with the -<symbol>XIMUnderline</symbol> -highlight should be underlined. -Characters drawn with the -<symbol>XIMHighlight</symbol>, -<symbol>XIMPrimary</symbol>, -<symbol>XIMSecondary</symbol>, -and -<symbol>XIMTertiary</symbol> -highlights should be drawn in some unique manner that must be different -from -<symbol>XIMReverse</symbol> -and -<symbol>XIMUnderline</symbol>. -<!-- .FS \(dg --> -The values for -<symbol>XIMPrimary</symbol>, -<symbol>XIMSecondary</symbol>, -and -<symbol>XIMTertiary</symbol> -were incorrectly defined in the R5 specification. -The X Consortium's X11R5 -implementation correctly implemented the values for these highlights. -The value of these highlights has been corrected in this specification -to agree with the values in the Consortium's X11R5 and X11R6 implementations. -<!-- .FE --> -</para> -</sect3> -<sect3 id="Preedit_Caret_Callback"> -<title>Preedit Caret Callback</title> -<!-- .XS --> -<!-- (SN Preedit Caret Callback --> -<!-- .XE --> -<para> -<!-- .LP --> -An input method may have its own navigation keys to allow the user -to move the text insertion point in the preedit area -(for example, to move backward or forward). -Consequently, input method needs to indicate to the client that it -should move the text insertion point. -It then calls the PreeditCaretCallback. -</para> -<indexterm significance="preferred"><primary>PreeditCaretCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='preeditcaretcallback'> -<funcprototype> - <funcdef>void <function><replaceable>PreeditCaretCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XIMPreeditCaretCallbackStruct<parameter> *call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies the preedit caret information. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The input method will trigger PreeditCaretCallback -to move the text insertion point during preedit. -The call_data argument contains a pointer to an -<structname>XIMPreeditCaretCallbackStruct</structname> -structure, -which indicates where the caret should be moved. -The callback must move the insertion point to its new location -and return, in field position, the new offset value from the initial position. -</para> -<para> -<!-- .LP --> -The -<structname>XIMPreeditCaretCallbackStruct</structname> -structure is defined as follows: -<indexterm significance="preferred"><primary>XIMPreeditCaretCallbackStruct</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct _XIMPreeditCaretCallbackStruct { - int position; /* Caret offset within preedit string */ - XIMCaretDirection direction; /* Caret moves direction */ - XIMCaretStyle style; /* Feedback of the caret */ -} XIMPreeditCaretCallbackStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<structname>XIMCaretStyle</structname> -structure is defined as follows: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XIMCaretStyle</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef enum { - XIMIsInvisible, /* Disable caret feedback */ - XIMIsPrimary, /* <acronym>UI</acronym> defined caret feedback */ - XIMIsSecondary, /* <acronym>UI</acronym> defined caret feedback */ -} XIMCaretStyle; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<structname>XIMCaretDirection</structname> -structure is defined as follows: -<indexterm significance="preferred"><primary>XIMCaretDirection</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef enum { - XIMForwardChar, XIMBackwardChar, - XIMForwardWord, XIMBackwardWord, - XIMCaretUp, XIMCaretDown, - XIMNextLine, XIMPreviousLine, - XIMLineStart, XIMLineEnd, - XIMAbsolutePosition, - XIMDontChange, - } XIMCaretDirection; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -These values are defined as follows: -</para> -<indexterm significance="preferred"><primary>XIMForwardChar</primary></indexterm> -<indexterm significance="preferred"><primary>XIMBackwardChar</primary></indexterm> -<indexterm significance="preferred"><primary>XIMForwardWord</primary></indexterm> -<indexterm significance="preferred"><primary>XIMBackwardWord</primary></indexterm> -<indexterm significance="preferred"><primary>XIMCaretUp</primary></indexterm> -<indexterm significance="preferred"><primary>XIMCaretDown</primary></indexterm> -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><constant>XIMForwardChar</constant></entry> - <entry>Move the caret forward one character position.</entry> - </row> - <row> - <entry><constant>XIMBackwardChar</constant></entry> - <entry>Move the caret backward one character position.</entry> - </row> - <row> - <entry><constant>XIMForwardWord</constant></entry> - <entry>Move the caret forward one word.</entry> - </row> - <row> - <entry><constant>XIMBackwardWord</constant></entry> - <entry>Move the caret backward one word.</entry> - </row> - <row> - <entry><constant>XIMCaretUp</constant></entry> - <entry>Move the caret up one line keeping the current horizontal offset.</entry> - </row> - <row> - <entry><constant>XIMCaretDown</constant></entry> - <entry>Move the caret down one line keeping the current horizontal offset.</entry> - </row> - <row> - <entry><constant>XIMPreviousLine</constant></entry> - <entry>Move the caret to the beginning of the previous line.</entry> - </row> - <row> - <entry><constant>XIMNextLine</constant></entry> - <entry>Move the caret to the beginning of the next line.</entry> - </row> - <row> - <entry><constant>XIMLineStart</constant></entry> - <entry>Move the caret to the beginning of the current display line that contains the caret.</entry> - </row> - <row> - <entry><constant>XIMLineEnd</constant></entry> - <entry>Move the caret to the end of the current display line that contains the caret.</entry> - </row> - <row> - <entry><constant>XIMAbsolutePosition</constant></entry> - <entry>The callback must move to the location specified by the position field - of the callback data, indicated in characters, starting from the beginning - of the preedit text. - Hence, a value of zero means move back to the beginning of the preedit text.</entry> - </row> - <row> - <entry><constant>XIMDontChange</constant></entry> - <entry>The caret position does not change.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<indexterm significance="preferred"><primary>XIMNextLine</primary></indexterm> -<indexterm significance="preferred"><primary>XIMPreviousLine</primary></indexterm> -<indexterm significance="preferred"><primary>XIMLineStart</primary></indexterm> -<indexterm significance="preferred"><primary>XIMLineEnd</primary></indexterm> -<indexterm significance="preferred"><primary>XIMAbsolutePosition</primary></indexterm> -<indexterm significance="preferred"><primary>XIMDontChange</primary></indexterm> -</sect3> -<sect3 id="Status_Callbacks"> -<title>Status Callbacks</title> -<!-- .XS --> -<!-- (SN Status Callbacks --> -<!-- .XE --> -<para> -<!-- .LP --> -An input method may communicate changes in the status of an input context -(for example, created, destroyed, or focus changes) with three status -callbacks: StatusStartCallback, StatusDoneCallback, and StatusDrawCallback. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -When the input context is created or gains focus, -the input method calls the StatusStartCallback callback. -</para> -<indexterm significance="preferred"><primary>StatusStartCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='statusstartcallback'> -<funcprototype> - <funcdef>void <function><replaceable>StatusStartCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback should initialize appropriate data for displaying status -and for responding to StatusDrawCallback calls. -Once StatusStartCallback is called, -it will not be called again before StatusDoneCallback has been called. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -When an input context -is destroyed or when it loses focus, the input method calls StatusDoneCallback. -</para> -<indexterm significance="preferred"><primary>StatusDoneCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='statusdonecallback'> -<funcprototype> - <funcdef>void <function><replaceable>StatusDoneCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XPointer<parameter> call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Not used for this callback and always passed as NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback may release any data allocated on -<function>StatusStart</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -When an input context status has to be updated, the input method calls -StatusDrawCallback. -</para> -<indexterm significance="preferred"><primary>StatusDrawCallback</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='statusdrawcallback'> -<funcprototype> - <funcdef>void <function><replaceable>StatusDrawCallback</replaceable></function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XPointer<parameter> client_data</parameter></paramdef> - <paramdef>XIMStatusDrawCallbackStruct<parameter> *call_data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>client_data</emphasis> - </term> - <listitem> - <para> -Specifies the additional client data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>call_data</emphasis> - </term> - <listitem> - <para> -Specifies the status drawing information. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The callback should update the status area by either drawing a string -or imaging a bitmap in the status area. -</para> -<para> -<!-- .LP --> -The -<structname>XIMStatusDataType</structname> -and -<structname>XIMStatusDrawCallbackStruct</structname> -structures are defined as follows: -<indexterm significance="preferred"><primary>XIMStatusDataType</primary></indexterm> -<indexterm significance="preferred"><primary>XIMStatusDrawCallbackStruct</primary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 1i 3i --> -<!-- .ta .5i 1i 3i --> -typedef enum { - XIMTextType, - XIMBitmapType, -} XIMStatusDataType; - -typedef struct _XIMStatusDrawCallbackStruct { - XIMStatusDataType type; - union { - XIMText *text; - Pixmap bitmap; - } data; -} XIMStatusDrawCallbackStruct; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -<para> -<!-- .LP --> -The feedback styles -<symbol>XIMVisibleToForward</symbol>, -<symbol>XIMVisibleToBackword</symbol>, -and -<symbol>XIMVisibleToCenter</symbol> -are not relevant and will not appear in the -<type>XIMFeedback</type> -element of the -<structname>XIMText</structname> -structure. -</para> -<para> -<!-- .LP --> -</para> -</sect3> -</sect2> -<sect2 id="Event_Filtering_b"> -<title>Event Filtering</title> -<!-- .XS --> -<!-- (SN Event Filtering --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides the ability for an input method -to register a filter internal to Xlib. -This filter is called by a client (or toolkit) by calling -<function>XFilterEvent</function> -after calling -<function>XNextEvent</function>. -Any client that uses the -<type>XIM</type> -interface should call -<function>XFilterEvent</function> -to allow input methods to process their events without knowledge -of the client's dispatching mechanism. -A client's user interface policy may determine the priority -of event filters with respect to other event-handling mechanisms -(for example, modal grabs). -</para> -<para> -<!-- .LP --> -Clients may not know how many filters there are, if any, -and what they do. -They may only know if an event has been filtered on return of -<function>XFilterEvent</function>. -Clients should discard filtered events. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To filter an event, use -<function>XFilterEvent</function>. -</para> -<indexterm significance="preferred"><primary>XFilterEvent</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfilterevent'> -<funcprototype> - <funcdef>Bool <function>XFilterEvent</function></funcdef> - <paramdef>XEvent<parameter> *event</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Ev event to filter --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>event</emphasis> - </term> - <listitem> - <para> -Specifies the (Ev. -<!-- .ds Wi for which the filter is to be applied --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window (Wi. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the window argument is -<symbol>None</symbol>, -<function>XFilterEvent</function> -applies the filter to the window specified in the -<structname>XEvent</structname> -structure. -The window argument is provided so that layers above Xlib -that do event redirection can indicate to which window an event -has been redirected. -</para> -<para> -<!-- .LP --> -If -<function>XFilterEvent</function> -returns -<symbol>True</symbol>, -then some input method has filtered the event, -and the client should discard the event. -If -<function>XFilterEvent</function> -returns -<symbol>False</symbol>, -then the client should continue processing the event. -</para> -<para> -<!-- .LP --> -If a grab has occurred in the client and -<function>XFilterEvent</function> -returns -<symbol>True</symbol>, -the client should ungrab the keyboard. -</para> -</sect2> -<sect2 id="Getting_Keyboard_Input_b"> -<title>Getting Keyboard Input</title> -<!-- .XS --> -<!-- (SN Getting Keyboard Input --> -<!-- .XE --> -<para> -<!-- .LP --> -To get composed input from an input method, -use -<function>XmbLookupString</function> -or -<function>XwcLookupString</function>. -</para> -<indexterm significance="preferred"><primary>XmbLookupString</primary></indexterm> -<indexterm significance="preferred"><primary>XwcLookupString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmblookupstring'> -<funcprototype> - <funcdef>int <function>XmbLookupString</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XKeyPressedEvent<parameter> *event</parameter></paramdef> - <paramdef>char<parameter> *buffer_return</parameter></paramdef> - <paramdef>int<parameter> bytes_buffer</parameter></paramdef> - <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef> - <paramdef>Status<parameter> *status_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwclookupstring'> -<funcprototype> - <funcdef>int <function>XwcLookupString</function></funcdef> - <paramdef>XIC<parameter> ic</parameter></paramdef> - <paramdef>XKeyPressedEvent<parameter> *event</parameter></paramdef> - <paramdef>wchar_t<parameter> *buffer_return</parameter></paramdef> - <paramdef>int<parameter> wchars_buffer</parameter></paramdef> - <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef> - <paramdef>Status<parameter> *status_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ic</emphasis> - </term> - <listitem> - <para> -Specifies the input context. -<!-- .ds Ev key event to be used --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>event</emphasis> - </term> - <listitem> - <para> -Specifies the (Ev. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer_return</emphasis> - </term> - <listitem> - <para> -Returns a multibyte string or wide character string (if any) -from the input method. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes_buffer</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>wchars_buffer</emphasis> - </term> - <listitem> - <para> -Specifies space available in the return buffer. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysym_return</emphasis> - </term> - <listitem> - <para> -Returns the KeySym computed from the event if this argument is not NULL. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>status_return</emphasis> - </term> - <listitem> - <para> -Returns a value indicating what kind of data is returned. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbLookupString</function> -and -<function>XwcLookupString</function> -functions return the string from the input method specified -in the buffer_return argument. -If no string is returned, -the buffer_return argument is unchanged. -</para> -<para> -<!-- .LP --> -The KeySym into which the KeyCode from the event was mapped is returned -in the keysym_return argument if it is non-NULL and the status_return -argument indicates that a KeySym was returned. -If both a string and a KeySym are returned, -the KeySym value does not necessarily correspond to the string returned. -</para> -<para> -<!-- .LP --> -<function>XmbLookupString</function> -returns the length of the string in bytes, and -<function>XwcLookupString</function> -returns the length of the string in characters. -Both -<function>XmbLookupString</function> -and -<function>XwcLookupString</function> -return text in the encoding of the locale bound to the input method -of the specified input context. -</para> -<para> -<!-- .LP --> -Each string returned by -<function>XmbLookupString</function> -and -<function>XwcLookupString</function> -begins in the initial state of the encoding of the locale -(if the encoding of the locale is state-dependent). -<!-- .NT --> -<note><para> -To insure proper input processing, -it is essential that the client pass only -<symbol>KeyPress</symbol> -events to -<function>XmbLookupString</function> -and -<function>XwcLookupString</function>. -Their behavior when a client passes a -<symbol>KeyRelease</symbol> -event is undefined. -</para></note> -<!-- .NE --> -</para> -<para> -<!-- .LP --> -Clients should check the status_return argument before -using the other returned values. -These two functions both return a value to status_return -that indicates what has been returned in the other arguments. -The possible values returned are: -</para> - -<informaltable> - <tgroup cols='2'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <tbody> - <row> - <entry><symbol>XBufferOverflow</symbol></entry> - <entry>The input string to be returned is too large for the supplied buffer_return. - The required size - (<function>XmbLookupString</function> - in bytes; - <function>XwcLookupString</function> - in characters) is returned as the value of the function, - and the contents of buffer_return and keysym_return are not modified. - The client should recall the function with the same event - and a buffer of adequate size to obtain the string.</entry> - </row> - <row> - <entry><symbol>XLookupNone</symbol></entry> - <entry>No consistent input has been composed so far. - The contents of buffer_return and keysym_return are not modified, - and the function returns zero.</entry> - </row> - <row> - <entry><symbol>XLookupChars</symbol></entry> - <entry>Some input characters have been composed. - They are placed in the buffer_return argument, - and the string length is returned as the value of the function. - The string is encoded in the locale bound to the input context. - The content of the keysym_return argument is not modified.</entry> - </row> - <row> - <entry><symbol>XLookupKeySym</symbol></entry> - <entry>A KeySym has been returned instead of a string - and is returned in keysym_return. - The content of the buffer_return argument is not modified, - and the function returns zero.</entry> - </row> - <row> - <entry><symbol>XLookupBoth</symbol></entry> - <entry>Both a KeySym and a string are returned; - <symbol>XLookupChars</symbol> - and - <symbol>XLookupKeySym</symbol> - occur simultaneously.</entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -<!-- .LP --> -It does not make any difference if the input context passed as an argument to -<function>XmbLookupString</function> -and -<function>XwcLookupString</function> -is the one currently in possession of the focus or not. -Input may have been composed within an input context before it lost the focus, -and that input may be returned on subsequent calls to -<function>XmbLookupString</function> -or -<function>XwcLookupString</function> -even though it does not have any more keyboard focus. -</para> -</sect2> -<sect2 id="Input_Method_Conventions"> -<title>Input Method Conventions</title> -<!-- .XS --> -<!-- (SN Input Method Conventions --> -<!-- .XE --> -<para> -<!-- .LP --> -The input method architecture is transparent to the client. -However, clients should respect a number of conventions in order -to work properly. -Clients must also be aware of possible effects of synchronization -between input method and library in the case of a remote input server. -</para> -<sect3 id="Client_Conventions"> -<title>Client Conventions</title> -<!-- .XS --> -<!-- (SN Client Conventions --> -<!-- .XE --> -<para> -<!-- .LP --> -A well-behaved client (or toolkit) should first query the input method style. -If the client cannot satisfy the requirements of the supported styles -(in terms of geometry management or callbacks), -it should negotiate with the user continuation of the program -or raise an exception or error of some sort. -</para> -</sect3> -<sect3 id="Synchronization_Conventions"> -<title>Synchronization Conventions</title> -<!-- .XS --> -<!-- (SN Synchronization Conventions --> -<!-- .XE --> -<para> -<!-- .LP --> -A -<symbol>KeyPress</symbol> -event with a KeyCode of zero is used exclusively as a -signal that an input method has composed input that can be returned by -<function>XmbLookupString</function> -or -<function>XwcLookupString</function>. -No other use is made of a -<symbol>KeyPress</symbol> -event with KeyCode of zero. -</para> -<para> -<!-- .LP --> -Such an event may be generated by either a front-end -or a back-end input method in an implementation-dependent manner. -Some possible ways to generate this event include: -</para> -<itemizedlist> - <listitem> - <para> -A synthetic event sent by an input method server - </para> - </listitem> - <listitem> - <para> -An artificial event created by a input method filter and pushed -onto a client's event queue - </para> - </listitem> - <listitem> - <para> -A -<symbol>KeyPress</symbol> -event whose KeyCode value is modified by an input method filter - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -When callback support is specified by the client, -input methods will not take action unless they explicitly -called back the client and obtained no response -(the callback is not specified or returned invalid data). -</para> -</sect3> -</sect2> -</sect1> -<sect1 id="String_Constants"> -<title>String Constants</title> -<!-- .XS --> -<!-- (SN String Constants --> -<!-- .XE --> -<para> -<!-- .LP --> -The following symbols for string constants are defined in -<filename class="headerfile"><X11/Xlib.h></filename>. -Although they are shown here with particular macro definitions, -they may be implemented as macros, as global symbols, or as a -mixture of the two. The string pointer value itself -is not significant; clients must not assume that inequality of two -values implies inequality of the actual string data. -</para> - -<literallayout class="monospaced"> -#define XNVaNestedList "XNVaNestedList" -#define XNSeparatorofNestedList "separatorofNestedList" -#define XNQueryInputStyle "queryInputStyle" -#define XNClientWindow "clientWindow" -#define XNInputStyle "inputStyle" -#define XNFocusWindow "focusWindow" -#define XNResourceName "resourceName" -#define XNResourceClass "resourceClass" -#define XNGeometryCallback "geometryCallback" -#define XNDestroyCallback "destroyCallback" -#define XNFilterEvents "filterEvents" -#define XNPreeditStartCallback "preeditStartCallback" -#define XNPreeditDoneCallback "preeditDoneCallback" -#define XNPreeditDrawCallback "preeditDrawCallback" -#define XNPreeditCaretCallback "preeditCaretCallback" -#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback" -#define XNPreeditAttributes "preeditAttributes" -#define XNStatusStartCallback "statusStartCallback" -#define XNStatusDoneCallback "statusDoneCallback" -#define XNStatusDrawCallback "statusDrawCallback" -#define XNStatusAttributes "statusAttributes" -#define XNArea "area" -#define XNAreaNeeded "areaNeeded" -#define XNSpotLocation "spotLocation" -#define XNColormap "colorMap" -#define XNStdColormap "stdColorMap" -#define XNForeground "foreground" -#define XNBackground "background" -#define XNBackgroundPixmap "backgroundPixmap" -#define XNFontSet "fontSet" -#define XNLineSpace "lineSpace" -#define XNCursor "cursor" -#define XNQueryIMValuesList "queryIMValuesList" -#define XNQueryICValuesList "queryICValuesList" -#define XNStringConversionCallback "stringConversionCallback" -#define XNStringConversion "stringConversion" -#define XNResetState "resetState" -#define XNHotKey "hotkey" -#define XNHotKeyState "hotkeyState" -#define XNPreeditState "preeditState" -#define XNVisiblePosition "visiblePosition" -#define XNR6PreeditCallbackBehavior "r6PreeditCallback" -#define XNRequiredCharSet "requiredCharSet" -#define XNQueryOrientation "queryOrientation" -#define XNDirectionalDependentDrawing "directionalDependentDrawing" -#define XNContextualDrawing "contextualDrawing" -#define XNBaseFontName "baseFontName" -#define XNMissingCharSet "missingCharSet" -#define XNDefaultString "defaultString" -#define XNOrientation "orientation" -#define XNFontInfo "fontInfo" -#define XNOMAutomatic "omAutomatic" - -</literallayout> - -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="locales_and_internationalized_text_functions">
+<title>Locales and Internationalized Text Functions</title>
+
+<para>
+An internationalized application is one that is adaptable to the requirements of different native
+languages, local customs, and character string encodings. The process of adapting the operation
+to a particular native language, local custom, or string encoding is called localization. A goal of
+internationalization is to permit localization without program source modifications or recompilation.
+</para>
+<para>
+As one of the localization mechanisms, Xlib provides an X Input Method (<acronym>XIM</acronym>)
+functional interface for internationalized text input and an X Output Method
+(<acronym>XOM</acronym>) functional interface for internationalized text output.
+</para>
+<para>
+Internationalization in X is based on the concept of a locale. A locale defines the localized
+behavior of a program at run time. Locales affect Xlib in its:
+</para>
+
+<itemizedlist>
+ <listitem><para>Encoding and processing of input method text</para></listitem>
+ <listitem><para>Encoding of resource files and values</para></listitem>
+ <listitem><para>Encoding and imaging of text strings</para></listitem>
+ <listitem><para>Encoding and decoding for inter-client text communication</para></listitem>
+</itemizedlist>
+
+
+<para>
+•
+Encoding and decoding for inter-client text communication
+Characters from various languages are represented in a computer using an encoding.
+Different languages have different encodings, and there are even different
+encodings for the same characters in the same language.
+</para>
+<para>
+This chapter defines support for localized text imaging and text input and describes the locale
+mechanism that controls all locale-dependent Xlib functions. Sets of functions are provided for
+multibyte (char *) text as well as wide character (wchar_t) text in the form supported by the host
+C language environment. The multibyte and wide character functions are equivalent except for
+the form of the text argument.
+</para>
+<para>
+The Xlib internationalization functions are not meant to provide support for
+multilingual applications (mixing multiple languages within a single piece of text),
+but they make it possible to implement applications that work in limited
+fashion with more than one language in independent contexts.
+</para>
+<para>
+The remainder of this chapter discusses:
+</para>
+
+<itemizedlist>
+ <listitem><para>X locale management</para></listitem>
+ <listitem><para>Locale and modifier dependencies</para></listitem>
+ <listitem><para>Variable argument lists</para></listitem>
+ <listitem><para>Output methods</para></listitem>
+ <listitem><para>Input methods</para></listitem>
+ <listitem><para>String constants</para></listitem>
+</itemizedlist>
+
+
+<sect1 id="X_Locale_Management">
+<title>X Locale Management</title>
+<!-- .XS -->
+<!-- (SN X Locale Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+X supports one or more of the locales defined by the host environment.
+On implementations that conform to the ANSI C library,
+the locale announcement method is
+<function>setlocale</function>.
+This function configures the locale operation of both
+the host C library and Xlib.
+The operation of Xlib is governed by the LC_CTYPE category;
+this is called the <emphasis remap='I'>current locale</emphasis>.
+An implementation is permitted to provide implementation-dependent
+mechanisms for announcing the locale in addition to
+<function>setlocale</function>.
+</para>
+<para>
+<!-- .LP -->
+On implementations that do not conform to the ANSI C library,
+the locale announcement method is Xlib implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+The mechanism by which the semantic operation of Xlib is defined
+for a specific locale is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+X is not required to support all the locales supported by the host.
+To determine if the current locale is supported by X, use
+<function>XSupportsLocale</function>.
+</para>
+
+<para>Bool XSupportsLocale()</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSupportsLocale</function>
+function returns
+<symbol>True</symbol>
+if Xlib functions are capable of operating under the current locale.
+If it returns
+<symbol>False</symbol>,
+Xlib locale-dependent functions for which the
+<symbol>XLocaleNotSupported</symbol>
+return status is defined will return
+<symbol>XLocaleNotSupported</symbol>.
+Other Xlib locale-dependent routines will operate in the ``C'' locale.
+</para>
+<para>
+<!-- .LP -->
+The client is responsible for selecting its locale and X modifiers.
+Clients should provide a means for the user to override the clients'
+locale selection at client invocation.
+Most single-display X clients operate in a single locale
+for both X and the host processing environment.
+They will configure the locale by calling three functions:
+the host locale configuration function,
+<function>XSupportsLocale</function>,
+and
+<function>XSetLocaleModifiers</function>.
+</para>
+<para>
+<!-- .LP -->
+The semantics of certain categories of X internationalization capabilities
+can be configured by setting modifiers.
+Modifiers are named by implementation-dependent and locale-specific strings.
+The only standard use for this capability at present
+is selecting one of several styles of keyboard input method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To configure Xlib locale modifiers for the current locale, use
+<function>XSetLocaleModifiers</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetLocaleModifiers</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetlocalemodifiers'>
+<funcprototype>
+ <funcdef>char *<function>XSetLocaleModifiers</function></funcdef>
+ <paramdef>char<parameter> *modifier_list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>modifier_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the modifiers.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetLocaleModifiers</function>
+function sets the X modifiers for the current locale setting.
+The modifier_list argument is a null-terminated string of the form
+``{@<emphasis remap='I'>category</emphasis>=<emphasis remap='I'>value</emphasis>}'', that is,
+having zero or more concatenated ``@<emphasis remap='I'>category</emphasis>=<emphasis remap='I'>value</emphasis>''
+entries, where <emphasis remap='I'>category</emphasis> is a category name
+and <emphasis remap='I'>value</emphasis> is the (possibly empty) setting for that category.
+The values are encoded in the current locale.
+Category names are restricted to the <acronym>POSIX</acronym> Portable Filename Character Set.
+</para>
+<para>
+<!-- .LP -->
+The local host X locale modifiers announcer (on <acronym>POSIX</acronym>-compliant systems,
+the XMODIFIERS environment variable) is appended to the modifier_list to
+provide default values on the local host.
+If a given category appears more than once in the list,
+the first setting in the list is used.
+If a given category is not included in the full modifier list,
+the category is set to an implementation-dependent default
+for the current locale.
+An empty value for a category explicitly specifies the
+implementation-dependent default.
+</para>
+<para>
+<!-- .LP -->
+If the function is successful, it returns a pointer to a string.
+The contents of the string are such that a subsequent call with that string
+(in the same locale) will restore the modifiers to the same settings.
+If modifier_list is a NULL pointer,
+<function>XSetLocaleModifiers</function>
+also returns a pointer to such a string,
+and the current locale modifiers are not changed.
+</para>
+<para>
+<!-- .LP -->
+If invalid values are given for one or more modifier categories supported by
+the locale, a NULL pointer is returned, and none of the
+current modifiers are changed.
+</para>
+<para>
+<!-- .LP -->
+At program startup,
+the modifiers that are in effect are unspecified until
+the first successful call to set them. Whenever the locale is changed, the
+modifiers that are in effect become unspecified until the next successful call
+to set them.
+Clients should always call
+<function>XSetLocaleModifiers</function>
+with a non-NULL modifier_list after setting the locale
+before they call any locale-dependent Xlib routine.
+</para>
+<para>
+<!-- .LP -->
+The only standard modifier category currently defined is ``im'',
+which identifies the desired input method.
+The values for input method are not standardized.
+A single locale may use multiple input methods,
+switching input method under user control.
+The modifier may specify the initial input method in effect
+or an ordered list of input methods.
+Multiple input methods may be specified in a single im value string
+in an implementation-dependent manner.
+</para>
+<para>
+<!-- .LP -->
+The returned modifiers string is owned by Xlib and should not be modified or
+freed by the client.
+It may be freed by Xlib after the current locale or modifiers are changed.
+Until freed, it will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+The recommended procedure for clients initializing their locale and modifiers
+is to obtain locale and modifier announcers separately from
+one of the following prioritized sources:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A command line option
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A resource
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The empty string ("")
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The first of these that is defined should be used.
+Note that when a locale command line option or locale resource is defined,
+the effect should be to set all categories to the specified locale,
+overriding any category-specific settings in the local host environment.
+</para>
+</sect1>
+<sect1 id="Locale_and_Modifier_Dependencies">
+<title>Locale and Modifier Dependencies</title>
+<!-- .XS -->
+<!-- (SN Locale and Modifier Dependencies -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The internationalized Xlib functions operate in the current locale
+configured by the host environment and X locale modifiers set by
+<function>XSetLocaleModifiers</function>
+or in the locale and modifiers configured at the time
+some object supplied to the function was created.
+For each locale-dependent function,
+the following table describes the locale (and modifiers) dependency:
+</para>
+
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry align='center'>Locale from</entry>
+ <entry align='center'>Affects the Function</entry>
+ <entry align='center'>In</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Locale Query/Configuration:</emphasis></entry>
+ </row>
+ <row>
+ <entry morerows='1'><function>setlocale</function></entry>
+ <entry><function>XSupportsLocale</function></entry>
+ <entry>Locale queried</entry>
+ </row>
+ <row>
+ <entry><function>XSetLocaleModifiers</function></entry>
+ <entry>Locale modified</entry>
+ </row>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Resources:</emphasis></entry>
+ </row>
+ <row>
+ <entry><function>setlocale</function></entry>
+ <entry>
+ <para><function>XrmGetFileDatabase</function></para>
+ <para><function>XrmGetStringDatabase</function></para>
+ </entry>
+ <entry>Locale of <type>XrmDatabase</type></entry>
+ </row>
+ <row>
+ <entry><type>XrmDatabase</type></entry>
+ <entry>
+ <para><function>XrmPutFileDatabase</function></para>
+ <para><function>XrmLocaleOfDatabase</function></para>
+ </entry>
+ <entry>Locale of <type>XrmDatabase</type></entry>
+ </row>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Setting Standard Properties:</emphasis></entry>
+ </row>
+ <row>
+ <entry><function>setlocale</function></entry>
+ <entry><function>XmbSetWMProperties</function></entry>
+ <entry>Encoding of supplied/returned
+ text (some WM_ property
+ text in environment locale)</entry>
+ </row>
+ <row>
+ <entry><function>setlocale</function></entry>
+ <entry>
+ <para><function>XmbTextPropertyToTextList</function></para>
+ <para><function>XwcTextPropertyToTextList</function></para>
+ <para><function>XmbTextListToTextProperty</function></para>
+ <para><function>XwcTextListToTextProperty</function></para>
+ </entry>
+ <entry>Encoding of supplied/returned text</entry>
+ </row>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Text Input:</emphasis></entry>
+ </row>
+ <row>
+ <entry morerows='2'><function>setlocale</function></entry>
+ <entry><function>XOpenIM</function></entry>
+ <entry><acronym>XIM</acronym> input method selection</entry>
+ </row>
+ <row>
+ <entry><function>XRegisterIMInstantiateCallback</function></entry>
+ <entry><acronym>XIM</acronym> selection</entry>
+ </row>
+ <row>
+ <entry><function>XUnregisterIMInstantiateCallback</function></entry>
+ <entry><acronym>XIM</acronym> selection</entry>
+ </row>
+ <row>
+ <entry morerows='1'><type>XIM</type></entry>
+ <entry><function>XCreateIC</function></entry>
+ <entry><acronym>XIC</acronym> input method configuration</entry>
+ </row>
+ <row>
+ <entry><function>XLocaleOfIM</function>, and so on</entry>
+ <entry>Queried locale</entry>
+ </row>
+ <row>
+ <entry morerows='1'><type>XIC</type></entry>
+ <entry><function>XmbLookupString</function></entry>
+ <entry>Keyboard layout</entry>
+ </row>
+ <row>
+ <entry><function>XwcLookupString</function></entry>
+ <entry>Encoding of returned text</entry>
+ </row>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Text Drawing:</emphasis></entry>
+ </row>
+ <row>
+ <entry morerows='1'><function>setlocale</function></entry>
+ <entry><function>XOpenOM</function></entry>
+ <entry><acronym>XOM</acronym> output method selection</entry>
+ </row>
+ <row>
+ <entry><function>XCreateFontSet</function></entry>
+ <entry>Charsets of fonts in XFontSet</entry>
+ </row>
+ <row>
+ <entry morerows='1'><type>XOM</type></entry>
+ <entry><function>XCreateOC</function></entry>
+ <entry><acronym>XOC</acronym> output method configuration</entry>
+ </row>
+ <row>
+ <entry><function>XLocaleOfOM</function>, and so on</entry>
+ <entry>Queried locale</entry>
+ </row>
+ <row>
+ <entry morerows='2'><type>XFontSet</type></entry>
+ <entry><function>XmbDrawText</function>,</entry>
+ <entry>Locale of supplied text</entry>
+ </row>
+ <row>
+ <entry><function>XwcDrawText</function>, and so on</entry>
+ <entry>Locale of supplied text</entry>
+ </row>
+ <row>
+ <entry>
+ <para><function>XExtentsOfFontSet</function>, and so on</para>
+ <para><function>XmbTextExtents</function>,</para>
+ <para><function>XwcTextExtents</function>, and so on</para>
+ </entry>
+ <entry>Locale-dependent metrics</entry>
+ </row>
+ <row>
+ <entry nameend='c3' namest='c1'>
+ <emphasis role='bold'>Xlib Errors:</emphasis></entry>
+ </row>
+ <row>
+ <entry><function>setlocale</function></entry>
+ <entry>
+ <para><function>XGetErrorDatabaseText</function>,</para>
+ <para><function>XGetErrorText</function>, and so on</para>
+ </entry>
+ <entry>Locale of error message</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Clients may assume that a locale-encoded text string returned
+by an X function can be passed to a C library routine, or vice versa,
+if the locale is the same at the two calls.
+</para>
+<para>
+<!-- .LP -->
+All text strings processed by internationalized Xlib functions are assumed
+to begin in the initial state of the encoding of the locale, if the encoding
+is state-dependent.
+</para>
+<para>
+<!-- .LP -->
+All Xlib functions behave as if they do not change the current locale
+or X modifier setting.
+(This means that if they do change locale or call
+<function>XSetLocaleModifiers</function>
+with a non-NULL argument, they must save and restore the current state on
+entry and exit.)
+Also, Xlib functions on implementations that conform to the ANSI C library do
+not alter the global state associated with the ANSI C functions
+<function>mblen</function>,
+<function>mbtowc</function>,
+<function>wctomb</function>,
+and
+<function>strtok</function>.
+</para>
+</sect1>
+<sect1 id="Variable_Argument_Lists">
+<title>Variable Argument Lists</title>
+<!-- .XS -->
+<!-- (SN Variable Argument Lists -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Various functions in this chapter have arguments that conform
+to the ANSI C variable argument list calling convention.
+Each function denoted with an argument of the form ``...'' takes
+a variable-length list of name and value pairs,
+where each name is a string and each value is of type
+<type>XPointer</type>.
+A name argument that is NULL identifies the end of the list.
+</para>
+<para>
+<!-- .LP -->
+A variable-length argument list may contain a nested list.
+If the name
+<symbol>XNVaNestedList</symbol>
+is specified in place of an argument name,
+then the following value is interpreted as an
+<type>XVaNestedList</type>
+value that specifies a list of values logically inserted into the
+original list at the point of declaration.
+A NULL identifies the end of a nested list.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a nested variable argument list dynamically, use
+<function>XVaCreateNestedList</function>.
+</para>
+<indexterm significance="preferred"><primary>XVaCreateNestedList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xvacreatenestedlist'>
+<funcprototype>
+ <funcdef>XVaNestedList <function>XVaCreateNestedList</function></funcdef>
+ <paramdef>int<parameter> dummy</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dummy</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an unused argument (required by ANSI C).
+<!-- .ds Al -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XVaCreateNestedList</function>
+function allocates memory and copies its arguments into
+a single list pointer,
+which may be used as a value for arguments requiring a list value.
+Any entries are copied as specified.
+Data passed by reference is not copied;
+the caller must ensure data remains valid for the lifetime
+of the nested list.
+The list should be freed using
+<function>XFree</function>
+when it is no longer needed.
+</para>
+</sect1>
+<sect1 id="Output_Methods">
+<title>Output Methods</title>
+<!-- .XS -->
+<!-- (SN Output Methods -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section provides discussions of the following X Output Method
+(<acronym>XOM</acronym>) topics:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Output method overview
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Output method functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Output method values
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Output context functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Output context values
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Creating and freeing a font set
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtaining font set metrics
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Drawing text using font sets
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Output_Method_Overview">
+<title>Output Method Overview</title>
+<!-- .XS -->
+<!-- (SN Output Method Overview -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Locale-dependent text may include one or more text components, each of
+which may require different fonts and character set encodings.
+In some languages, each component might have a different
+drawing direction, and some components might contain
+context-dependent characters that change shape based on
+relationships with neighboring characters.
+</para>
+<para>
+<!-- .LP -->
+When drawing such locale-dependent text, some locale-specific
+knowledge is required;
+for example, what fonts are required to draw the text,
+how the text can be separated into components, and which
+fonts are selected to draw each component.
+Further, when bidirectional text must be drawn,
+the internal representation order of the text must be changed
+into the visual representation order to be drawn.
+</para>
+<para>
+<!-- .LP -->
+An X Output Method provides a functional interface so that clients
+do not have to deal directly with such locale-dependent details.
+Output methods provide the following capabilities:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Creating a set of fonts required to draw locale-dependent text.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Drawing locale-dependent text with a font set without the caller
+needing to be aware of locale dependencies.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Obtaining the escapement and extents in pixels of locale-dependent text.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determining if bidirectional or context-dependent drawing is required
+in a specific locale with a specific font set.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Two different abstractions are used in the representation of
+the output method for clients.
+</para>
+<para>
+<!-- .LP -->
+The abstraction used to communicate with an output method
+is an opaque data structure represented by the
+<type>XOM</type>
+data type.
+The abstraction for representing the state of a particular output thread
+is called an <emphasis remap='I'>output context</emphasis>.
+The Xlib representation of an output context is an
+<type>XOC</type>,
+which is compatible with
+<type>XFontSet</type>
+in terms of its functional interface, but is
+a broader, more generalized abstraction.
+</para>
+</sect2>
+<sect2 id="Output_Method_Functions">
+<title>Output Method Functions</title>
+<!-- .XS -->
+<!-- (SN Output Method Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To open an output method, use
+<function>XOpenOM</function>.
+</para>
+<indexterm significance="preferred"><primary>XOpenOM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xopenom'>
+<funcprototype>
+ <funcdef>XOM <function>XOpenOM</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> db</parameter></paramdef>
+ <paramdef>char<parameter> *res_name</parameter></paramdef>
+ <paramdef>char<parameter> *res_class</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full resource name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full class name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XOpenOM</function>
+function opens an output method
+matching the current locale and modifiers specification.
+The current locale and modifiers are bound to the output method
+when
+<function>XOpenOM</function>
+is called.
+The locale associated with an output method cannot be changed.
+</para>
+<para>
+<!-- .LP -->
+The specific output method to which this call will be routed
+is identified on the basis of the current locale and modifiers.
+<function>XOpenOM</function>
+will identify a default output method corresponding to the
+current locale.
+That default can be modified using
+<function>XSetLocaleModifiers</function>
+to set the output method modifier.
+</para>
+<para>
+<!-- .LP -->
+The db argument is the resource database to be used by the output method
+for looking up resources that are private to the output method.
+It is not intended that this database be used to look
+up values that can be set as OC values in an output context.
+If db is NULL,
+no database is passed to the output method.
+</para>
+<para>
+<!-- .LP -->
+The res_name and res_class arguments specify the resource name
+and class of the application.
+They are intended to be used as prefixes by the output method
+when looking up resources that are common to all output contexts
+that may be created for this output method.
+The characters used for resource names and classes must be in the
+X Portable Character Set.
+The resources looked up are not fully specified
+if res_name or res_class is NULL.
+</para>
+<para>
+<!-- .LP -->
+The res_name and res_class arguments are not assumed to exist beyond
+the call to
+<function>XOpenOM</function>.
+The specified resource database is assumed to exist for the lifetime
+of the output method.
+</para>
+<para>
+<!-- .LP -->
+<function>XOpenOM</function>
+returns NULL if no output method could be opened.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To close an output method, use
+<function>XCloseOM</function>.
+</para>
+<indexterm significance="preferred"><primary>XCloseOM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcloseom'>
+<funcprototype>
+ <funcdef>Status <function>XCloseOM</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCloseOM</function>
+function closes the specified output method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set output method attributes, use
+<function>XSetOMValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetOMValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetomvalues'>
+<funcprototype>
+ <funcdef>char *<function>XSetOMValues</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+<!-- .ds Al \ to set <acronym>XOM</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetOMValues</function>
+function presents a variable argument list programming interface
+for setting properties or features of the specified output method.
+This function returns NULL if it succeeds;
+otherwise,
+it returns the name of the first argument that could not be obtained.
+</para>
+<para>
+<!-- .LP -->
+No standard arguments are currently defined by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To query an output method, use
+<function>XGetOMValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetOMValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetomvalues'>
+<funcprototype>
+ <funcdef>char *<function>XGetOMValues</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+<!-- .ds Al \ to get XOM values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetOMValues</function>
+function presents a variable argument list programming interface
+for querying properties or features of the specified output method.
+This function returns NULL if it succeeds;
+otherwise,
+it returns the name of the first argument that could not be obtained.
+</para>
+<para>
+<!-- .LP -->
+To obtain the display associated with an output method, use
+<function>XDisplayOfOM</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisplayOfOM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisplayofom'>
+<funcprototype>
+ <funcdef>Display *<function>XDisplayOfOM</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDisplayOfOM</function>
+function returns the display associated with the specified output method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the locale associated with an output method, use
+<function>XLocaleOfOM</function>.
+</para>
+<indexterm significance="preferred"><primary>XLocaleOfOM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlocaleofom'>
+<funcprototype>
+ <funcdef>char *<function>XLocaleOfOM</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLocaleOfOM</function>
+returns the locale associated with the specified output method.
+</para>
+</sect2>
+<sect2 id="X_Output_Method_Values">
+<title>X Output Method Values</title>
+<!-- .XS -->
+<!-- (SN X Output Method Values -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following table describes how <acronym>XOM</acronym> values are interpreted by an
+output method.
+The first column lists the <acronym>XOM</acronym> values. The second column indicates
+how each of the <acronym>XOM</acronym> values are treated by a particular output style.
+</para>
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+The following key applies to this table.
+</para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'>Key</entry>
+ <entry align='left'>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>G</entry>
+ <entry>This value may be read using <function>XGetOMValues</function>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para></para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'><acronym>XOM</acronym> Value</entry>
+ <entry align='left'>Key</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><symbol>XNRequiredCharSet</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNQueryOrientation</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNDirectionalDependentDrawing</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNContextualDrawing</symbol></entry>
+ <entry>G</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+</para>
+<sect3 id="Required_Char_Set">
+<title>Required Char Set</title>
+<!-- .XS -->
+<!-- (SN Required Char Set -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNRequiredCharSet</symbol>
+argument returns the list of charsets that are required for loading the fonts
+needed for the locale.
+The value of the argument is a pointer to a structure of type
+<structname>XOMCharSetList</structname>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XOMCharSetList</structname>
+structure is defined as follows:
+<indexterm significance="preferred"><primary>XOMCharSetList</primary></indexterm>
+<!-- .sM -->
+</para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int charset_count;
+ char **charset_list;
+} XOMCharSetList;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The charset_list member is a list of one or more null-terminated
+charset names, and the charset_count member is the number of
+charset names.
+</para>
+<para>
+<!-- .LP -->
+The required charset list is owned by Xlib and should not be modified or
+freed by the client.
+It will be freed by a call to
+<function>XCloseOM</function>
+with the associated
+<type>XOM</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Query_Orientation">
+<title>Query Orientation</title>
+<!-- .XS -->
+<!-- (SN Query Orientation -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNQueryOrientation</symbol>
+argument returns the global orientation of text when drawn.
+Other than
+<constant>XOMOrientation_LTR_TTB</constant>,
+the set of orientations supported is locale-dependent.
+The value of the argument is a pointer to a structure of type
+<structname>XOMOrientation</structname>.
+Clients are responsible for freeing the
+<structname>XOMOrientation</structname>
+structure by using
+<function>XFree</function>;
+this also frees the contents of the structure.
+</para>
+
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int num_orientation;
+ XOrientation *orientation; /* Input Text description */
+} XOMOrientation;
+
+typedef enum {
+ XOMOrientation_LTR_TTB,
+ XOMOrientation_RTL_TTB,
+ XOMOrientation_TTB_LTR,
+ XOMOrientation_TTB_RTL,
+ XOMOrientation_Context
+} XOrientation;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The possible value for XOrientation may be:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+<constant>XOMOrientation_LTR_TTB</constant>
+left-to-right, top-to-bottom global orientation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<constant>XOMOrientation_RTL_TTB</constant>
+right-to-left, top-to-bottom global orientation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<constant>XOMOrientation_TTB_LTR</constant>
+top-to-bottom, left-to-right global orientation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<constant>XOMOrientation_TTB_RTL</constant>
+top-to-bottom, right-to-left global orientation
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<constant>XOMOrientation_Context</constant>
+contextual global orientation
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Directional_Dependent_Drawing">
+<title>Directional Dependent Drawing</title>
+<!-- .XS -->
+<!-- (SN Directional Dependent Drawing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNDirectionalDependentDrawing</symbol>
+argument indicates whether the text rendering functions
+implement implicit handling of directional text. If this value
+is
+<symbol>True</symbol>,
+the output method has knowledge of directional
+dependencies and reorders text as necessary when
+rendering text. If this value is
+<symbol>False</symbol>,
+the output method does not implement any directional text
+handling, and all character directions are assumed to be left-to-right.
+</para>
+<para>
+<!-- .LP -->
+Regardless of the rendering order of characters,
+the origins of all characters are on the primary draw direction side
+of the drawing origin.
+</para>
+<para>
+<!-- .LP -->
+This OM value presents functionality identical to the
+<function>XDirectionalDependentDrawing</function>
+function.
+</para>
+</sect3>
+<sect3 id="Context_Dependent_Drawing">
+<title>Context Dependent Drawing</title>
+<!-- .XS -->
+<!-- (SN Context Dependent Drawing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNContextualDrawing</symbol>
+argument indicates whether the text rendering functions
+implement implicit context-dependent drawing. If this value is
+<symbol>True</symbol>,
+the output method has knowledge of context dependencies and
+performs character shape editing, combining glyphs to present
+a single character as necessary. The actual shape editing is
+dependent on the locale implementation and the font set used.
+</para>
+<para>
+<!-- .LP -->
+This OM value presents functionality identical to the
+<function>XContextualDrawing</function>
+function.
+</para>
+</sect3>
+</sect2>
+<sect2 id="Output_Context_Functions">
+<title>Output Context Functions</title>
+<!-- .XS -->
+<!-- (SN Output Context Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An output context is an abstraction that contains both the data
+required by an output method and the information required
+to display that data.
+There can be multiple output contexts for one output method.
+The programming interfaces for creating, reading, or modifying
+an output context use a variable argument list.
+The name elements of the argument lists are referred to as <acronym>XOC</acronym> values.
+It is intended that output methods be controlled by these <acronym>XOC</acronym> values.
+As new <acronym>XOC</acronym> values are created,
+they should be registered with the X Consortium.
+An
+<type>XOC</type>
+can be used anywhere an
+<type>XFontSet</type>
+can be used, and vice versa;
+<type>XFontSet</type>
+is retained for compatibility with previous releases.
+The concepts of output methods and output contexts include broader,
+more generalized abstraction than font set,
+supporting complex and more intelligent text display, and dealing not only
+with multiple fonts but also with context dependencies.
+However,
+<type>XFontSet</type>
+is widely used in several interfaces, so
+<type>XOC</type>
+is defined as an upward compatible type of
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create an output context, use
+<function>XCreateOC</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateOC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreateoc'>
+<funcprototype>
+ <funcdef>XOC <function>XCreateOC</function></funcdef>
+ <paramdef>XOM<parameter> om</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>om</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output method.
+<!-- .ds Al \ to set <acronym>XOC</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateOC</function>
+function creates an output context within the specified output method.
+</para>
+<para>
+<!-- .LP -->
+The base font names argument is mandatory at creation time, and
+the output context will not be created unless it is provided.
+All other output context values can be set later.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateOC</function>
+returns NULL if no output context could be created.
+NULL can be returned for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A required argument was not set.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A read-only argument was set.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The output method encountered an output method implementation-dependent error.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XCreateOC</function>
+can generate a
+<errorname>BadAtom</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy an output context, use
+<function>XDestroyOC</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyOC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroyoc'>
+<funcprototype>
+ <funcdef>void <function>XDestroyOC</function></funcdef>
+ <paramdef>XOC<parameter> oc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>oc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDestroyOC</function>
+function destroys the specified output context.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the output method associated with an output context, use
+<function>XOMOfOC</function>.
+</para>
+<indexterm significance="preferred"><primary>XOMOfOC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xomofoc'>
+<funcprototype>
+ <funcdef>XOM <function>XOMOfOC</function></funcdef>
+ <paramdef>XOC<parameter> oc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>oc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XOMOfOC</function>
+function returns the output method associated with the
+specified output context.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Xlib provides two functions for setting and reading output context values,
+respectively,
+<function>XSetOCValues</function>
+and
+<function>XGetOCValues</function>.
+Both functions have a variable-length argument list.
+In that argument list, any <acronym>XOC</acronym> value's name must be denoted
+with a character string using the X Portable Character Set.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set <acronym>XOC</acronym> values, use
+<function>XSetOCValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetOCValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetocvalues'>
+<funcprototype>
+ <funcdef>char *<function>XSetOCValues</function></funcdef>
+ <paramdef>XOC<parameter> oc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>oc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output context.
+<!-- .ds Al \ to set <acronym>XOC</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetOCValues</function>
+function returns NULL if no error occurred;
+otherwise,
+it returns the name of the first argument that could not be set.
+An argument might not be set for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The argument is read-only.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An implementation-dependent error occurs.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Each value to be set must be an appropriate datum,
+matching the data type imposed by the semantics of the argument.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetOCValues</function>
+can generate a
+<errorname>BadAtom</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain <acronym>XOC</acronym> values, use
+<function>XGetOCValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetOCValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetocvalues'>
+<funcprototype>
+ <funcdef>char *<function>XGetOCValues</function></funcdef>
+ <paramdef>XOC<parameter> oc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>oc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the output context.
+<!-- .ds Al \ to get XOC values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetOCValues</function>
+function returns NULL if no error occurred; otherwise,
+it returns the name of the first argument that could not be obtained.
+An argument might not be obtained for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An implementation-dependent error occurs.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Each argument value
+following a name must point to a location where the value is to be stored.
+</para>
+</sect2>
+
+<sect2 id="Output_Context_Values">
+<title>Output Context Values</title>
+<!-- .XS -->
+<!-- (SN Output Context Values -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following table describes how <acronym>XOC</acronym> values are interpreted
+by an output method.
+The first column lists the <acronym>XOC</acronym> values.
+The second column indicates the alternative interfaces that function
+identically and are provided for compatibility with previous releases.
+The third column indicates how each of the <acronym>XOC</acronym> values is treated.
+</para>
+<!-- .LP -->
+<para>
+The following keys apply to this table.
+</para>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'>Key</entry>
+ <entry align='left'>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C</entry>
+ <entry>This value must be set with <function>XCreateOC</function>.</entry>
+ </row>
+ <row>
+ <entry>D</entry>
+ <entry>This value may be set using <function>XCreateOC</function>.
+ If it is not set,a default is provided.</entry>
+ </row>
+ <row>
+ <entry>G</entry>
+ <entry>This value may be read using <function>XGetOCValues</function>.</entry>
+ </row>
+ <row>
+ <entry>S</entry>
+ <entry>This value must be set using <function>XSetOCValues</function>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para></para>
+
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry align='left'><acronym>XOC</acronym> Value</entry>
+ <entry align='left'>Alternative Interface</entry>
+ <entry align='left'>Key</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>BaseFontName</entry>
+ <entry><function>XCreateFontSet</function></entry>
+ <entry>C-G</entry>
+ </row>
+ <row>
+ <entry>MissingCharSet</entry>
+ <entry><function>XCreateFontSet</function></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry>DefaultString</entry>
+ <entry><function>XCreateFontSet</function></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry>Orientation</entry>
+ <entry>-</entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry>ResourceName</entry>
+ <entry>-</entry>
+ <entry>S-G</entry>
+ </row>
+ <row>
+ <entry>ResourceClass</entry>
+ <entry>-</entry>
+ <entry>S-G</entry>
+ </row>
+ <row>
+ <entry>FontInfo</entry>
+ <entry><function>XFontsOfFontSet</function></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry>OMAutomatic</entry>
+ <entry>-</entry>
+ <entry>G</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+</para>
+<sect3 id="Base_Font_Name">
+<title>Base Font Name</title>
+<!-- .XS -->
+<!-- (SN Base Font Name -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNBaseFontName</symbol>
+argument is a list of base font names that Xlib uses
+to load the fonts needed for the locale.
+The base font names are a comma-separated list. The string is null-terminated
+and is assumed to be in the Host Portable Character Encoding;
+otherwise, the result is implementation-dependent.
+White space immediately on either side of a separating comma is ignored.
+</para>
+<para>
+<!-- .LP -->
+Use of <acronym>XLFD</acronym> font names permits Xlib to obtain the fonts needed for a
+variety of locales from a single locale-independent base font name.
+The single base font name should name a family of fonts whose members
+are encoded in the various charsets needed by the locales of interest.
+</para>
+<para>
+<!-- .LP -->
+An <acronym>XLFD</acronym> base font name can explicitly name a charset needed for the locale.
+This allows the user to specify an exact font for use with a charset required
+by a locale, fully controlling the font selection.
+</para>
+<para>
+<!-- .LP -->
+If a base font name is not an <acronym>XLFD</acronym> name,
+Xlib will attempt to obtain an <acronym>XLFD</acronym> name from the font properties
+for the font.
+If Xlib is successful, the
+<function>XGetOCValues</function>
+function will return this <acronym>XLFD</acronym> name instead of the client-supplied name.
+</para>
+<para>
+<!-- .LP -->
+This argument must be set at creation time
+and cannot be changed.
+If no fonts exist for any of the required charsets,
+or if the locale definition in Xlib requires that a font exist
+for a particular charset and a font is not found for that charset,
+<function>XCreateOC</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+When querying for the
+<symbol>XNBaseFontName</symbol>
+<acronym>XOC</acronym> value,
+<function>XGetOCValues</function>
+returns a null-terminated string identifying the base font names that
+Xlib used to load the fonts needed for the locale.
+This string is owned by Xlib and should not be modified or freed by
+the client.
+The string will be freed by a call to
+<function>XDestroyOC</function>
+with the associated
+<type>XOC</type>.
+Until freed, the string contents will not be modified by Xlib.
+</para>
+</sect3>
+<sect3 id="Missing_CharSet">
+<title>Missing CharSet</title>
+<!-- .XS -->
+<!-- (SN Missing CharSet -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNMissingCharSet</symbol>
+argument returns the list of required charsets that are missing from the
+font set.
+The value of the argument is a pointer to a structure of type
+<structname>XOMCharSetList</structname>.
+</para>
+<para>
+<!-- .LP -->
+If fonts exist for all of the charsets required by the current locale,
+charset_list is set to NULL and charset_count is set to zero.
+If no fonts exist for one or more of the required charsets,
+charset_list is set to a list of one or more null-terminated charset names
+for which no fonts exist, and charset_count is set to the number of
+missing charsets.
+The charsets are from the list of the required charsets for
+the encoding of the locale and do not include any charsets to which Xlib
+may be able to remap a required charset.
+</para>
+<para>
+<!-- .LP -->
+The missing charset list is owned by Xlib and should not be modified or
+freed by the client.
+It will be freed by a call to
+<function>XDestroyOC</function>
+with the associated
+<type>XOC</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+</sect3>
+<sect3 id="Default_String">
+<title>Default String</title>
+<!-- .XS -->
+<!-- (SN Default String -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When a drawing or measuring function is called with an
+<type>XOC</type>
+that has missing charsets, some characters in the locale will not be
+drawable.
+The
+<symbol>XNDefaultString</symbol>
+argument returns a pointer to a string that represents the glyphs
+that are drawn with this
+<type>XOC</type>
+when the charsets of the available fonts do not include all glyphs
+required to draw a character.
+The string does not necessarily consist of valid characters
+in the current locale and is not necessarily drawn with
+the fonts loaded for the font set,
+but the client can draw or measure the default glyphs
+by including this string in a string being drawn or measured with the
+<type>XOC</type>.
+</para>
+<para>
+<!-- .LP -->
+If the
+<symbol>XNDefaultString</symbol>
+argument returned the empty string (""),
+no glyphs are drawn and the escapement is zero.
+The returned string is null-terminated.
+It is owned by Xlib and should not be modified or freed by the client.
+It will be freed by a call to
+<function>XDestroyOC</function>
+with the associated
+<type>XOC</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+</sect3>
+<sect3 id="Orientation">
+<title>Orientation</title>
+<!-- .XS -->
+<!-- (SN Orientation -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNOrientation</symbol>
+argument specifies the current orientation of text when drawn. The value of
+this argument is one of the values returned by the
+<function>XGetOMValues</function>
+function with the
+<symbol>XNQueryOrientation</symbol>
+argument specified in the
+<type>XOrientation</type>
+list.
+The value of the argument is of type
+<type>XOrientation</type>.
+When
+<symbol>XNOrientation</symbol>
+is queried, the value specifies the current orientation.
+When
+<symbol>XNOrientation</symbol>
+is set, a value is used to set the current orientation.
+</para>
+<para>
+<!-- .LP -->
+When
+<constant>XOMOrientation_Context</constant>
+is set, the text orientation of the
+text is determined according to an implementation-defined method
+(for example, ISO 6429 control sequences), and the initial text orientation for
+locale-dependent Xlib functions is assumed to
+be
+<constant>XOMOrientation_LTR_TTB</constant>.
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNOrientation</symbol>
+value does not change the prime drawing direction
+for Xlib drawing functions.
+</para>
+</sect3>
+<sect3 id="Resource_Name_and_Class">
+<title>Resource Name and Class</title>
+<!-- .XS -->
+<!-- (SN Resource Name and Class -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNResourceName</symbol>
+and
+<symbol>XNResourceClass</symbol>
+arguments are strings that specify the full name and class
+used by the client to obtain resources for the display of the output context.
+These values should be used as prefixes for name and class
+when looking up resources that may vary according to the output context.
+If these values are not set,
+the resources will not be fully specified.
+</para>
+<para>
+<!-- .LP -->
+It is not intended that values that can be set as <acronym>XOM</acronym> values be
+set as resources.
+</para>
+<para>
+<!-- .LP -->
+When querying for the
+<symbol>XNResourceName</symbol>
+or
+<symbol>XNResourceClass</symbol>
+<acronym>XOC</acronym> value,
+<function>XGetOCValues</function>
+returns a null-terminated string.
+This string is owned by Xlib and should not be modified or freed by
+the client.
+The string will be freed by a call to
+<function>XDestroyOC</function>
+with the associated
+<type>XOC</type>
+or when the associated value is changed via
+<function>XSetOCValues</function>.
+Until freed, the string contents will not be modified by Xlib.
+</para>
+</sect3>
+<sect3 id="Font_Info">
+<title>Font Info</title>
+<!-- .XS -->
+<!-- (SN Font Info -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNFontInfo</symbol>
+argument specifies a list of one or more
+<structname>XFontStruct</structname>
+structures
+and font names for the fonts used for drawing by the given output context.
+The value of the argument is a pointer to a structure of type
+<structname>XOMFontInfo</structname>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int num_font;
+ XFontStruct **font_struct_list;
+ char **font_name_list;
+} XOMFontInfo;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+A list of pointers to the
+<structname>XFontStruct</structname>
+structures is returned to font_struct_list.
+A list of pointers to null-terminated, fully-specified font name strings
+in the locale of the output context is returned to font_name_list.
+The font_name_list order corresponds to the font_struct_list order.
+The number of
+<structname>XFontStruct</structname>
+structures and font names is returned to num_font.
+</para>
+<para>
+<!-- .LP -->
+Because it is not guaranteed that a given character will be imaged using a
+single font glyph,
+there is no provision for mapping a character or default string
+to the font properties, font ID, or direction hint for the font
+for the character.
+The client may access the
+<structname>XFontStruct</structname>
+list to obtain these values for all the fonts currently in use.
+</para>
+<para>
+<!-- .LP -->
+Xlib does not guarantee that fonts are loaded from the server
+at the creation of an
+<type>XOC</type>.
+Xlib may choose to cache font data, loading it only as needed to draw text
+or compute text dimensions.
+Therefore, existence of the per_char metrics in the
+<structname>XFontStruct</structname>
+structures in the
+<structname>XFontStructSet</structname>
+is undefined.
+Also, note that all properties in the
+<structname>XFontStruct</structname>
+structures are in the STRING encoding.
+</para>
+<para>
+<!-- .LP -->
+The client must not free the
+<structname>XOMFontInfo</structname>
+struct itself; it will be freed when the
+<type>XOC</type>
+is closed.
+</para>
+</sect3>
+<sect3 id="OM_Automatic">
+<title>OM Automatic</title>
+<!-- .XS -->
+<!-- (SN OM Automatic -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNOMAutomatic</symbol>
+argument returns whether the associated output context was created by
+<function>XCreateFontSet</function>
+or not. Because the
+<function>XFreeFontSet</function>
+function not only destroys the output context but also closes the implicit
+output method associated with it,
+<function>XFreeFontSet</function>
+should be used with any output context created by
+<function>XCreateFontSet</function>.
+However, it is possible that a client does not know how the output context
+was created.
+Before a client destroys the output context,
+it can query whether
+<symbol>XNOMAutomatic</symbol>
+is set to determine whether
+<function>XFreeFontSet</function>
+or
+<function>XDestroyOC</function>
+should be used to destroy the output context.
+</para>
+</sect3>
+</sect2>
+<sect2 id="Creating_and_Freeing_a_Font_Set">
+<title>Creating and Freeing a Font Set</title>
+<!-- .XS -->
+<!-- (SN Creating and Freeing a Font Set -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib international text drawing is done using a set of one or more fonts,
+as needed for the locale of the text.
+Fonts are loaded according to a list of base font names
+supplied by the client and the charsets required by the locale.
+The
+<type>XFontSet</type>
+is an opaque type representing the state of a particular output thread
+and is equivalent to the type
+<type>XOC</type>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+The
+<function>XCreateFontSet</function>
+function is a convenience function for creating an output context using
+only default values. The returned
+<type>XFontSet</type>
+has an implicitly created
+<type>XOM</type>.
+This
+<type>XOM</type>
+has an OM value
+<symbol>XNOMAutomatic</symbol>
+automatically set to
+<symbol>True</symbol>
+so that the output context self indicates whether it was created by
+<function>XCreateOC</function>
+or
+<function>XCreateFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatefontset'>
+<funcprototype>
+ <funcdef>XFontSet <function>XCreateFontSet</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *base_font_name_list</parameter></paramdef>
+ <paramdef>char<parameter> ***missing_charset_list_return</parameter></paramdef>
+ <paramdef>int<parameter> *missing_charset_count_return</parameter></paramdef>
+ <paramdef>char<parameter> **def_string_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>base_font_name_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the base font names.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>missing_charset_list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the missing charsets.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>missing_charset_count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of missing charsets.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>def_string_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the string drawn for missing charsets.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateFontSet</function>
+function creates a font set for the specified display.
+The font set is bound to the current locale when
+<function>XCreateFontSet</function>
+is called.
+The font set may be used in subsequent calls to obtain font
+and character information and to image text in the locale of the font set.
+</para>
+<para>
+<!-- .LP -->
+The base_font_name_list argument is a list of base font names
+that Xlib uses to load the fonts needed for the locale.
+The base font names are a comma-separated list.
+The string is null-terminated
+and is assumed to be in the Host Portable Character Encoding;
+otherwise, the result is implementation-dependent.
+White space immediately on either side of a separating comma is ignored.
+</para>
+<para>
+<!-- .LP -->
+Use of <acronym>XLFD</acronym> font names permits Xlib to obtain the fonts needed for a
+variety of locales from a single locale-independent base font name.
+The single base font name should name a family of fonts whose members
+are encoded in the various charsets needed by the locales of interest.
+</para>
+<para>
+<!-- .LP -->
+An <acronym>XLFD</acronym> base font name can explicitly name a charset needed for the locale.
+This allows the user to specify an exact font for use with a charset required
+by a locale, fully controlling the font selection.
+</para>
+<para>
+<!-- .LP -->
+If a base font name is not an <acronym>XLFD</acronym> name,
+Xlib will attempt to obtain an <acronym>XLFD</acronym> name from the font properties
+for the font.
+If this action is successful in obtaining an <acronym>XLFD</acronym> name, the
+<function>XBaseFontNameListOfFontSet</function>
+function will return this <acronym>XLFD</acronym> name instead of the client-supplied name.
+</para>
+<para>
+<!-- .LP -->
+Xlib uses the following algorithm to select the fonts
+that will be used to display text with the
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+For each font charset required by the locale,
+the base font name list is searched for the first appearance of one
+of the following cases that names a set of fonts that exist at the server:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The first <acronym>XLFD</acronym>-conforming base font name that specifies the required
+charset or a superset of the required charset in its
+<structfield>CharSetRegistry</structfield>
+and
+<structfield>CharSetEncoding</structfield>
+fields.
+The implementation may use a base font name whose specified charset
+is a superset of the required charset, for example,
+an ISO8859-1 font for an ASCII charset.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The first set of one or more <acronym>XLFD</acronym>-conforming base font names
+that specify one or more charsets that can be remapped to support the
+required charset.
+The Xlib implementation may recognize various mappings
+from a required charset to one or more other charsets
+and use the fonts for those charsets.
+For example, JIS Roman is ASCII with tilde and backslash replaced
+by yen and overbar;
+Xlib may load an ISO8859-1 font to support this character set
+if a JIS Roman font is not available.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The first <acronym>XLFD</acronym>-conforming font name or the first non-<acronym>XLFD</acronym> font name
+for which an <acronym>XLFD</acronym> font name can be obtained, combined with the
+required charset (replacing the
+<structfield>CharSetRegistry</structfield>
+and
+<structfield>CharSetEncoding</structfield>
+fields in the <acronym>XLFD</acronym> font name).
+As in case 1,
+the implementation may use a charset that is a superset
+of the required charset.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The first font name that can be mapped in some implementation-dependent
+manner to one or more fonts that support imaging text in the charset.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+For example, assume that a locale required the charsets:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+ISO8859-1
+JISX0208.1983
+JISX0201.1976
+GB2312-1980.0
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The user could supply a base_font_name_list that explicitly specifies the
+charsets, ensuring that specific fonts are used if they exist.
+For example:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+"-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-240-JISX0208.1983-0,\\
+-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-120-JISX0201.1976-0,\\
+-GB-Fixed-Medium-R-Normal--26-180-100-100-C-240-GB2312-1980.0,\\
+-Adobe-Courier-Bold-R-Normal--25-180-75-75-M-150-ISO8859-1"
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Alternatively, the user could supply a base_font_name_list
+that omits the charsets,
+letting Xlib select font charsets required for the locale.
+For example:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+"-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-240,\\
+-JIS-Fixed-Medium-R-Normal--26-180-100-100-C-120,\\
+-GB-Fixed-Medium-R-Normal--26-180-100-100-C-240,\\
+-Adobe-Courier-Bold-R-Normal--25-180-100-100-M-150"
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Alternatively, the user could simply supply a single base font name
+that allows Xlib to select from all available fonts
+that meet certain minimum <acronym>XLFD</acronym> property requirements.
+For example:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+"-*-*-*-R-Normal--*-180-100-100-*-*"
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If
+<function>XCreateFontSet</function>
+is unable to create the font set,
+either because there is insufficient memory or because the current locale
+is not supported,
+<function>XCreateFontSet</function>
+returns NULL, missing_charset_list_return is set to NULL,
+and missing_charset_count_return
+is set to zero.
+If fonts exist for all of the charsets required by the current locale,
+<function>XCreateFontSet</function>
+returns a valid
+<type>XFontSet</type>,
+missing_charset_list_return is set to NULL,
+and missing_charset_count_return is set to zero.
+</para>
+<para>
+<!-- .LP -->
+If no font exists for one or more of the required charsets,
+<function>XCreateFontSet</function>
+sets missing_charset_list_return to a
+list of one or more null-terminated charset names for which no font exists
+and sets missing_charset_count_return to the number of missing fonts.
+The charsets are from the list of the required charsets for
+the encoding of the locale and do not include any charsets to which Xlib
+may be able to remap a required charset.
+</para>
+<para>
+<!-- .LP -->
+If no font exists for any of the required charsets
+or if the locale definition in Xlib requires that a font exist
+for a particular charset and a font is not found for that charset,
+<function>XCreateFontSet</function>
+returns NULL.
+Otherwise,
+<function>XCreateFontSet</function>
+returns a valid
+<type>XFontSet</type>
+to font_set.
+</para>
+<para>
+<!-- .LP -->
+When an Xmb/wc drawing or measuring function is called with an
+<type>XFontSet</type>
+that has missing charsets, some characters in the locale will not be
+drawable.
+If def_string_return is non-NULL,
+<function>XCreateFontSet</function>
+returns a pointer to a string that represents the glyphs
+that are drawn with this
+<type>XFontSet</type>
+when the charsets of the available fonts do not include all font glyphs
+required to draw a codepoint.
+The string does not necessarily consist of valid characters
+in the current locale and is not necessarily drawn with
+the fonts loaded for the font set,
+but the client can draw and measure the default glyphs
+by including this string in a string being drawn or measured with the
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+If the string returned to def_string_return is the empty string (""),
+no glyphs are drawn, and the escapement is zero.
+The returned string is null-terminated.
+It is owned by Xlib and should not be modified or freed by the client.
+It will be freed by a call to
+<function>XFreeFontSet</function>
+with the associated
+<type>XFontSet</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+The client is responsible for constructing an error message from the
+missing charset and default string information and may choose to continue
+operation in the case that some fonts did not exist.
+</para>
+<para>
+<!-- .LP -->
+The returned
+<type>XFontSet</type>
+and missing charset list should be freed with
+<function>XFreeFontSet</function>
+and
+<function>XFreeStringList</function>,
+respectively.
+The client-supplied base_font_name_list may be freed
+by the client after calling
+<function>XCreateFontSet</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a list of
+<structname>XFontStruct</structname>
+structures and full font names given an
+<type>XFontSet</type>,
+use
+<function>XFontsOfFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XFontsOfFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfontsoffontset'>
+<funcprototype>
+ <funcdef>int <function>XFontsOfFontSet</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>XFontStruct<parameter> ***font_struct_list_return</parameter></paramdef>
+ <paramdef>char<parameter> ***font_name_list_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_struct_list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of font structs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_name_list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of font names.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFontsOfFontSet</function>
+function returns a list of one or more
+<structname>XFontStruct</structname>s
+and font names for the fonts used by the Xmb and Xwc layers
+for the given font set.
+A list of pointers to the
+<structname>XFontStruct</structname>
+structures is returned to font_struct_list_return.
+A list of pointers to null-terminated, fully specified font name strings
+in the locale of the font set is returned to font_name_list_return.
+The font_name_list order corresponds to the font_struct_list order.
+The number of
+<structname>XFontStruct</structname>
+structures and font names is returned as the value of the function.
+</para>
+<para>
+<!-- .LP -->
+Because it is not guaranteed that a given character will be imaged using a
+single font glyph,
+there is no provision for mapping a character or default string
+to the font properties, font ID, or direction hint for the font
+for the character.
+The client may access the
+<structname>XFontStruct</structname>
+list to obtain these values for all the fonts currently in use.
+</para>
+<para>
+<!-- .LP -->
+Xlib does not guarantee that fonts are loaded from the server
+at the creation of an
+<type>XFontSet</type>.
+Xlib may choose to cache font data, loading it only as needed to draw text
+or compute text dimensions.
+Therefore, existence of the per_char metrics in the
+<structname>XFontStruct</structname>
+structures in the
+<structname>XFontStructSet</structname>
+is undefined.
+Also, note that all properties in the
+<structname>XFontStruct</structname>
+structures are in the STRING encoding.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XFontStruct</structname>
+and font name lists are owned by Xlib
+and should not be modified or freed by the client.
+They will be freed by a call to
+<function>XFreeFontSet</function>
+with the associated
+<type>XFontSet</type>.
+Until freed, their contents will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the base font name list and the selected font name list given an
+<type>XFontSet</type>,
+use
+<function>XBaseFontNameListOfFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XBaseFontNameListOfFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xbasefontnamelistoffontset'>
+<funcprototype>
+ <funcdef>char *<function>XBaseFontNameListOfFontSet</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XBaseFontNameListOfFontSet</function>
+function returns the original base font name list supplied
+by the client when the
+<type>XFontSet</type>
+was created.
+A null-terminated string containing a list of
+comma-separated font names is returned
+as the value of the function.
+White space may appear immediately on either side of separating commas.
+</para>
+<para>
+<!-- .LP -->
+If
+<function>XCreateFontSet</function>
+obtained an <acronym>XLFD</acronym> name from the font properties for the font specified
+by a non-<acronym>XLFD</acronym> base name, the
+<function>XBaseFontNameListOfFontSet</function>
+function will return the <acronym>XLFD</acronym> name instead of the non-<acronym>XLFD</acronym> base name.
+</para>
+<para>
+<!-- .LP -->
+The base font name list is owned by Xlib and should not be modified or
+freed by the client.
+It will be freed by a call to
+<function>XFreeFontSet</function>
+with the associated
+<type>XFontSet</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the locale name given an
+<type>XFontSet</type>,
+use
+<function>XLocaleOfFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XLocaleOfFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlocaleoffontset'>
+<funcprototype>
+ <funcdef>char *<function>XLocaleOfFontSet</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLocaleOfFontSet</function>
+function
+returns the name of the locale bound to the specified
+<type>XFontSet</type>,
+as a null-terminated string.
+</para>
+<para>
+<!-- .LP -->
+The returned locale name string is owned by Xlib
+and should not be modified or freed by the client.
+It may be freed by a call to
+<function>XFreeFontSet</function>
+with the associated
+<type>XFontSet</type>.
+Until freed, it will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+The
+<function>XFreeFontSet</function>
+function is a convenience function for freeing an output context.
+<function>XFreeFontSet</function>
+also frees its associated
+<type>XOM</type>
+if the output context was created by
+<function>XCreateFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreefontset'>
+<funcprototype>
+ <funcdef>void <function>XFreeFontSet</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeFontSet</function>
+function frees the specified font set.
+The associated base font name list, font name list,
+<structname>XFontStruct</structname>
+list, and
+<structname>XFontSetExtents</structname>,
+if any, are freed.
+</para>
+</sect2>
+<sect2 id="Obtaining_Font_Set_Metrics">
+<title>Obtaining Font Set Metrics</title>
+<!-- .XS -->
+<!-- (SN Obtaining Font Set Metrics -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Metrics for the internationalized text drawing functions
+are defined in terms of a primary draw direction,
+which is the default direction in which the character origin advances
+for each succeeding character in the string.
+The Xlib interface is currently defined to support only a left-to-right
+primary draw direction.
+The drawing origin is the position passed to the drawing function
+when the text is drawn.
+The baseline is a line drawn through the drawing origin parallel
+to the primary draw direction.
+Character ink is the pixels painted in the foreground color
+and does not include interline or intercharacter spacing
+or image text background pixels.
+</para>
+<para>
+<!-- .LP -->
+The drawing functions are allowed to implement implicit text
+directionality control, reversing the order in which characters are
+rendered along the primary draw direction in response to locale-specific
+lexical analysis of the string.
+</para>
+<para>
+<!-- .LP -->
+Regardless of the character rendering order,
+the origins of all characters are on the primary draw direction side
+of the drawing origin.
+The screen location of a particular character image may be determined with
+<function>XmbTextPerCharExtents</function>
+or
+<function>XwcTextPerCharExtents</function>.
+</para>
+<para>
+<!-- .LP -->
+The drawing functions are allowed to implement context-dependent
+rendering, where the glyphs drawn for a string are not simply a
+concatenation of the glyphs that represent each individual character.
+A string of two characters drawn with
+<function>XmbDrawString</function>
+may render differently than if the two characters
+were drawn with separate calls to
+<function>XmbDrawString</function>.
+If the client appends or inserts a character
+in a previously drawn string,
+the client may need to redraw some adjacent characters
+to obtain proper rendering.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To find out about direction-dependent rendering, use
+<function>XDirectionalDependentDrawing</function>.
+</para>
+<indexterm significance="preferred"><primary>XDirectionalDependentDrawing</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdirectionaldependentdrawing'>
+<funcprototype>
+ <funcdef>Bool <function>XDirectionalDependentDrawing</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDirectionalDependentDrawing</function>
+function returns
+<symbol>True</symbol>
+if the drawing functions implement implicit text directionality;
+otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To find out about context-dependent rendering, use
+<function>XContextualDrawing</function>.
+</para>
+<indexterm significance="preferred"><primary>XContextualDrawing</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcontextualdrawing'>
+<funcprototype>
+ <funcdef>Bool <function>XContextualDrawing</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XContextualDrawing</function>
+function returns
+<symbol>True</symbol>
+if text drawn with the font set might include context-dependent drawing;
+otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To find out about context-dependent or direction-dependent rendering, use
+<function>XContextDependentDrawing</function>.
+</para>
+<indexterm significance="preferred"><primary>XContextDependentDrawing</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcontextdependentdrawing'>
+<funcprototype>
+ <funcdef>Bool <function>XContextDependentDrawing</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XContextDependentDrawing</function>
+function returns
+<symbol>True</symbol>
+if the drawing functions implement implicit text directionality or
+if text drawn with the font_set might include context-dependent drawing;
+otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The drawing functions do not interpret newline, tab, or other control
+characters.
+The behavior when nonprinting characters other than space are drawn
+is implementation-dependent.
+It is the client's responsibility to interpret control characters
+in a text stream.
+</para>
+<para>
+<!-- .LP -->
+The maximum character extents for the fonts that are used by the text
+drawing layers can be accessed by the
+<structname>XFontSetExtents</structname>
+structure:
+<indexterm significance="preferred"><primary>XFontSetExtents</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ XRectangle max_ink_extent; /* over all drawable characters */
+ XRectangle max_logical_extent; /* over all drawable characters */
+} XFontSetExtents;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XRectangle</structname>
+structures used to return font set metrics are the usual Xlib screen-oriented
+rectangles
+with x, y giving the upper left corner, and width and height always positive.
+</para>
+<para>
+<!-- .LP -->
+The max_ink_extent member gives the maximum extent, over all drawable characters, of
+the rectangles that bound the character glyph image drawn in the
+foreground color, relative to a constant origin.
+See
+<function>XmbTextExtents</function>
+and
+<function>XwcTextExtents</function>
+for detailed semantics.
+</para>
+<para>
+<!-- .LP -->
+The max_logical_extent member gives the maximum extent,
+over all drawable characters, of the rectangles
+that specify minimum spacing to other graphical features,
+relative to a constant origin.
+Other graphical features drawn by the client, for example,
+a border surrounding the text, should not intersect this rectangle.
+The max_logical_extent member should be used to compute minimum
+interline spacing and the minimum area that must be allowed
+in a text field to draw a given number of arbitrary characters.
+</para>
+<para>
+<!-- .LP -->
+Due to context-dependent rendering,
+appending a given character to a string may change
+the string's extent by an amount other than that character's
+individual extent.
+</para>
+<para>
+<!-- .LP -->
+The rectangles for a given character in a string can be obtained from
+<function>XmbTextPerCharExtents</function>
+or
+<function>XwcTextPerCharExtents</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the maximum extents structure given an
+<type>XFontSet</type>,
+use
+<function>XExtentsOfFontSet</function>.
+</para>
+<indexterm significance="preferred"><primary>XExtentsOfFontSet</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xextentsoffontset'>
+<funcprototype>
+ <funcdef>XFontSetExtents *<function>XExtentsOfFontSet</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XExtentsOfFontSet</function>
+function returns an
+<structname>XFontSetExtents</structname>
+structure for the fonts used by the Xmb and Xwc layers
+for the given font set.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XFontSetExtents</structname>
+structure is owned by Xlib and should not be modified
+or freed by the client.
+It will be freed by a call to
+<function>XFreeFontSet</function>
+with the associated
+<type>XFontSet</type>.
+Until freed, its contents will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the escapement in pixels of the specified text as a value,
+use
+<function>XmbTextEscapement</function>
+or
+<function>XwcTextEscapement</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbTextEscapement</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcTextEscapement</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbtextescapement'>
+<funcprototype>
+ <funcdef>int <function>XmbTextEscapement</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwctextescapement'>
+<funcprototype>
+ <funcdef>int <function>XwcTextEscapement</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_wchars</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_wchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbTextEscapement</function>
+and
+<function>XwcTextEscapement</function>
+functions return the escapement in pixels of the specified string as a value,
+using the fonts loaded for the specified font set.
+The escapement is the distance in pixels in the primary draw
+direction from the drawing origin to the origin of the next character to
+be drawn, assuming that the rendering of the next character is not
+dependent on the supplied string.
+</para>
+<para>
+<!-- .LP -->
+Regardless of the character rendering order,
+the escapement is always positive.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the overall_ink_return and overall_logical_return arguments,
+the overall bounding box of the string's image, and a logical bounding box,
+use
+<function>XmbTextExtents</function>
+ or
+<function>XwcTextExtents</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbTextExtents</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcTextExtents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbtextextents'>
+<funcprototype>
+ <funcdef>int <function>XmbTextExtents</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis>
+<funcprototype id='xwctextextents'>
+ <funcdef>int <function>XwcTextExtents</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_wchars</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_wchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+<!-- .ds Ov dimensions -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_ink_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall ink dimensions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_logical_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall logical dimensions.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbTextExtents</function>
+and
+<function>XwcTextExtents</function>
+functions set the components of the specified overall_ink_return and
+overall_logical_return
+arguments to the overall bounding box of the string's image
+and a logical bounding box for spacing purposes, respectively.
+They return the value returned by
+<function>XmbTextEscapement</function>
+or
+<function>XwcTextEscapement</function>.
+These metrics are relative to the drawing origin of the string,
+using the fonts loaded for the specified font set.
+</para>
+<para>
+<!-- .LP -->
+If the overall_ink_return argument is non-NULL,
+it is set to the bounding box of the string's character ink.
+The overall_ink_return for a nondescending, horizontally drawn
+Latin character is conventionally entirely above the baseline;
+that is, overall_ink_return.height <= -overall_ink_return.y.
+The overall_ink_return for a nonkerned character
+is entirely at, and to the right of, the origin;
+that is, overall_ink_return.x >= 0.
+A character consisting of a single pixel at the origin would set
+overall_ink_return fields y = 0, x = 0, width = 1, and height = 1.
+</para>
+<para>
+<!-- .LP -->
+If the overall_logical_return argument is non-NULL,
+it is set to the bounding box that provides minimum spacing
+to other graphical features for the string.
+Other graphical features, for example, a border surrounding the text,
+should not intersect this rectangle.
+</para>
+<para>
+<!-- .LP -->
+When the
+<type>XFontSet</type>
+has missing charsets,
+metrics for each unavailable character are taken
+from the default string returned by
+<function>XCreateFontSet</function>
+so that the metrics represent the text as it will actually be drawn.
+The behavior for an invalid codepoint is undefined.
+</para>
+<para>
+<!-- .LP -->
+To determine the effective drawing origin for a character in a drawn string,
+the client should call
+<function>XmbTextPerCharExtents</function>
+on the entire string, then on the character,
+and subtract the x values of the returned
+rectangles for the character.
+This is useful to redraw portions of a line of text
+or to justify words, but for context-dependent rendering,
+the client should not assume that it can redraw the character by itself
+and get the same rendering.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain per-character information for a text string,
+use
+<function>XmbTextPerCharExtents</function>
+or
+<function>XwcTextPerCharExtents</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbTextPerCharExtents</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcTextPerCharExtents</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbtextpercharextents'>
+<funcprototype>
+ <funcdef>Status <function>XmbTextPerCharExtents</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *ink_array_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *logical_array_return</parameter></paramdef>
+ <paramdef>int<parameter> array_size</parameter></paramdef>
+ <paramdef>int<parameter> *num_chars_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwctextpercharextents'>
+<funcprototype>
+ <funcdef>Status <function>XwcTextPerCharExtents</function></funcdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_wchars</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *ink_array_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *logical_array_return</parameter></paramdef>
+ <paramdef>int<parameter> array_size</parameter></paramdef>
+ <paramdef>int<parameter> *num_chars_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_ink_return</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *overall_logical_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_wchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ink_array_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the ink dimensions for each character.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>logical_array_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the logical dimensions for each character.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>array_size</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size of ink_array_return and logical_array_return.
+The caller must pass in arrays of this size.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_chars_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of characters in the string argument.
+<!-- .ds Ov extents of the entire string -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_ink_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall ink dimensions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>overall_logical_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the overall logical dimensions.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbTextPerCharExtents</function>
+and
+<function>XwcTextPerCharExtents</function>
+functions return the text dimensions of each character of the specified text,
+using the fonts loaded for the specified font set.
+Each successive element of ink_array_return and logical_array_return
+is set to the successive character's drawn metrics,
+relative to the drawing origin of the string and one
+rectangle
+for each character in the supplied text string.
+The number of elements of ink_array_return and logical_array_return
+that have been set is returned to num_chars_return.
+</para>
+<para>
+<!-- .LP -->
+Each element of ink_array_return is set to the bounding box
+of the corresponding character's drawn foreground color.
+Each element of logical_array_return is set to the bounding box
+that provides minimum spacing to other graphical features
+for the corresponding character.
+Other graphical features should not intersect any of the
+logical_array_return rectangles.
+</para>
+<para>
+<!-- .LP -->
+Note that an
+<structname>XRectangle</structname>
+represents the effective drawing dimensions of the character,
+regardless of the number of font glyphs that are used to draw
+the character or the direction in which the character is drawn.
+If multiple characters map to a single character glyph,
+the dimensions of all the
+<structname>XRectangle</structname>s
+of those characters are the same.
+</para>
+<para>
+<!-- .LP -->
+When the
+<type>XFontSet</type>
+has missing charsets, metrics for each unavailable
+character are taken from the default string returned by
+<function>XCreateFontSet</function>
+so that the metrics represent the text as it will actually be drawn.
+The behavior for an invalid codepoint is undefined.
+</para>
+<para>
+<!-- .LP -->
+If the array_size is too small for the number of characters in the
+supplied text, the functions return zero
+and num_chars_return is set to the number of rectangles required.
+Otherwise, the functions return a nonzero value.
+</para>
+<para>
+<!-- .LP -->
+If the overall_ink_return or overall_logical_return argument is non-NULL,
+<function>XmbTextPerCharExtents</function>
+and
+<function>XwcTextPerCharExtents</function>
+return the maximum extent of the string's metrics to overall_ink_return
+or overall_logical_return, as returned by
+<function>XmbTextExtents</function>
+or
+<function>XwcTextExtents</function>.
+</para>
+</sect2>
+<sect2 id="Drawing_Text_Using_Font_Sets">
+<title>Drawing Text Using Font Sets</title>
+<!-- .XS -->
+<!-- (SN Drawing Text Using Font Sets -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The functions defined in this section
+draw text at a specified location in a drawable.
+They are similar to the functions
+<function>XDrawText</function>,
+<function>XDrawString</function>,
+and
+<function>XDrawImageString</function>
+except that they work with font sets instead of single fonts
+and interpret the text based on the locale of the font set
+instead of treating the bytes of the string as direct font indexes.
+See <link linkend="Drawing_Text">section 8.6</link> for details
+of the use of Graphics Contexts (GCs)
+and possible protocol errors.
+If a
+<errorname>BadFont</errorname>
+error is generated,
+characters prior to the offending character may have been drawn.
+</para>
+<para>
+<!-- .LP -->
+The text is drawn using the fonts loaded for the specified font set;
+the font in the GC is ignored and may be modified by the functions.
+No validation that all fonts conform to some width rule is performed.
+</para>
+<para>
+<!-- .LP -->
+The text functions
+<function>XmbDrawText</function>
+and
+<function>XwcDrawText</function>
+use the following structures:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XmbTextItem</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ char *chars; /* pointer to string */
+ int nchars; /* number of bytes */
+ int delta; /* pixel delta between strings */
+ XFontSet font_set; /* fonts, None means don't change */
+} XmbTextItem;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XwcTextItem</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ wchar_t *chars; /* pointer to wide char string */
+ int nchars; /* number of wide characters */
+ int delta; /* pixel delta between strings */
+ XFontSet font_set; /* fonts, None means don't change */
+} XwcTextItem;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To draw text using multiple font sets in a given drawable, use
+<function>XmbDrawText</function>
+or
+<function>XwcDrawText</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbDrawText</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcDrawText</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbdrawtext'>
+<funcprototype>
+ <funcdef>void <function>XmbDrawText</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XmbTextItem<parameter> *items</parameter></paramdef>
+ <paramdef>int<parameter> nitems</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwcdrawtext'>
+<funcprototype>
+ <funcdef>void <function>XwcDrawText</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>XwcTextItem<parameter> *items</parameter></paramdef>
+ <paramdef>int<parameter> nitems</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>items</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of text items.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nitems</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of text items in the array.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbDrawText</function>
+and
+<function>XwcDrawText</function>
+functions allow complex spacing and font set shifts between text strings.
+Each text item is processed in turn, with the origin of a text
+element advanced in the primary draw direction by the escapement of the
+previous text item.
+A text item delta specifies an additional escapement of the text item
+drawing origin in the primary draw direction.
+A font_set member other than
+<symbol>None</symbol>
+in an item causes the font set to be used for this and subsequent text items
+in the text_items list.
+Leading text items with a font_set member set to
+<symbol>None</symbol>
+will not be drawn.
+</para>
+<para>
+<!-- .LP -->
+<function>XmbDrawText</function>
+and
+<function>XwcDrawText</function>
+do not perform any context-dependent rendering between text segments.
+Clients may compute the drawing metrics by passing each text segment to
+<function>XmbTextExtents</function>
+and
+<function>XwcTextExtents</function>
+or
+<function>XmbTextPerCharExtents</function>
+and
+<function>XwcTextPerCharExtents</function>.
+When the
+<type>XFontSet</type>
+has missing charsets, each unavailable character is drawn
+with the default string returned by
+<function>XCreateFontSet</function>.
+The behavior for an invalid codepoint is undefined.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To draw text using a single font set in a given drawable, use
+<function>XmbDrawString</function>
+or
+<function>XwcDrawString</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbDrawString</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcDrawString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbdrawstring'>
+<funcprototype>
+ <funcdef>void <function>XmbDrawString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwcdrawstring'>
+<funcprototype>
+ <funcdef>void <function>XwcDrawString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_wchars</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_wchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbDrawString</function>
+and
+<function>XwcDrawString</function>
+functions draw the specified text with the foreground pixel.
+When the
+<type>XFontSet</type>
+has missing charsets, each unavailable character is drawn
+with the default string returned by
+<function>XCreateFontSet</function>.
+The behavior for an invalid codepoint is undefined.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To draw image text using a single font set in a given drawable, use
+<function>XmbDrawImageString</function>
+or
+<function>XwcDrawImageString</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbDrawImageString</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcDrawImageString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbdrawimagestring'>
+<funcprototype>
+ <funcdef>void <function>XmbDrawImageString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwcdrawimagestring'>
+<funcprototype>
+ <funcdef>void <function>XwcDrawImageString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>XFontSet<parameter> font_set</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_wchars</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>font_set</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the font set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+<!-- .ds Xy -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the character string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_wchars</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of characters in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbDrawImageString</function>
+and
+<function>XwcDrawImageString</function>
+functions fill a destination rectangle with the background pixel defined
+in the GC and then paint the text with the foreground pixel.
+The filled rectangle is the rectangle returned to overall_logical_return by
+<function>XmbTextExtents</function>
+or
+<function>XwcTextExtents</function>
+for the same text and
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+When the
+<type>XFontSet</type>
+has missing charsets, each unavailable character is drawn
+with the default string returned by
+<function>XCreateFontSet</function>.
+The behavior for an invalid codepoint is undefined.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Input_Methods">
+<title>Input Methods</title>
+<!-- .XS -->
+<!-- (SN Input Methods -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section provides discussions of the following X Input Method
+(<acronym>XIM</acronym>) topics:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Input method overview
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input method management
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input method functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input method values
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input context functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input context values
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input method callback semantics
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Event filtering
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Getting keyboard input
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Input method conventions
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Input_Method_Overview">
+<title>Input Method Overview</title>
+<!-- .XS -->
+<!-- (SN Input Method Overview -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section provides definitions for terms and concepts used
+for internationalized text input and a brief overview of the
+intended use of the mechanisms provided by Xlib.
+</para>
+<para>
+<!-- .LP -->
+A large number of languages in the world use alphabets
+consisting of a small set of symbols (letters) to form words.
+To enter text into a computer in an alphabetic language,
+a user usually has a keyboard on which there exist key symbols corresponding
+to the alphabet.
+Sometimes, a few characters of an alphabetic language are missing
+on the keyboard.
+Many computer users who speak a Latin-alphabet-based language
+only have an English-based keyboard.
+They need to hit a combination of keystrokes
+to enter a character that does not exist directly on the keyboard.
+A number of algorithms have been developed for entering such characters.
+These are known as European input methods, compose input methods,
+or dead-key input methods.
+</para>
+<para>
+<!-- .LP -->
+Japanese is an example of a language with a phonetic symbol set,
+where each symbol represents a specific sound.
+There are two phonetic symbol sets in Japanese: Katakana and Hiragana.
+In general,
+Katakana is used for words that are of foreign origin,
+and Hiragana is used for writing native Japanese words.
+Collectively, the two systems are called Kana.
+Each set consists of 48 characters.
+</para>
+<para>
+<!-- .LP -->
+Korean also has a phonetic symbol set, called Hangul.
+Each of the 24 basic phonetic symbols (14 consonants and 10 vowels)
+represents a specific sound.
+A syllable is composed of two or three parts:
+the initial consonants, the vowels, and the optional last consonants.
+With Hangul,
+syllables can be treated as the basic units on which text processing is done.
+For example,
+a delete operation may work on a phonetic symbol or a syllable.
+Korean code sets include several thousands of these syllables.
+A user types the phonetic symbols that make up the syllables of the words
+to be entered.
+The display may change as each phonetic symbol is entered.
+For example,
+when the second phonetic symbol of a syllable is entered,
+the first phonetic symbol may change its shape and size.
+Likewise, when the third phonetic symbol is entered,
+the first two phonetic symbols may change their shape and size.
+</para>
+<para>
+<!-- .LP -->
+Not all languages rely solely on alphabetic or phonetic systems.
+Some languages, including Japanese and Korean, employ an
+ideographic writing system.
+In an ideographic system, rather than taking a small set of
+symbols and combining them in different ways to create words,
+each word consists of one unique symbol (or, occasionally, several symbols).
+The number of symbols can be very large:
+approximately 50,000 have been identified in Hanzi,
+the Chinese ideographic system.
+</para>
+<para>
+<!-- .LP -->
+Two major aspects of ideographic systems impact their use with computers.
+First, the standard computer character sets in Japan, China, and Korea
+include roughly 8,000 characters,
+while sets in Taiwan have between 15,000 and 30,000 characters.
+This makes it necessary to use more than one byte to represent a character.
+Second, it obviously is impractical to have a keyboard that includes
+all of a given language's ideographic symbols.
+Therefore, a mechanism is required for entering characters
+so that a keyboard with a reasonable number of keys can be used.
+Those input methods are usually based on phonetics,
+but there also exist methods based on the graphical properties of
+characters.
+</para>
+<para>
+<!-- .LP -->
+In Japan, both Kana and the ideographic system Kanji are used.
+In Korea, Hangul and sometimes the ideographic system Hanja are used.
+Now consider entering ideographs in Japan, Korea, China, and Taiwan.
+</para>
+<para>
+<!-- .LP -->
+In Japan, either Kana or English characters are typed and then a region
+is selected (sometimes automatically) for conversion to Kanji.
+Several Kanji characters may have the same phonetic representation.
+If that is the case with the string entered,
+a menu of characters is presented and
+the user must choose the appropriate one.
+If no choice is necessary or a preference has been established,
+the input method does the substitution directly.
+When Latin characters are converted to Kana or Kanji,
+it is called a romaji conversion.
+</para>
+<para>
+<!-- .LP -->
+In Korea, it is usually acceptable to keep Korean text in Hangul form,
+but some people may choose to write Hanja-originated words in Hanja
+rather than in Hangul.
+To change Hangul to Hanja,
+the user selects a region for conversion
+and then follows the same basic method as that described for Japanese.
+</para>
+<para>
+<!-- .LP -->
+Probably because there are well-accepted phonetic writing systems
+for Japanese and Korean,
+computer input methods in these countries for entering ideographs
+are fairly standard.
+Keyboard keys have both English characters and phonetic symbols
+engraved on them, and the user can switch between the two sets.
+</para>
+<para>
+<!-- .LP -->
+The situation is different for Chinese.
+While there is a phonetic system called Pinyin promoted by authorities,
+there is no consensus for entering Chinese text.
+Some vendors use a phonetic decomposition (Pinyin or another),
+others use ideographic decomposition of Chinese words,
+with various implementations and keyboard layouts.
+There are about 16 known methods, none of which is a clear standard.
+</para>
+<para>
+<!-- .LP -->
+Also, there are actually two ideographic sets used:
+Traditional Chinese (the original written Chinese)
+and Simplified Chinese.
+Several years ago,
+the People's Republic of China launched a campaign to simplify
+some ideographic characters and eliminate redundancies altogether.
+Under the plan,
+characters would be streamlined every five years.
+Characters have been revised several times now,
+resulting in the smaller, simpler set that makes up Simplified Chinese.
+</para>
+<sect3 id="Input_Method_Architecture">
+<title>Input Method Architecture</title>
+<!-- .XS -->
+<!-- (SN Input Method Architecture -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+As shown in the previous section,
+there are many different input methods in use today,
+each varying with language, culture, and history.
+A common feature of many input methods is that the user may type
+multiple keystrokes to compose a single character (or set
+of characters).
+The process of composing characters from keystrokes is called
+<emphasis remap='I'>preediting</emphasis>.
+It may require complex algorithms and large dictionaries
+involving substantial computer resources.
+</para>
+<para>
+<!-- .LP -->
+Input methods may require one or more areas in which to show the
+feedback of the actual keystrokes, to propose disambiguation to the
+user, to list dictionaries, and so on.
+The input method areas of concern are as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The <emphasis remap='I'>status</emphasis> area is a logical extension of the
+LEDs that exist on the physical keyboard.
+It is a window that is intended to present the internal state
+of the input method that is critical to the user.
+The status area may consist of text data and bitmaps or some combination.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The <emphasis remap='I'>preedit</emphasis> area displays the
+intermediate text for those languages that are composing prior to
+the client handling the data.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The <emphasis remap='I'>auxiliary</emphasis> area is used for pop-up menus and customizing
+dialogs that may be required for an input method.
+There may be multiple auxiliary areas for an input method.
+Auxiliary areas are managed by the input method independent of the client.
+Auxiliary areas are assumed to be separate dialogs,
+which are maintained by the input method.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+There are various user interaction styles used for preediting.
+The ones supported by Xlib are as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+For <emphasis remap='I'>on-the-spot</emphasis> input methods,
+preediting data will be displayed directly in the application window.
+Application data is moved to allow preedit data to appear
+at the point of insertion.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>Over-the-spot</emphasis> preediting means that the data is displayed in
+a preedit window that is placed over the point of insertion.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>Off-the-spot</emphasis> preediting means that the preedit window is
+inside the application window but not at the point of insertion.
+Often, this type of window is placed at the bottom of the application window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>Root-window</emphasis> preediting refers to input methods that use a preedit
+window that is the child of
+<function>RootWindow</function>.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+It would require a lot of computing resources if portable applications
+had to include input methods for all the languages in the world.
+To avoid this,
+a goal of the Xlib design is to allow an application
+to communicate with an input method placed in a separate process.
+Such a process is called an <emphasis remap='I'>input server</emphasis>.
+The server to which the application should connect is dependent on
+the environment when the application is started up,
+that is, the user language and the actual encoding to be used for it.
+The input method connection is said to be <emphasis remap='I'>locale-dependent</emphasis>.
+It is also user-dependent.
+For a given language, the user can choose, to some extent,
+the user interface style of input method (if choice is possible among
+several).
+</para>
+<para>
+<!-- .LP -->
+Using an input server implies communication overhead,
+but applications can be migrated without relinking.
+Input methods can be implemented either as a
+stub communicating to an input server or as a local library.
+</para>
+<para>
+<!-- .LP -->
+An input method may be based on a <emphasis remap='I'>front-end</emphasis> or a <emphasis remap='I'>back-end</emphasis>
+architecture.
+In a front-end architecture,
+there are two separate connections to the X server:
+keystrokes go directly from the X server to the input method on
+one connection and other events to the regular client connection.
+The input method is then acting as a filter and sends composed strings
+to the client.
+A front-end architecture requires synchronization between the
+two connections to avoid lost key events or locking issues.
+</para>
+<para>
+<!-- .LP -->
+In a back-end architecture,
+a single X server connection is used.
+A dispatching mechanism must decide on this channel to delegate appropriate
+keystrokes to the input method.
+For instance,
+it may retain a Help keystroke for its own purpose.
+In the case where the input method is a separate process (that is, a server),
+there must be a special communication protocol between the back-end client
+and the input server.
+</para>
+<para>
+<!-- .LP -->
+A front-end architecture introduces synchronization issues
+and a filtering mechanism for noncharacter keystrokes
+(Function keys, Help, and so on).
+A back-end architecture sometimes implies more communication overhead
+and more process switching.
+If all three processes (X server, input server, client)
+are running on a single workstation,
+there are two process switches for each keystroke in a back-end
+architecture,
+but there is only one in a front-end architecture.
+</para>
+<para>
+<!-- .LP -->
+The abstraction used by a client to communicate with an input method
+is an opaque data structure represented by the
+<type>XIM</type>
+data type.
+This data structure is returned by the
+<function>XOpenIM</function>
+function, which opens an input method on a given display.
+Subsequent operations on this data structure encapsulate all communication
+between client and input method.
+There is no need for an X client to use any networking library
+or natural language package to use an input method.
+</para>
+<para>
+<!-- .LP -->
+A single input server may be used for one or more languages,
+supporting one or more encoding schemes.
+But the strings returned from an input method will always be encoded
+in the (single) locale associated with the
+<type>XIM</type>
+object.
+</para>
+</sect3>
+<sect3 id="Input_Contexts">
+<title>Input Contexts</title>
+<!-- .XS -->
+<!-- (SN Input Contexts -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides the ability to manage a multi-threaded state for text input.
+A client may be using multiple windows,
+each window with multiple text entry areas,
+and the user possibly switching among them at any time.
+The abstraction for representing the state of a particular input thread
+is called an <emphasis remap='I'>input context</emphasis>.
+The Xlib representation of an input context is an
+<type>XIC</type>.
+</para>
+<para>
+<!-- .LP -->
+An input context is the abstraction retaining the state, properties,
+and semantics of communication between a client and an input method.
+An input context is a combination of an input method, a locale
+specifying the encoding of the character strings to be returned,
+a client window, internal state information,
+and various layout or appearance characteristics.
+The input context concept somewhat matches for input the graphics context
+abstraction defined for graphics output.
+</para>
+<para>
+<!-- .LP -->
+One input context belongs to exactly one input method.
+Different input contexts may be associated with the same input method,
+possibly with the same client window.
+An
+<type>XIC</type>
+is created with the
+<function>XCreateIC</function>
+function, providing an
+<type>XIM</type>
+argument and affiliating the input context to the input method
+for its lifetime.
+When an input method is closed with
+<function>XCloseIM</function>,
+all of its affiliated input contexts should not be used any more
+(and should preferably be destroyed before closing the input method).
+</para>
+<para>
+<!-- .LP -->
+Considering the example of a client window with multiple text entry areas,
+the application programmer could, for example, choose to implement as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+As many input contexts are created as text entry areas, and the client
+will get the input accumulated on each context each time it looks up
+in that context.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A single context is created for a top-level window in the application.
+If such a window contains several text entry areas,
+each time the user moves to another text entry area,
+the client has to indicate changes in the context.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+A range of choices can be made by application designers to use
+either a single or multiple input contexts,
+according to the needs of their application.
+</para>
+</sect3>
+<sect3 id="Getting_Keyboard_Input">
+<title>Getting Keyboard Input</title>
+<!-- .XS -->
+<!-- (SN Getting Keyboard Input -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To obtain characters from an input method,
+a client must call the function
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>
+with an input context created from that input method.
+Both a locale and display are bound to an input method when it is opened,
+and an input context inherits this locale and display.
+Any strings returned by
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>
+will be encoded in that locale.
+</para>
+</sect3>
+<sect3 id="Focus_Management">
+<title>Focus Management</title>
+<!-- .XS -->
+<!-- (SN Focus Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+For each text entry area in which the
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>
+functions are used,
+there will be an associated input context.
+</para>
+<para>
+<!-- .LP -->
+When the application focus moves to a text entry area,
+the application must set the input context focus to the
+input context associated with that area.
+The input context focus is set by calling
+<function>XSetICFocus</function>
+with the appropriate input context.
+</para>
+<para>
+<!-- .LP -->
+Also, when the application focus moves out of a text entry area, the
+application should unset the focus for the associated input context
+by calling
+<function>XUnsetICFocus</function>.
+As an optimization, if
+<function>XSetICFocus</function>
+is called successively on two different input contexts,
+setting the focus on the second
+will automatically unset the focus on the first.
+</para>
+<para>
+<!-- .LP -->
+To set and unset the input context focus correctly,
+it is necessary to track application-level focus changes.
+Such focus changes do not necessarily correspond to X server focus changes.
+</para>
+<para>
+<!-- .LP -->
+If a single input context
+is being used to do input for
+multiple text entry areas, it will also be necessary
+to set the focus window of the
+input context whenever the focus window changes
+(see <link linkend="Focus_Window">section 13.5.6.3</link>).
+</para>
+</sect3>
+<sect3 id="Geometry_Management">
+<title>Geometry Management</title>
+<!-- .XS -->
+<!-- (SN Geometry Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+In most input method architectures
+(on-the-spot being the notable exception),
+the input method will perform the display of its own data.
+To provide better visual locality,
+it is often desirable to have the input method areas embedded within a client.
+To do this,
+the client may need to allocate space for an input method.
+Xlib provides support that allows the size and position of input method
+areas to be provided by a client.
+The input method areas that are supported for geometry management
+are the status area and the preedit area.
+</para>
+<para>
+<!-- .LP -->
+The fundamental concept on which geometry management for input method windows
+is based is the proper division of responsibilities between the
+client (or toolkit) and the input method.
+The division of responsibilities is as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The client is responsible for the geometry of the input method window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The input method is responsible for the contents of the input method window.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+An input method is able to suggest a size to the client,
+but it cannot suggest a placement.
+Also the input method can only suggest a size.
+It does not determine the size,
+and it must accept the size it is given.
+</para>
+<para>
+<!-- .LP -->
+Before a client provides geometry management for an input method,
+it must determine if geometry management is needed.
+The input method indicates the need for geometry management
+by setting
+<symbol>XIMPreeditArea</symbol>
+or
+<symbol>XIMStatusArea</symbol>
+in its
+<structname>XIMStyles</structname>
+value returned by
+<function>XGetIMValues</function>.
+When a client has decided that it will provide geometry management
+for an input method,
+it indicates that decision by setting the
+<symbol>XNInputStyle</symbol>
+value in the
+<type>XIC</type>.
+</para>
+<para>
+<!-- .LP -->
+After a client has established with the input method
+that it will do geometry management,
+the client must negotiate the geometry with the input method.
+The geometry is negotiated by the following steps:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The client suggests an area to the input method by setting the
+<symbol>XNAreaNeeded</symbol>
+value for that area.
+If the client has no constraints for the input method,
+it either will not suggest an area or will set the width and height to zero.
+Otherwise, it will set one of the values.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The client will get the <acronym>XIC</acronym> value
+<symbol>XNAreaNeeded</symbol>.
+The input method will return its suggested size in this value.
+The input method should pay attention to any constraints suggested
+by the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The client sets the <acronym>XIC</acronym> value
+<symbol>XNArea</symbol>
+to inform the input method of the geometry of its window.
+The client should try to honor the geometry requested by the input method.
+The input method must accept this geometry.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Clients doing geometry management must be aware that setting other
+<acronym>XIC</acronym> values may affect the geometry desired by an input method.
+For example,
+<symbol>XNFontSet</symbol>
+and
+<symbol>XNLineSpace</symbol>
+may change the geometry desired by the input method.
+</para>
+<para>
+<!-- .LP -->
+The table of <acronym>XIC</acronym> values
+(see <link linkend="Input_Context_Values">section 13.5.6</link>)
+indicates the values that can cause the desired geometry to change
+when they are set.
+It is the responsibility of the client to renegotiate the geometry
+of the input method window when it is needed.
+</para>
+<para>
+<!-- .LP -->
+In addition,
+a geometry management callback is provided
+by which an input method can initiate a geometry change.
+</para>
+</sect3>
+<sect3 id="Event_Filtering">
+<title>Event Filtering</title>
+<!-- .XS -->
+<!-- (SN Event Filtering -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A filtering mechanism is provided to allow input methods
+to capture X events transparently to clients.
+It is expected that toolkits (or clients) using
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>
+will call this filter at some point in the event processing mechanism
+to make sure that events needed by an input method can be filtered
+by that input method.
+</para>
+<para>
+<!-- .LP -->
+If there were no filter,
+a client could receive and discard events that are necessary
+for the proper functioning of an input method.
+The following provides a few examples of such events:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Expose events on preedit window in local mode.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Events may be used by an input method to communicate with an input server.
+Such input server protocol-related events have to be intercepted
+if one does not want to disturb client code.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Key events can be sent to a filter before they are bound
+to translations such as those the X Toolkit Intrinsics library provides.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Clients are expected to get the <acronym>XIC</acronym> value
+<symbol>XNFilterEvents</symbol>
+and augment the event mask for the client window with that event mask.
+This mask may be zero.
+</para>
+</sect3>
+<sect3 id="Callbacks">
+<title>Callbacks</title>
+<!-- .XS -->
+<!-- (SN Callbacks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When an on-the-spot input method is implemented,
+only the client can insert or delete preedit data in place
+and possibly scroll existing text.
+This means that the echo of the keystrokes has to be achieved
+by the client itself, tightly coupled with the input method logic.
+</para>
+<para>
+<!-- .LP -->
+When the user enters a keystroke,
+the client calls
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>.
+At this point, in the on-the-spot case,
+the echo of the keystroke in the preedit has not yet been done.
+Before returning to the client logic that handles the input characters,
+the look-up function
+must call the echoing logic to insert the new keystroke.
+If the keystrokes entered so far make up a character,
+the keystrokes entered need to be deleted,
+and the composed character will be returned.
+Hence, what happens is that, while being called by client code,
+the input method logic has to call back to the client before it returns.
+The client code, that is, a callback procedure,
+is called from the input method logic.
+</para>
+<para>
+<!-- .LP -->
+There are a number of cases where the input method logic has to
+call back the client.
+Each of those cases is associated with a well-defined callback action.
+It is possible for the client to specify, for each input context,
+what callback is to be called for each action.
+</para>
+<para>
+<!-- .LP -->
+There are also callbacks provided for feedback of status information
+and a callback to initiate a geometry request for an input method.
+</para>
+</sect3>
+<sect3 id="Visible_Position_Feedback_Masks">
+<title>Visible Position Feedback Masks</title>
+<!-- .XS -->
+<!-- (SN Visible Position Feedback Masks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+In the on-the-spot input style, there is a problem when
+attempting to draw preedit strings that are longer than the
+available space. Once the display area is exceeded, it is not
+clear how best to display the preedit string.
+The visible position feedback masks of
+<structname>XIMText</structname>
+help resolve this problem by allowing the input method to specify hints that
+indicate the essential portions of the preedit string.
+For example, such hints can help developers implement
+scrolling of a long preedit string within a short preedit display area.
+</para>
+</sect3>
+<sect3 id="Preedit_String_Management">
+<title>Preedit String Management</title>
+<!-- .XS -->
+<!-- (SN Preedit String Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+As highlighted before, the input method architecture provides
+preediting, which supports a type of preprocessor input composition.
+In this case, composition consists of interpreting a sequence
+of key events and returning a committed string via
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>.
+This provides the basics for input methods.
+</para>
+<para>
+<!-- .LP -->
+In addition to preediting based on key events, a general framework
+is provided to give a client that desires it more advanced preediting based
+on the text within the client. This framework is called
+<emphasis remap='I'>string conversion</emphasis> and is provided using <acronym>XIC</acronym> values.
+The fundamental concept of string conversion
+is to allow the input method to manipulate the client's
+text independent of any user preediting operation.
+</para>
+<para>
+<!-- .LP -->
+The need for string conversion is based on
+language needs and input method capabilities.
+The following are some examples of string conversion:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Transliteration conversion provides language-specific conversions
+within the input method.
+In the case of Korean input, users wish to convert a Hangul string
+into a Hanja string while in preediting, after preediting,
+or in other situations (for example, on a selected string).
+The conversion is triggered when the user
+presses a Hangul-to-Hanja key sequence (which may be input method specific).
+Sometimes the user may want to invoke the conversion after finishing
+preediting or on a user-selected string.
+Thus, the string to be converted is in an application buffer, not in
+the preedit area of the input method. The string conversion services
+allow the client to request this transliteration conversion from the
+input method.
+There are many other transliteration conversions defined for
+various languages, for example, Kana-to-Kanji conversion in Japanese.
+<!-- .sp -->
+The key to remember is that transliteration conversions are triggered
+at the request of the user and returned to the client
+immediately without affecting the preedit area of the input method.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Reconversion of a previously committed string or
+a selected string is supported by many input methods as a
+convenience to the user.
+For example, a user tends to mistype the commit key while
+preediting. In that case, some input methods provide a special
+key sequence to request a ``reconvert'' operation on the
+committed string, similiar to the undo facility provided by most
+text editors.
+Another example is where the user is proofreading a document
+that has some misconversions from preediting and wants to correct
+the misconverted text. Such reconversion is again triggered
+by the user invoking some special action, but reconversions should
+not affect the state of the preedit area.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Context-sensitive conversion is required for some languages
+and input methods that need to retrieve text that surrounds the
+current spot location (cursor position) of the client's buffer.
+Such text is needed when the preediting operation depends on
+some surrounding characters (usually preceding the spot location).
+For example,
+in Thai language input, certain character sequences may be invalid and
+the input method may want to check whether characters constitute a
+valid word. Input methods that do such context-dependent
+checking need to retrieve the characters surrounding the current
+cursor position to obtain complete words.
+<!-- .sp -->
+Unlike other conversions, this conversion is not explicitly
+requested by the user.
+Input methods that provide such context-sensitive conversion
+continuously need to request context from the client, and any change
+in the context of the spot location may affect such conversions.
+The client's context would be needed if the user moves the cursor
+and starts editing again.
+<!-- .sp -->
+For this reason, an input method supporting this type of conversion
+should take notice of when the client calls
+<function>XmbResetIC</function>
+or
+<function>XwcResetIC</function>,
+which is usually an indication of a context change.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Context-sensitive conversions just need a copy of the client's text,
+while other conversions replace the client's text with new text
+to achieve the reconversion or transliteration. Yet in all
+cases the result of a conversion, either immediately or via preediting,
+is returned by the
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>
+functions.
+</para>
+<para>
+<!-- .LP -->
+String conversion support is dependent on the availability of the
+<symbol>XNStringConversion</symbol>
+or
+<symbol>XNStringConversionCallback</symbol>
+<acronym>XIC</acronym> values.
+Because the input method may not support string conversions,
+clients have to query the availability of string conversion
+operations by checking the supported <acronym>XIC</acronym> values list by calling
+<function>XGetIMValues</function>
+with the
+<symbol>XNQueryICValuesList</symbol>
+IM value.
+</para>
+<para>
+<!-- .LP -->
+The difference between these two values is whether the
+conversion is invoked by the client or the input method.
+The
+<symbol>XNStringConversion</symbol>
+<acronym>XIC</acronym> value is used by clients to request
+a string conversion from the input method. The client
+is responsible for determining which events are used
+to trigger the string conversion and whether the string to be
+converted should be copied or deleted. The type of conversion
+is determined by the input method; the client can only
+pass the string to be converted. The client is guaranteed that
+no
+<symbol>XNStringConversionCallback</symbol>
+will be issued when this value is set; thus, the client need
+only set one of these values.
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNStringConversionCallback</symbol>
+<acronym>XIC</acronym> value is used by the client to notify the input method that
+it will accept requests from the input method for string conversion.
+If this value is set,
+it is the input method's responsibility to determine which
+events are used to trigger the string conversion.
+When such events occur, the input method issues a call to the
+client-supplied procedure to retrieve the string to be converted. The client's
+callback procedure is notified whether to copy or delete the string and
+is provided with hints as to the amount of text needed.
+The
+<structname>XIMStringConversionCallbackStruct</structname>
+specifies which text should be passed back to the input method.
+</para>
+<para>
+<!-- .LP -->
+Finally, the input method may call the client's
+<symbol>XNStringConversionCallback</symbol>
+procedure multiple times if the string returned from the callback is
+not sufficient to perform a successful conversion. The arguments
+to the client's procedure allow the input method to define a
+position (in character units) relative to the client's cursor position
+and the size of the text needed. By varying the position and size of
+the desired text in subsequent callbacks, the input method can retrieve
+additional text.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+</sect2>
+<sect2 id="Input_Method_Management">
+<title>Input Method Management</title>
+<!-- .XS -->
+<!-- (SN Input Method Management -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The interface to input methods might appear to be simply creating
+an input method
+(<function>XOpenIM</function>)
+and freeing an input method
+(<function>XCloseIM</function>).
+However, input methods may
+require complex communication with input method servers (IM servers),
+for example:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+If the X server, IM server, and X clients are started asynchronously,
+some clients may attempt to connect to the IM server before it is
+fully operational, and fail.
+Therefore, some mechanism is needed to allow clients to detect when an IM
+server has started.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+It is up to clients to decide what should be done when an IM server is
+not available (for example, wait, or use some other IM server).
+</para>
+<para>
+<!-- .LP -->
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Some input methods may allow the underlying IM server to be switched.
+Such customization may be desired without restarting the entire client.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+To support management of input methods in these cases, the following
+functions are provided:
+</para>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><function>XRegisterIMInstantiateCallback</function></entry>
+ <entry>This function allows clients to register a callback procedure
+ to be called when Xlib detects that an IM server is up and available.</entry>
+ </row>
+ <row>
+ <entry><function>XOpenIM</function></entry>
+ <entry>A client calls this function as a result of the callback procedure
+ being called.</entry>
+ </row>
+ <row>
+ <entry><function>XSetIMValues</function>, <function>XSetICValues</function></entry>
+ <entry>These functions use the <acronym>XIM</acronym> and <acronym>XIC</acronym> values,
+ <symbol>XNDestroyCallback</symbol>,
+ to allow a client
+ to register a callback procedure to be called when Xlib detects that
+ an IM server that was associated with an opened
+ input method is no longer available.
+ In addition, this function can be used to switch IM servers for those input
+ methods that support such functionality. The IM value for switching IM
+ servers is implementation-dependent; see the description below about
+ switching IM servers.</entry>
+ </row>
+ <row>
+ <entry><function>XUnregisterIMInstantiateCallback</function></entry>
+ <entry>This function removes a callback procedure registered by the client.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+Input methods that support switching of IM servers may exhibit some
+side-effects:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The input method will ensure that any new IM server supports any of the
+input styles being used by input contexts already associated with the
+input method.
+However, the list of supported input styles may be different.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Geometry management requests on previously created input contexts
+may be initiated by the new IM server.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+</para>
+<sect3 id="Hot_Keys">
+<title>Hot Keys</title>
+<!-- .XS -->
+<!-- (SN Hot Keys -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Some clients need to guarantee which keys can be used to escape from the
+input method, regardless of the input method state;
+for example, the client-specific Help key or the keys to move the
+input focus.
+The HotKey mechanism allows clients
+to specify a set of keys for this purpose. However, the input
+method might not allow clients to specify hot keys.
+Therefore, clients have to query support of hot keys by checking the
+supported <acronym>XIC</acronym> values list by calling
+<function>XGetIMValues</function>
+with the
+<symbol>XNQueryICValuesList</symbol>
+IM value.
+When the hot keys specified conflict with the key bindings of the
+input method, hot keys take precedence over the key bindings of the input
+method.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Preedit_State_Operation">
+<title>Preedit State Operation</title>
+<!-- .XS -->
+<!-- (SN Preedit State Operation -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An input method may have several internal states, depending on its
+implementation and the locale. However, one state that is
+independent of locale and implementation is whether the input method
+is currently performing a preediting operation.
+Xlib provides the ability for an application to manage the preedit state
+programmatically. Two methods are provided for
+retrieving the preedit state of an input context.
+One method is to query the state by calling
+<function>XGetICValues</function>
+with the
+<symbol>XNPreeditState</symbol>
+<acronym>XIC</acronym> value.
+Another method is to receive notification whenever
+the preedit state is changed. To receive such notification,
+an application needs to register a callback by calling
+<function>XSetICValues</function>
+with the
+<symbol>XNPreeditStateNotifyCallback</symbol>
+<acronym>XIC</acronym> value.
+In order to change the preedit state programmatically, an application
+needs to call
+<function>XSetICValues</function>
+with
+<symbol>XNPreeditState</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Availability of the preedit state is input method dependent. The input
+method may not provide the ability to set the state or to
+retrieve the state programmatically. Therefore, clients have to
+query availability of preedit state operations by checking the
+supported <acronym>XIC</acronym> values list by calling
+<function>XGetIMValues</function>
+with the
+<symbol>XNQueryICValuesList</symbol>
+IM value.
+</para>
+</sect3>
+</sect2>
+<sect2 id="Input_Method_Functions">
+<title>Input Method Functions</title>
+<!-- .XS -->
+<!-- (SN Input Method Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To open a connection, use
+<function>XOpenIM</function>.
+</para>
+<indexterm significance="preferred"><primary>XOpenIM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xopenim'>
+<funcprototype>
+ <funcdef>XIM <function>XOpenIM</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> db</parameter></paramdef>
+ <paramdef>char<parameter> *res_name</parameter></paramdef>
+ <paramdef>char<parameter> *res_class</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full resource name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full class name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XOpenIM</function>
+function opens an input method,
+matching the current locale and modifiers specification.
+Current locale and modifiers are bound to the input method at opening time.
+The locale associated with an input method cannot be changed dynamically.
+This implies that the strings returned by
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>,
+for any input context affiliated with a given input method,
+will be encoded in the locale current at the time the input method is opened.
+</para>
+<para>
+<!-- .LP -->
+The specific input method to which this call will be routed
+is identified on the basis of the current locale.
+<function>XOpenIM</function>
+will identify a default input method corresponding to the
+current locale.
+That default can be modified using
+<function>XSetLocaleModifiers</function>
+for the input method modifier.
+</para>
+<para>
+<!-- .LP -->
+The db argument is the resource database to be used by the input method
+for looking up resources that are private to the input method.
+It is not intended that this database be used to look
+up values that can be set as IC values in an input context.
+If db is NULL,
+no database is passed to the input method.
+</para>
+<para>
+<!-- .LP -->
+The res_name and res_class arguments specify the resource name
+and class of the application.
+They are intended to be used as prefixes by the input method
+when looking up resources that are common to all input contexts
+that may be created for this input method.
+The characters used for resource names and classes must be in the
+X Portable Character Set.
+The resources looked up are not fully specified
+if res_name or res_class is NULL.
+</para>
+<para>
+<!-- .LP -->
+The res_name and res_class arguments are not assumed to exist beyond
+the call to
+<function>XOpenIM</function>.
+The specified resource database is assumed to exist for the lifetime
+of the input method.
+</para>
+<para>
+<!-- .LP -->
+<function>XOpenIM</function>
+returns NULL if no input method could be opened.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To close a connection, use
+<function>XCloseIM</function>.
+</para>
+<indexterm significance="preferred"><primary>XCloseIM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcloseim'>
+<funcprototype>
+ <funcdef>Status <function>XCloseIM</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCloseIM</function>
+function closes the specified input method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set input method attributes, use
+<function>XSetIMValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetIMValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetimvalues'>
+<funcprototype>
+ <funcdef>char *<function>XSetIMValues</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+<!-- .ds Al \ to set <acronym>XIM</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable-length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetIMValues</function>
+function presents a variable argument list programming interface
+for setting attributes of the specified input method.
+It returns NULL if it succeeds;
+otherwise,
+it returns the name of the first argument that could not be set.
+Xlib does not attempt to set arguments from the supplied list that
+follow the failed argument;
+all arguments in the list preceding the failed argument have been set
+correctly.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To query an input method, use
+<function>XGetIMValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetIMValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetimvalues'>
+<funcprototype>
+ <funcdef>char *<function>XGetIMValues</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+<!-- .ds Al \ to get XIM values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetIMValues</function>
+function presents a variable argument list programming interface
+for querying properties or features of the specified input method.
+This function returns NULL if it succeeds;
+otherwise,
+it returns the name of the first argument that could not be obtained.
+</para>
+<para>
+<!-- .LP -->
+Each <acronym>XIM</acronym> value argument (following a name) must point to
+a location where the <acronym>XIM</acronym> value is to be stored.
+That is, if the <acronym>XIM</acronym> value is of type T,
+the argument must be of type T*.
+If T itself is a pointer type,
+then
+<function>XGetIMValues</function>
+allocates memory to store the actual data,
+and the client is responsible for freeing this data by calling
+<function>XFree</function>
+with the returned pointer.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the display associated with an input method, use
+<function>XDisplayOfIM</function>.
+</para>
+<indexterm significance="preferred"><primary>XDisplayOfIM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdisplayofim'>
+<funcprototype>
+ <funcdef>Display *<function>XDisplayOfIM</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDisplayOfIM</function>
+function returns the display associated with the specified input method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the locale associated with an input method, use
+<function>XLocaleOfIM</function>.
+</para>
+<indexterm significance="preferred"><primary>XLocaleOfIM</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlocaleofim'>
+<funcprototype>
+ <funcdef>char *<function>XLocaleOfIM</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLocaleOfIM</function>
+function returns the locale associated with the specified input method.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To register an input method instantiate callback, use
+<function>XRegisterIMInstantiateCallback</function>.
+</para>
+<indexterm significance="preferred"><primary>XRegisterIMInstantiateCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xregisteriminstantiatecallback'>
+<funcprototype>
+ <funcdef>Bool <function>XRegisterIMInstantiateCallback</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> db</parameter></paramdef>
+ <paramdef>char<parameter> *res_name</parameter></paramdef>
+ <paramdef>char<parameter> *res_class</parameter></paramdef>
+ <paramdef>XIMProc<parameter> callback</parameter></paramdef>
+ <paramdef>XPointer<parameter> *client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full resource name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full class name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>callback</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the input method instantiate callback.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRegisterIMInstantiateCallback</function>
+function registers a callback to be invoked whenever a new input method
+becomes available for the specified display that matches the current
+locale and modifiers.
+</para>
+<para>
+<!-- .LP -->
+The function returns
+<symbol>True</symbol>
+ if it succeeds; otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The generic prototype is as follows:
+</para>
+<indexterm significance="preferred"><primary>IMInstantiateCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='iminstantiatecallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>IMInstantiateCallback</replaceable></function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+To unregister an input method instantiation callback, use
+<function>XUnregisterIMInstantiateCallback</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnregisterIMInstantiateCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunregisteriminstantiatecallback'>
+<funcprototype>
+ <funcdef>Bool <function>XUnregisterIMInstantiateCallback</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> db</parameter></paramdef>
+ <paramdef>char<parameter> *res_name</parameter></paramdef>
+ <paramdef>char<parameter> *res_class</parameter></paramdef>
+ <paramdef>XIMProc<parameter> callback</parameter></paramdef>
+ <paramdef>XPointer<parameter> *client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full resource name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>res_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the full class name of the application.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>callback</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a pointer to the input method instantiate callback.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnregisterIMInstantiateCallback</function>
+function removes an input method instantiation callback previously
+registered.
+The function returns
+<symbol>True</symbol>
+if it succeeds; otherwise, it returns
+<symbol>False</symbol>.
+</para>
+</sect2>
+<sect2 id="Input_Method_Values">
+<title>Input Method Values</title>
+<!-- .XS -->
+<!-- (SN Input Method Values -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following table describes how <acronym>XIM</acronym> values are interpreted
+by an input method.
+The first column lists the <acronym>XIM</acronym> values.
+The second column indicates how each of the <acronym>XIM</acronym> values
+are treated by that input style.
+</para>
+<para>
+<!-- .LP -->
+</para>
+<para>
+<!-- .LP -->
+The following keys apply to this table.
+</para>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'>Key</entry>
+ <entry align='left'>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>D</entry>
+ <entry>This value may be set using
+ <function>XSetIMValues</function>.
+ If it is not set,
+ a default is provided.</entry>
+ </row>
+ <row>
+ <entry>S</entry>
+ <entry>This value may be set using <function>XSetIMValues</function>.</entry>
+ </row>
+ <row>
+ <entry>G</entry>
+ <entry>This value may be read using <function>XGetIMValues</function>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para></para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'><acronym>XIM</acronym> Value</entry>
+ <entry align='left'>Key</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><symbol>XNQueryInputStyle</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNResourceName</symbol></entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNResourceClass</symbol></entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNDestroyCallback</symbol></entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNQueryIMValuesList</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNQueryICValuesList</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNVisiblePosition</symbol></entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><symbol>XNR6PreeditCallback</symbol></entry>
+ <entry>D-S-G</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+<symbol>XNR6PreeditCallback</symbol>
+is obsolete and its use is not recommended
+(see <link linkend="Preedit_Callback_Behavior">section 13.5.4.6</link>).
+</para>
+
+<sect3 id="Query_Input_Style">
+<title>Query Input Style</title>
+<!-- .XS -->
+<!-- (SN Query Input Style -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A client should always query the input method to determine which input
+styles are supported.
+The client should then find an input style it is capable of supporting.
+</para>
+<para>
+<!-- .LP -->
+If the client cannot find an input style that it can support,
+it should negotiate with the user the continuation of the program
+(exit, choose another input method, and so on).
+</para>
+<para>
+<!-- .LP -->
+The argument value must be a pointer to a location
+where the returned value will be stored.
+The returned value is a pointer to a structure of type
+<structname>XIMStyles</structname>.
+Clients are responsible for freeing the
+<structname>XIMStyles</structname>
+structure.
+To do so, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMStyles</structname>
+structure is defined as follows:
+</para>
+
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMStyle</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditArea</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditCallbacks</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditPosition</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditNothing</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditNone</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusArea</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusCallbacks</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusNothing</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusNone</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStyles</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+typedef unsigned long XIMStyle;
+
+
+#define XIMPreeditArea 0x0001L
+#define XIMPreeditCallbacks 0x0002L
+#define XIMPreeditPosition 0x0004L
+#define XIMPreeditNothing 0x0008L
+#define XIMPreeditNone 0x0010L
+
+#define XIMStatusArea 0x0100L
+#define XIMStatusCallbacks 0x0200L
+#define XIMStatusNothing 0x0400L
+#define XIMStatusNone 0x0800L
+
+typedef struct {
+ unsigned short count_styles;
+ XIMStyle * supported_styles;
+} XIMStyles;
+
+</literallayout>
+
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+An
+<structname>XIMStyles</structname>
+structure contains the number of input styles supported
+in its count_styles field.
+This is also the size of the supported_styles array.
+</para>
+<para>
+<!-- .LP -->
+The supported styles is a list of bitmask combinations,
+which indicate the combination of styles for each of the areas supported.
+These areas are described later.
+Each element in the list should select one of the bitmask values for
+each area.
+The list describes the complete set of combinations supported.
+Only these combinations are supported by the input method.
+</para>
+<para>
+<!-- .LP -->
+The preedit category defines what type of support is provided
+by the input method for preedit information.
+</para>
+<indexterm significance="preferred"><primary>XIMPreeditArea</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditPosition</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditCallbacks</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditNothing</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditNone</primary></indexterm>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>XIMPreeditArea</symbol></entry>
+ <entry>If chosen,
+ the input method would require the client to provide some area values
+ for it to do its preediting.
+ Refer to <acronym>XIC</acronym> values
+ <symbol>XNArea</symbol>
+ and
+ <symbol>XNAreaNeeded</symbol>.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMPreeditPosition</symbol></entry>
+ <entry>If chosen,
+ the input method would require the client to provide positional values.
+ Refer to <acronym>XIC</acronym> values
+ <symbol>XNSpotLocation</symbol>
+ and
+ <symbol>XNFocusWindow</symbol>.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMPreeditCallbacks</symbol></entry>
+ <entry>If chosen,
+ the input method would require the client to define the set of preedit callbacks.
+ Refer to <acronym>XIC</acronym> values
+ <symbol>XNPreeditStartCallback</symbol>,
+ <symbol>XNPreeditDoneCallback</symbol>,
+ <symbol>XNPreeditDrawCallback</symbol>,
+ and
+ <symbol>XNPreeditCaretCallback</symbol>.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMPreeditNothing</symbol></entry>
+ <entry>If chosen, the input method can function without any preedit values.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMPreeditNone</symbol></entry>
+ <entry>The input method does not provide any preedit feedback.
+ Any preedit value is ignored.
+ This style is mutually exclusive with the other preedit styles.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+The status category defines what type of support is provided
+by the input method for status information.
+</para>
+<indexterm significance="preferred"><primary>XIMStatusArea</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusCallbacks</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusNothing</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusNone</primary></indexterm>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>XIMStatusArea</symbol></entry>
+ <entry>The input method requires the client to provide
+ some area values for it to do its status feedback.
+ See
+ <symbol>XNArea</symbol>
+ and
+ <symbol>XNAreaNeeded</symbol>.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMStatusCallbacks</symbol></entry>
+ <entry>The input method requires the client to define the set of status callbacks,
+ <symbol>XNStatusStartCallback</symbol>,
+ <symbol>XNStatusDoneCallback</symbol>,
+ and
+ <symbol>XNStatusDrawCallback</symbol>.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMStatusNothing</symbol></entry>
+ <entry>The input method can function without any status values.</entry>
+ </row>
+ <row>
+ <entry><symbol>XIMStatusNone</symbol></entry>
+ <entry>The input method does not provide any status feedback.
+ If chosen, any status value is ignored.
+ This style is mutually exclusive with the other status styles.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+</sect3>
+<sect3 id="Resource_Name_and_Class_c">
+<title>Resource Name and Class</title>
+<!-- .XS -->
+<!-- (SN Resource Name and Class -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNResourceName</symbol>
+and
+<symbol>XNResourceClass</symbol>
+arguments are strings that specify the full name and class
+used by the input method.
+These values should be used as prefixes for the name and class
+when looking up resources that may vary according to the input method.
+If these values are not set,
+the resources will not be fully specified.
+</para>
+<para>
+<!-- .LP -->
+It is not intended that values that can be set as <acronym>XIM</acronym> values be
+set as resources.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Destroy_Callback">
+<title>Destroy Callback</title>
+<!-- .XS -->
+<!-- (SN Destroy Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNDestroyCallback</symbol>
+argument is a pointer to a structure of type
+<structname>XIMCallback</structname>.
+<symbol>XNDestroyCallback</symbol>
+is triggered when an input method stops its service for any reason.
+After the callback is invoked, the input method is closed and the
+associated input context(s) are destroyed by Xlib.
+Therefore, the client should not call
+<function>XCloseIM</function>
+or
+<function>XDestroyIC</function>.
+</para>
+<para>
+<!-- .LP -->
+The generic prototype of this callback function is as follows:
+</para>
+<indexterm significance="preferred"><primary>DestroyCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='destroycallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>DestroyCallback</replaceable></function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+A DestroyCallback is always called with a NULL call_data argument.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Query_IM_IC_Values_List">
+<title>Query IM/IC Values List</title>
+<!-- .XS -->
+<!-- (SN Query IM/IC Values List -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<symbol>XNQueryIMValuesList</symbol>
+and
+<symbol>XNQueryICValuesList</symbol>
+are used to query about <acronym>XIM</acronym> and <acronym>XIC</acronym> values supported by the input method.
+</para>
+<para>
+<!-- .LP -->
+The argument value must be a pointer to a location where the returned
+value will be stored. The returned value is a pointer to a structure
+of type
+<structname>XIMValuesList</structname>.
+Clients are responsible for freeing the
+<structname>XIMValuesList</structname>
+structure.
+To do so, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMValuesList</structname>
+structure is defined as follows:
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ unsigned short count_values;
+ char **supported_values;
+} XIMValuesList;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect3>
+<sect3 id="Visible_Position">
+<title>Visible Position</title>
+<!-- .XS -->
+<!-- (SN Visible Position -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNVisiblePosition</symbol>
+argument indicates whether the visible position masks of
+<type>XIMFeedback</type>
+in
+<structname>XIMText</structname>
+are available.
+</para>
+<para>
+<!-- .LP -->
+The argument value must be a pointer to a location where the returned
+value will be stored. The returned value is of type
+<type>Bool</type>.
+If the returned value is
+<symbol>True</symbol>,
+the input method uses the visible position masks of
+<type>XIMFeedback</type>
+in
+<structname>XIMText</structname>;
+otherwise, the input method does not use the masks.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIM</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryIMValuesList</symbol>
+before using this argument.
+If the
+<symbol>XNVisiblePosition</symbol>
+does not exist in the IM values list returned from
+<symbol>XNQueryIMValuesList</symbol>,
+the visible position masks of
+<type>XIMFeedback</type>
+in
+<structname>XIMText</structname>
+are not used to indicate the visible position.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Preedit_Callback_Behavior">
+<title>Preedit Callback Behavior</title>
+<!-- .XS -->
+<!-- (SN Preedit Callback Behavior -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNR6PreeditCallback</symbol>
+argument originally included in the X11R6 specification has been
+deprecated.\(dg
+<!-- .\" If XNR6PreeditCallbackBehavior is not deprecated, then its type -->
+<!-- .\" should be changed from *Bool to Bool. -->
+<!-- .FS \(dg -->
+During formulation of the X11R6 specification, the behavior of
+the R6 PreeditDrawCallbacks was going to differ significantly from
+that of the R5 callbacks.
+Late changes to the specification converged the R5 and R6 behaviors,
+eliminating the need for
+<symbol>XNR6PreeditCallback</symbol>.
+Unfortunately, this argument was not removed from the R6 specification
+before it was published.
+<!-- .FE -->
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNR6PreeditCallback</symbol>
+argument indicates whether the behavior of preedit callbacks regarding
+<structname>XIMPreeditDrawCallbackStruct</structname>
+values follows Release 5 or Release 6 semantics.
+</para>
+<para>
+<!-- .LP -->
+The value is of type
+<type>Bool</type>.
+When querying for
+<symbol>XNR6PreeditCallback</symbol>,
+if the returned value is
+<symbol>True</symbol>,
+the input method uses the Release 6 behavior;
+otherwise, it uses the Release 5 behavior.
+The default value is
+<symbol>False</symbol>.
+In order to use Release 6 semantics, the value of
+<symbol>XNR6PreeditCallback</symbol>
+must be set to
+<symbol>True</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIM</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryIMValuesList</symbol>
+before using this argument.
+If the
+<symbol>XNR6PreeditCallback</symbol>
+does not exist in the IM values list returned from
+<symbol>XNQueryIMValuesList</symbol>,
+the PreeditCallback behavior is Release 5 semantics.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+</sect2>
+<sect2 id="Input_Context_Functions">
+<title>Input Context Functions</title>
+<!-- .XS -->
+<!-- (SN Input Context Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An input context is an abstraction that is used to contain both the data
+required (if any) by an input method and the information required
+to display that data.
+There may be multiple input contexts for one input method.
+The programming interfaces for creating, reading, or modifying
+an input context use a variable argument list.
+The name elements of the argument lists are referred to as <acronym>XIC</acronym> values.
+It is intended that input methods be controlled by these <acronym>XIC</acronym> values.
+As new <acronym>XIC</acronym> values are created,
+they should be registered with the X Consortium.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create an input context, use
+<function>XCreateIC</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateIC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreateic'>
+<funcprototype>
+ <funcdef>XIC <function>XCreateIC</function></funcdef>
+ <paramdef>XIM<parameter> im</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>im</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+<!-- .ds Al \ to set <acronym>XIC</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateIC</function>
+function creates a context within the specified input method.
+</para>
+<para>
+<!-- .LP -->
+Some of the arguments are mandatory at creation time, and
+the input context will not be created if those arguments are not provided.
+The mandatory arguments are the input style and the set of text callbacks
+(if the input style selected requires callbacks).
+All other input context values can be set later.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateIC</function>
+returns a NULL value if no input context could be created.
+A NULL value could be returned for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A required argument was not set.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A read-only argument was set (for example,
+<symbol>XNFilterEvents</symbol>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The input method encountered an input method implementation-dependent error.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XCreateIC</function>
+can generate
+<errorname>BadAtom</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy an input context, use
+<function>XDestroyIC</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyIC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroyic'>
+<funcprototype>
+ <funcdef>void <function>XDestroyIC</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<function>XDestroyIC</function>
+destroys the specified input context.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To communicate to and synchronize with input method
+for any changes in keyboard focus from the client side,
+use
+<function>XSetICFocus</function>
+and
+<function>XUnsetICFocus</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetICFocus</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xseticfocus'>
+<funcprototype>
+ <funcdef>void <function>XSetICFocus</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetICFocus</function>
+function allows a client to notify an input method that the focus window
+attached to the specified input context has received keyboard focus.
+The input method should take action to provide appropriate feedback.
+Complete feedback specification is a matter of user interface policy.
+</para>
+<para>
+<!-- .LP -->
+Calling
+<function>XSetICFocus</function>
+does not affect the focus window value.
+</para>
+<indexterm significance="preferred"><primary>XUnsetICFocus</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunseticfocus'>
+<funcprototype>
+ <funcdef>void <function>XUnsetICFocus</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnsetICFocus</function>
+function allows a client to notify an input method that the specified input context
+has lost the keyboard focus and that no more input is expected on the focus window
+attached to that input context.
+The input method should take action to provide appropriate feedback.
+Complete feedback specification is a matter of user interface policy.
+</para>
+<para>
+<!-- .LP -->
+Calling
+<function>XUnsetICFocus</function>
+does not affect the focus window value;
+the client may still receive
+events from the input method that are directed to the focus window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To reset the state of an input context to its initial state, use
+<function>XmbResetIC</function>
+or
+<function>XwcResetIC</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbResetIC</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcResetIC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbresetic'>
+<funcprototype>
+ <funcdef>char *<function>XmbResetIC</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwcresetic'>
+<funcprototype>
+ <funcdef>wchar_t *<function>XwcResetIC</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When
+<symbol>XNResetState</symbol>
+is set to
+<symbol>XIMInitialState</symbol>,
+<function>XmbResetIC</function>
+and
+<function>XwcResetIC</function>
+reset an input context to its initial state;
+when
+<symbol>XNResetState</symbol>
+is set to
+<symbol>XIMPreserveState</symbol>,
+the current input context state is preserved.
+In both cases, any input pending on that context is deleted.
+The input method is required to clear the preedit area, if any,
+and update the status accordingly.
+Calling
+<function>XmbResetIC</function>
+or
+<function>XwcResetIC</function>
+does not change the focus.
+</para>
+<para>
+<!-- .LP -->
+The return value of
+<function>XmbResetIC</function>
+is its current preedit string as a multibyte string.
+If there is any preedit text drawn or visible to the user,
+then these procedures must return a non-NULL string.
+If there is no visible preedit text,
+then it is input method implementation-dependent
+whether these procedures return a non-NULL string or NULL.
+</para>
+<para>
+<!-- .LP -->
+The client should free the returned string by calling
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the input method associated with an input context, use
+<function>XIMOfIC</function>.
+</para>
+<indexterm significance="preferred"><primary>XIMOfIC</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='ximofic'>
+<funcprototype>
+ <funcdef>XIM <function>XIMOfIC</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XIMOfIC</function>
+function returns the input method associated with the specified input context.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Xlib provides two functions for setting and reading <acronym>XIC</acronym> values, respectively,
+<function>XSetICValues</function>
+and
+<function>XGetICValues</function>.
+Both functions have a variable-length argument list.
+In that argument list, any <acronym>XIC</acronym> value's name must be denoted
+with a character string using the X Portable Character Set.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set <acronym>XIC</acronym> values, use
+<function>XSetICValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetICValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xseticvalues'>
+<funcprototype>
+ <funcdef>char *<function>XSetICValues</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+<!-- .ds Al \ to set <acronym>XIC</acronym> values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetICValues</function>
+function returns NULL if no error occurred;
+otherwise,
+it returns the name of the first argument that could not be set.
+An argument might not be set for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The argument is read-only (for example,
+<symbol>XNFilterEvents</symbol>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An implementation-dependent error occurs.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Each value to be set must be an appropriate datum,
+matching the data type imposed by the semantics of the argument.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetICValues</function>
+can generate
+<errorname>BadAtom</errorname>,
+<errorname>BadColor</errorname>,
+<errorname>BadCursor</errorname>,
+<errorname>BadPixmap</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain <acronym>XIC</acronym> values, use
+<function>XGetICValues</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetICValues</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeticvalues'>
+<funcprototype>
+ <funcdef>char *<function>XGetICValues</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+<!-- .ds Al \ to get XIC values -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ ...
+ </term>
+ <listitem>
+ <para>
+Specifies the variable length argument list(Al.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetICValues</function>
+function returns NULL if no error occurred; otherwise,
+it returns the name of the first argument that could not be obtained.
+An argument could not be obtained for any of the following reasons:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The argument name is not recognized.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The input method encountered an implementation-dependent error.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+Each IC attribute value argument (following a name) must point to
+a location where the IC value is to be stored.
+That is, if the IC value is of type T,
+the argument must be of type T*.
+If T itself is a pointer type,
+then
+<function>XGetICValues</function>
+allocates memory to store the actual data,
+and the client is responsible for freeing this data by calling
+<function>XFree</function>
+with the returned pointer.
+The exception to this rule is for an IC value of type
+<type>XVaNestedList</type>
+(for preedit and status attributes).
+In this case, the argument must also be of type
+<type>XVaNestedList</type>.
+Then, the rule of changing type T to T* and freeing the allocated data
+applies to each element of the nested list.
+</para>
+</sect2>
+<sect2 id="Input_Context_Values">
+<title>Input Context Values</title>
+<!-- .XS -->
+<!-- (SN Input Context Values -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following tables describe how <acronym>XIC</acronym> values are interpreted
+by an input method depending on the input style chosen by the
+user.
+</para>
+<para>
+<!-- .LP -->
+The first column lists the <acronym>XIC</acronym> values.
+The second column indicates which values are involved in affecting,
+negotiating, and setting the geometry of the input method windows.
+The subentries under the third column indicate the different
+input styles that are supported.
+Each of these columns indicates how each of the <acronym>XIC</acronym> values
+are treated by that input style.
+</para>
+<para>
+<!-- .LP -->
+The following keys apply to these tables.
+</para>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <thead>
+ <row>
+ <entry align='left'>Key</entry>
+ <entry align='left'>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>C</entry>
+ <entry>This value must be set with <function>XCreateIC</function>.</entry>
+ </row>
+ <row>
+ <entry>D</entry>
+ <entry>This value may be set using
+ <function>XCreateIC</function>.>
+ If it is not set,>
+ a default is provided.</entry>
+ </row>
+ <row>
+ <entry>G</entry>
+ <entry>This value may be read using
+ <function>XGetICValues</function>.</entry>
+ </row>
+ <row>
+ <entry>GN</entry>
+ <entry>This value may cause geometry negotiation when its value is set by means of
+ <function>XCreateIC</function>
+ or
+ <function>XSetICValues</function>.</entry>
+ </row>
+ <row>
+ <entry>GR</entry>
+ <entry>This value will be the response of the input method when any
+ GN value is changed.</entry>
+ </row>
+ <row>
+ <entry>GS</entry>
+ <entry>This value will cause the geometry of the input method window to be set.</entry>
+ </row>
+ <row>
+ <entry>O</entry>
+ <entry>This value must be set once and only once.
+ It need not be set at create time.</entry>
+ </row>
+ <row>
+ <entry>S</entry>
+ <entry>This value may be set with
+ <function>XSetICValues</function>.</entry>
+ </row>
+ <row>
+ <entry>Ignored</entry>
+ <entry>This value is ignored by the input method for the given input style.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para></para>
+
+<!-- .LP -->
+<informaltable>
+ <tgroup cols='7'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <colspec colname='c4'/>
+ <colspec colname='c5'/>
+ <colspec colname='c6'/>
+ <colspec colname='c7'/>
+ <thead>
+ <row>
+ <entry><acronym>XIC</acronym> Value</entry>
+ <entry>Geometry Mangement</entry>
+ <entry>Preedit Callback</entry>
+ <entry>Preedit Position</entry>
+ <entry>Input Style Preedit Area</entry>
+ <entry>Preedit Nothing</entry>
+ <entry>Preedit None</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Input Style</entry>
+ <entry></entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ </row>
+ <row>
+ <entry>Client Window</entry>
+ <entry></entry>
+ <entry>O-G</entry>
+ <entry>O-G</entry>
+ <entry>O-G</entry>
+ <entry>O-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Focus Window</entry>
+ <entry>GN</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Resource Name</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Resource Class</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Geometry Callback</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Filter Events</entry>
+ <entry></entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Destroy Callback</entry>
+ <entry></entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry>String Conversion Callback</entry>
+ <entry></entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ </row>
+ <row>
+ <entry>String Conversion</entry>
+ <entry></entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ </row>
+ <row>
+ <entry>Reset State</entry>
+ <entry></entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>HotKey</entry>
+ <entry></entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>HotKeyState</entry>
+ <entry></entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry><function>Preedit</function></entry>
+ </row>
+ <row>
+ <entry>Area</entry>
+ <entry>GS</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Area Needed</entry>
+ <entry>GN-GR</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Spot Location</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Colormap</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Foreground</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Background</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Background Pixmap</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Font Set</entry>
+ <entry>GN</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Line Spacing</entry>
+ <entry>GN</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Cursor</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Preedit State</entry>
+ <entry></entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Preedit State Notify Callback</entry>
+ <entry></entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Preedit Callbacks</entry>
+ <entry></entry>
+ <entry>C-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para></para>
+
+<!-- .LP -->
+<informaltable>
+ <tgroup cols='6'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <colspec colname='c4'/>
+ <colspec colname='c5'/>
+ <colspec colname='c6'/>
+ <thead>
+ <row>
+ <entry><acronym>XIC</acronym> Value</entry>
+ <entry>Geomentry Management</entry>
+ <entry>Status Callback</entry>
+ <entry>Status Area</entry>
+ <entry>Status Nothing</entry>
+ <entry>Status None</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Input Style</entry>
+ <entry></entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ <entry>C-G</entry>
+ </row>
+ <row>
+ <entry>Client Window</entry>
+ <entry></entry>
+ <entry>O-G</entry>
+ <entry>O-G</entry>
+ <entry>O-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Focus Window</entry>
+ <entry>GN</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Resource Name</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Resource Class</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Geometry Callback</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Filter Events</entry>
+ <entry></entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ <entry>G</entry>
+ </row>
+ <row>
+ <entry><type>Status</type></entry>
+ </row>
+ <row>
+ <entry>Area</entry>
+ <entry>GS</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Area Needed</entry>
+ <entry>GN-GR</entry>
+ <entry>Ignored</entry>
+ <entry>S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Colormap</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Foreground</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Background</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Background Pixmap</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Font Set</entry>
+ <entry>GN</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Line Spacing</entry>
+ <entry>GN</entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Cursor</entry>
+ <entry></entry>
+ <entry>Ignored</entry>
+ <entry>D-S-G</entry>
+ <entry>D-S-G</entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry>Status Callbacks</entry>
+ <entry></entry>
+ <entry>C-S-G</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ <entry>Ignored</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<sect3 id="Input_Style">
+<title>Input Style</title>
+<!-- .XS -->
+<!-- (SN Input Style -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNInputStyle</symbol>
+argument specifies the input style to be used.
+The value of this argument must be one of the values returned by the
+<function>XGetIMValues</function>
+function with the
+<symbol>XNQueryInputStyle</symbol>
+argument specified in the supported_styles list.
+</para>
+<para>
+<!-- .LP -->
+Note that this argument must be set at creation time
+and cannot be changed.
+</para>
+</sect3>
+<sect3 id="Client_Window">
+<title>Client Window</title>
+<!-- .XS -->
+<!-- (SN Client Window -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNClientWindow</primary></indexterm>
+The
+<symbol>XNClientWindow</symbol>
+argument specifies to the input method the client window in
+which the input method
+can display data or create subwindows.
+Geometry values for input method areas are given with respect to the client
+window.
+Dynamic change of client window is not supported.
+This argument may be set only once and
+should be set before any input is done using this input context.
+If it is not set,
+the input method may not operate correctly.
+</para>
+<para>
+<!-- .LP -->
+If an attempt is made to set this value a second time with
+<function>XSetICValues</function>,
+the string
+<symbol>XNClientWindow</symbol>
+will be returned by
+<function>XSetICValues</function>,
+and the client window will not be changed.
+</para>
+<para>
+<!-- .LP -->
+If the client window is not a valid window ID on the display
+attached to the input method,
+a
+<errorname>BadWindow</errorname>
+error can be generated when this value is used by the input method.
+</para>
+</sect3>
+<sect3 id="Focus_Window">
+<title>Focus Window</title>
+<!-- .XS -->
+<!-- (SN Focus Window -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNFocusWindow</primary></indexterm>
+The
+<symbol>XNFocusWindow</symbol>
+argument specifies the focus window.
+The primary purpose of the
+<symbol>XNFocusWindow</symbol>
+is to identify the window that will receive the key event when input
+is composed.
+In addition, the input method may possibly affect the focus window
+as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Select events on it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Send events to it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Modify its properties
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Grab the keyboard within that window
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The associated value must be of type
+<type>Window</type>.
+If the focus window is not a valid window ID on the display
+attached to the input method,
+a
+<errorname>BadWindow</errorname>
+error can be generated when this value is used by the input method.
+</para>
+<para>
+<!-- .LP -->
+When this <acronym>XIC</acronym> value is left unspecified,
+the input method will use the client window as the default focus window.
+</para>
+</sect3>
+<sect3 id="Resource_Name_and_Class_b">
+<title>Resource Name and Class</title>
+<!-- .XS -->
+<!-- (SN Resource Name and Class -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNResourceName</primary></indexterm>
+<indexterm significance="preferred"><primary>XNResourceClass</primary></indexterm>
+The
+<symbol>XNResourceName</symbol>
+and
+<symbol>XNResourceClass</symbol>
+arguments are strings that specify the full name and class
+used by the client to obtain resources for the client window.
+These values should be used as prefixes for name and class
+when looking up resources that may vary according to the input context.
+If these values are not set,
+the resources will not be fully specified.
+</para>
+<para>
+<!-- .LP -->
+It is not intended that values that can be set as <acronym>XIC</acronym> values be
+set as resources.
+</para>
+</sect3>
+<sect3 id="Geometry_Callback">
+<title>Geometry Callback</title>
+<!-- .XS -->
+<!-- (SN Geometry Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNGeometryCallback</primary></indexterm>
+The
+<symbol>XNGeometryCallback</symbol>
+argument is a structure of type
+<structname>XIMCallback</structname>
+(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>).
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNGeometryCallback</symbol>
+argument specifies the geometry callback that a client can set.
+This callback is not required for correct operation of either
+an input method or a client.
+It can be set for a client whose user interface policy permits
+an input method to request the dynamic change of that input
+method's window.
+An input method that does dynamic change will need to filter any
+events that it uses to initiate the change.
+</para>
+</sect3>
+<sect3 id="Filter_Events">
+<title>Filter Events</title>
+<!-- .XS -->
+<!-- (SN Filter Events -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNFilterEvents</primary></indexterm>
+The
+<symbol>XNFilterEvents</symbol>
+argument returns the event mask that an input method needs
+to have selected for.
+The client is expected to augment its own event mask
+for the client window with this one.
+</para>
+<para>
+<!-- .LP -->
+This argument is read-only, is set by the input method at create time,
+and is never changed.
+</para>
+<para>
+<!-- .LP -->
+The type of this argument is
+<type>unsigned</type>
+<type>long</type>.
+Setting this value will cause an error.
+</para>
+</sect3>
+<sect3 id="Destroy_Callback_b">
+<title>Destroy Callback</title>
+<!-- .XS -->
+<!-- (SN Destroy Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNDestroyCallback</symbol>
+argument is a pointer to a structure of type
+<structname>XIMCallback</structname>
+(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>).
+This callback is triggered when the input method
+stops its service for any reason; for example, when a connection to an IM
+server is broken. After the destroy callback is called,
+the input context is destroyed and the input method is closed.
+Therefore, the client should not call
+<function>XDestroyIC</function>
+and
+<function>XCloseIM</function>.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="String_Conversion_Callback">
+<title>String Conversion Callback</title>
+<!-- .XS -->
+<!-- (SN String Conversion Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNStringConversionCallback</symbol>
+argument is a structure of type
+<structname>XIMCallback</structname>
+(see <link linkend="Preedit_and_Status_Callbacks">section 13.5.6.13.12</link>).
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNStringConversionCallback</symbol>
+argument specifies a string conversion callback. This callback
+is not required for correct operation of
+either the input method or the client. It can be set by a client
+to support string conversions that may be requested
+by the input method. An input method that does string conversions
+will filter any events that it uses to initiate the conversion.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this argument.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="String_Conversion_">
+<title>String Conversion </title>
+<!-- .XS -->
+<!-- (SN String Conversion -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNStringConversion</symbol>
+argument is a structure of type
+<structname>XIMStringConversionText</structname>.
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>XNStringConversion</symbol>
+argument specifies the string to be converted by an input method.
+This argument is not required for correct operation of either
+the input method or the client.
+</para>
+<para>
+<!-- .LP -->
+String conversion facilitates the manipulation of text independent
+of preediting.
+It is essential for some input methods and clients to manipulate
+text by performing context-sensitive conversion,
+reconversion, or transliteration conversion on it.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this argument.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMStringConversionText</structname>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+
+typedef struct _XIMStringConversionText {
+ unsigned short length;
+ XIMStringConversionFeedback *feedback;
+ Bool encoding_is_wchar;
+ union {
+ char *mbs;
+ wchar_t *wcs;
+ } string;
+} XIMStringConversionText;
+
+typedef unsigned long XIMStringConversionFeedback;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The feedback member is reserved for future use. The text to be
+converted is defined by the string and length members. The length
+is indicated in characters. To prevent the library from freeing memory
+pointed to by an uninitialized pointer, the client should set the feedback
+element to NULL.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Reset_State">
+<title>Reset State</title>
+<!-- .XS -->
+<!-- (SN Reset State -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNResetState</symbol>
+argument specifies the state the input context will return to after calling
+<function>XmbResetIC</function>
+or
+<function>XwcResetIC</function>.
+</para>
+<para>
+<!-- .LP -->
+The <acronym>XIC</acronym> state may be set to its initial state, as specified by the
+<symbol>XNPreeditState</symbol>
+value when
+<function>XCreateIC</function>
+was called, or it may be set to preserve the current state.
+</para>
+<para>
+<!-- .LP -->
+The valid masks for
+<type>XIMResetState</type>
+are as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMInitialState</primary></indexterm>
+<indexterm significance="preferred"><primary>XINPreserveState</primary></indexterm>
+<!-- .sM -->
+</para>
+<literallayout class="monospaced">
+typedef unsigned long XIMResetState;
+
+#define XIMInitialState (1L)
+#define XIMPreserveState (1L<<1)
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If
+<symbol>XIMInitialState</symbol>
+is set, then
+<function>XmbResetIC</function>
+and
+<function>XwcResetIC</function>
+will return to the initial
+<symbol>XNPreeditState</symbol>
+state of the <acronym>XIC</acronym>.
+</para>
+<para>
+<!-- .LP -->
+If
+<symbol>XIMPreserveState</symbol>
+is set, then
+<function>XmbResetIC</function>
+and
+<function>XwcResetIC</function>
+will preserve the current state of the <acronym>XIC</acronym>.
+</para>
+<para>
+<!-- .LP -->
+If
+<symbol>XNResetState</symbol>
+is left unspecified, the default is
+<symbol>XIMInitialState</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<type>XIMResetState</type>
+values other than those specified above will default to
+<symbol>XIMInitialState</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this argument.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Hot_Keys_b">
+<title>Hot Keys</title>
+<!-- .XS -->
+<!-- (SN Hot Keys -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNHotKey</symbol>
+argument specifies the hot key list to the <acronym>XIC</acronym>.
+The hot key list is a pointer to the structure of type
+<structname>XIMHotKeyTriggers</structname>,
+which specifies the key events that must be received
+without any interruption of the input method.
+For the hot key list set with this argument to be utilized, the client
+must also set
+<symbol>XNHotKeyState</symbol>
+to
+<symbol>XIMHotKeyStateON</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this functionality.
+</para>
+<para>
+<!-- .LP -->
+The value of the argument is a pointer to a structure of type
+<structname>XIMHotKeyTriggers</structname>.
+</para>
+<para>
+<!-- .LP -->
+If an event for a key in the hot key list is found, then the process will
+receive the event and it will be processed inside the client.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ KeySym keysym;
+ unsigned int modifier;
+ unsigned int modifier_mask;
+} XIMHotKeyTrigger;
+
+typedef struct {
+ int num_hot_key;
+ XIMHotKeyTrigger *key;
+} XIMHotKeyTriggers;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+<para>
+<!-- .LP -->
+The combination of modifier and modifier_mask are used to represent one of
+three states for each modifier:
+either the modifier must be on, or the modifier must be off, or the modifier
+is a ``don't care'' - it may be on or off.
+When a modifier_mask bit is set to 0, the state of the associated modifier
+is ignored when evaluating whether the key is hot or not.
+</para>
+
+<informaltable>
+ <tgroup cols='3'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <thead>
+ <row>
+ <entry>Modifier Bit</entry>
+ <entry>Mask Bit</entry>
+ <entry>Meaning</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>The modifier must be off.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>1</entry>
+ <entry>The modifier must be on.</entry>
+ </row>
+ <row>
+ <entry>n/a</entry>
+ <entry>0</entry>
+ <entry>Do not care if the modifier is on or off.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+</sect3>
+<sect3 id="Hot_Key_State">
+<title>Hot Key State</title>
+<!-- .XS -->
+<!-- (SN Hot Key State -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNHotKeyState</symbol>
+argument specifies the hot key state of the input method.
+This is usually used to switch the input method between hot key
+operation and normal input processing.
+</para>
+<para>
+<!-- .LP -->
+The value of the argument is a pointer to a structure of type
+XIMHotKeyState .
+</para>
+<literallayout class="monospaced">
+typedef unsigned long XIMHotKeyState;
+
+#define XIMHotKeyStateON (0x0001L)
+#define XIMHotKeyStateOFF (0x0002L)
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+<para>
+<!-- .LP -->
+If not specified, the default is
+<symbol>XIMHotKeyStateOFF</symbol>.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+<sect3 id="Preedit_and_Status_Attributes">
+<title>Preedit and Status Attributes</title>
+<!-- .XS -->
+<!-- (SN Preedit and Status Attributes -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNPreeditAttributes</primary></indexterm>
+<indexterm significance="preferred"><primary>XNStatusAttributes</primary></indexterm>
+The
+<symbol>XNPreeditAttributes</symbol>
+and
+<symbol>XNStatusAttributes</symbol>
+arguments specify to an input method the attributes to be used for the
+preedit and status areas,
+if any.
+Those attributes are passed to
+<function>XSetICValues</function>
+or
+<function>XGetICValues</function>
+as a nested variable-length list.
+The names to be used in these lists are described in the following sections.
+</para>
+<sect4 id="Area">
+<title>Area</title>
+<!-- .XS -->
+<!-- (SN Area -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNArea</primary></indexterm>
+The value of the
+<symbol>XNArea</symbol>
+argument must be a pointer to a structure of type
+<structname>XRectangle</structname>.
+The interpretation of the
+<symbol>XNArea</symbol>
+argument is dependent on the input method style that has been set.
+</para>
+<para>
+<!-- .LP -->
+If the input method style is
+<symbol>XIMPreeditPosition</symbol>,
+<symbol>XNArea</symbol>
+specifies the clipping region within which preediting will take place.
+If the focus window has been set,
+the coordinates are assumed to be relative to the focus window.
+Otherwise, the coordinates are assumed to be relative to the client window.
+If neither has been set,
+the results are undefined.
+</para>
+<para>
+<!-- .LP -->
+If
+<symbol>XNArea</symbol>
+is not specified, is set to NULL, or is invalid,
+the input method will default the clipping region
+to the geometry of the
+<symbol>XNFocusWindow</symbol>.
+If the area specified is NULL or invalid,
+the results are undefined.
+</para>
+<para>
+<!-- .LP -->
+If the input style is
+<symbol>XIMPreeditArea</symbol>
+or
+<symbol>XIMStatusArea</symbol>,
+<symbol>XNArea</symbol>
+specifies the geometry provided by the client to the input method.
+The input method may use this area to display its data,
+either preedit or status depending on the area designated.
+The input method may create a window as a child of the client window
+with dimensions that fit the
+<symbol>XNArea</symbol>.
+The coordinates are relative to the client window.
+If the client window has not been set yet,
+the input method should save these values
+and apply them when the client window is set.
+If
+<symbol>XNArea</symbol>
+is not specified, is set to NULL, or is invalid,
+the results are undefined.
+</para>
+</sect4>
+<sect4 id="Area_Needed">
+<title>Area Needed</title>
+<!-- .XS -->
+<!-- (SN Area Needed -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNAreaNeeded</primary></indexterm>
+When set, the
+<symbol>XNAreaNeeded</symbol>
+argument specifies the geometry suggested by the client for this area
+(preedit or status).
+The value associated with the argument must be a pointer to a
+structure of type
+<structname>XRectangle</structname>.
+Note that the x, y values are not used
+and that nonzero values for width or height are the constraints
+that the client wishes the input method to respect.
+</para>
+<para>
+<!-- .LP -->
+When read, the
+<symbol>XNAreaNeeded</symbol>
+argument specifies the preferred geometry desired by the input method
+for the area.
+</para>
+<para>
+<!-- .LP -->
+This argument is only valid if the input style is
+<symbol>XIMPreeditArea</symbol>
+or
+<symbol>XIMStatusArea</symbol>.
+It is used for geometry negotiation between the client and the input method
+and has no other effect on the input method
+(see <link linkend="Geometry_Management">section 13.5.1.5</link>).
+</para>
+</sect4>
+<sect4 id="Spot_Location">
+<title>Spot Location</title>
+<!-- .XS -->
+<!-- (SN Spot Location -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNSpotLocation</primary></indexterm>
+The
+<symbol>XNSpotLocation</symbol>
+argument specifies to the input method the coordinates of the spot
+to be used by an input method executing with
+<symbol>XNInputStyle</symbol>
+set to
+<symbol>XIMPreeditPosition</symbol>.
+When specified to any input method other than
+<symbol>XIMPreeditPosition</symbol>,
+this <acronym>XIC</acronym> value is ignored.
+</para>
+<para>
+<!-- .LP -->
+The x coordinate specifies the position where the next character
+would be inserted.
+The y coordinate is the position of the baseline used
+by the current text line in the focus window.
+The x and y coordinates are relative to the focus window, if it has been set;
+otherwise, they are relative to the client window.
+If neither the focus window nor the client window has been set,
+the results are undefined.
+</para>
+<para>
+<!-- .LP -->
+The value of the argument is a pointer to a structure of type
+<structname>XPoint</structname>.
+</para>
+</sect4>
+<sect4 id="Colormap">
+<title>Colormap</title>
+<!-- .XS -->
+<!-- (SN Colormap -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Two different arguments can be used to indicate what colormap the input method
+should use to allocate colors, a colormap ID, or a standard colormap name.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNColormap</primary></indexterm>
+The
+<symbol>XNColormap</symbol>
+argument is used to specify a colormap ID.
+The argument value is of type
+<type>Colormap</type>.
+An invalid argument may generate a
+<errorname>BadColor</errorname>
+error when it is used by the input method.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNStdColormap</primary></indexterm>
+The
+<symbol>XNStdColormap</symbol>
+argument is used to indicate the name of the standard colormap
+in which the input method should allocate colors.
+The argument value is an
+<type>Atom</type>
+that should be a valid atom for calling
+<function>XGetRGBColormaps</function>.
+An invalid argument may generate a
+<errorname>BadAtom</errorname>
+error when it is used by the input method.
+</para>
+<para>
+<!-- .LP -->
+If the colormap is left unspecified,
+the client window colormap becomes the default.
+</para>
+</sect4>
+<sect4 id="Foreground_and_Background">
+<title>Foreground and Background</title>
+<!-- .XS -->
+<!-- (SN Foreground and Background -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNForeground</primary></indexterm>
+<indexterm significance="preferred"><primary>XNBackground</primary></indexterm>
+The
+<symbol>XNForeground</symbol>
+and
+<symbol>XNBackground</symbol>
+arguments specify the foreground and background pixel, respectively.
+The argument value is of type
+<type>unsigned</type>
+<type>long</type>.
+It must be a valid pixel in the input method colormap.
+</para>
+<para>
+<!-- .LP -->
+If these values are left unspecified,
+the default is determined by the input method.
+</para>
+</sect4>
+<sect4 id="Background_Pixmap">
+<title>Background Pixmap</title>
+<!-- .XS -->
+<!-- (SN Background Pixmap -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNBackgroundPixmap</symbol>
+argument specifies a background pixmap to be used as the background of the
+window.
+The value must be of type
+<type>Pixmap</type>.
+An invalid argument may generate a
+<errorname>BadPixmap</errorname>
+error when it is used by the input method.
+</para>
+<para>
+<!-- .LP -->
+If this value is left unspecified,
+the default is determined by the input method.
+</para>
+</sect4>
+<sect4 id="Font_Set">
+<title>Font Set</title>
+<!-- .XS -->
+<!-- (SN Font Set -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNFontSet</primary></indexterm>
+The
+<symbol>XNFontSet</symbol>
+argument specifies to the input method what font set is to be used.
+The argument value is of type
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+If this value is left unspecified,
+the default is determined by the input method.
+</para>
+</sect4>
+<sect4 id="Line_Spacing">
+<title>Line Spacing</title>
+<!-- .XS -->
+<!-- (SN Line Spacing -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNLineSpace</symbol>
+argument specifies to the input method what line spacing is to be used
+in the preedit window if more than one line is to be used.
+This argument is of type
+<type>int</type>.
+</para>
+<para>
+<!-- .LP -->
+If this value is left unspecified,
+the default is determined by the input method.
+</para>
+</sect4>
+<sect4 id="Cursor">
+<title>Cursor</title>
+<!-- .XS -->
+<!-- (SN Cursor -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XNCursor</primary></indexterm>
+The
+<symbol>XNCursor</symbol>
+argument specifies to the input method what cursor is to be used
+in the specified window.
+This argument is of type
+<type>Cursor</type>.
+</para>
+<para>
+<!-- .LP -->
+An invalid argument may generate a
+<errorname>BadCursor</errorname>
+error when it is used by the input method.
+If this value is left unspecified,
+the default is determined by the input method.
+</para>
+</sect4>
+<sect4 id="Preedit_State">
+<title>Preedit State</title>
+<!-- .XS -->
+<!-- (SN Preedit State -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<symbol>XNPreeditState</symbol>
+argument specifies the state of input preediting for the input method.
+Input preediting can be on or off.
+</para>
+<para>
+<!-- .LP -->
+The valid mask names for
+<symbol>XNPreeditState</symbol>
+are as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMPreeditUnknown</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditEnable</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreeditDisable</primary></indexterm>
+<!-- .sM -->
+</para>
+<!-- .LP -->
+<literallayout class="monospaced">
+typedef unsigned long XIMPreeditState;
+
+#define XIMPreeditUnknown 0L
+#define XIMPreeditEnable 1L
+#define XIMPreeditDisable (1L<<1)
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If a value of
+<symbol>XIMPreeditEnable</symbol>
+is set, then input preediting is turned on by the input method.
+</para>
+<para>
+<!-- .LP -->
+If a value of
+<symbol>XIMPreeditDisable</symbol>
+is set, then input preediting is turned off by the input method.
+</para>
+<para>
+<!-- .LP -->
+If
+<symbol>XNPreeditState</symbol>
+is left unspecified, then the state will be implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+When
+<symbol>XNResetState</symbol>
+is set to
+<symbol>XIMInitialState</symbol>,
+the
+<symbol>XNPreeditState</symbol>
+value specified at the creation time will be reflected as the initial state for
+<function>XmbResetIC</function>
+and
+<function>XwcResetIC</function>.
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this argument.
+</para>
+</sect4>
+<sect4 id="Preedit_State_Notify_Callback">
+<title>Preedit State Notify Callback</title>
+<!-- .XS -->
+<!-- (SN Preedit State Notify Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The preedit state notify callback is triggered by the input method
+when the preediting state has changed.
+The value of the
+<symbol>XNPreeditStateNotifyCallback</symbol>
+argument is a pointer to a structure of type
+<structname>XIMCallback</structname>.
+The generic prototype is as follows:
+</para>
+<indexterm significance="preferred"><primary>PreeditStateNotifyCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='preeditstatenotifycallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>PreeditStateNotifyCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XIMPreeditStateNotifyCallbackStruct<parameter> *call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the current preedit state.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<structname>XIMPreeditStateNotifyCallbackStruct</structname>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMPreeditStateNotifyCallbackStruct</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct _XIMPreeditStateNotifyCallbackStruct {
+ XIMPreeditState state;
+} XIMPreeditStateNotifyCallbackStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+<para>
+<!-- .LP -->
+Because this <acronym>XIC</acronym> value is optional, a client should call
+<function>XGetIMValues</function>
+with argument
+<symbol>XNQueryICValuesList</symbol>
+before using this argument.
+</para>
+</sect4>
+<sect4 id="Preedit_and_Status_Callbacks">
+<title>Preedit and Status Callbacks</title>
+<!-- .XS -->
+<!-- (SN Preedit and Status Callbacks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A client that wants to support the input style
+<symbol>XIMPreeditCallbacks</symbol>
+must provide a set of preedit callbacks to the input method.
+The set of preedit callbacks is as follows:
+</para>
+<indexterm significance="preferred"><primary>XNPreeditStartCallback</primary></indexterm>
+<indexterm significance="preferred"><primary>XNPreeditDoneCallback</primary></indexterm>
+<indexterm significance="preferred"><primary>XNPreeditDrawCallback</primary></indexterm>
+<indexterm significance="preferred"><primary>XNPreeditCaretCallback</primary></indexterm>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>XNPreeditStartCallback</symbol></entry>
+ <entry>This is called when the input method starts preedit.</entry>
+ </row>
+ <row>
+ <entry><symbol>XNPreeditDoneCallback</symbol></entry>
+ <entry>This is called when the input method stops preedit.</entry>
+ </row>
+ <row>
+ <entry><symbol>XNPreeditDrawCallback</symbol></entry>
+ <entry>This is called when a number of preedit keystrokes should be echoed.</entry>
+ </row>
+ <row>
+ <entry><symbol>XNPreeditCaretCallback</symbol></entry>
+ <entry>This is called to move the text insertion point within the preedit string.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+A client that wants to support the input style
+<symbol>XIMStatusCallbacks</symbol>
+must provide a set of status callbacks to the input method.
+The set of status callbacks is as follows:
+</para>
+
+<indexterm significance="preferred"><primary>XNStatusStartCallback</primary></indexterm>
+<indexterm significance="preferred"><primary>XNStatusDoneCallback</primary></indexterm>
+<indexterm significance="preferred"><primary>XNStatusDrawCallback</primary></indexterm>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>XNStatusStartCallback</symbol></entry>
+ <entry>This is called when the input method initializes the status area.</entry>
+ </row>
+ <row>
+ <entry><symbol>XNStatusDoneCallback</symbol></entry>
+ <entry>This is called when the input method no longer needs the status area.</entry>
+ </row>
+ <row>
+ <entry><symbol>XNStatusDrawCallback</symbol></entry>
+ <entry>This is called when updating of the status area is required.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+<para>
+<!-- .LP -->
+The value of any status or preedit argument is a pointer
+to a structure of type
+<structname>XIMCallback</structname>.
+<indexterm significance="preferred"><primary>XIMProc</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMCallback</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef void (*XIMProc)();
+
+typedef struct {
+ XPointer client_data;
+ XIMProc callback;
+} XIMCallback;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Each callback has some particular semantics and will carry the data
+that expresses the environment necessary to the client
+into a specific data structure.
+This paragraph only describes the arguments to be used to set
+the callback.
+</para>
+<para>
+<!-- .LP -->
+Setting any of these values while doing preedit
+may cause unexpected results.
+</para>
+</sect4>
+</sect3>
+</sect2>
+<sect2 id="Input_Method_Callback_Semantics">
+<title>Input Method Callback Semantics</title>
+<!-- .XS -->
+<!-- (SN Input Method Callback Semantics -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<acronym>XIM</acronym> callbacks are procedures defined by clients or text drawing packages
+that are to be called from the input method when selected events occur.
+Most clients will use a text editing package or a toolkit
+and, hence, will not need to define such callbacks.
+This section defines the callback semantics, when they are triggered,
+and what their arguments are.
+This information is mostly useful for X toolkit implementors.
+</para>
+<para>
+<!-- .LP -->
+Callbacks are mostly provided so that clients (or text editing
+packages) can implement on-the-spot preediting in their own window.
+In that case,
+the input method needs to communicate and synchronize with the client.
+The input method needs to communicate changes in the preedit window
+when it is under control of the client.
+Those callbacks allow the client to initialize the preedit area,
+display a new preedit string,
+move the text insertion point during preedit,
+terminate preedit, or update the status area.
+</para>
+<para>
+<!-- .LP -->
+All callback procedures follow the generic prototype:
+</para>
+<indexterm significance="preferred"><primary>CallbackPrototype</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function><replaceable>CallbackPrototype</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>SomeType<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies data specific to the callback.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The call_data argument is a structure that expresses the arguments needed
+to achieve the semantics;
+that is,
+it is a specific data structure appropriate to the callback.
+In cases where no data is needed in the callback,
+this call_data argument is NULL.
+The client_data argument is a closure that has been initially specified
+by the client when specifying the callback and passed back.
+It may serve, for example, to inherit application context in the callback.
+</para>
+<para>
+<!-- .LP -->
+The following paragraphs describe the programming semantics
+and specific data structure associated with the different reasons.
+</para>
+<sect3 id="Geometry_Callback_b">
+<title>Geometry Callback</title>
+<!-- .XS -->
+<!-- (SN Geometry Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The geometry callback is triggered by the input method
+to indicate that it wants the client to negotiate geometry.
+The generic prototype is as follows:
+</para>
+<indexterm significance="preferred"><primary>GeometryCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis>
+<funcprototype>
+ <funcdef>void <function><replaceable>GeometryCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback is called with a NULL call_data argument.
+</para>
+</sect3>
+<sect3 id="Destroy_Callback_c">
+<title>Destroy Callback</title>
+<!-- .XS -->
+<!-- (SN Destroy Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The destroy callback is triggered by the input method
+when it stops service for any reason.
+After the callback is invoked, the input context will be freed by Xlib.
+The generic prototype is as follows:
+</para>
+<indexterm significance="preferred"><primary>DestroyCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='destroycallback_xic'>
+<funcprototype>
+ <funcdef>void <function><replaceable>DestroyCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback is called with a NULL call_data argument.
+</para>
+</sect3>
+<sect3 id="String_Conversion_Callback_b">
+<title>String Conversion Callback</title>
+<!-- .XS -->
+<!-- (SN String Conversion Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The string conversion callback is triggered by the input method
+to request the client to return the string to be converted. The
+returned string may be either a multibyte or wide character string,
+with an encoding matching the locale bound to the input context.
+The callback prototype is as follows:
+</para>
+<indexterm significance="preferred"><primary>StringConversionCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='stringconversioncallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>StringConversionCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XIMStringConversionCallbackStruct<parameter> *call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the amount of the string to be converted.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback is passed an
+<structname>XIMStringConversionCallbackStruct</structname>
+structure in the call_data argument.
+The text member is an
+<structname>XIMStringConversionText</structname>
+structure (see <link linkend="String_Conversion_">section 13.5.6.9</link>)
+to be filled in by the client
+and describes the text to be sent to the input method.
+The data pointed to by the
+string and feedback elements of the
+<structname>XIMStringConversionText</structname>
+structure will be freed using
+<function>XFree</function>
+by the input method
+after the callback returns. So the client should not point to
+internal buffers that are critical to the client.
+Similarly, because the feedback element is currently reserved for future
+use, the client should set feedback to NULL to prevent the library from
+freeing memory at some random location due to an uninitialized pointer.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMStringConversionCallbackStruct</structname>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMStringConversionCallbackStruct</primary></indexterm>
+<!-- .sM -->
+</para>
+<!-- .LP -->
+<literallayout class="monospaced">
+typedef struct _XIMStringConversionCallbackStruct {
+ XIMStringConversionPosition position;
+ XIMCaretDirection direction;
+ short factor;
+ XIMStringConversionOperation operation;
+ XIMStringConversionText *text;
+} XIMStringConversionCallbackStruct;
+
+typedef short XIMStringConversionPosition;
+
+typedef unsigned short XIMStringConversionOperation;
+
+#define XIMStringConversionSubstitution (0x0001)
+#define XIMStringConversionRetrieval (0x0001)
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<type>XIMStringConversionPosition</type>
+specifies the starting position of the string to be returned
+in the
+<structname>XIMStringConversionText</structname>
+structure. The value identifies a position, in units of characters,
+relative to the client's cursor position in the client's buffer.
+</para>
+<para>
+<!-- .LP -->
+The ending position of the text buffer is determined by
+the direction and factor members. Specifically, it is the character position
+relative to the starting point as defined by the
+<structname>XIMCaretDirection</structname>.
+The factor member of
+<structname>XIMStringConversionCallbackStruct</structname>
+specifies the number of
+<structname>XIMCaretDirection</structname>
+positions to be applied. For example, if the direction specifies
+<constant>XIMLineEnd</constant>
+and factor is 1, then all characters from the starting position to
+the end of the current display line are returned. If the direction
+specifies
+<constant>XIMForwardChar</constant>
+or
+<constant>XIMBackwardChar</constant>,
+then the factor specifies a relative position, indicated in characters,
+from the starting position.
+</para>
+<para>
+<!-- .LP -->
+<type>XIMStringConversionOperation</type>
+specifies whether the string to be converted should be
+deleted (substitution) or copied (retrieval) from the client's
+buffer. When the
+<type>XIMStringConversionOperation</type>
+is
+<symbol>XIMStringConversionSubstitution</symbol>,
+the client must delete the string to be converted from its own buffer.
+When the
+<type>XIMStringConversionOperation</type>
+is
+<symbol>XIMStringConversionRetrieval</symbol>,
+the client must not delete the string to be converted from its buffer.
+The substitute operation is typically used for reconversion and
+transliteration conversion,
+while the retrieval operation is typically used for context-sensitive
+conversion.
+</para>
+</sect3>
+<sect3 id="Preedit_State_Callbacks">
+<title>Preedit State Callbacks</title>
+<!-- .XS -->
+<!-- (SN Preedit State Callbacks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+When the input method turns preediting on or off, a
+<function><replaceable>PreeditStartCallback</replaceable></function>
+or
+<function><replaceable>PreeditDoneCallback</replaceable></function>
+callback is triggered to let the toolkit do the setup
+or the cleanup for the preedit region.
+</para>
+<indexterm significance="preferred"><primary>PreeditStartCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='preeditstartcallback'>
+<funcprototype>
+ <funcdef>int <function><replaceable>PreeditStartCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When preedit starts on the specified input context,
+the callback is called with a NULL call_data argument.
+<function><replaceable>PreeditStartCallback</replaceable></function>
+will return the maximum size of the preedit string.
+A positive number indicates the maximum number of bytes allowed
+in the preedit string,
+and a value of -1 indicates there is no limit.
+</para>
+<indexterm significance="preferred"><primary>PreeditDoneCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='preeditdonecallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>PreeditDoneCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+When preedit stops on the specified input context,
+the callback is called with a NULL call_data argument.
+The client can release the data allocated by
+<function><replaceable>PreeditStartCallback</replaceable></function>.
+</para>
+<para>
+<!-- .LP -->
+<function><replaceable>PreeditStartCallback</replaceable></function>
+should initialize appropriate data needed for
+displaying preedit information and for handling further
+<function><replaceable>PreeditDrawCallback</replaceable></function>
+calls.
+Once
+<function><replaceable>PreeditStartCallback</replaceable></function>
+is called, it will not be called again before
+<function><replaceable>PreeditDoneCallback</replaceable></function>
+has been called.
+</para>
+</sect3>
+<sect3 id="Preedit_Draw_Callback">
+<title>Preedit Draw Callback</title>
+<!-- .XS -->
+<!-- (SN Preedit Draw Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This callback is triggered to draw and insert, delete or replace,
+preedit text in the preedit region.
+The preedit text may include unconverted input text such as Japanese Kana,
+converted text such as Japanese Kanji characters, or characters of both kinds.
+That string is either a multibyte or wide character string,
+whose encoding matches the locale bound to the input context.
+The callback prototype
+is as follows:
+</para>
+<indexterm significance="preferred"><primary>PreeditDrawCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='preeditdrawcallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>PreeditDrawCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XIMPreeditDrawCallbackStruct<parameter> *call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the preedit drawing information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback is passed an
+<structname>XIMPreeditDrawCallbackStruct</structname>
+structure in the call_data argument.
+The text member of this structure contains the text to be drawn.
+After the string has been drawn,
+the caret should be moved to the specified location.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMPreeditDrawCallbackStruct</structname>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMPreeditDrawCallbackStruct</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct _XIMPreeditDrawCallbackStruct {
+ int caret; /* Cursor offset within preedit string */
+ int chg_first; /* Starting change position */
+ int chg_length; /* Length of the change in character count */
+ XIMText *text;
+} XIMPreeditDrawCallbackStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The client must keep updating a buffer of the preedit text
+and the callback arguments referring to indexes in that buffer.
+The call_data fields have specific meanings according to the operation,
+as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+To indicate text deletion,
+the call_data member specifies a NULL text field.
+The text to be deleted is then the current text in the buffer
+from position chg_first (starting at zero) on a character length
+of chg_length.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When text is non-NULL,
+it indicates insertion or replacement of text in the buffer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The chg_length member
+identifies the number of characters in the current preedit buffer
+that are affected by this call.
+A positive chg_length indicates that chg_length number of characters, starting
+at chg_first, must be deleted or must be replaced by text, whose length is
+specified in the
+<structname>XIMText</structname>
+structure.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A chg_length value of zero indicates that text must be inserted
+right at the position specified by chg_first.
+A value of zero for chg_first specifies the first character in the buffer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+chg_length and chg_first combine to identify the modification required to
+the preedit buffer; beginning at chg_first, replace chg_length number of
+characters with the text in the supplied
+<structname>XIMText</structname>
+structure. For example, suppose the preedit buffer contains the string "ABCDE".
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<literallayout class="monospaced">
+<!-- .ft C -->
+Text: A B C D E
+ ^ ^ ^ ^ ^ ^
+CharPos: 0 1 2 3 4 5
+<!-- .sp -->
+<!-- .ft P -->
+</literallayout>
+The CharPos in the diagram shows the location of the character position
+relative to the character.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the value of chg_first is 1 and the value of chg_length is 3, this
+says to replace 3 characters beginning at character position 1 with the
+string in the
+<structname>XIMText</structname>
+structure.
+Hence, <acronym>BCD</acronym> would be replaced by the value in the structure.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Though chg_length and chg_first are both signed integers they will
+never have a negative value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The caret member
+identifies the character position before which the cursor should
+be placed - after modification to the preedit buffer has been completed.
+For example, if caret is zero, the cursor is at
+the beginning of the buffer. If the caret is one, the cursor is between
+the first and second character.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMText</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1.5i 3i -->
+typedef struct _XIMText {
+ unsigned short length;
+ XIMFeedback * feedback;
+ Bool encoding_is_wchar;
+ union {
+ char * multi_byte;
+ wchar_t * wide_char;
+ } string;
+} XIMText;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The text string passed is actually a structure specifying as follows:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+The length member is the text length in characters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The encoding_is_wchar member is a value that indicates
+if the text string is encoded in wide character or multibyte format.
+The text string may be passed either as multibyte or as wide character;
+the input method controls in which form data is passed.
+The client's
+callback routine must be able to handle data passed in either form.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The string member is the text string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+The feedback member indicates rendering type for each character in the
+string member.
+If string is NULL (indicating that only highlighting of the existing
+preedit buffer should be updated), feedback points to length highlight
+elements that should be applied to the existing preedit buffer, beginning
+at chg_first.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+The feedback member expresses the types of rendering feedback
+the callback should apply when drawing text.
+Rendering of the text to be drawn is specified either in generic ways
+(for example, primary, secondary) or in specific ways (reverse, underline).
+When generic indications are given,
+the client is free to choose the rendering style.
+It is necessary, however, that primary and secondary be mapped
+to two distinct rendering styles.
+</para>
+<para>
+<!-- .LP -->
+If an input method wants to control display of the preedit string, an
+input method can indicate the visibility hints using feedbacks in
+a specific way.
+The
+<symbol>XIMVisibleToForward</symbol>,
+<symbol>XIMVisibleToBackword</symbol>,
+and
+<symbol>XIMVisibleToCenter</symbol>
+masks are exclusively used for these visibility hints.
+The
+<symbol>XIMVisibleToForward</symbol>
+mask
+indicates that the preedit text is preferably displayed in the
+primary draw direction from the
+caret position in the preedit area forward.
+The
+<symbol>XIMVisibleToBackword</symbol>
+mask
+indicates that the preedit text is preferably displayed from
+the caret position in the preedit area backward, relative to the primary
+draw direction.
+The
+<symbol>XIMVisibleToCenter</symbol>
+mask
+indicates that the preedit text is preferably displayed with
+the caret position in the preedit area centered.
+</para>
+<para>
+<!-- .LP -->
+The insertion point of the preedit string could exist outside of
+the visible area when visibility hints are used.
+Only one of the
+masks
+is valid for the entire preedit string, and only one character
+can hold one of these feedbacks for a given input context at one time.
+This feedback may be OR'ed together with another highlight (such as
+<symbol>XIMReverse</symbol>).
+Only the most recently set feedback is valid, and any previous
+feedback is automatically canceled. This is a hint to the client, and
+the client is free to choose how to display the preedit string.
+</para>
+<para>
+<!-- .LP -->
+The feedback member also specifies how rendering of the text argument
+should be performed.
+If the feedback is NULL,
+the callback should apply the same feedback as is used for the surrounding
+characters in the preedit buffer; if chg_first is at a highlight boundary,
+the client can choose which of the two highlights to use.
+If feedback is not NULL, feedback specifies an array defining the
+rendering for each
+character of the string, and the length of the array is thus length.
+</para>
+<para>
+<!-- .LP -->
+If an input method wants to indicate that it is only updating the feedback of
+the preedit text without changing the content of it,
+the
+<structname>XIMText</structname>
+structure will contain a NULL value for the string field,
+the number of characters affected (relative to chg_first)
+will be in the length field,
+and the feedback field will point to an array of
+<type>XIMFeedback</type>.
+</para>
+<para>
+<!-- .LP -->
+Each element in the feedback array is a bitmask represented by a value of type
+<type>XIMFeedback</type>.
+The valid mask names are as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMReverse</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMUnderline</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMHighlight</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPrimary</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMSecondary</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMTertiary</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMVisibleToForward</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMVisibleToBackward</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMVisibleToCenter</primary></indexterm>
+<!-- .sM -->
+</para>
+<literallayout class="monospaced">
+typedef unsigned long XIMFeedback;
+
+#define XIMReverse 1L
+#define XIMUnderline (1L<<1)
+#define XIMHighlight (1L<<2)
+#define XIMPrimary (1L<<5)*
+#define XIMSecondary (1L<<6)*
+#define XIMTertiary (1L<<7)*
+#define XIMVisibleToForward (1L<<8)
+#define XIMVisibleToBackward (1L<<9)
+#define XIMVisibleToCenter (1L<<10)
+
+*†The values for XIMPrimary, XIMSecondary, and XIMTertiary were incorrectly defined in
+the R5 specification. The X Consortium’s X11R5 implementation correctly
+implemented the values for these highlights. The value of these highlights has
+been corrected in this specification to agree with the values in the
+Consortium’s X11R5 and X11R6 implementations.
+
+</literallayout>
+
+<para>
+<!-- .LP -->
+Characters drawn with the
+<symbol>XIMReverse</symbol>
+highlight should be drawn by swapping the foreground and background colors
+used to draw normal, unhighlighted characters.
+Characters drawn with the
+<symbol>XIMUnderline</symbol>
+highlight should be underlined.
+Characters drawn with the
+<symbol>XIMHighlight</symbol>,
+<symbol>XIMPrimary</symbol>,
+<symbol>XIMSecondary</symbol>,
+and
+<symbol>XIMTertiary</symbol>
+highlights should be drawn in some unique manner that must be different
+from
+<symbol>XIMReverse</symbol>
+and
+<symbol>XIMUnderline</symbol>.
+<!-- .FS \(dg -->
+The values for
+<symbol>XIMPrimary</symbol>,
+<symbol>XIMSecondary</symbol>,
+and
+<symbol>XIMTertiary</symbol>
+were incorrectly defined in the R5 specification.
+The X Consortium's X11R5
+implementation correctly implemented the values for these highlights.
+The value of these highlights has been corrected in this specification
+to agree with the values in the Consortium's X11R5 and X11R6 implementations.
+<!-- .FE -->
+</para>
+</sect3>
+<sect3 id="Preedit_Caret_Callback">
+<title>Preedit Caret Callback</title>
+<!-- .XS -->
+<!-- (SN Preedit Caret Callback -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An input method may have its own navigation keys to allow the user
+to move the text insertion point in the preedit area
+(for example, to move backward or forward).
+Consequently, input method needs to indicate to the client that it
+should move the text insertion point.
+It then calls the PreeditCaretCallback.
+</para>
+<indexterm significance="preferred"><primary>PreeditCaretCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='preeditcaretcallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>PreeditCaretCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XIMPreeditCaretCallbackStruct<parameter> *call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the preedit caret information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The input method will trigger PreeditCaretCallback
+to move the text insertion point during preedit.
+The call_data argument contains a pointer to an
+<structname>XIMPreeditCaretCallbackStruct</structname>
+structure,
+which indicates where the caret should be moved.
+The callback must move the insertion point to its new location
+and return, in field position, the new offset value from the initial position.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMPreeditCaretCallbackStruct</structname>
+structure is defined as follows:
+<indexterm significance="preferred"><primary>XIMPreeditCaretCallbackStruct</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct _XIMPreeditCaretCallbackStruct {
+ int position; /* Caret offset within preedit string */
+ XIMCaretDirection direction; /* Caret moves direction */
+ XIMCaretStyle style; /* Feedback of the caret */
+} XIMPreeditCaretCallbackStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<structname>XIMCaretStyle</structname>
+structure is defined as follows:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XIMCaretStyle</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef enum {
+ XIMIsInvisible, /* Disable caret feedback */
+ XIMIsPrimary, /* <acronym>UI</acronym> defined caret feedback */
+ XIMIsSecondary, /* <acronym>UI</acronym> defined caret feedback */
+} XIMCaretStyle;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<structname>XIMCaretDirection</structname>
+structure is defined as follows:
+<indexterm significance="preferred"><primary>XIMCaretDirection</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef enum {
+ XIMForwardChar, XIMBackwardChar,
+ XIMForwardWord, XIMBackwardWord,
+ XIMCaretUp, XIMCaretDown,
+ XIMNextLine, XIMPreviousLine,
+ XIMLineStart, XIMLineEnd,
+ XIMAbsolutePosition,
+ XIMDontChange,
+ } XIMCaretDirection;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+These values are defined as follows:
+</para>
+<indexterm significance="preferred"><primary>XIMForwardChar</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMBackwardChar</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMForwardWord</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMBackwardWord</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMCaretUp</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMCaretDown</primary></indexterm>
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><constant>XIMForwardChar</constant></entry>
+ <entry>Move the caret forward one character position.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMBackwardChar</constant></entry>
+ <entry>Move the caret backward one character position.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMForwardWord</constant></entry>
+ <entry>Move the caret forward one word.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMBackwardWord</constant></entry>
+ <entry>Move the caret backward one word.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMCaretUp</constant></entry>
+ <entry>Move the caret up one line keeping the current horizontal offset.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMCaretDown</constant></entry>
+ <entry>Move the caret down one line keeping the current horizontal offset.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMPreviousLine</constant></entry>
+ <entry>Move the caret to the beginning of the previous line.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMNextLine</constant></entry>
+ <entry>Move the caret to the beginning of the next line.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMLineStart</constant></entry>
+ <entry>Move the caret to the beginning of the current display line that contains the caret.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMLineEnd</constant></entry>
+ <entry>Move the caret to the end of the current display line that contains the caret.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMAbsolutePosition</constant></entry>
+ <entry>The callback must move to the location specified by the position field
+ of the callback data, indicated in characters, starting from the beginning
+ of the preedit text.
+ Hence, a value of zero means move back to the beginning of the preedit text.</entry>
+ </row>
+ <row>
+ <entry><constant>XIMDontChange</constant></entry>
+ <entry>The caret position does not change.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<indexterm significance="preferred"><primary>XIMNextLine</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMPreviousLine</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMLineStart</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMLineEnd</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMAbsolutePosition</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMDontChange</primary></indexterm>
+</sect3>
+<sect3 id="Status_Callbacks">
+<title>Status Callbacks</title>
+<!-- .XS -->
+<!-- (SN Status Callbacks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+An input method may communicate changes in the status of an input context
+(for example, created, destroyed, or focus changes) with three status
+callbacks: StatusStartCallback, StatusDoneCallback, and StatusDrawCallback.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+When the input context is created or gains focus,
+the input method calls the StatusStartCallback callback.
+</para>
+<indexterm significance="preferred"><primary>StatusStartCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='statusstartcallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>StatusStartCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback should initialize appropriate data for displaying status
+and for responding to StatusDrawCallback calls.
+Once StatusStartCallback is called,
+it will not be called again before StatusDoneCallback has been called.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+When an input context
+is destroyed or when it loses focus, the input method calls StatusDoneCallback.
+</para>
+<indexterm significance="preferred"><primary>StatusDoneCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='statusdonecallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>StatusDoneCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XPointer<parameter> call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Not used for this callback and always passed as NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback may release any data allocated on
+<function>StatusStart</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+When an input context status has to be updated, the input method calls
+StatusDrawCallback.
+</para>
+<indexterm significance="preferred"><primary>StatusDrawCallback</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='statusdrawcallback'>
+<funcprototype>
+ <funcdef>void <function><replaceable>StatusDrawCallback</replaceable></function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XPointer<parameter> client_data</parameter></paramdef>
+ <paramdef>XIMStatusDrawCallbackStruct<parameter> *call_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>client_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the additional client data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>call_data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the status drawing information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The callback should update the status area by either drawing a string
+or imaging a bitmap in the status area.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIMStatusDataType</structname>
+and
+<structname>XIMStatusDrawCallbackStruct</structname>
+structures are defined as follows:
+<indexterm significance="preferred"><primary>XIMStatusDataType</primary></indexterm>
+<indexterm significance="preferred"><primary>XIMStatusDrawCallbackStruct</primary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1i 3i -->
+<!-- .ta .5i 1i 3i -->
+typedef enum {
+ XIMTextType,
+ XIMBitmapType,
+} XIMStatusDataType;
+
+typedef struct _XIMStatusDrawCallbackStruct {
+ XIMStatusDataType type;
+ union {
+ XIMText *text;
+ Pixmap bitmap;
+ } data;
+} XIMStatusDrawCallbackStruct;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+<para>
+<!-- .LP -->
+The feedback styles
+<symbol>XIMVisibleToForward</symbol>,
+<symbol>XIMVisibleToBackword</symbol>,
+and
+<symbol>XIMVisibleToCenter</symbol>
+are not relevant and will not appear in the
+<type>XIMFeedback</type>
+element of the
+<structname>XIMText</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+</para>
+</sect3>
+</sect2>
+<sect2 id="Event_Filtering_b">
+<title>Event Filtering</title>
+<!-- .XS -->
+<!-- (SN Event Filtering -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides the ability for an input method
+to register a filter internal to Xlib.
+This filter is called by a client (or toolkit) by calling
+<function>XFilterEvent</function>
+after calling
+<function>XNextEvent</function>.
+Any client that uses the
+<type>XIM</type>
+interface should call
+<function>XFilterEvent</function>
+to allow input methods to process their events without knowledge
+of the client's dispatching mechanism.
+A client's user interface policy may determine the priority
+of event filters with respect to other event-handling mechanisms
+(for example, modal grabs).
+</para>
+<para>
+<!-- .LP -->
+Clients may not know how many filters there are, if any,
+and what they do.
+They may only know if an event has been filtered on return of
+<function>XFilterEvent</function>.
+Clients should discard filtered events.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To filter an event, use
+<function>XFilterEvent</function>.
+</para>
+<indexterm significance="preferred"><primary>XFilterEvent</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfilterevent'>
+<funcprototype>
+ <funcdef>Bool <function>XFilterEvent</function></funcdef>
+ <paramdef>XEvent<parameter> *event</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Ev event to filter -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the (Ev.
+<!-- .ds Wi for which the filter is to be applied -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window (Wi.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the window argument is
+<symbol>None</symbol>,
+<function>XFilterEvent</function>
+applies the filter to the window specified in the
+<structname>XEvent</structname>
+structure.
+The window argument is provided so that layers above Xlib
+that do event redirection can indicate to which window an event
+has been redirected.
+</para>
+<para>
+<!-- .LP -->
+If
+<function>XFilterEvent</function>
+returns
+<symbol>True</symbol>,
+then some input method has filtered the event,
+and the client should discard the event.
+If
+<function>XFilterEvent</function>
+returns
+<symbol>False</symbol>,
+then the client should continue processing the event.
+</para>
+<para>
+<!-- .LP -->
+If a grab has occurred in the client and
+<function>XFilterEvent</function>
+returns
+<symbol>True</symbol>,
+the client should ungrab the keyboard.
+</para>
+</sect2>
+<sect2 id="Getting_Keyboard_Input_b">
+<title>Getting Keyboard Input</title>
+<!-- .XS -->
+<!-- (SN Getting Keyboard Input -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To get composed input from an input method,
+use
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbLookupString</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcLookupString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmblookupstring'>
+<funcprototype>
+ <funcdef>int <function>XmbLookupString</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XKeyPressedEvent<parameter> *event</parameter></paramdef>
+ <paramdef>char<parameter> *buffer_return</parameter></paramdef>
+ <paramdef>int<parameter> bytes_buffer</parameter></paramdef>
+ <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef>
+ <paramdef>Status<parameter> *status_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwclookupstring'>
+<funcprototype>
+ <funcdef>int <function>XwcLookupString</function></funcdef>
+ <paramdef>XIC<parameter> ic</parameter></paramdef>
+ <paramdef>XKeyPressedEvent<parameter> *event</parameter></paramdef>
+ <paramdef>wchar_t<parameter> *buffer_return</parameter></paramdef>
+ <paramdef>int<parameter> wchars_buffer</parameter></paramdef>
+ <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef>
+ <paramdef>Status<parameter> *status_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ic</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the input context.
+<!-- .ds Ev key event to be used -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the (Ev.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a multibyte string or wide character string (if any)
+from the input method.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes_buffer</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>wchars_buffer</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies space available in the return buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the KeySym computed from the event if this argument is not NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>status_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a value indicating what kind of data is returned.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>
+functions return the string from the input method specified
+in the buffer_return argument.
+If no string is returned,
+the buffer_return argument is unchanged.
+</para>
+<para>
+<!-- .LP -->
+The KeySym into which the KeyCode from the event was mapped is returned
+in the keysym_return argument if it is non-NULL and the status_return
+argument indicates that a KeySym was returned.
+If both a string and a KeySym are returned,
+the KeySym value does not necessarily correspond to the string returned.
+</para>
+<para>
+<!-- .LP -->
+<function>XmbLookupString</function>
+returns the length of the string in bytes, and
+<function>XwcLookupString</function>
+returns the length of the string in characters.
+Both
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>
+return text in the encoding of the locale bound to the input method
+of the specified input context.
+</para>
+<para>
+<!-- .LP -->
+Each string returned by
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>
+begins in the initial state of the encoding of the locale
+(if the encoding of the locale is state-dependent).
+<!-- .NT -->
+<note><para>
+To insure proper input processing,
+it is essential that the client pass only
+<symbol>KeyPress</symbol>
+events to
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>.
+Their behavior when a client passes a
+<symbol>KeyRelease</symbol>
+event is undefined.
+</para></note>
+<!-- .NE -->
+</para>
+<para>
+<!-- .LP -->
+Clients should check the status_return argument before
+using the other returned values.
+These two functions both return a value to status_return
+that indicates what has been returned in the other arguments.
+The possible values returned are:
+</para>
+
+<informaltable>
+ <tgroup cols='2'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <tbody>
+ <row>
+ <entry><symbol>XBufferOverflow</symbol></entry>
+ <entry>The input string to be returned is too large for the supplied buffer_return.
+ The required size
+ (<function>XmbLookupString</function>
+ in bytes;
+ <function>XwcLookupString</function>
+ in characters) is returned as the value of the function,
+ and the contents of buffer_return and keysym_return are not modified.
+ The client should recall the function with the same event
+ and a buffer of adequate size to obtain the string.</entry>
+ </row>
+ <row>
+ <entry><symbol>XLookupNone</symbol></entry>
+ <entry>No consistent input has been composed so far.
+ The contents of buffer_return and keysym_return are not modified,
+ and the function returns zero.</entry>
+ </row>
+ <row>
+ <entry><symbol>XLookupChars</symbol></entry>
+ <entry>Some input characters have been composed.
+ They are placed in the buffer_return argument,
+ and the string length is returned as the value of the function.
+ The string is encoded in the locale bound to the input context.
+ The content of the keysym_return argument is not modified.</entry>
+ </row>
+ <row>
+ <entry><symbol>XLookupKeySym</symbol></entry>
+ <entry>A KeySym has been returned instead of a string
+ and is returned in keysym_return.
+ The content of the buffer_return argument is not modified,
+ and the function returns zero.</entry>
+ </row>
+ <row>
+ <entry><symbol>XLookupBoth</symbol></entry>
+ <entry>Both a KeySym and a string are returned;
+ <symbol>XLookupChars</symbol>
+ and
+ <symbol>XLookupKeySym</symbol>
+ occur simultaneously.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+<!-- .LP -->
+It does not make any difference if the input context passed as an argument to
+<function>XmbLookupString</function>
+and
+<function>XwcLookupString</function>
+is the one currently in possession of the focus or not.
+Input may have been composed within an input context before it lost the focus,
+and that input may be returned on subsequent calls to
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>
+even though it does not have any more keyboard focus.
+</para>
+</sect2>
+<sect2 id="Input_Method_Conventions">
+<title>Input Method Conventions</title>
+<!-- .XS -->
+<!-- (SN Input Method Conventions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The input method architecture is transparent to the client.
+However, clients should respect a number of conventions in order
+to work properly.
+Clients must also be aware of possible effects of synchronization
+between input method and library in the case of a remote input server.
+</para>
+<sect3 id="Client_Conventions">
+<title>Client Conventions</title>
+<!-- .XS -->
+<!-- (SN Client Conventions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A well-behaved client (or toolkit) should first query the input method style.
+If the client cannot satisfy the requirements of the supported styles
+(in terms of geometry management or callbacks),
+it should negotiate with the user continuation of the program
+or raise an exception or error of some sort.
+</para>
+</sect3>
+<sect3 id="Synchronization_Conventions">
+<title>Synchronization Conventions</title>
+<!-- .XS -->
+<!-- (SN Synchronization Conventions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A
+<symbol>KeyPress</symbol>
+event with a KeyCode of zero is used exclusively as a
+signal that an input method has composed input that can be returned by
+<function>XmbLookupString</function>
+or
+<function>XwcLookupString</function>.
+No other use is made of a
+<symbol>KeyPress</symbol>
+event with KeyCode of zero.
+</para>
+<para>
+<!-- .LP -->
+Such an event may be generated by either a front-end
+or a back-end input method in an implementation-dependent manner.
+Some possible ways to generate this event include:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+A synthetic event sent by an input method server
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An artificial event created by a input method filter and pushed
+onto a client's event queue
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+A
+<symbol>KeyPress</symbol>
+event whose KeyCode value is modified by an input method filter
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+When callback support is specified by the client,
+input methods will not take action unless they explicitly
+called back the client and obtained no response
+(the callback is not specified or returned invalid data).
+</para>
+</sect3>
+</sect2>
+</sect1>
+<sect1 id="String_Constants">
+<title>String Constants</title>
+<!-- .XS -->
+<!-- (SN String Constants -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The following symbols for string constants are defined in
+<filename class="headerfile"><X11/Xlib.h></filename>.
+Although they are shown here with particular macro definitions,
+they may be implemented as macros, as global symbols, or as a
+mixture of the two. The string pointer value itself
+is not significant; clients must not assume that inequality of two
+values implies inequality of the actual string data.
+</para>
+
+<literallayout class="monospaced">
+#define XNVaNestedList "XNVaNestedList"
+#define XNSeparatorofNestedList "separatorofNestedList"
+#define XNQueryInputStyle "queryInputStyle"
+#define XNClientWindow "clientWindow"
+#define XNInputStyle "inputStyle"
+#define XNFocusWindow "focusWindow"
+#define XNResourceName "resourceName"
+#define XNResourceClass "resourceClass"
+#define XNGeometryCallback "geometryCallback"
+#define XNDestroyCallback "destroyCallback"
+#define XNFilterEvents "filterEvents"
+#define XNPreeditStartCallback "preeditStartCallback"
+#define XNPreeditDoneCallback "preeditDoneCallback"
+#define XNPreeditDrawCallback "preeditDrawCallback"
+#define XNPreeditCaretCallback "preeditCaretCallback"
+#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback"
+#define XNPreeditAttributes "preeditAttributes"
+#define XNStatusStartCallback "statusStartCallback"
+#define XNStatusDoneCallback "statusDoneCallback"
+#define XNStatusDrawCallback "statusDrawCallback"
+#define XNStatusAttributes "statusAttributes"
+#define XNArea "area"
+#define XNAreaNeeded "areaNeeded"
+#define XNSpotLocation "spotLocation"
+#define XNColormap "colorMap"
+#define XNStdColormap "stdColorMap"
+#define XNForeground "foreground"
+#define XNBackground "background"
+#define XNBackgroundPixmap "backgroundPixmap"
+#define XNFontSet "fontSet"
+#define XNLineSpace "lineSpace"
+#define XNCursor "cursor"
+#define XNQueryIMValuesList "queryIMValuesList"
+#define XNQueryICValuesList "queryICValuesList"
+#define XNStringConversionCallback "stringConversionCallback"
+#define XNStringConversion "stringConversion"
+#define XNResetState "resetState"
+#define XNHotKey "hotkey"
+#define XNHotKeyState "hotkeyState"
+#define XNPreeditState "preeditState"
+#define XNVisiblePosition "visiblePosition"
+#define XNR6PreeditCallbackBehavior "r6PreeditCallback"
+#define XNRequiredCharSet "requiredCharSet"
+#define XNQueryOrientation "queryOrientation"
+#define XNDirectionalDependentDrawing "directionalDependentDrawing"
+#define XNContextualDrawing "contextualDrawing"
+#define XNBaseFontName "baseFontName"
+#define XNMissingCharSet "missingCharSet"
+#define XNDefaultString "defaultString"
+#define XNOrientation "orientation"
+#define XNFontInfo "fontInfo"
+#define XNOMAutomatic "omAutomatic"
+
+</literallayout>
+
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH14.xml b/libX11/specs/libX11/CH14.xml index 20693eb13..8d6dd2e09 100644 --- a/libX11/specs/libX11/CH14.xml +++ b/libX11/specs/libX11/CH14.xml @@ -1,5223 +1,5223 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="inter_client_communication_functions"> -<title>Inter-Client Communication Functions</title> -<para> -The Inter-Client Communication Conventions Manual, hereafter referred to as the <acronym>ICCCM</acronym>, -details the X Consortium approved conventions that govern inter-client communications. These -conventions ensure peer-to-peer client cooperation in the use of selections, cut buffers, and shared -resources as well as client cooperation with window and session managers. For further information, -see the Inter-Client Communication Conventions Manual. -</para> -<para> -Xlib provides a number of standard properties and programming interfaces that are <acronym>ICCCM</acronym> -compliant. The predefined atoms for some of these properties are defined in the <X11/Xatom.h> -header file, where to avoid name conflicts with user symbols their #define name has an XA_ prefix. -For further information about atoms and properties, -see <link linkend="Properties_and_Atoms">section 4.3</link>. -</para> -<para> -Xlib’s selection and cut buffer mechanisms provide the primary programming interfaces by which -peer client applications communicate with each other -(see sections <link linkend="Selections">4.5</link> and -<link linkend="Using_Cut_Buffers">16.6</link>). The functions -discussed in this chapter provide the primary programming interfaces by which client applications -communicate with their window and session managers as well as share standard colormaps. -</para> -<para> -The standard properties that are of special interest for communicating with window and session -managers are: -</para> - -<informaltable> - <tgroup cols='4'> - <colspec colname='c1'/> - <colspec colname='c2'/> - <colspec colname='c3'/> - <colspec colname='c4'/> - <thead> - <row> - <entry align='center'>Name</entry> - <entry align='center'>Type</entry> - <entry align='center'>Format</entry> - <entry align='center'>Description</entry> - </row> - </thead> - <tbody> - <row> - <entry><property>WM_CLASS</property></entry> - <entry>STRING</entry> - <entry>8</entry> - <entry>Set by application programs to allow - window and session managers to - obtain the application’s resources - from the resource database. - </entry> - </row> - <row> - <entry><property>WM_CLIENT_MACHINE</property></entry> - <entry>TEXT</entry> - <entry></entry> - <entry>The string name of the machine on - which the client application is running. - </entry> - </row> - <row> - <entry><property>WM_COLORMAP_WINDOWS</property></entry> - <entry>WINDOWS</entry> - <entry>32</entry> - <entry>The list of window IDs that may - need a different colormap from that - of their top-level window. - </entry> - </row> - <row> - <entry><property>WM_COMMAND</property></entry> - <entry>TEXT</entry> - <entry></entry> - <entry>The command and arguments, null - separated, used to invoke the application. - </entry> - </row> - <row> - <entry><property>WM_HINTS</property></entry> - <entry><property>WM_HINTS</property></entry> - <entry>32</entry> - <entry>Additional hints set by the client for - use by the window manager. The C - type of this property is XWMHints. - </entry> - </row> - <row> - <entry><property>WM_ICON_NAME</property></entry> - <entry>TEXT</entry> - <entry></entry> - <entry>The name to be used in an icon.</entry> - </row> - <row> - <entry><property>WM_ICON_SIZE</property></entry> - <entry><property>WM_ICON_SIZE</property></entry> - <entry>32</entry> - <entry>The window manager may set this - property on the root window to - specify the icon sizes it supports. - The C type of this property is - XIconSize. - </entry> - </row> - <row> - <entry><property>WM_NAME</property></entry> - <entry>TEXT</entry> - <entry></entry> - <entry>The name of the application.</entry> - </row> - <row> - <entry><property>WM_NORMAL_HINTS</property></entry> - <entry><property>WM_NORMAL_HINTS</property></entry> - <entry>32</entry> - <entry>Size hints for a window in its - normal state. The C type of this - property is XSizeHints. - </entry> - </row> - <row> - <entry><property>WM_PROTOCOLS</property></entry> - <entry>ATOM</entry> - <entry>32</entry> - <entry>List of atoms that identify the - communications protocols between the - client and window manager in - which the client is willing to participate. - </entry> - </row> - <row> - <entry><property>WM_STATE</property></entry> - <entry><property>WM_STATE</property></entry> - <entry>32</entry> - <entry>Intended for communication - between window and session managers only. - </entry> - </row> - <row> - <entry><property>WM_TRANSIENT_FOR</property></entry> - <entry>WINDOW</entry> - <entry>32</entry> - <entry>Set by application programs to - indicate to the window manager that a - transient top-level window, such as a - dialog box. - </entry> - </row> - </tbody> - </tgroup> -</informaltable> - -<para> -The remainder of this chapter discusses: -</para> - -<itemizedlist> - <listitem><para>Client to window manager communication</para></listitem> - <listitem><para>Client to session manager communication</para></listitem> - <listitem><para>Standard colormaps</para></listitem> -</itemizedlist> - -<sect1 id="Client_to_Window_Manager_Communication"> -<title>Client to Window Manager Communication</title> -<!-- .XS --> -<!-- (SN Client to Window Manager Communication --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Manipulate top-level windows - </para> - </listitem> - <listitem> - <para> -Convert string lists - </para> - </listitem> - <listitem> - <para> -Set and read text properties - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_NAME</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_ICON_NAME</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_HINTS</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_NORMAL_HINTS</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_CLASS</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_TRANSIENT_FOR</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_PROTOCOLS</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_COLORMAP_WINDOWS</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_ICON_SIZE</property> property - </para> - </listitem> - <listitem> - <para> -Use window manager convenience functions - </para> - </listitem> -</itemizedlist> -<sect2 id="Manipulating_Top_Level_Windows"> -<title>Manipulating Top-Level Windows</title> -<!-- .XS --> -<!-- (SN Manipulating Top-Level Windows --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to change the visibility or size -of top-level windows (that is, those that were created as children -of the root window). -Note that the subwindows that you create are ignored by window managers. -Therefore, -you should use the basic window functions described in -<link linkend="window_functions">chapter 3</link> -to manipulate your application's subwindows. -</para> -<para> -<!-- .LP --> -To request that a top-level window be iconified, use -<function>XIconifyWindow</function>. -</para> -<indexterm significance="preferred"><primary>XIconifyWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xiconifywindow'> -<funcprototype> - <funcdef>Status <function>XIconifyWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XIconifyWindow</function> -function sends a <property>WM_CHANGE_STATE</property> -<symbol>ClientMessage</symbol> -event with a format of 32 and a first data element of -<symbol>IconicState</symbol> -(as described in section 4.1.4 of the -<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>) -and a window of w -to the root window of the specified screen -with an event mask set to -<symbol>SubstructureNotifyMask</symbol> | -<symbol>SubstructureRedirectMask</symbol>. -Window managers may elect to receive this message and -if the window is in its normal state, -may treat it as a request to change the window's state from normal to iconic. -If the <property>WM_CHANGE_STATE</property> property cannot be interned, -<function>XIconifyWindow</function> -does not send a message and returns a zero status. -It returns a nonzero status if the client message is sent successfully; -otherwise, it returns a zero status. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To request that a top-level window be withdrawn, use -<function>XWithdrawWindow</function>. -</para> -<indexterm significance="preferred"><primary>XWithdrawWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwithdrawwindow'> -<funcprototype> - <funcdef>Status <function>XWithdrawWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XWithdrawWindow</function> -function unmaps the specified window -and sends a synthetic -<symbol>UnmapNotify</symbol> -event to the root window of the specified screen. -Window managers may elect to receive this message -and may treat it as a request to change the window's state to withdrawn. -When a window is in the withdrawn state, -neither its normal nor its iconic representations is visible. -It returns a nonzero status if the -<symbol>UnmapNotify</symbol> -event is successfully sent; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -<function>XWithdrawWindow</function> -can generate a -<errorname>BadWindow</errorname> -error. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To request that a top-level window be reconfigured, use -<function>XReconfigureWMWindow</function>. -</para> -<indexterm significance="preferred"><primary>XReconfigureWMWindow</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xreconfigurewmwindow'> -<funcprototype> - <funcdef>Status <function>XReconfigureWMWindow</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>int<parameter> screen_number</parameter></paramdef> - <paramdef>unsignedint<parameter> value_mask</parameter></paramdef> - <paramdef>XWindowChanges<parameter> *values</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen_number</emphasis> - </term> - <listitem> - <para> -Specifies the appropriate screen number on the host server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_mask</emphasis> - </term> - <listitem> - <para> -Specifies which values are to be set using information in -the values structure. -This mask is the bitwise inclusive OR of the valid configure window values bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>values</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XWindowChanges</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XReconfigureWMWindow</function> -function issues a -<systemitem>ConfigureWindow</systemitem> -request on the specified top-level window. -If the stacking mode is changed and the request fails with a -<errorname>BadMatch</errorname> -error, -the error is trapped by Xlib and a synthetic -<systemitem class="event">ConfigureRequestEvent</systemitem> -containing the same configuration parameters is sent to the root -of the specified window. -Window managers may elect to receive this event -and treat it as a request to reconfigure the indicated window. -It returns a nonzero status if the request or event is successfully sent; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -<function>XReconfigureWMWindow</function> -can generate -<errorname>BadValue</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Converting_String_Lists"> -<title>Converting String Lists</title> -<!-- .XS --> -<!-- (SN Converting String Lists --> -<!-- .XE --> -<para> -<!-- .LP --> -Many of the text properties allow a variety of types and formats. -Because the data stored in these properties are not -simple null-terminated strings, an -<structname>XTextProperty</structname> -structure is used to describe the encoding, type, and length of the text -as well as its value. -The -<structname>XTextProperty</structname> -structure contains: -<indexterm significance="preferred"><primary>XTextProperty</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - unsigned char *value; /* property data */ - Atom encoding; /* type of property */ - int format; /* 8, 16, or 32 */ - unsigned long nitems; /* number of items in value */ -} XTextProperty; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Xlib provides functions to convert localized text to or from encodings -that support the inter-client communication conventions for text. -In addition, functions are provided for converting between lists of pointers -to character strings and text properties in the STRING encoding. -</para> -<para> -<!-- .LP --> -The functions for localized text return a signed integer error status -that encodes -<symbol>Success</symbol> -as zero, specific error conditions as negative numbers, and partial conversion -as a count of unconvertible characters. -</para> - -<literallayout class="monospaced"> - -#define #XNoMemory -1 -#define #XLocaleNotSupported -2 -#define #XConverterNotFound -3 - -typedef enum { - XStringStyle, /* STRING */ - XCompoundTextStyle, /* COMPOUND_TEXT */ - XTextStyle, /* text in owner's encoding (current locale) */ - XStdICCTextStyle /* STRING, else COMPOUND_TEXT */ -} XICCEncodingStyle; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To convert a list of text strings to an -<structname>XTextProperty</structname> -structure, use -<function>XmbTextListToTextProperty</function> -or -<function>XwcTextListToTextProperty</function>. -</para> -<indexterm significance="preferred"><primary>XmbTextListToTextProperty</primary></indexterm> -<indexterm significance="preferred"><primary>XwcTextListToTextProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbtextlisttotextproperty'> -<funcprototype> - <funcdef>int <function>XmbTextListToTextProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> **list</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>XICCEncodingStyle<parameter> style</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwctextlisttotextproperty'> -<funcprototype> - <funcdef>int <function>XwcTextListToTextProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>wchar_t<parameter> **list</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>XICCEncodingStyle<parameter> style</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies a list of null-terminated character strings. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of strings specified. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>style</emphasis> - </term> - <listitem> - <para> -Specifies the manner in which the property is encoded. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbTextListToTextProperty</function> -and -<function>XwcTextListToTextProperty</function> -functions set the specified -<structname>XTextProperty</structname> -value to a set of null-separated elements representing the concatenation -of the specified list of null-terminated text strings. -A final terminating null is stored at the end of the value field -of text_prop_return but is not included in the nitems member. -</para> -<para> -<!-- .LP --> -The functions set the encoding field of text_prop_return to an -<type>Atom</type> -for the specified display -naming the encoding determined by the specified style -and convert the specified text list to this encoding for storage in -the text_prop_return value field. -If the style -<constant>XStringStyle</constant> -or -<constant>XCompoundTextStyle</constant> -is specified, -this encoding is ``STRING'' or ``COMPOUND_TEXT'', respectively. -If the style -<constant>XTextStyle</constant> -is specified, -this encoding is the encoding of the current locale. -If the style -<constant>XStdICCTextStyle</constant> -is specified, -this encoding is ``STRING'' if the text is fully convertible to STRING, -else ``COMPOUND_TEXT''. -</para> -<para> -<!-- .LP --> -If insufficient memory is available for the new value string, -the functions return -<symbol>XNoMemory</symbol>. -If the current locale is not supported, -the functions return -<symbol>XLocaleNotSupported</symbol>. -In both of these error cases, -the functions do not set text_prop_return. -</para> -<para> -<!-- .LP --> -To determine if the functions are guaranteed not to return -<symbol>XLocaleNotSupported</symbol>, -use -<function>XSupportsLocale</function>. -</para> -<para> -<!-- .LP --> -If the supplied text is not fully convertible to the specified encoding, -the functions return the number of unconvertible characters. -Each unconvertible character is converted to an implementation-defined and -encoding-specific default string. -Otherwise, the functions return -<symbol>Success</symbol>. -Note that full convertibility to all styles except -<constant>XStringStyle</constant> -is guaranteed. -</para> -<para> -<!-- .LP --> -To free the storage for the value field, use -<function>XFree</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain a list of text strings from an -<structname>XTextProperty</structname> -structure, use -<function>XmbTextPropertyToTextList</function> -or -<function>XwcTextPropertyToTextList</function>. -</para> -<indexterm significance="preferred"><primary>XmbTextPropertyToTextList</primary></indexterm> -<indexterm significance="preferred"><primary>XwcTextPropertyToTextList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbtextpropertytotextlist'> -<funcprototype> - <funcdef>int <function>XmbTextPropertyToTextList</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> - <paramdef>char<parameter> ***list_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<funcsynopsis id='xwctextpropertytotextlist'> -<funcprototype> - <funcdef>int <function>XwcTextPropertyToTextList</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> - <paramdef>wchar_t<parameter> ***list_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list_return</emphasis> - </term> - <listitem> - <para> -Returns a list of null-terminated character strings. -<!-- .ds Cn strings --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbTextPropertyToTextList</function> -and -<function>XwcTextPropertyToTextList</function> -functions return a list of text strings in the current locale representing the -null-separated elements of the specified -<structname>XTextProperty</structname> -structure. -The data in text_prop must be format 8. -</para> -<para> -<!-- .LP --> -Multiple elements of the property (for example, the strings in a disjoint -text selection) are separated by a null byte. -The contents of the property are not required to be null-terminated; -any terminating null should not be included in text_prop.nitems. -</para> -<para> -<!-- .LP --> -If insufficient memory is available for the list and its elements, -<function>XmbTextPropertyToTextList</function> -and -<function>XwcTextPropertyToTextList</function> -return -<symbol>XNoMemory</symbol>. -If the current locale is not supported, -the functions return -<symbol>XLocaleNotSupported</symbol>. -Otherwise, if the encoding field of text_prop is not convertible -to the encoding of the current locale, -the functions return -<symbol>XConverterNotFound</symbol>. -For supported locales, -existence of a converter from COMPOUND_TEXT, STRING -or the encoding of the current locale is guaranteed if -<function>XSupportsLocale</function> -returns -<symbol>True</symbol> -for the current locale (but the actual text -may contain unconvertible characters). -Conversion of other encodings is implementation-dependent. -In all of these error cases, -the functions do not set any return values. -</para> -<para> -<!-- .LP --> -Otherwise, -<function>XmbTextPropertyToTextList</function> -and -<function>XwcTextPropertyToTextList</function> -return the list of null-terminated text strings to list_return -and the number of text strings to count_return. -</para> -<para> -<!-- .LP --> -If the value field of text_prop is not fully convertible to the encoding of -the current locale, -the functions return the number of unconvertible characters. -Each unconvertible character is converted to a string in the -current locale that is specific to the current locale. -To obtain the value of this string, -use -<function>XDefaultString</function>. -Otherwise, -<function>XmbTextPropertyToTextList</function> -and -<function>XwcTextPropertyToTextList</function> -return -<symbol>Success</symbol>. -</para> -<para> -<!-- .LP --> -To free the storage for the list and its contents returned by -<function>XmbTextPropertyToTextList</function>, -use -<function>XFreeStringList</function>. -To free the storage for the list and its contents returned by -<function>XwcTextPropertyToTextList</function>, -use -<function>XwcFreeStringList</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To free the in-memory data associated with the specified -wide character string list, use -<function>XwcFreeStringList</function>. -</para> -<indexterm significance="preferred"><primary>XwcFreeStringList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwcfreestringlist'> -<funcprototype> - <funcdef>void <function>XwcFreeStringList</function></funcdef> - <paramdef>wchar_t<parameter> **list</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the list of strings to be freed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XwcFreeStringList</function> -function frees memory allocated by -<function>XwcTextPropertyToTextList</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the default string for text conversion in the current locale, -use</para> - -<para>char *XDefaultString()</para> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDefaultString</function> -function returns the default string used by Xlib for text conversion -(for example, in -<function>XmbTextPropertyToTextList</function>). -The default string is the string in the current locale that is output -when an unconvertible character is found during text conversion. -If the string returned by -<function>XDefaultString</function> -is the empty string (""), -no character is output in the converted text. -<function>XDefaultString</function> -does not return NULL. -</para> -<para> -<!-- .LP --> -The string returned by -<function>XDefaultString</function> -is independent of the default string for text drawing; -see -<function>XCreateFontSet</function> -to obtain the default string for an -<type>XFontSet</type>. -</para> -<para> -<!-- .LP --> -The behavior when an invalid codepoint is supplied to any Xlib function is -undefined. -</para> -<para> -<!-- .LP --> -The returned string is null-terminated. -It is owned by Xlib and should not be modified or freed by the client. -It may be freed after the current locale is changed. -Until freed, it will not be modified by Xlib. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set the specified list of strings in the STRING encoding to a -<structname>XTextProperty</structname> -structure, use -<function>XStringListToTextProperty</function>. -</para> -<indexterm significance="preferred"><primary>XStringListToTextProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstringlisttotextproperty'> -<funcprototype> - <funcdef>Status <function>XStringListToTextProperty</function></funcdef> - <paramdef>char<parameter> **list</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies a list of null-terminated character strings. -<!-- .ds Cn strings --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XStringListToTextProperty</function> -function sets the specified -<structname>XTextProperty</structname> -to be of type STRING (format 8) with a value representing the -concatenation of the specified list of null-separated character strings. -An extra null byte (which is not included in the nitems member) -is stored at the end of the value field of text_prop_return. -The strings are assumed (without verification) to be in the STRING encoding. -If insufficient memory is available for the new value string, -<function>XStringListToTextProperty</function> -does not set any fields in the -<structname>XTextProperty</structname> -structure and returns a zero status. -Otherwise, it returns a nonzero status. -To free the storage for the value field, use -<function>XFree</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain a list of strings from a specified -<structname>XTextProperty</structname> -structure in the STRING encoding, use -<function>XTextPropertyToStringList</function>. -</para> -<indexterm significance="preferred"><primary>XTextPropertyToStringList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xtextpropertytostringlist'> -<funcprototype> - <funcdef>Status <function>XTextPropertyToStringList</function></funcdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> - <paramdef>char<parameter> ***list_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list_return</emphasis> - </term> - <listitem> - <para> -Returns a list of null-terminated character strings. -<!-- .ds Cn strings --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XTextPropertyToStringList</function> -function returns a list of strings representing the null-separated elements -of the specified -<structname>XTextProperty</structname> -structure. -The data in text_prop must be of type STRING and format 8. -Multiple elements of the property -(for example, the strings in a disjoint text selection) -are separated by NULL (encoding 0). -The contents of the property are not null-terminated. -If insufficient memory is available for the list and its elements, -<function>XTextPropertyToStringList</function> -sets no return values and returns a zero status. -Otherwise, it returns a nonzero status. -To free the storage for the list and its contents, use -<function>XFreeStringList</function>. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To free the in-memory data associated with the specified string list, use -<function>XFreeStringList</function>. -</para> -<indexterm significance="preferred"><primary>XFreeStringList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfreestringlist'> -<funcprototype> - <funcdef>void <function>XFreeStringList</function></funcdef> - <paramdef>char<parameter> **list</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the list of strings to be freed. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFreeStringList</function> -function releases memory allocated by -<function>XmbTextPropertyToTextList</function> -and -<function>XTextPropertyToStringList</function> -and the missing charset list allocated by -<function>XCreateFontSet</function>. -</para> -</sect2> -<sect2 id="Setting_and_Reading_Text_Properties"> -<title>Setting and Reading Text Properties</title> -<!-- .XS --> -<!-- (SN Setting and Reading Text Properties --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides two functions that you can use to set and read -the text properties for a given window. -You can use these functions to set and read those properties of type TEXT -(<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property>). -In addition, -Xlib provides separate convenience functions that you can use to set each -of these properties. -For further information about these convenience functions, -see sections -<link linkend="Setting_and_Reading_the_WM_NAME_Property">14.1.4</link>, -<link linkend="Setting_and_Reading_the_WM_ICON_NAME_Property">14.1.5</link>, -<link linkend="Setting_and_Reading_the_WM_COMMAND_Property">14.2.1</link>, and -<link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">14.2.2</link>, -respectively. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set one of a window's text properties, use -<function>XSetTextProperty</function>. -</para> -<indexterm significance="preferred"><primary>XSetTextProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsettextproperty'> -<funcprototype> - <funcdef>void <function>XSetTextProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetTextProperty</function> -function replaces the existing specified property for the named window -with the data, type, format, and number of items determined -by the value field, the encoding field, the format field, -and the nitems field, respectively, of the specified -<structname>XTextProperty</structname> -structure. -If the property does not already exist, -<function>XSetTextProperty</function> -sets it for the specified window. -</para> -<para> -<!-- .LP --> -<function>XSetTextProperty</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -<errorname>BadValue</errorname>, -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read one of a window's text properties, use -<function>XGetTextProperty</function>. -</para> -<indexterm significance="preferred"><primary>XGetTextProperty</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgettextproperty'> -<funcprototype> - <funcdef>Status <function>XGetTextProperty</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetTextProperty</function> -function reads the specified property from the window -and stores the data in the returned -<structname>XTextProperty</structname> -structure. -It stores the data in the value field, -the type of the data in the encoding field, -the format of the data in the format field, -and the number of items of data in the nitems field. -An extra byte containing null (which is not included in the nitems member) -is stored at the end of the value field of text_prop_return. -The particular interpretation of the property's encoding -and data as text is left to the calling application. -If the specified property does not exist on the window, -<function>XGetTextProperty</function> -sets the value field to NULL, -the encoding field to -<symbol>None</symbol>, -the format field to zero, -and the nitems field to zero. -</para> -<para> -<!-- .LP --> -If it was able to read and store the data in the -<structname>XTextProperty</structname> -structure, -<function>XGetTextProperty</function> -returns a nonzero status; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -<function>XGetTextProperty</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_NAME_Property"> -<title>Setting and Reading the WM_NAME Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_NAME Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides convenience functions that you can use to set and read -the <property>WM_NAME</property> property for a given window. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_NAME</property> property with the supplied convenience function, use -<function>XSetWMName</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmname'> -<funcprototype> - <funcdef>void <function>XSetWMName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMName</function> -convenience function calls -<function>XSetTextProperty</function> -to set the <property>WM_NAME</property> property. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_NAME</property> property with the supplied convenience function, use -<function>XGetWMName</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmname'> -<funcprototype> - <funcdef>Status <function>XGetWMName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMName</function> -convenience function calls -<function>XGetTextProperty</function> -to obtain the <property>WM_NAME</property> property. -It returns a nonzero status on success; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -The following two functions have been superseded by -<function>XSetWMName</function> -and -<function>XGetWMName</function>, -respectively. -You can use these additional convenience functions -for window names that are encoded as STRING properties. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To assign a name to a window, use -<function>XStoreName</function>. -</para> -<indexterm><primary>Window</primary><secondary>name</secondary></indexterm> -<indexterm significance="preferred"><primary>XStoreName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorename'> -<funcprototype> - <funcdef><function>XStoreName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> *window_name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_name</emphasis> - </term> - <listitem> - <para> -Specifies the window name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XStoreName</function> -function assigns the name passed to window_name to the specified window. -A window manager can display the window name in some prominent -place, such as the title bar, to allow users to identify windows easily. -Some window managers may display a window's name in the window's icon, -although they are encouraged to use the window's icon name -if one is provided by the application. -If the string is not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -<function>XStoreName</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the name of a window, use -<function>XFetchName</function>. -</para> -<indexterm significance="preferred"><primary>XFetchName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfetchname'> -<funcprototype> - <funcdef>Status <function>XFetchName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> **window_name_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_name_return</emphasis> - </term> - <listitem> - <para> -Returns the window name, which is a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFetchName</function> -function returns the name of the specified window. -If it succeeds, -it returns a nonzero status; -otherwise, no name has been set for the window, -and it returns zero. -If the <property>WM_NAME</property> property has not been set for this window, -<function>XFetchName</function> -sets window_name_return to NULL. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned string is in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -When finished with it, a client must free -the window name string using -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XFetchName</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_ICON_NAME_Property"> -<title>Setting and Reading the WM_ICON_NAME Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_ICON_NAME Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides convenience functions that you can use to set and read -the <property>WM_ICON_NAME</property> property for a given window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_ICON_NAME</property> property, -use -<function>XSetWMIconName</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMIconName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmiconname'> -<funcprototype> - <funcdef>void <function>XSetWMIconName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMIconName</function> -convenience function calls -<function>XSetTextProperty</function> -to set the <property>WM_ICON_NAME</property> property. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_ICON_NAME</property> property, -use -<function>XGetWMIconName</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMIconName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmiconname'> -<funcprototype> - <funcdef>Status <function>XGetWMIconName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMIconName</function> -convenience function calls -<function>XGetTextProperty</function> -to obtain the <property>WM_ICON_NAME</property> property. -It returns a nonzero status on success; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -The next two functions have been superseded by -<function>XSetWMIconName</function> -and -<function>XGetWMIconName</function>, -respectively. -You can use these additional convenience functions -for window names that are encoded as STRING properties. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the name to be displayed in a window's icon, use -<function>XSetIconName</function>. -</para> -<indexterm><primary>Window</primary><secondary>icon name</secondary></indexterm> -<indexterm significance="preferred"><primary>XSetIconName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xseticonname'> -<funcprototype> - <funcdef><function>XSetIconName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> *icon_name</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_name</emphasis> - </term> - <listitem> - <para> -Specifies the icon name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the string is not in the Host Portable Character Encoding, -the result is implementation-dependent. -<function>XSetIconName</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the name a window wants displayed in its icon, use -<function>XGetIconName</function>. -</para> -<indexterm significance="preferred"><primary>XGetIconName</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeticonname'> -<funcprototype> - <funcdef>Status <function>XGetIconName</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> **icon_name_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_name_return</emphasis> - </term> - <listitem> - <para> -Returns the window's icon name, -which is a null-terminated string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetIconName</function> -function returns the name to be displayed in the specified window's icon. -If it succeeds, it returns a nonzero status; otherwise, -if no icon name has been set for the window, -it returns zero. -If you never assigned a name to the window, -<function>XGetIconName</function> -sets icon_name_return to NULL. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned string is in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -When finished with it, a client must free -the icon name string using -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetIconName</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_HINTS_Property"> -<title>Setting and Reading the WM_HINTS Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_HINTS Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_HINTS</property> property for a given window. -These functions use the flags and the -<structname>XWMHints</structname> -structure, as defined in the -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -header file. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To allocate an -<structname>XWMHints</structname> -structure, use -<function>XAllocWMHints</function>. -</para> - -<para> - XWMHints *XAllocWMHints() -</para> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocWMHints</function> -function allocates and returns a pointer to an -<structname>XWMHints</structname> -structure. -Note that all fields in the -<structname>XWMHints</structname> -structure are initially set to zero. -If insufficient memory is available, -<function>XAllocWMHints</function> -returns NULL. -To free the memory allocated to this structure, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XWMHints</structname> -structure contains: -</para> - -<literallayout class="monospaced"> -/* Window manager hints mask bits */ - -#define InputHint (1L<<0) -#define StateHint (1L<<1) -#define IconPixmapHint (1L<<2) -#define IconWindowHint (1L<<3) -#define IconPositionHint (1L<<4) -#define IconMaskHint (1L<<5) -#define WindowGroupHint (1L<<6) -#define UrgencyHint (1L<<8) -#define AllHints (InputHint|StateHint|IconPixmapHint| - IconWIndowHint|IconPositionHint| - IconMaskHint|WindowGroupHint) - - -/* Values */ - -typedef struct { - long flags; /* marks which fields in this structure are defined */ - Bool input; /* does this application rely on the window manager to - get keyboard input? */ - int initial_state; /* see below */ - Pixmap icon_pixmap; /* pixmap to be used as icon */ - Window icon_window; /* window to be used as icon */ - int icon_x, icon_y; /* initial position of icon */ - Pixmap icon_mask; /* pixmap to be used as mask for icon_pixmap */ - XID window_group; /* id of related window group */ - /* this structure may be extended in the future */ -} XWMHints; -</literallayout> -<para> -<!-- .LP --> -<!-- .eM --> -The input member is used to communicate to the window manager the input focus -model used by the application. -Applications that expect input but never explicitly set focus to any -of their subwindows (that is, use the push model of focus management), -such as X Version 10 style applications that use real-estate -driven focus, should set this member to -<symbol>True</symbol>. -Similarly, applications -that set input focus to their subwindows only when it is given to their -top-level window by a window manager should also set this member to -<symbol>True</symbol>. -Applications that manage their own input focus by explicitly setting -focus to one of their subwindows whenever they want keyboard input -(that is, use the pull model of focus management) should set this member to -<symbol>False</symbol>. -Applications that never expect any keyboard input also should set this member -to -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -Pull model window managers should make it possible for push model -applications to get input by setting input focus to the top-level windows of -applications whose input member is -<symbol>True</symbol>. -Push model window managers should -make sure that pull model applications do not break them -by resetting input focus to -<symbol>PointerRoot</symbol> -when it is appropriate (for example, whenever an application whose -input member is -<symbol>False</symbol> -sets input focus to one of its subwindows). -</para> -<para> -<!-- .LP --> -The definitions for the initial_state flag are: -</para> - -<literallayout class="monospaced"> -#define WithdrawnState 0 -#define NormalState 1 /* most applications start this way */ -#define IconicState 2 /* application wants to start as an icon */ - -</literallayout> -<para> -The icon_mask specifies which pixels of the icon_pixmap should be used as the -icon. -This allows for nonrectangular icons. -Both icon_pixmap and icon_mask must be bitmaps. -The icon_window lets an application provide a window for use as an icon -for window managers that support such use. -The window_group lets you specify that this window belongs to a group -of other windows. -For example, if a single application manipulates multiple -top-level windows, this allows you to provide enough -information that a window manager can iconify all of the windows -rather than just the one window. -</para> -<para> -<!-- .LP --> -The -<symbol>UrgencyHint</symbol> -flag, if set in the flags field, indicates that the client deems the window -contents to be urgent, requiring the timely response of the user. The -window manager will make some effort to draw the user's attention to this -window while this flag is set. The client must provide some means by which the -user can cause the urgency flag to be cleared (either mitigating -the condition that made the window urgent or merely shutting off the alarm) -or the window to be withdrawn. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_HINTS</property> property, use -<function>XSetWMHints</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmhints'> -<funcprototype> - <funcdef><function>XSetWMHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XWMHints<parameter> *wmhints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>wmhints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XWMHints</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMHints</function> -function sets the window manager hints that include icon information and location, -the initial state of the window, and whether the application relies on the -window manager to get keyboard input. -</para> -<para> -<!-- .LP --> -<function>XSetWMHints</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a window's <property>WM_HINTS</property> property, use -<function>XGetWMHints</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmhints'> -<funcprototype> - <funcdef>XWMHints *<function>XGetWMHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMHints</function> -function reads the window manager hints and -returns NULL if no <property>WM_HINTS</property> property was set on the window -or returns a pointer to an -<structname>XWMHints</structname> -structure if it succeeds. -When finished with the data, -free the space used for it by calling -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetWMHints</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_NORMAL_HINTS_Property"> -<title>Setting and Reading the WM_NORMAL_HINTS Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_NORMAL_HINTS Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set or read -the <property>WM_NORMAL_HINTS</property> property for a given window. -The functions use the flags and the -<structname>XSizeHints</structname> -structure, as defined in the -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -header file. -</para> -<para> -<!-- .LP --> -The size of the -<structname>XSizeHints</structname> -structure may grow in future releases, as new components are -added to support new <acronym>ICCCM</acronym> features. -Passing statically allocated instances of this structure into -Xlib may result in memory corruption when running against a -future release of the library. -As such, it is recommended that only dynamically allocated -instances of the structure be used. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To allocate an -<structname>XSizeHints</structname> -structure, use -<function>XAllocSizeHints</function>. -</para> - -<para> -XSizeHints *XAllocSizeHints() -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocSizeHints</function> -function allocates and returns a pointer to an -<structname>XSizeHints</structname> -structure. -Note that all fields in the -<structname>XSizeHints</structname> -structure are initially set to zero. -If insufficient memory is available, -<function>XAllocSizeHints</function> -returns NULL. -To free the memory allocated to this structure, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XSizeHints</structname> -structure contains: -</para> - - -<literallayout class="monospaced"> -/* Size hints mask bits */ - -#define USPosition (1L<<0) /* user specified x,y */ -#define USSize (1L<<1) /* user specified width,height */ -#define PPosition (1L<<2) /* program specified posistion */ -#define PSize (1L<<3) /* program specified size */ -#define PMinSize (1L<<4) /* program specified minimum size */ -#define PMaxSize (1L<<5) /* program specified maximum size */ -#define PResizeInc (1L<<5) /* program specified resize increments */ -#define PAspect (1L<<6) /* program specified min and max aspect ratios */ -#define PBaseSize (1L<<8) -#define PWinGravity (1L<<9) -#define PAllHints (PPosition|Psize| - PMinSize|PMaxSize| - PResizeInc|PAspect) - - -/* Values */ - -typedef struct { - long flags; /* marks which fields in this structure are defined */ - int x, y; /* Obsolete */ - int width, height; /* Obsolete */ - int min_width, min_height; - int max_width, max_height; - int width_inc, height_inc; - struct { - int x; /* numerator */ - int y; /* denominator */ - } min_aspect, max_aspect; - int base_width, base_height; - int win_gravity; - /* this structure may be extended in the future */ -} XSizeHints; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The x, y, width, and height members are now obsolete -and are left solely for compatibility reasons. -The min_width and min_height members specify the -minimum window size that still allows the application to be useful. -The max_width and max_height members specify the maximum window size. -The width_inc and height_inc members define an arithmetic progression of -sizes (minimum to maximum) into which the window prefers to be resized. -The min_aspect and max_aspect members are expressed -as ratios of x and y, -and they allow an application to specify the range of aspect -ratios it prefers. -The base_width and base_height members define the desired size of the window. -The window manager will interpret the position of the window -and its border width to position the point of the outer rectangle -of the overall window specified by the win_gravity member. -The outer rectangle of the window includes any borders or decorations -supplied by the window manager. -In other words, -if the window manager decides to place the window where the client asked, -the position on the parent window's border named by the win_gravity -will be placed where the client window would have been placed -in the absence of a window manager. -</para> -<para> -<!-- .LP --> -Note that use of the -<symbol>PAllHints</symbol> -macro is highly discouraged. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_NORMAL_HINTS</property> property, use -<function>XSetWMNormalHints</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMNormalHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmnormalhints'> -<funcprototype> - <funcdef>void <function>XSetWMNormalHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMNormalHints</function> -function replaces the size hints for the <property>WM_NORMAL_HINTS</property> property -on the specified window. -If the property does not already exist, -<function>XSetWMNormalHints</function> -sets the size hints for the <property>WM_NORMAL_HINTS</property> property on the specified window. -The property is stored with a type of <property>WM_SIZE_HINTS</property> and a format of 32. -</para> -<para> -<!-- .LP --> -<function>XSetWMNormalHints</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_NORMAL_HINTS</property> property, use -<function>XGetWMNormalHints</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMNormalHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmnormalhints'> -<funcprototype> - <funcdef>Status <function>XGetWMNormalHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef> - <paramdef>long<parameter> *supplied_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints_return</emphasis> - </term> - <listitem> - <para> -Returns the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>supplied_return</emphasis> - </term> - <listitem> - <para> -Returns the hints that were supplied by the user. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMNormalHints</function> -function returns the size hints stored in the <property>WM_NORMAL_HINTS</property> property -on the specified window. -If the property is of type <property>WM_SIZE_HINTS</property>, is of format 32, -and is long enough to contain either an old (pre-<acronym>ICCCM</acronym>) -or new size hints structure, -<function>XGetWMNormalHints</function> -sets the various fields of the -<structname>XSizeHints</structname> -structure, sets the supplied_return argument to the list of fields -that were supplied by the user (whether or not they contained defined values), -and returns a nonzero status. -Otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -If -<function>XGetWMNormalHints</function> -returns successfully and a pre-<acronym>ICCCM</acronym> size hints property is read, -the supplied_return argument will contain the following bits: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -(USPosition|USSize|PPosition|PSize|PMinSize| - PMaxSize|PResizeInc|PAspect) -</literallayout> -</para> -<para> -<!-- .LP --> -If the property is large enough to contain the base size -and window gravity fields as well, -the supplied_return argument will also contain the following bits: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -PBaseSize|PWinGravity -</literallayout> -</para> -<para> -<!-- .LP --> -<function>XGetWMNormalHints</function> -can generate a -<errorname>BadWindow</errorname> -error. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_SIZE_HINTS</property> property, use -<function>XSetWMSizeHints</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMSizeHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmsizehints'> -<funcprototype> - <funcdef>void <function>XSetWMSizeHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XSizeHints</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMSizeHints</function> -function replaces the size hints for the specified property -on the named window. -If the specified property does not already exist, -<function>XSetWMSizeHints</function> -sets the size hints for the specified property -on the named window. -The property is stored with a type of <property>WM_SIZE_HINTS</property> and a format of 32. -To set a window's normal size hints, -you can use the -<function>XSetWMNormalHints</function> -function. -</para> -<para> -<!-- .LP --> -<function>XSetWMSizeHints</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_SIZE_HINTS</property> property, use -<function>XGetWMSizeHints</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMSizeHints</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmsizehints'> -<funcprototype> - <funcdef>Status <function>XGetWMSizeHints</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef> - <paramdef>long<parameter> *supplied_return</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XSizeHints</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>supplied_return</emphasis> - </term> - <listitem> - <para> -Returns the hints that were supplied by the user. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMSizeHints</function> -function returns the size hints stored in the specified property -on the named window. -If the property is of type <property>WM_SIZE_HINTS</property>, is of format 32, -and is long enough to contain either an old (pre-<acronym>ICCCM</acronym>) -or new size hints structure, -<function>XGetWMSizeHints</function> -sets the various fields of the -<structname>XSizeHints</structname> -structure, sets the supplied_return argument to the -list of fields that were supplied by the user -(whether or not they contained defined values), -and returns a nonzero status. -Otherwise, it returns a zero status. -To get a window's normal size hints, -you can use the -<function>XGetWMNormalHints</function> -function. -</para> -<para> -<!-- .LP --> -If -<function>XGetWMSizeHints</function> -returns successfully and a pre-<acronym>ICCCM</acronym> size hints property is read, -the supplied_return argument will contain the following bits: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -(USPosition|USSize|PPosition|PSize|PMinSize| - PMaxSize|PResizeInc|PAspect) -</literallayout> -</para> -<para> -<!-- .LP --> -If the property is large enough to contain the base size -and window gravity fields as well, -the supplied_return argument will also contain the following bits: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -PBaseSize|PWinGravity -</literallayout> -</para> -<para> -<!-- .LP --> -<function>XGetWMSizeHints</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_CLASS_Property"> -<title>Setting and Reading the WM_CLASS Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_CLASS Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and get -the <property>WM_CLASS</property> property for a given window. -These functions use the -<structname>XClassHint</structname> -structure, which is defined in the -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -header file. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To allocate an -<structname>XClassHint</structname> -structure, use -<function>XAllocClassHint</function>. -<indexterm significance="preferred"><primary>XAllocClassHint</primary></indexterm> -<!-- .sM --> -</para> -<para> - - XClassHint *XAllocClassHint() -</para> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocClassHint</function> -function allocates and returns a pointer to an -<structname>XClassHint</structname> -structure. -Note that the pointer fields in the -<structname>XClassHint</structname> -structure are initially set to NULL. -If insufficient memory is available, -<function>XAllocClassHint</function> -returns NULL. -To free the memory allocated to this structure, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XClassHint</structname> -contains: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<indexterm significance="preferred"><primary>XClassHint</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i --> -<!-- .ta .5i --> -typedef struct { - char *res_name; - char *res_class; -} XClassHint; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The res_name member contains the application name, -and the res_class member contains the application class. -Note that the name set in this property may differ from the name set as <property>WM_NAME</property>. -That is, <property>WM_NAME</property> specifies what should be displayed in the title bar and, -therefore, can contain temporal information (for example, the name of -a file currently in an editor's buffer). -On the other hand, -the name specified as part of <property>WM_CLASS</property> is the formal name of the application -that should be used when retrieving the application's resources from the -resource database. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_CLASS</property> property, use -<function>XSetClassHint</function>. -</para> -<indexterm significance="preferred"><primary>XSetClassHint</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetclasshint'> -<funcprototype> - <funcdef><function>XSetClassHint</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class_hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XClassHint</structname> -structure that is to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetClassHint</function> -function sets the class hint for the specified window. -If the strings are not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -<function>XSetClassHint</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a window's <property>WM_CLASS</property> property, use -<function>XGetClassHint</function>. -</para> -<indexterm significance="preferred"><primary>XGetClassHint</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetclasshint'> -<funcprototype> - <funcdef>Status <function>XGetClassHint</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XClassHint<parameter> *class_hints_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class_hints_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XClassHint</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetClassHint</function> -function returns the class hint of the specified window to the members -of the supplied structure. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned strings are in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -It returns a nonzero status on success; -otherwise, it returns a zero status. -To free res_name and res_class when finished with the strings, -use -<function>XFree</function> -on each individually. -</para> -<para> -<!-- .LP --> -<function>XGetClassHint</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_TRANSIENT_FOR_Property"> -<title>Setting and Reading the WM_TRANSIENT_FOR Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_TRANSIENT_FOR Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_TRANSIENT_FOR</property> property for a given window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_TRANSIENT_FOR</property> property, use -<function>XSetTransientForHint</function>. -</para> -<indexterm significance="preferred"><primary>XSetTransientForHint</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsettransientforhint'> -<funcprototype> - <funcdef><function>XSetTransientForHint</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> prop_window</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>prop_window</emphasis> - </term> - <listitem> - <para> -Specifies the window that the <property>WM_TRANSIENT_FOR</property> property is to be set to. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetTransientForHint</function> -function sets the <property>WM_TRANSIENT_FOR</property> property of the specified window to the -specified prop_window. -</para> -<para> -<!-- .LP --> -<function>XSetTransientForHint</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a window's <property>WM_TRANSIENT_FOR</property> property, use -<function>XGetTransientForHint</function>. -</para> -<indexterm significance="preferred"><primary>XGetTransientForHint</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgettransientforhint'> -<funcprototype> - <funcdef>Status <function>XGetTransientForHint</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> *prop_window_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>prop_window_return</emphasis> - </term> - <listitem> - <para> -Returns the <property>WM_TRANSIENT_FOR</property> property of the specified window. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetTransientForHint</function> -function returns the <property>WM_TRANSIENT_FOR</property> property for the specified window. -It returns a nonzero status on success; -otherwise, it returns a zero status. -</para> -<para> -<!-- .LP --> -<function>XGetTransientForHint</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_PROTOCOLS_Property"> -<title>Setting and Reading the WM_PROTOCOLS Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_PROTOCOLS Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_PROTOCOLS</property> property for a given window. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_PROTOCOLS</property> property, use -<function>XSetWMProtocols</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMProtocols</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmprotocols'> -<funcprototype> - <funcdef>Status <function>XSetWMProtocols</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Atom<parameter> *protocols</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>protocols</emphasis> - </term> - <listitem> - <para> -Specifies the list of protocols. -<!-- .ds Cn protocols in the list --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMProtocols</function> -function replaces the <property>WM_PROTOCOLS</property> property on the specified window -with the list of atoms specified by the protocols argument. -If the property does not already exist, -<function>XSetWMProtocols</function> -sets the <property>WM_PROTOCOLS</property> property on the specified window -to the list of atoms specified by the protocols argument. -The property is stored with a type of ATOM and a format of 32. -If it cannot intern the <property>WM_PROTOCOLS</property> atom, -<function>XSetWMProtocols</function> -returns a zero status. -Otherwise, it returns a nonzero status. -</para> -<para> -<!-- .LP --> -<function>XSetWMProtocols</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_PROTOCOLS</property> property, use -<function>XGetWMProtocols</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMProtocols</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmprotocols'> -<funcprototype> - <funcdef>Status <function>XGetWMProtocols</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Atom<parameter> **protocols_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>protocols_return</emphasis> - </term> - <listitem> - <para> -Returns the list of protocols. -<!-- .ds Cn protocols in the list --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMProtocols</function> -function returns the list of atoms stored in the <property>WM_PROTOCOLS</property> property -on the specified window. -These atoms describe window manager protocols in which the owner -of this window is willing to participate. -If the property exists, is of type ATOM, is of format 32, -and the atom <property>WM_PROTOCOLS</property> can be interned, -<function>XGetWMProtocols</function> -sets the protocols_return argument to a list of atoms, -sets the count_return argument to the number of elements in the list, -and returns a nonzero status. -Otherwise, it sets neither of the return arguments -and returns a zero status. -To release the list of atoms, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetWMProtocols</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_COLORMAP_WINDOWS_Property"> -<title>Setting and Reading the WM_COLORMAP_WINDOWS Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_COLORMAP_WINDOWS Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_COLORMAP_WINDOWS</property> property for a given window. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_COLORMAP_WINDOWS</property> property, use -<function>XSetWMColormapWindows</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMColormapWindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmcolormapwindows'> -<funcprototype> - <funcdef>Status <function>XSetWMColormapWindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> *colormap_windows</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap_windows</emphasis> - </term> - <listitem> - <para> -Specifies the list of windows. -<!-- .ds Cn windows in the list --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMColormapWindows</function> -function replaces the <property>WM_COLORMAP_WINDOWS</property> property on the specified -window with the list of windows specified by the colormap_windows argument. -If the property does not already exist, -<function>XSetWMColormapWindows</function> -sets the <property>WM_COLORMAP_WINDOWS</property> property on the specified -window to the list of windows specified by the colormap_windows argument. -The property is stored with a type of WINDOW and a format of 32. -If it cannot intern the <property>WM_COLORMAP_WINDOWS</property> atom, -<function>XSetWMColormapWindows</function> -returns a zero status. -Otherwise, it returns a nonzero status. -</para> -<para> -<!-- .LP --> -<function>XSetWMColormapWindows</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_COLORMAP_WINDOWS</property> property, use -<function>XGetWMColormapWindows</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMColormapWindows</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmcolormapwindows'> -<funcprototype> - <funcdef>Status <function>XGetWMColormapWindows</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>Window<parameter> **colormap_windows_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>colormap_windows_return</emphasis> - </term> - <listitem> - <para> -Returns the list of windows. -<!-- .ds Cn windows in the list --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMColormapWindows</function> -function returns the list of window identifiers stored -in the <property>WM_COLORMAP_WINDOWS</property> property on the specified window. -These identifiers indicate the colormaps that the window manager -may need to install for this window. -If the property exists, is of type WINDOW, is of format 32, -and the atom <property>WM_COLORMAP_WINDOWS</property> can be interned, -<function>XGetWMColormapWindows</function> -sets the windows_return argument to a list of window identifiers, -sets the count_return argument to the number of elements in the list, -and returns a nonzero status. -Otherwise, it sets neither of the return arguments -and returns a zero status. -To release the list of window identifiers, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetWMColormapWindows</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_ICON_SIZE_Property"> -<title>Setting and Reading the WM_ICON_SIZE Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_ICON_SIZE Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_ICON_SIZE</property> property for a given window. -These functions use the -<structname>XIconSize</structname> -<indexterm><primary>XIconSize</primary></indexterm> -structure, which is defined in the -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -header file. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To allocate an -<structname>XIconSize</structname> -structure, use -<function>XAllocIconSize</function>. -</para> - -<para> - XIconSize *XAllocIconSize() -</para> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocIconSize</function> -function allocates and returns a pointer to an -<structname>XIconSize</structname> -structure. -Note that all fields in the -<structname>XIconSize</structname> -structure are initially set to zero. -If insufficient memory is available, -<function>XAllocIconSize</function> -returns NULL. -To free the memory allocated to this structure, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XIconSize</structname> -structure contains: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<indexterm significance="preferred"><primary>XIconSize</primary></indexterm> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - int min_width, min_height; - int max_width, max_height; - int width_inc, height_inc; -} XIconSize; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The width_inc and height_inc members define an arithmetic progression of -sizes (minimum to maximum) that represent the supported icon sizes. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a window's <property>WM_ICON_SIZE</property> property, use -<function>XSetIconSizes</function>. -</para> -<indexterm significance="preferred"><primary>XSetIconSizes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xseticonsizes'> -<funcprototype> - <funcdef><function>XSetIconSizes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XIconSize<parameter> *size_list</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>size_list</emphasis> - </term> - <listitem> - <para> -Specifies the size list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of items in the size list. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetIconSizes</function> -function is used only by window managers to set the supported icon sizes. -</para> -<para> -<!-- .LP --> -<function>XSetIconSizes</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a window's <property>WM_ICON_SIZE</property> property, use -<function>XGetIconSizes</function>. -</para> -<indexterm significance="preferred"><primary>XGetIconSizes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgeticonsizes'> -<funcprototype> - <funcdef>Status <function>XGetIconSizes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XIconSize<parameter> **size_list_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>size_list_return</emphasis> - </term> - <listitem> - <para> -Returns the size list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of items in the size list. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetIconSizes</function> -function returns zero if a window manager has not set icon sizes; -otherwise, it returns nonzero. -<function>XGetIconSizes</function> -should be called by an application that -wants to find out what icon sizes would be most appreciated by the -window manager under which the application is running. -The application -should then use -<function>XSetWMHints</function> -to supply the window manager with an icon pixmap or window in one of the -supported sizes. -To free the data allocated in size_list_return, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<function>XGetIconSizes</function> -can generate a -<errorname>BadWindow</errorname> -error. -</para> -</sect2> -<sect2 id="Using_Window_Manager_Convenience_Functions"> -<title>Using Window Manager Convenience Functions</title> -<!-- .XS --> -<!-- (SN Using Window Manager Convenience Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<function>XmbSetWMProperties</function> -function stores the standard set of window manager properties, -with text properties in standard encodings -for internationalized text communication. -The standard window manager properties for a given window are -<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_NORMAL_HINTS</property>, <property>WM_CLASS</property>, -<property>WM_COMMAND</property>, <property>WM_CLIENT_MACHINE</property>, and <property>WM_LOCALE_NAME</property>. -</para> -<indexterm significance="preferred"><primary>XmbSetWMProperties</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmbsetwmproperties'> -<funcprototype> - <funcdef>void <function>XmbSetWMProperties</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> *window_name</parameter></paramdef> - <paramdef>char<parameter> *icon_name</parameter></paramdef> - <paramdef>char<parameter> *argv[]</parameter></paramdef> - <paramdef>int<parameter> argc</parameter></paramdef> - <paramdef>XSizeHints<parameter> *normal_hints</parameter></paramdef> - <paramdef>XWMHints<parameter> *wm_hints</parameter></paramdef> - <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_name</emphasis> - </term> - <listitem> - <para> -Specifies the window name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_name</emphasis> - </term> - <listitem> - <para> -Specifies the icon name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv</emphasis> - </term> - <listitem> - <para> -Specifies the application's argument list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc</emphasis> - </term> - <listitem> - <para> -Specifies the number of arguments. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>wm_hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XWMHints</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class_hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XClassHint</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XmbSetWMProperties</function> -convenience function provides a simple programming interface -for setting those essential window properties that are used -for communicating with other clients -(particularly window and session managers). -</para> -<para> -<!-- .LP --> -If the window_name argument is non-NULL, -<function>XmbSetWMProperties</function> -sets the <property>WM_NAME</property> property. -If the icon_name argument is non-NULL, -<function>XmbSetWMProperties</function> -sets the <property>WM_ICON_NAME</property> property. -The window_name and icon_name arguments are null-terminated strings -in the encoding of the current locale. -If the arguments can be fully converted to the STRING encoding, -the properties are created with type ``STRING''; -otherwise, the arguments are converted to Compound Text, -and the properties are created with type ``COMPOUND_TEXT''. -</para> -<para> -<!-- .LP --> -If the normal_hints argument is non-NULL, -<function>XmbSetWMProperties</function> -calls -<function>XSetWMNormalHints</function>, -which sets the <property>WM_NORMAL_HINTS</property> property -(see <link linkend="Setting_and_Reading_the_WM_NORMAL_HINTS_Property">section 14.1.7</link>). -If the wm_hints argument is non-NULL, -<function>XmbSetWMProperties</function> -calls -<function>XSetWMHints</function>, -which sets the <property>WM_HINTS</property> property -(see <link linkend="Setting_and_Reading_the_WM_HINTS_Property">section 14.1.6</link>). -</para> -<para> -<!-- .LP --> -If the argv argument is non-NULL, -<function>XmbSetWMProperties</function> -sets the <property>WM_COMMAND</property> property from argv and argc. -An argc of zero indicates a zero-length command. -</para> -<para> -<!-- .LP --> -The hostname of the machine is stored using -<function>XSetWMClientMachine</function> -(see <link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">section 14.2.2</link>). -</para> -<para> -<!-- .LP --> -If the class_hints argument is non-NULL, -<function>XmbSetWMProperties</function> -sets the <property>WM_CLASS</property> property. -If the res_name member in the -<structname>XClassHint</structname> -structure is set to the NULL pointer and the RESOURCE_NAME -environment variable is set, -the value of the environment variable is substituted for res_name. -If the res_name member is NULL, -the environment variable is not set, and argv and argv[0] are set, -then the value of argv[0], stripped of any directory prefixes, -is substituted for res_name. -</para> -<para> -<!-- .LP --> -It is assumed that the supplied class_hints.res_name and argv, -the RESOURCE_NAME environment variable, and the hostname of the machine -are in the encoding of the locale announced for the LC_CTYPE category -(on <acronym>POSIX</acronym>-compliant systems, the LC_CTYPE, else LANG environment variable). -The corresponding <property>WM_CLASS</property>, <property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property> properties -are typed according to the local host locale announcer. -No encoding conversion is performed prior to storage in the properties. -</para> -<para> -<!-- .LP --> -For clients that need to process the property text in a locale, -<function>XmbSetWMProperties</function> -sets the <property>WM_LOCALE_NAME</property> property to be the name of the current locale. -The name is assumed to be in the Host Portable Character Encoding -and is converted to STRING for storage in the property. -</para> -<para> -<!-- .LP --> -<function>XmbSetWMProperties</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's standard window manager properties -with strings in client-specified encodings, use -<function>XSetWMProperties</function>. -The standard window manager properties for a given window are -<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_NORMAL_HINTS</property>, <property>WM_CLASS</property>, -<property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property>. -</para> -<indexterm significance="preferred"><primary>XSetWMProperties</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmproperties'> -<funcprototype> - <funcdef>void <function>XSetWMProperties</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *window_name</parameter></paramdef> - <paramdef>XTextProperty<parameter> *icon_name</parameter></paramdef> - <paramdef>char<parameter> **argv</parameter></paramdef> - <paramdef>int<parameter> argc</parameter></paramdef> - <paramdef>XSizeHints<parameter> *normal_hints</parameter></paramdef> - <paramdef>XWMHints<parameter> *wm_hints</parameter></paramdef> - <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>window_name</emphasis> - </term> - <listitem> - <para> -Specifies the window name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>icon_name</emphasis> - </term> - <listitem> - <para> -Specifies the icon name, -which should be a null-terminated string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv</emphasis> - </term> - <listitem> - <para> -Specifies the application's argument list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc</emphasis> - </term> - <listitem> - <para> -Specifies the number of arguments. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>normal_hints</emphasis> - </term> - <listitem> - <para> -Specifies the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>wm_hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XWMHints</structname> -structure to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class_hints</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XClassHint</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMProperties</function> -convenience function provides a single programming interface -for setting those essential window properties that are used -for communicating with other clients (particularly window and session -managers). -</para> -<para> -<!-- .LP --> -If the window_name argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetWMName</function>, -which, in turn, sets the <property>WM_NAME</property> property -(see <link linkend="Setting_and_Reading_the_WM_NAME_Property">section 14.1.4</link>). -If the icon_name argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetWMIconName</function>, -which sets the <property>WM_ICON_NAME</property> property -(see <link linkend="Setting_and_Reading_the_WM_ICON_NAME_Property">section 14.1.5</link>). -If the argv argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetCommand</function>, -which sets the <property>WM_COMMAND</property> property -(see <link linkend="Setting_and_Reading_the_WM_COMMAND_Property">section 14.2.1</link>). -Note that an argc of zero is allowed to indicate a zero-length command. -Note also that the hostname of this machine is stored using -<function>XSetWMClientMachine</function> -(see <link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">section 14.2.2</link>). -</para> -<para> -<!-- .LP --> -If the normal_hints argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetWMNormalHints</function>, -which sets the <property>WM_NORMAL_HINTS</property> property -(see <link linkend="Setting_and_Reading_the_WM_NORMAL_HINTS_Property">section 14.1.7</link>). -If the wm_hints argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetWMHints</function>, -which sets the <property>WM_HINTS</property> property -(see <link linkend="Setting_and_Reading_the_WM_HINTS_Property">section 14.1.6</link>). -</para> -<para> -<!-- .LP --> -If the class_hints argument is non-NULL, -<function>XSetWMProperties</function> -calls -<function>XSetClassHint</function>, -which sets the <property>WM_CLASS</property> property -(see <link linkend="Setting_and_Reading_the_WM_CLASS_Property">section 14.1.8</link>). -If the res_name member in the -<structname>XClassHint</structname> -structure is set to the NULL pointer and the RESOURCE_NAME environment -variable is set, -then the value of the environment variable is substituted for res_name. -If the res_name member is NULL, -the environment variable is not set, -and argv and argv[0] are set, -then the value of argv[0], stripped of -any directory prefixes, is substituted for res_name. -</para> -<para> -<!-- .LP --> -<function>XSetWMProperties</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -</para> -</sect2> -</sect1> -<sect1 id="Client_to_Session_Manager_Communication"> -<title>Client to Session Manager Communication</title> -<!-- .XS --> -<!-- (SN Client to Session Manager Communication --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses how to: -</para> -<itemizedlist> - <listitem> - <para> -Set and read the <property>WM_COMMAND</property> property - </para> - </listitem> - <listitem> - <para> -Set and read the <property>WM_CLIENT_MACHINE</property> property - </para> - </listitem> -</itemizedlist> -<sect2 id="Setting_and_Reading_the_WM_COMMAND_Property"> -<title>Setting and Reading the WM_COMMAND Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_COMMAND Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_COMMAND</property> property for a given window. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_COMMAND</property> property, use -<function>XSetCommand</function>. -</para> -<indexterm significance="preferred"><primary>XSetCommand</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetcommand'> -<funcprototype> - <funcdef><function>XSetCommand</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> **argv</parameter></paramdef> - <paramdef>int<parameter> argc</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv</emphasis> - </term> - <listitem> - <para> -Specifies the application's argument list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc</emphasis> - </term> - <listitem> - <para> -Specifies the number of arguments. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetCommand</function> -function sets the command and arguments used to invoke the -application. -(Typically, argv is the argv array of your main program.) -If the strings are not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -<function>XSetCommand</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_COMMAND</property> property, use -<function>XGetCommand</function>. -</para> -<indexterm significance="preferred"><primary>XGetCommand</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetcommand'> -<funcprototype> - <funcdef>Status <function>XGetCommand</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>char<parameter> ***argv_return</parameter></paramdef> - <paramdef>int<parameter> *argc_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv_return</emphasis> - </term> - <listitem> - <para> -Returns the application's argument list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc_return</emphasis> - </term> - <listitem> - <para> -Returns the number of arguments returned. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetCommand</function> -function reads the <property>WM_COMMAND</property> property from the specified window -and returns a string list. -If the <property>WM_COMMAND</property> property exists, -it is of type STRING and format 8. -If sufficient memory can be allocated to contain the string list, -<function>XGetCommand</function> -fills in the argv_return and argc_return arguments -and returns a nonzero status. -Otherwise, it returns a zero status. -If the data returned by the server is in the Latin Portable Character Encoding, -then the returned strings are in the Host Portable Character Encoding. -Otherwise, the result is implementation-dependent. -To free the memory allocated to the string list, use -<function>XFreeStringList</function>. -</para> -</sect2> -<sect2 id="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property"> -<title>Setting and Reading the WM_CLIENT_MACHINE Property</title> -<!-- .XS --> -<!-- (SN Setting and Reading the WM_CLIENT_MACHINE Property --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and read -the <property>WM_CLIENT_MACHINE</property> property for a given window. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set a window's <property>WM_CLIENT_MACHINE</property> property, use -<function>XSetWMClientMachine</function>. -</para> -<indexterm significance="preferred"><primary>XSetWMClientMachine</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetwmclientmachine'> -<funcprototype> - <funcdef>void <function>XSetWMClientMachine</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XTextProperty</structname> -structure to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetWMClientMachine</function> -convenience function calls -<function>XSetTextProperty</function> -to set the <property>WM_CLIENT_MACHINE</property> property. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To read a window's <property>WM_CLIENT_MACHINE</property> property, use -<function>XGetWMClientMachine</function>. -</para> -<indexterm significance="preferred"><primary>XGetWMClientMachine</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetwmclientmachine'> -<funcprototype> - <funcdef>Status <function>XGetWMClientMachine</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>text_prop_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XTextProperty</structname> -structure. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetWMClientMachine</function> -convenience function performs an -<function>XGetTextProperty</function> -on the <property>WM_CLIENT_MACHINE</property> property. -It returns a nonzero status on success; -otherwise, it returns a zero status. -</para> -</sect2> -</sect1> -<sect1 id="Standard_Colormaps"> -<title>Standard Colormaps</title> -<!-- .XS --> -<!-- (SN Standard Colormaps --> -<!-- .XE --> -<para> -<!-- .LP --> -Applications with color palettes, smooth-shaded drawings, or digitized -images demand large numbers of colors. -In addition, these applications often require an efficient mapping -from color triples to pixel values that display the appropriate colors. -</para> -<para> -<!-- .LP --> -As an example, consider a three-dimensional display program that wants -to draw a smoothly shaded sphere. -At each pixel in the image of the sphere, -the program computes the intensity and color of light -reflected back to the viewer. -The result of each computation is a triple of red, green, and blue (<acronym>RGB</acronym>) -coefficients in the range 0.0 to 1.0. -To draw the sphere, the program needs a colormap that provides a -large range of uniformly distributed colors. -The colormap should be arranged so that the program can -convert its <acronym>RGB</acronym> triples into pixel values very quickly, -because drawing the entire sphere requires many such -conversions. -</para> -<para> -<!-- .LP --> -On many current workstations, -the display is limited to 256 or fewer colors. -Applications must allocate colors carefully, -not only to make sure they cover the entire range they need -but also to make use of as many of the available colors as possible. -On a typical X display, -many applications are active at once. -Most workstations have only one hardware look-up table for colors, -so only one application colormap can be installed at a given time. -The application using the installed colormap is displayed correctly, -and the other applications go technicolor and are -displayed with false colors. -</para> -<para> -<!-- .LP --> -As another example, consider a user who is running an -image processing program to display earth-resources data. -The image processing program needs a colormap set up with 8 reds, -8 greens, and 4 blues, for a total of 256 colors. -Because some colors are already in use in the default colormap, -the image processing program allocates and installs a new colormap. -</para> -<para> -<!-- .LP --> -The user decides to alter some of the colors in the image -by invoking a color palette program to mix and choose colors. -The color palette program also needs a -colormap with eight reds, eight greens, and four blues, so just like -the image processing program, it must allocate and -install a new colormap. -</para> -<para> -<!-- .LP --> -Because only one colormap can be installed at a time, -the color palette may be displayed incorrectly -whenever the image processing program is active. -Conversely, whenever the palette program is active, -the image may be displayed incorrectly. -The user can never match or compare colors in the palette and image. -Contention for colormap resources can be reduced if applications -with similar color needs share colormaps. -</para> -<para> -<!-- .LP --> -The image processing program and the color palette program -could share the same colormap if there existed a convention that described -how the colormap was set up. -Whenever either program was active, -both would be displayed correctly. -</para> -<para> -<!-- .LP --> -The standard colormap properties define a set of commonly used -colormaps. -Applications that share these colormaps and conventions display -true colors more often and provide a better interface to the user. -</para> -<para> -<!-- .LP --> -Standard colormaps allow applications to share commonly used color -resources. -This allows many applications to be displayed in true colors -simultaneously, even when each application needs an entirely filled -colormap. -</para> -<para> -<!-- .LP --> -Several standard colormaps are described in this section. -Usually, a window manager creates these colormaps. -Applications should use the standard colormaps if they already exist. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To allocate an -<structname>XStandardColormap</structname> -structure, use -<function>XAllocStandardColormap</function>. -</para> - -<para> -XStandardColormap *XAllocStandardColormap() -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAllocStandardColormap</function> -function allocates and returns a pointer to an -<structname>XStandardColormap</structname> -structure. -Note that all fields in the -<structname>XStandardColormap</structname> -structure are initially set to zero. -If insufficient memory is available, -<function>XAllocStandardColormap</function> -returns NULL. -To free the memory allocated to this structure, -use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -The -<structname>XStandardColormap</structname> -structure contains: -</para> -<literallayout class="monospaced"> -/* Hints */ - -#define ReeaseByFreeingColormap ((XID)1L) - -/* Values */ - -typedef struct { - Colormap colormap; - unsigned long red_max; - unsigned long red_mult; - unsigned long green_max; - unsigned long green_mult; - unsigned long blue_max; - unsigned long blue_mult; - unsigned long base_pixel; - VisualID visualid; - XID killid; -} XStandardColormap; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -The colormap member is the colormap created by the -<function>XCreateColormap</function> -function. -The red_max, green_max, and blue_max members give the maximum -red, green, and blue values, respectively. -Each color coefficient ranges from zero to its max, inclusive. -For example, -a common colormap allocation is 3/3/2 (3 planes for red, 3 -planes for green, and 2 planes for blue). -This colormap would have red_max = 7, green_max = 7, -and blue_max = 3. -An alternate allocation that uses only 216 colors is red_max = 5, -green_max = 5, and blue_max = 5. -</para> -<para> -<!-- .LP --> -The red_mult, green_mult, and blue_mult members give the -scale factors used to compose a full pixel value. -(See the discussion of the base_pixel members for further information.) -For a 3/3/2 allocation, red_mult might be 32, -green_mult might be 4, and blue_mult might be 1. -For a 6-colors-each allocation, red_mult might be 36, -green_mult might be 6, and blue_mult might be 1. -</para> -<para> -<!-- .LP --> -The base_pixel member gives the base pixel value used to -compose a full pixel value. -Usually, the base_pixel is obtained from a call to the -<function>XAllocColorPlanes</function> -function. -Given integer red, green, and blue coefficients in their appropriate -ranges, one then can compute a corresponding pixel value by -using the following expression: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 1.5i --> -<!-- .ta .5i 1.5i --> -(r * red_mult + g * green_mult + b * blue_mult + base_pixel) & 0xFFFFFFFF -</literallayout> -</para> -<para> -<!-- .LP --> -For -<symbol>GrayScale</symbol> -colormaps, -only the colormap, red_max, red_mult, -and base_pixel members are defined. -The other members are ignored. -To compute a -<symbol>GrayScale</symbol> -pixel value, use the following expression: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .5i 1.5i --> -<!-- .ta .5i 1.5i --> -(gray * red_mult + base_pixel) & 0xFFFFFFFF -</literallayout> -</para> -<para> -<!-- .LP --> -Negative multipliers can be represented by converting the 2's -complement representation of the multiplier into an unsigned long and -storing the result in the appropriate _mult field. -The step of masking by 0xFFFFFFFF effectively converts the resulting -positive multiplier into a negative one. -The masking step will take place automatically on many machine architectures, -depending on the size of the integer type used to do the computation. -</para> -<para> -<!-- .LP --> -The visualid member gives the ID number of the visual from which the -colormap was created. -The killid member gives a resource ID that indicates whether -the cells held by this standard colormap are to be released -by freeing the colormap ID or by calling the -<function>XKillClient</function> -function on the indicated resource. -(Note that this method is necessary for allocating out of an existing colormap.) -</para> -<para> -<!-- .LP --> -The properties containing the -<structname>XStandardColormap</structname> -information have -the type RGB_COLOR_MAP. -</para> -<para> -<!-- .LP --> -The remainder of this section discusses standard colormap properties and atoms -as well as how to manipulate standard colormaps. -</para> -<sect2 id="Standard_Colormap_Properties_and_Atoms"> -<title>Standard Colormap Properties and Atoms</title> -<!-- .XS --> -<!-- (SN Standard Colormap Properties and Atoms --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Standard Colormaps</primary></indexterm> -<indexterm><primary>Colormaps</primary><secondary>standard</secondary></indexterm> -Several standard colormaps are available. -Each standard colormap is defined by a property, -and each such property is identified by an atom. -The following list names the atoms and describes the colormap -associated with each one. -The -<filename class="headerfile"><X11/Xatom.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm> -header file contains the definitions for each of the following atoms, -which are prefixed with XA_. -</para> - - - -<variablelist> - <varlistentry> - <term>RGB_DEFAULT_MAP</term> - <listitem> - <para> -This atom names a property. -The value of the property is an array of -<structname>XStandardColormap</structname> -structures. -Each entry in the array describes an <acronym>RGB</acronym> subset of the default color -map for the Visual specified by visual_id. - </para> - <para> -Some applications only need a few <acronym>RGB</acronym> colors and -may be able to allocate them from the system default colormap. -This is the ideal situation because the fewer colormaps that are -active in the system the more applications are displayed -with correct colors at all times. - </para> - <para> -A typical allocation for the RGB_DEFAULT_MAP on 8-plane displays -is 6 reds, 6 greens, and 6 blues. -This gives 216 uniformly distributed colors -(6 intensities of 36 different hues) and still leaves 40 elements -of a 256-element colormap available for special-purpose colors -for text, borders, and so on. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>RGB_BEST_MAP</term> - <listitem> - <para> -This atom names a property. The value of the property is an -<structname>XStandardColormap</structname>. - </para> - <para> -The property defines the best <acronym>RGB</acronym> colormap available on -the screen. -(Of course, this is a subjective evaluation.) -Many image processing and three-dimensional applications need to -use all available colormap cells and to distribute as many -perceptually distinct colors as possible over those cells. -This implies that there may be more green values available than -red, as well as more green or red than blue. - </para> - <para> -For an 8-plane -<symbol>PseudoColor</symbol> -visual, -RGB_BEST_MAP is likely to be a 3/3/2 allocation. -For a 24-plane -<symbol>DirectColor</symbol> -visual, -RGB_BEST_MAP is normally an 8/8/8 allocation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>RGB_RED_MAP,RGB_GREEN_MAP,RGB_BLUE_MAP</term> - <listitem> - <para> -These atoms name properties. -The value of each property is an -<structname>XStandardColormap</structname>. - </para> - <para> -The properties define all-red, all-green, and all-blue -colormaps, respectively. -These maps are used by applications that want to make color-separated -images. -For example, a user might generate a full-color image -on an 8-plane display both by rendering an image three times -(once with high color resolution in red, once with green, -and once with blue) and by multiply exposing a single frame in a camera. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>RGB_GRAY_MAP</term> - <listitem> - <para> -This atom names a property. -The value of the property is an -<structname>XStandardColormap</structname>. - </para> - <para> -The property describes the best -<symbol>GrayScale</symbol> -colormap available on the screen. -As previously mentioned, -only the colormap, red_max, red_mult, and base_pixel members of the -<structname>XStandardColormap</structname> -structure are used for -<symbol>GrayScale</symbol> -colormaps. - </para> - </listitem> - </varlistentry> -</variablelist> - -</sect2> - -<sect2 id="Setting_and_Obtaining_Standard_Colormaps"> -<title>Setting and Obtaining Standard Colormaps</title> -<!-- .XS --> -<!-- (SN Setting and Obtaining Standard Colormaps --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to set and obtain an -<structname>XStandardColormap</structname> -structure. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To set an -<structname>XStandardColormap</structname> -structure, use -<function>XSetRGBColormaps</function>. -</para> -<indexterm significance="preferred"><primary>XSetRGBColormaps</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetrgbcolormaps'> -<funcprototype> - <funcdef>void <function>XSetRGBColormaps</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XStandardColormap<parameter> *std_colormap</parameter></paramdef> - <paramdef>int<parameter> count</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>std_colormap</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>XStandardColormap</structname> -structure to be used. -<!-- .ds Cn colormaps --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count</emphasis> - </term> - <listitem> - <para> -Specifies the number of (Cn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetRGBColormaps</function> -function replaces the <acronym>RGB</acronym> colormap definition in the specified property -on the named window. -If the property does not already exist, -<function>XSetRGBColormaps</function> -sets the <acronym>RGB</acronym> colormap definition in the specified property -on the named window. -The property is stored with a type of RGB_COLOR_MAP and a format of 32. -Note that it is the caller's responsibility to honor the <acronym>ICCCM</acronym> -restriction that only RGB_DEFAULT_MAP contain more than one definition. -</para> -<para> -<!-- .LP --> -The -<function>XSetRGBColormaps</function> -function usually is only used by window or session managers. -To create a standard colormap, -follow this procedure: -</para> -<itemizedlist> - <listitem> - <para> -Open a new connection to the same server. - </para> - </listitem> - <listitem> - <para> -Grab the server. - </para> - </listitem> - <listitem> - <para> -See if the property is on the property list of the root window for the screen. - </para> - </listitem> - <listitem> - <para> -If the desired property is not present: -<!-- .RS --> - </para> - </listitem> - <listitem> - <para> -Create a colormap (unless you are using the default colormap of the screen). - </para> - </listitem> - <listitem> - <para> -Determine the color characteristics of the visual. - </para> - </listitem> - <listitem> - <para> -Allocate cells in the colormap (or create it with -<symbol>AllocAll</symbol>). - </para> - </listitem> - <listitem> - <para> -Call -<function>XStoreColors</function> -to store appropriate color values in the colormap. - </para> - </listitem> - <listitem> - <para> -Fill in the descriptive members in the -<structname>XStandardColormap</structname> -structure. - </para> - </listitem> - <listitem> - <para> -Attach the property to the root window. - </para> - </listitem> - <listitem> - <para> -Use -<function>XSetCloseDownMode</function> -to make the resource permanent. -<!-- .RE --> - </para> - </listitem> - <listitem> - <para> -Ungrab the server. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -<function>XSetRGBColormaps</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadAtom</errorname>, -and -<errorname>BadWindow</errorname> -errors. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To obtain the -<structname>XStandardColormap</structname> -structure associated with the specified property, use -<function>XGetRGBColormaps</function>. -</para> -<indexterm significance="preferred"><primary>XGetRGBColormaps</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetrgbcolormaps'> -<funcprototype> - <funcdef>Status <function>XGetRGBColormaps</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Window<parameter> w</parameter></paramdef> - <paramdef>XStandardColormap<parameter> **std_colormap_return</parameter></paramdef> - <paramdef>int<parameter> *count_return</parameter></paramdef> - <paramdef>Atom<parameter> property</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>w</emphasis> - </term> - <listitem> - <para> -Specifies the window. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>std_colormap_return</emphasis> - </term> - <listitem> - <para> -Returns the -<structname>XStandardColormap</structname> -structure. -<!-- .ds Cn colormaps --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>count_return</emphasis> - </term> - <listitem> - <para> -Returns the number of (Cn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>property</emphasis> - </term> - <listitem> - <para> -Specifies the property name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetRGBColormaps</function> -function returns the <acronym>RGB</acronym> colormap definitions stored -in the specified property on the named window. -If the property exists, is of type RGB_COLOR_MAP, is of format 32, -and is long enough to contain a colormap definition, -<function>XGetRGBColormaps</function> -allocates and fills in space for the returned colormaps -and returns a nonzero status. -If the visualid is not present, -<function>XGetRGBColormaps</function> -assumes the default visual for the screen on which the window is located; -if the killid is not present, -<symbol>None</symbol> -is assumed, which indicates that the resources cannot be released. -Otherwise, -none of the fields are set, and -<function>XGetRGBColormaps</function> -returns a zero status. -Note that it is the caller's responsibility to honor the <acronym>ICCCM</acronym> -restriction that only RGB_DEFAULT_MAP contain more than one definition. -</para> -<para> -<!-- .LP --> -<function>XGetRGBColormaps</function> -can generate -<errorname>BadAtom</errorname> -and -<errorname>BadWindow</errorname> -errors. -<!-- .bp --> - -</para> -</sect2> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="inter_client_communication_functions">
+<title>Inter-Client Communication Functions</title>
+<para>
+The Inter-Client Communication Conventions Manual, hereafter referred to as the <acronym>ICCCM</acronym>,
+details the X Consortium approved conventions that govern inter-client communications. These
+conventions ensure peer-to-peer client cooperation in the use of selections, cut buffers, and shared
+resources as well as client cooperation with window and session managers. For further information,
+see the Inter-Client Communication Conventions Manual.
+</para>
+<para>
+Xlib provides a number of standard properties and programming interfaces that are <acronym>ICCCM</acronym>
+compliant. The predefined atoms for some of these properties are defined in the <X11/Xatom.h>
+header file, where to avoid name conflicts with user symbols their #define name has an XA_ prefix.
+For further information about atoms and properties,
+see <link linkend="Properties_and_Atoms">section 4.3</link>.
+</para>
+<para>
+Xlib’s selection and cut buffer mechanisms provide the primary programming interfaces by which
+peer client applications communicate with each other
+(see sections <link linkend="Selections">4.5</link> and
+<link linkend="Using_Cut_Buffers">16.6</link>). The functions
+discussed in this chapter provide the primary programming interfaces by which client applications
+communicate with their window and session managers as well as share standard colormaps.
+</para>
+<para>
+The standard properties that are of special interest for communicating with window and session
+managers are:
+</para>
+
+<informaltable>
+ <tgroup cols='4'>
+ <colspec colname='c1'/>
+ <colspec colname='c2'/>
+ <colspec colname='c3'/>
+ <colspec colname='c4'/>
+ <thead>
+ <row>
+ <entry align='center'>Name</entry>
+ <entry align='center'>Type</entry>
+ <entry align='center'>Format</entry>
+ <entry align='center'>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><property>WM_CLASS</property></entry>
+ <entry>STRING</entry>
+ <entry>8</entry>
+ <entry>Set by application programs to allow
+ window and session managers to
+ obtain the application’s resources
+ from the resource database.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_CLIENT_MACHINE</property></entry>
+ <entry>TEXT</entry>
+ <entry></entry>
+ <entry>The string name of the machine on
+ which the client application is running.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_COLORMAP_WINDOWS</property></entry>
+ <entry>WINDOWS</entry>
+ <entry>32</entry>
+ <entry>The list of window IDs that may
+ need a different colormap from that
+ of their top-level window.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_COMMAND</property></entry>
+ <entry>TEXT</entry>
+ <entry></entry>
+ <entry>The command and arguments, null
+ separated, used to invoke the application.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_HINTS</property></entry>
+ <entry><property>WM_HINTS</property></entry>
+ <entry>32</entry>
+ <entry>Additional hints set by the client for
+ use by the window manager. The C
+ type of this property is XWMHints.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_ICON_NAME</property></entry>
+ <entry>TEXT</entry>
+ <entry></entry>
+ <entry>The name to be used in an icon.</entry>
+ </row>
+ <row>
+ <entry><property>WM_ICON_SIZE</property></entry>
+ <entry><property>WM_ICON_SIZE</property></entry>
+ <entry>32</entry>
+ <entry>The window manager may set this
+ property on the root window to
+ specify the icon sizes it supports.
+ The C type of this property is
+ XIconSize.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_NAME</property></entry>
+ <entry>TEXT</entry>
+ <entry></entry>
+ <entry>The name of the application.</entry>
+ </row>
+ <row>
+ <entry><property>WM_NORMAL_HINTS</property></entry>
+ <entry><property>WM_NORMAL_HINTS</property></entry>
+ <entry>32</entry>
+ <entry>Size hints for a window in its
+ normal state. The C type of this
+ property is XSizeHints.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_PROTOCOLS</property></entry>
+ <entry>ATOM</entry>
+ <entry>32</entry>
+ <entry>List of atoms that identify the
+ communications protocols between the
+ client and window manager in
+ which the client is willing to participate.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_STATE</property></entry>
+ <entry><property>WM_STATE</property></entry>
+ <entry>32</entry>
+ <entry>Intended for communication
+ between window and session managers only.
+ </entry>
+ </row>
+ <row>
+ <entry><property>WM_TRANSIENT_FOR</property></entry>
+ <entry>WINDOW</entry>
+ <entry>32</entry>
+ <entry>Set by application programs to
+ indicate to the window manager that a
+ transient top-level window, such as a
+ dialog box.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
+
+<para>
+The remainder of this chapter discusses:
+</para>
+
+<itemizedlist>
+ <listitem><para>Client to window manager communication</para></listitem>
+ <listitem><para>Client to session manager communication</para></listitem>
+ <listitem><para>Standard colormaps</para></listitem>
+</itemizedlist>
+
+<sect1 id="Client_to_Window_Manager_Communication">
+<title>Client to Window Manager Communication</title>
+<!-- .XS -->
+<!-- (SN Client to Window Manager Communication -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Manipulate top-level windows
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Convert string lists
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read text properties
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_NAME</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_ICON_NAME</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_HINTS</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_NORMAL_HINTS</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_CLASS</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_TRANSIENT_FOR</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_PROTOCOLS</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_COLORMAP_WINDOWS</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_ICON_SIZE</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use window manager convenience functions
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Manipulating_Top_Level_Windows">
+<title>Manipulating Top-Level Windows</title>
+<!-- .XS -->
+<!-- (SN Manipulating Top-Level Windows -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to change the visibility or size
+of top-level windows (that is, those that were created as children
+of the root window).
+Note that the subwindows that you create are ignored by window managers.
+Therefore,
+you should use the basic window functions described in
+<link linkend="window_functions">chapter 3</link>
+to manipulate your application's subwindows.
+</para>
+<para>
+<!-- .LP -->
+To request that a top-level window be iconified, use
+<function>XIconifyWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XIconifyWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xiconifywindow'>
+<funcprototype>
+ <funcdef>Status <function>XIconifyWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XIconifyWindow</function>
+function sends a <property>WM_CHANGE_STATE</property>
+<symbol>ClientMessage</symbol>
+event with a format of 32 and a first data element of
+<symbol>IconicState</symbol>
+(as described in section 4.1.4 of the
+<emphasis remap='I'>Inter-Client Communication Conventions Manual</emphasis>)
+and a window of w
+to the root window of the specified screen
+with an event mask set to
+<symbol>SubstructureNotifyMask</symbol> |
+<symbol>SubstructureRedirectMask</symbol>.
+Window managers may elect to receive this message and
+if the window is in its normal state,
+may treat it as a request to change the window's state from normal to iconic.
+If the <property>WM_CHANGE_STATE</property> property cannot be interned,
+<function>XIconifyWindow</function>
+does not send a message and returns a zero status.
+It returns a nonzero status if the client message is sent successfully;
+otherwise, it returns a zero status.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To request that a top-level window be withdrawn, use
+<function>XWithdrawWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XWithdrawWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwithdrawwindow'>
+<funcprototype>
+ <funcdef>Status <function>XWithdrawWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XWithdrawWindow</function>
+function unmaps the specified window
+and sends a synthetic
+<symbol>UnmapNotify</symbol>
+event to the root window of the specified screen.
+Window managers may elect to receive this message
+and may treat it as a request to change the window's state to withdrawn.
+When a window is in the withdrawn state,
+neither its normal nor its iconic representations is visible.
+It returns a nonzero status if the
+<symbol>UnmapNotify</symbol>
+event is successfully sent;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XWithdrawWindow</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To request that a top-level window be reconfigured, use
+<function>XReconfigureWMWindow</function>.
+</para>
+<indexterm significance="preferred"><primary>XReconfigureWMWindow</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xreconfigurewmwindow'>
+<funcprototype>
+ <funcdef>Status <function>XReconfigureWMWindow</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>int<parameter> screen_number</parameter></paramdef>
+ <paramdef>unsignedint<parameter> value_mask</parameter></paramdef>
+ <paramdef>XWindowChanges<parameter> *values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen_number</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the appropriate screen number on the host server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies which values are to be set using information in
+the values structure.
+This mask is the bitwise inclusive OR of the valid configure window values bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>values</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XWindowChanges</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XReconfigureWMWindow</function>
+function issues a
+<systemitem>ConfigureWindow</systemitem>
+request on the specified top-level window.
+If the stacking mode is changed and the request fails with a
+<errorname>BadMatch</errorname>
+error,
+the error is trapped by Xlib and a synthetic
+<systemitem class="event">ConfigureRequestEvent</systemitem>
+containing the same configuration parameters is sent to the root
+of the specified window.
+Window managers may elect to receive this event
+and treat it as a request to reconfigure the indicated window.
+It returns a nonzero status if the request or event is successfully sent;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XReconfigureWMWindow</function>
+can generate
+<errorname>BadValue</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Converting_String_Lists">
+<title>Converting String Lists</title>
+<!-- .XS -->
+<!-- (SN Converting String Lists -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Many of the text properties allow a variety of types and formats.
+Because the data stored in these properties are not
+simple null-terminated strings, an
+<structname>XTextProperty</structname>
+structure is used to describe the encoding, type, and length of the text
+as well as its value.
+The
+<structname>XTextProperty</structname>
+structure contains:
+<indexterm significance="preferred"><primary>XTextProperty</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ unsigned char *value; /* property data */
+ Atom encoding; /* type of property */
+ int format; /* 8, 16, or 32 */
+ unsigned long nitems; /* number of items in value */
+} XTextProperty;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Xlib provides functions to convert localized text to or from encodings
+that support the inter-client communication conventions for text.
+In addition, functions are provided for converting between lists of pointers
+to character strings and text properties in the STRING encoding.
+</para>
+<para>
+<!-- .LP -->
+The functions for localized text return a signed integer error status
+that encodes
+<symbol>Success</symbol>
+as zero, specific error conditions as negative numbers, and partial conversion
+as a count of unconvertible characters.
+</para>
+
+<literallayout class="monospaced">
+
+#define #XNoMemory -1
+#define #XLocaleNotSupported -2
+#define #XConverterNotFound -3
+
+typedef enum {
+ XStringStyle, /* STRING */
+ XCompoundTextStyle, /* COMPOUND_TEXT */
+ XTextStyle, /* text in owner's encoding (current locale) */
+ XStdICCTextStyle /* STRING, else COMPOUND_TEXT */
+} XICCEncodingStyle;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To convert a list of text strings to an
+<structname>XTextProperty</structname>
+structure, use
+<function>XmbTextListToTextProperty</function>
+or
+<function>XwcTextListToTextProperty</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbTextListToTextProperty</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcTextListToTextProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbtextlisttotextproperty'>
+<funcprototype>
+ <funcdef>int <function>XmbTextListToTextProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> **list</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>XICCEncodingStyle<parameter> style</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwctextlisttotextproperty'>
+<funcprototype>
+ <funcdef>int <function>XwcTextListToTextProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>wchar_t<parameter> **list</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>XICCEncodingStyle<parameter> style</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of null-terminated character strings.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of strings specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>style</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the manner in which the property is encoded.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbTextListToTextProperty</function>
+and
+<function>XwcTextListToTextProperty</function>
+functions set the specified
+<structname>XTextProperty</structname>
+value to a set of null-separated elements representing the concatenation
+of the specified list of null-terminated text strings.
+A final terminating null is stored at the end of the value field
+of text_prop_return but is not included in the nitems member.
+</para>
+<para>
+<!-- .LP -->
+The functions set the encoding field of text_prop_return to an
+<type>Atom</type>
+for the specified display
+naming the encoding determined by the specified style
+and convert the specified text list to this encoding for storage in
+the text_prop_return value field.
+If the style
+<constant>XStringStyle</constant>
+or
+<constant>XCompoundTextStyle</constant>
+is specified,
+this encoding is ``STRING'' or ``COMPOUND_TEXT'', respectively.
+If the style
+<constant>XTextStyle</constant>
+is specified,
+this encoding is the encoding of the current locale.
+If the style
+<constant>XStdICCTextStyle</constant>
+is specified,
+this encoding is ``STRING'' if the text is fully convertible to STRING,
+else ``COMPOUND_TEXT''.
+</para>
+<para>
+<!-- .LP -->
+If insufficient memory is available for the new value string,
+the functions return
+<symbol>XNoMemory</symbol>.
+If the current locale is not supported,
+the functions return
+<symbol>XLocaleNotSupported</symbol>.
+In both of these error cases,
+the functions do not set text_prop_return.
+</para>
+<para>
+<!-- .LP -->
+To determine if the functions are guaranteed not to return
+<symbol>XLocaleNotSupported</symbol>,
+use
+<function>XSupportsLocale</function>.
+</para>
+<para>
+<!-- .LP -->
+If the supplied text is not fully convertible to the specified encoding,
+the functions return the number of unconvertible characters.
+Each unconvertible character is converted to an implementation-defined and
+encoding-specific default string.
+Otherwise, the functions return
+<symbol>Success</symbol>.
+Note that full convertibility to all styles except
+<constant>XStringStyle</constant>
+is guaranteed.
+</para>
+<para>
+<!-- .LP -->
+To free the storage for the value field, use
+<function>XFree</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain a list of text strings from an
+<structname>XTextProperty</structname>
+structure, use
+<function>XmbTextPropertyToTextList</function>
+or
+<function>XwcTextPropertyToTextList</function>.
+</para>
+<indexterm significance="preferred"><primary>XmbTextPropertyToTextList</primary></indexterm>
+<indexterm significance="preferred"><primary>XwcTextPropertyToTextList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbtextpropertytotextlist'>
+<funcprototype>
+ <funcdef>int <function>XmbTextPropertyToTextList</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+ <paramdef>char<parameter> ***list_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<funcsynopsis id='xwctextpropertytotextlist'>
+<funcprototype>
+ <funcdef>int <function>XwcTextPropertyToTextList</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+ <paramdef>wchar_t<parameter> ***list_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a list of null-terminated character strings.
+<!-- .ds Cn strings -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbTextPropertyToTextList</function>
+and
+<function>XwcTextPropertyToTextList</function>
+functions return a list of text strings in the current locale representing the
+null-separated elements of the specified
+<structname>XTextProperty</structname>
+structure.
+The data in text_prop must be format 8.
+</para>
+<para>
+<!-- .LP -->
+Multiple elements of the property (for example, the strings in a disjoint
+text selection) are separated by a null byte.
+The contents of the property are not required to be null-terminated;
+any terminating null should not be included in text_prop.nitems.
+</para>
+<para>
+<!-- .LP -->
+If insufficient memory is available for the list and its elements,
+<function>XmbTextPropertyToTextList</function>
+and
+<function>XwcTextPropertyToTextList</function>
+return
+<symbol>XNoMemory</symbol>.
+If the current locale is not supported,
+the functions return
+<symbol>XLocaleNotSupported</symbol>.
+Otherwise, if the encoding field of text_prop is not convertible
+to the encoding of the current locale,
+the functions return
+<symbol>XConverterNotFound</symbol>.
+For supported locales,
+existence of a converter from COMPOUND_TEXT, STRING
+or the encoding of the current locale is guaranteed if
+<function>XSupportsLocale</function>
+returns
+<symbol>True</symbol>
+for the current locale (but the actual text
+may contain unconvertible characters).
+Conversion of other encodings is implementation-dependent.
+In all of these error cases,
+the functions do not set any return values.
+</para>
+<para>
+<!-- .LP -->
+Otherwise,
+<function>XmbTextPropertyToTextList</function>
+and
+<function>XwcTextPropertyToTextList</function>
+return the list of null-terminated text strings to list_return
+and the number of text strings to count_return.
+</para>
+<para>
+<!-- .LP -->
+If the value field of text_prop is not fully convertible to the encoding of
+the current locale,
+the functions return the number of unconvertible characters.
+Each unconvertible character is converted to a string in the
+current locale that is specific to the current locale.
+To obtain the value of this string,
+use
+<function>XDefaultString</function>.
+Otherwise,
+<function>XmbTextPropertyToTextList</function>
+and
+<function>XwcTextPropertyToTextList</function>
+return
+<symbol>Success</symbol>.
+</para>
+<para>
+<!-- .LP -->
+To free the storage for the list and its contents returned by
+<function>XmbTextPropertyToTextList</function>,
+use
+<function>XFreeStringList</function>.
+To free the storage for the list and its contents returned by
+<function>XwcTextPropertyToTextList</function>,
+use
+<function>XwcFreeStringList</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the in-memory data associated with the specified
+wide character string list, use
+<function>XwcFreeStringList</function>.
+</para>
+<indexterm significance="preferred"><primary>XwcFreeStringList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwcfreestringlist'>
+<funcprototype>
+ <funcdef>void <function>XwcFreeStringList</function></funcdef>
+ <paramdef>wchar_t<parameter> **list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of strings to be freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XwcFreeStringList</function>
+function frees memory allocated by
+<function>XwcTextPropertyToTextList</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the default string for text conversion in the current locale,
+use</para>
+
+<para>char *XDefaultString()</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDefaultString</function>
+function returns the default string used by Xlib for text conversion
+(for example, in
+<function>XmbTextPropertyToTextList</function>).
+The default string is the string in the current locale that is output
+when an unconvertible character is found during text conversion.
+If the string returned by
+<function>XDefaultString</function>
+is the empty string (""),
+no character is output in the converted text.
+<function>XDefaultString</function>
+does not return NULL.
+</para>
+<para>
+<!-- .LP -->
+The string returned by
+<function>XDefaultString</function>
+is independent of the default string for text drawing;
+see
+<function>XCreateFontSet</function>
+to obtain the default string for an
+<type>XFontSet</type>.
+</para>
+<para>
+<!-- .LP -->
+The behavior when an invalid codepoint is supplied to any Xlib function is
+undefined.
+</para>
+<para>
+<!-- .LP -->
+The returned string is null-terminated.
+It is owned by Xlib and should not be modified or freed by the client.
+It may be freed after the current locale is changed.
+Until freed, it will not be modified by Xlib.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set the specified list of strings in the STRING encoding to a
+<structname>XTextProperty</structname>
+structure, use
+<function>XStringListToTextProperty</function>.
+</para>
+<indexterm significance="preferred"><primary>XStringListToTextProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstringlisttotextproperty'>
+<funcprototype>
+ <funcdef>Status <function>XStringListToTextProperty</function></funcdef>
+ <paramdef>char<parameter> **list</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of null-terminated character strings.
+<!-- .ds Cn strings -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XStringListToTextProperty</function>
+function sets the specified
+<structname>XTextProperty</structname>
+to be of type STRING (format 8) with a value representing the
+concatenation of the specified list of null-separated character strings.
+An extra null byte (which is not included in the nitems member)
+is stored at the end of the value field of text_prop_return.
+The strings are assumed (without verification) to be in the STRING encoding.
+If insufficient memory is available for the new value string,
+<function>XStringListToTextProperty</function>
+does not set any fields in the
+<structname>XTextProperty</structname>
+structure and returns a zero status.
+Otherwise, it returns a nonzero status.
+To free the storage for the value field, use
+<function>XFree</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain a list of strings from a specified
+<structname>XTextProperty</structname>
+structure in the STRING encoding, use
+<function>XTextPropertyToStringList</function>.
+</para>
+<indexterm significance="preferred"><primary>XTextPropertyToStringList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xtextpropertytostringlist'>
+<funcprototype>
+ <funcdef>Status <function>XTextPropertyToStringList</function></funcdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+ <paramdef>char<parameter> ***list_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a list of null-terminated character strings.
+<!-- .ds Cn strings -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XTextPropertyToStringList</function>
+function returns a list of strings representing the null-separated elements
+of the specified
+<structname>XTextProperty</structname>
+structure.
+The data in text_prop must be of type STRING and format 8.
+Multiple elements of the property
+(for example, the strings in a disjoint text selection)
+are separated by NULL (encoding 0).
+The contents of the property are not null-terminated.
+If insufficient memory is available for the list and its elements,
+<function>XTextPropertyToStringList</function>
+sets no return values and returns a zero status.
+Otherwise, it returns a nonzero status.
+To free the storage for the list and its contents, use
+<function>XFreeStringList</function>.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To free the in-memory data associated with the specified string list, use
+<function>XFreeStringList</function>.
+</para>
+<indexterm significance="preferred"><primary>XFreeStringList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfreestringlist'>
+<funcprototype>
+ <funcdef>void <function>XFreeStringList</function></funcdef>
+ <paramdef>char<parameter> **list</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of strings to be freed.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFreeStringList</function>
+function releases memory allocated by
+<function>XmbTextPropertyToTextList</function>
+and
+<function>XTextPropertyToStringList</function>
+and the missing charset list allocated by
+<function>XCreateFontSet</function>.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_Text_Properties">
+<title>Setting and Reading Text Properties</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading Text Properties -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides two functions that you can use to set and read
+the text properties for a given window.
+You can use these functions to set and read those properties of type TEXT
+(<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property>).
+In addition,
+Xlib provides separate convenience functions that you can use to set each
+of these properties.
+For further information about these convenience functions,
+see sections
+<link linkend="Setting_and_Reading_the_WM_NAME_Property">14.1.4</link>,
+<link linkend="Setting_and_Reading_the_WM_ICON_NAME_Property">14.1.5</link>,
+<link linkend="Setting_and_Reading_the_WM_COMMAND_Property">14.2.1</link>, and
+<link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">14.2.2</link>,
+respectively.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set one of a window's text properties, use
+<function>XSetTextProperty</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetTextProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsettextproperty'>
+<funcprototype>
+ <funcdef>void <function>XSetTextProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetTextProperty</function>
+function replaces the existing specified property for the named window
+with the data, type, format, and number of items determined
+by the value field, the encoding field, the format field,
+and the nitems field, respectively, of the specified
+<structname>XTextProperty</structname>
+structure.
+If the property does not already exist,
+<function>XSetTextProperty</function>
+sets it for the specified window.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetTextProperty</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+<errorname>BadValue</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read one of a window's text properties, use
+<function>XGetTextProperty</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetTextProperty</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgettextproperty'>
+<funcprototype>
+ <funcdef>Status <function>XGetTextProperty</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetTextProperty</function>
+function reads the specified property from the window
+and stores the data in the returned
+<structname>XTextProperty</structname>
+structure.
+It stores the data in the value field,
+the type of the data in the encoding field,
+the format of the data in the format field,
+and the number of items of data in the nitems field.
+An extra byte containing null (which is not included in the nitems member)
+is stored at the end of the value field of text_prop_return.
+The particular interpretation of the property's encoding
+and data as text is left to the calling application.
+If the specified property does not exist on the window,
+<function>XGetTextProperty</function>
+sets the value field to NULL,
+the encoding field to
+<symbol>None</symbol>,
+the format field to zero,
+and the nitems field to zero.
+</para>
+<para>
+<!-- .LP -->
+If it was able to read and store the data in the
+<structname>XTextProperty</structname>
+structure,
+<function>XGetTextProperty</function>
+returns a nonzero status;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetTextProperty</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_NAME_Property">
+<title>Setting and Reading the WM_NAME Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_NAME Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides convenience functions that you can use to set and read
+the <property>WM_NAME</property> property for a given window.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_NAME</property> property with the supplied convenience function, use
+<function>XSetWMName</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmname'>
+<funcprototype>
+ <funcdef>void <function>XSetWMName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMName</function>
+convenience function calls
+<function>XSetTextProperty</function>
+to set the <property>WM_NAME</property> property.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_NAME</property> property with the supplied convenience function, use
+<function>XGetWMName</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmname'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMName</function>
+convenience function calls
+<function>XGetTextProperty</function>
+to obtain the <property>WM_NAME</property> property.
+It returns a nonzero status on success;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+The following two functions have been superseded by
+<function>XSetWMName</function>
+and
+<function>XGetWMName</function>,
+respectively.
+You can use these additional convenience functions
+for window names that are encoded as STRING properties.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To assign a name to a window, use
+<function>XStoreName</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>name</secondary></indexterm>
+<indexterm significance="preferred"><primary>XStoreName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorename'>
+<funcprototype>
+ <funcdef><function>XStoreName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> *window_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XStoreName</function>
+function assigns the name passed to window_name to the specified window.
+A window manager can display the window name in some prominent
+place, such as the title bar, to allow users to identify windows easily.
+Some window managers may display a window's name in the window's icon,
+although they are encouraged to use the window's icon name
+if one is provided by the application.
+If the string is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreName</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the name of a window, use
+<function>XFetchName</function>.
+</para>
+<indexterm significance="preferred"><primary>XFetchName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfetchname'>
+<funcprototype>
+ <funcdef>Status <function>XFetchName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> **window_name_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_name_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the window name, which is a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFetchName</function>
+function returns the name of the specified window.
+If it succeeds,
+it returns a nonzero status;
+otherwise, no name has been set for the window,
+and it returns zero.
+If the <property>WM_NAME</property> property has not been set for this window,
+<function>XFetchName</function>
+sets window_name_return to NULL.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned string is in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+When finished with it, a client must free
+the window name string using
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XFetchName</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_ICON_NAME_Property">
+<title>Setting and Reading the WM_ICON_NAME Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_ICON_NAME Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides convenience functions that you can use to set and read
+the <property>WM_ICON_NAME</property> property for a given window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_ICON_NAME</property> property,
+use
+<function>XSetWMIconName</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMIconName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmiconname'>
+<funcprototype>
+ <funcdef>void <function>XSetWMIconName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMIconName</function>
+convenience function calls
+<function>XSetTextProperty</function>
+to set the <property>WM_ICON_NAME</property> property.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_ICON_NAME</property> property,
+use
+<function>XGetWMIconName</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMIconName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmiconname'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMIconName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMIconName</function>
+convenience function calls
+<function>XGetTextProperty</function>
+to obtain the <property>WM_ICON_NAME</property> property.
+It returns a nonzero status on success;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+The next two functions have been superseded by
+<function>XSetWMIconName</function>
+and
+<function>XGetWMIconName</function>,
+respectively.
+You can use these additional convenience functions
+for window names that are encoded as STRING properties.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the name to be displayed in a window's icon, use
+<function>XSetIconName</function>.
+</para>
+<indexterm><primary>Window</primary><secondary>icon name</secondary></indexterm>
+<indexterm significance="preferred"><primary>XSetIconName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xseticonname'>
+<funcprototype>
+ <funcdef><function>XSetIconName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> *icon_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the icon name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the string is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+<function>XSetIconName</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the name a window wants displayed in its icon, use
+<function>XGetIconName</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetIconName</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeticonname'>
+<funcprototype>
+ <funcdef>Status <function>XGetIconName</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> **icon_name_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_name_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the window's icon name,
+which is a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetIconName</function>
+function returns the name to be displayed in the specified window's icon.
+If it succeeds, it returns a nonzero status; otherwise,
+if no icon name has been set for the window,
+it returns zero.
+If you never assigned a name to the window,
+<function>XGetIconName</function>
+sets icon_name_return to NULL.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned string is in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+When finished with it, a client must free
+the icon name string using
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetIconName</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_HINTS_Property">
+<title>Setting and Reading the WM_HINTS Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_HINTS Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_HINTS</property> property for a given window.
+These functions use the flags and the
+<structname>XWMHints</structname>
+structure, as defined in the
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+header file.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To allocate an
+<structname>XWMHints</structname>
+structure, use
+<function>XAllocWMHints</function>.
+</para>
+
+<para>
+ XWMHints *XAllocWMHints()
+</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocWMHints</function>
+function allocates and returns a pointer to an
+<structname>XWMHints</structname>
+structure.
+Note that all fields in the
+<structname>XWMHints</structname>
+structure are initially set to zero.
+If insufficient memory is available,
+<function>XAllocWMHints</function>
+returns NULL.
+To free the memory allocated to this structure,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XWMHints</structname>
+structure contains:
+</para>
+
+<literallayout class="monospaced">
+/* Window manager hints mask bits */
+
+#define InputHint (1L<<0)
+#define StateHint (1L<<1)
+#define IconPixmapHint (1L<<2)
+#define IconWindowHint (1L<<3)
+#define IconPositionHint (1L<<4)
+#define IconMaskHint (1L<<5)
+#define WindowGroupHint (1L<<6)
+#define UrgencyHint (1L<<8)
+#define AllHints (InputHint|StateHint|IconPixmapHint|
+ IconWIndowHint|IconPositionHint|
+ IconMaskHint|WindowGroupHint)
+
+
+/* Values */
+
+typedef struct {
+ long flags; /* marks which fields in this structure are defined */
+ Bool input; /* does this application rely on the window manager to
+ get keyboard input? */
+ int initial_state; /* see below */
+ Pixmap icon_pixmap; /* pixmap to be used as icon */
+ Window icon_window; /* window to be used as icon */
+ int icon_x, icon_y; /* initial position of icon */
+ Pixmap icon_mask; /* pixmap to be used as mask for icon_pixmap */
+ XID window_group; /* id of related window group */
+ /* this structure may be extended in the future */
+} XWMHints;
+</literallayout>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The input member is used to communicate to the window manager the input focus
+model used by the application.
+Applications that expect input but never explicitly set focus to any
+of their subwindows (that is, use the push model of focus management),
+such as X Version 10 style applications that use real-estate
+driven focus, should set this member to
+<symbol>True</symbol>.
+Similarly, applications
+that set input focus to their subwindows only when it is given to their
+top-level window by a window manager should also set this member to
+<symbol>True</symbol>.
+Applications that manage their own input focus by explicitly setting
+focus to one of their subwindows whenever they want keyboard input
+(that is, use the pull model of focus management) should set this member to
+<symbol>False</symbol>.
+Applications that never expect any keyboard input also should set this member
+to
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+Pull model window managers should make it possible for push model
+applications to get input by setting input focus to the top-level windows of
+applications whose input member is
+<symbol>True</symbol>.
+Push model window managers should
+make sure that pull model applications do not break them
+by resetting input focus to
+<symbol>PointerRoot</symbol>
+when it is appropriate (for example, whenever an application whose
+input member is
+<symbol>False</symbol>
+sets input focus to one of its subwindows).
+</para>
+<para>
+<!-- .LP -->
+The definitions for the initial_state flag are:
+</para>
+
+<literallayout class="monospaced">
+#define WithdrawnState 0
+#define NormalState 1 /* most applications start this way */
+#define IconicState 2 /* application wants to start as an icon */
+
+</literallayout>
+<para>
+The icon_mask specifies which pixels of the icon_pixmap should be used as the
+icon.
+This allows for nonrectangular icons.
+Both icon_pixmap and icon_mask must be bitmaps.
+The icon_window lets an application provide a window for use as an icon
+for window managers that support such use.
+The window_group lets you specify that this window belongs to a group
+of other windows.
+For example, if a single application manipulates multiple
+top-level windows, this allows you to provide enough
+information that a window manager can iconify all of the windows
+rather than just the one window.
+</para>
+<para>
+<!-- .LP -->
+The
+<symbol>UrgencyHint</symbol>
+flag, if set in the flags field, indicates that the client deems the window
+contents to be urgent, requiring the timely response of the user. The
+window manager will make some effort to draw the user's attention to this
+window while this flag is set. The client must provide some means by which the
+user can cause the urgency flag to be cleared (either mitigating
+the condition that made the window urgent or merely shutting off the alarm)
+or the window to be withdrawn.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_HINTS</property> property, use
+<function>XSetWMHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmhints'>
+<funcprototype>
+ <funcdef><function>XSetWMHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XWMHints<parameter> *wmhints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>wmhints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XWMHints</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMHints</function>
+function sets the window manager hints that include icon information and location,
+the initial state of the window, and whether the application relies on the
+window manager to get keyboard input.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMHints</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a window's <property>WM_HINTS</property> property, use
+<function>XGetWMHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmhints'>
+<funcprototype>
+ <funcdef>XWMHints *<function>XGetWMHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMHints</function>
+function reads the window manager hints and
+returns NULL if no <property>WM_HINTS</property> property was set on the window
+or returns a pointer to an
+<structname>XWMHints</structname>
+structure if it succeeds.
+When finished with the data,
+free the space used for it by calling
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWMHints</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_NORMAL_HINTS_Property">
+<title>Setting and Reading the WM_NORMAL_HINTS Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_NORMAL_HINTS Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set or read
+the <property>WM_NORMAL_HINTS</property> property for a given window.
+The functions use the flags and the
+<structname>XSizeHints</structname>
+structure, as defined in the
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+header file.
+</para>
+<para>
+<!-- .LP -->
+The size of the
+<structname>XSizeHints</structname>
+structure may grow in future releases, as new components are
+added to support new <acronym>ICCCM</acronym> features.
+Passing statically allocated instances of this structure into
+Xlib may result in memory corruption when running against a
+future release of the library.
+As such, it is recommended that only dynamically allocated
+instances of the structure be used.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To allocate an
+<structname>XSizeHints</structname>
+structure, use
+<function>XAllocSizeHints</function>.
+</para>
+
+<para>
+XSizeHints *XAllocSizeHints()
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocSizeHints</function>
+function allocates and returns a pointer to an
+<structname>XSizeHints</structname>
+structure.
+Note that all fields in the
+<structname>XSizeHints</structname>
+structure are initially set to zero.
+If insufficient memory is available,
+<function>XAllocSizeHints</function>
+returns NULL.
+To free the memory allocated to this structure,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XSizeHints</structname>
+structure contains:
+</para>
+
+
+<literallayout class="monospaced">
+/* Size hints mask bits */
+
+#define USPosition (1L<<0) /* user specified x,y */
+#define USSize (1L<<1) /* user specified width,height */
+#define PPosition (1L<<2) /* program specified posistion */
+#define PSize (1L<<3) /* program specified size */
+#define PMinSize (1L<<4) /* program specified minimum size */
+#define PMaxSize (1L<<5) /* program specified maximum size */
+#define PResizeInc (1L<<5) /* program specified resize increments */
+#define PAspect (1L<<6) /* program specified min and max aspect ratios */
+#define PBaseSize (1L<<8)
+#define PWinGravity (1L<<9)
+#define PAllHints (PPosition|Psize|
+ PMinSize|PMaxSize|
+ PResizeInc|PAspect)
+
+
+/* Values */
+
+typedef struct {
+ long flags; /* marks which fields in this structure are defined */
+ int x, y; /* Obsolete */
+ int width, height; /* Obsolete */
+ int min_width, min_height;
+ int max_width, max_height;
+ int width_inc, height_inc;
+ struct {
+ int x; /* numerator */
+ int y; /* denominator */
+ } min_aspect, max_aspect;
+ int base_width, base_height;
+ int win_gravity;
+ /* this structure may be extended in the future */
+} XSizeHints;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The x, y, width, and height members are now obsolete
+and are left solely for compatibility reasons.
+The min_width and min_height members specify the
+minimum window size that still allows the application to be useful.
+The max_width and max_height members specify the maximum window size.
+The width_inc and height_inc members define an arithmetic progression of
+sizes (minimum to maximum) into which the window prefers to be resized.
+The min_aspect and max_aspect members are expressed
+as ratios of x and y,
+and they allow an application to specify the range of aspect
+ratios it prefers.
+The base_width and base_height members define the desired size of the window.
+The window manager will interpret the position of the window
+and its border width to position the point of the outer rectangle
+of the overall window specified by the win_gravity member.
+The outer rectangle of the window includes any borders or decorations
+supplied by the window manager.
+In other words,
+if the window manager decides to place the window where the client asked,
+the position on the parent window's border named by the win_gravity
+will be placed where the client window would have been placed
+in the absence of a window manager.
+</para>
+<para>
+<!-- .LP -->
+Note that use of the
+<symbol>PAllHints</symbol>
+macro is highly discouraged.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_NORMAL_HINTS</property> property, use
+<function>XSetWMNormalHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMNormalHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmnormalhints'>
+<funcprototype>
+ <funcdef>void <function>XSetWMNormalHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMNormalHints</function>
+function replaces the size hints for the <property>WM_NORMAL_HINTS</property> property
+on the specified window.
+If the property does not already exist,
+<function>XSetWMNormalHints</function>
+sets the size hints for the <property>WM_NORMAL_HINTS</property> property on the specified window.
+The property is stored with a type of <property>WM_SIZE_HINTS</property> and a format of 32.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMNormalHints</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_NORMAL_HINTS</property> property, use
+<function>XGetWMNormalHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMNormalHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmnormalhints'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMNormalHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef>
+ <paramdef>long<parameter> *supplied_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>supplied_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the hints that were supplied by the user.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMNormalHints</function>
+function returns the size hints stored in the <property>WM_NORMAL_HINTS</property> property
+on the specified window.
+If the property is of type <property>WM_SIZE_HINTS</property>, is of format 32,
+and is long enough to contain either an old (pre-<acronym>ICCCM</acronym>)
+or new size hints structure,
+<function>XGetWMNormalHints</function>
+sets the various fields of the
+<structname>XSizeHints</structname>
+structure, sets the supplied_return argument to the list of fields
+that were supplied by the user (whether or not they contained defined values),
+and returns a nonzero status.
+Otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+If
+<function>XGetWMNormalHints</function>
+returns successfully and a pre-<acronym>ICCCM</acronym> size hints property is read,
+the supplied_return argument will contain the following bits:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+(USPosition|USSize|PPosition|PSize|PMinSize|
+ PMaxSize|PResizeInc|PAspect)
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If the property is large enough to contain the base size
+and window gravity fields as well,
+the supplied_return argument will also contain the following bits:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+PBaseSize|PWinGravity
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWMNormalHints</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_SIZE_HINTS</property> property, use
+<function>XSetWMSizeHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMSizeHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmsizehints'>
+<funcprototype>
+ <funcdef>void <function>XSetWMSizeHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XSizeHints</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMSizeHints</function>
+function replaces the size hints for the specified property
+on the named window.
+If the specified property does not already exist,
+<function>XSetWMSizeHints</function>
+sets the size hints for the specified property
+on the named window.
+The property is stored with a type of <property>WM_SIZE_HINTS</property> and a format of 32.
+To set a window's normal size hints,
+you can use the
+<function>XSetWMNormalHints</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMSizeHints</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_SIZE_HINTS</property> property, use
+<function>XGetWMSizeHints</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMSizeHints</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmsizehints'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMSizeHints</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints_return</parameter></paramdef>
+ <paramdef>long<parameter> *supplied_return</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XSizeHints</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>supplied_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the hints that were supplied by the user.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMSizeHints</function>
+function returns the size hints stored in the specified property
+on the named window.
+If the property is of type <property>WM_SIZE_HINTS</property>, is of format 32,
+and is long enough to contain either an old (pre-<acronym>ICCCM</acronym>)
+or new size hints structure,
+<function>XGetWMSizeHints</function>
+sets the various fields of the
+<structname>XSizeHints</structname>
+structure, sets the supplied_return argument to the
+list of fields that were supplied by the user
+(whether or not they contained defined values),
+and returns a nonzero status.
+Otherwise, it returns a zero status.
+To get a window's normal size hints,
+you can use the
+<function>XGetWMNormalHints</function>
+function.
+</para>
+<para>
+<!-- .LP -->
+If
+<function>XGetWMSizeHints</function>
+returns successfully and a pre-<acronym>ICCCM</acronym> size hints property is read,
+the supplied_return argument will contain the following bits:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+(USPosition|USSize|PPosition|PSize|PMinSize|
+ PMaxSize|PResizeInc|PAspect)
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If the property is large enough to contain the base size
+and window gravity fields as well,
+the supplied_return argument will also contain the following bits:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+PBaseSize|PWinGravity
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWMSizeHints</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_CLASS_Property">
+<title>Setting and Reading the WM_CLASS Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_CLASS Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and get
+the <property>WM_CLASS</property> property for a given window.
+These functions use the
+<structname>XClassHint</structname>
+structure, which is defined in the
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+header file.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To allocate an
+<structname>XClassHint</structname>
+structure, use
+<function>XAllocClassHint</function>.
+<indexterm significance="preferred"><primary>XAllocClassHint</primary></indexterm>
+<!-- .sM -->
+</para>
+<para>
+
+ XClassHint *XAllocClassHint()
+</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocClassHint</function>
+function allocates and returns a pointer to an
+<structname>XClassHint</structname>
+structure.
+Note that the pointer fields in the
+<structname>XClassHint</structname>
+structure are initially set to NULL.
+If insufficient memory is available,
+<function>XAllocClassHint</function>
+returns NULL.
+To free the memory allocated to this structure,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XClassHint</structname>
+contains:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<indexterm significance="preferred"><primary>XClassHint</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i -->
+<!-- .ta .5i -->
+typedef struct {
+ char *res_name;
+ char *res_class;
+} XClassHint;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The res_name member contains the application name,
+and the res_class member contains the application class.
+Note that the name set in this property may differ from the name set as <property>WM_NAME</property>.
+That is, <property>WM_NAME</property> specifies what should be displayed in the title bar and,
+therefore, can contain temporal information (for example, the name of
+a file currently in an editor's buffer).
+On the other hand,
+the name specified as part of <property>WM_CLASS</property> is the formal name of the application
+that should be used when retrieving the application's resources from the
+resource database.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_CLASS</property> property, use
+<function>XSetClassHint</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetClassHint</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetclasshint'>
+<funcprototype>
+ <funcdef><function>XSetClassHint</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XClassHint</structname>
+structure that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetClassHint</function>
+function sets the class hint for the specified window.
+If the strings are not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetClassHint</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a window's <property>WM_CLASS</property> property, use
+<function>XGetClassHint</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetClassHint</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetclasshint'>
+<funcprototype>
+ <funcdef>Status <function>XGetClassHint</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XClassHint<parameter> *class_hints_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class_hints_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XClassHint</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetClassHint</function>
+function returns the class hint of the specified window to the members
+of the supplied structure.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned strings are in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+It returns a nonzero status on success;
+otherwise, it returns a zero status.
+To free res_name and res_class when finished with the strings,
+use
+<function>XFree</function>
+on each individually.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetClassHint</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_TRANSIENT_FOR_Property">
+<title>Setting and Reading the WM_TRANSIENT_FOR Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_TRANSIENT_FOR Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_TRANSIENT_FOR</property> property for a given window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_TRANSIENT_FOR</property> property, use
+<function>XSetTransientForHint</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetTransientForHint</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsettransientforhint'>
+<funcprototype>
+ <funcdef><function>XSetTransientForHint</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> prop_window</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prop_window</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window that the <property>WM_TRANSIENT_FOR</property> property is to be set to.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetTransientForHint</function>
+function sets the <property>WM_TRANSIENT_FOR</property> property of the specified window to the
+specified prop_window.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetTransientForHint</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a window's <property>WM_TRANSIENT_FOR</property> property, use
+<function>XGetTransientForHint</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetTransientForHint</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgettransientforhint'>
+<funcprototype>
+ <funcdef>Status <function>XGetTransientForHint</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> *prop_window_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>prop_window_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the <property>WM_TRANSIENT_FOR</property> property of the specified window.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetTransientForHint</function>
+function returns the <property>WM_TRANSIENT_FOR</property> property for the specified window.
+It returns a nonzero status on success;
+otherwise, it returns a zero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetTransientForHint</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_PROTOCOLS_Property">
+<title>Setting and Reading the WM_PROTOCOLS Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_PROTOCOLS Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_PROTOCOLS</property> property for a given window.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_PROTOCOLS</property> property, use
+<function>XSetWMProtocols</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMProtocols</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmprotocols'>
+<funcprototype>
+ <funcdef>Status <function>XSetWMProtocols</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Atom<parameter> *protocols</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>protocols</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of protocols.
+<!-- .ds Cn protocols in the list -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMProtocols</function>
+function replaces the <property>WM_PROTOCOLS</property> property on the specified window
+with the list of atoms specified by the protocols argument.
+If the property does not already exist,
+<function>XSetWMProtocols</function>
+sets the <property>WM_PROTOCOLS</property> property on the specified window
+to the list of atoms specified by the protocols argument.
+The property is stored with a type of ATOM and a format of 32.
+If it cannot intern the <property>WM_PROTOCOLS</property> atom,
+<function>XSetWMProtocols</function>
+returns a zero status.
+Otherwise, it returns a nonzero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMProtocols</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_PROTOCOLS</property> property, use
+<function>XGetWMProtocols</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMProtocols</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmprotocols'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMProtocols</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Atom<parameter> **protocols_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>protocols_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of protocols.
+<!-- .ds Cn protocols in the list -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMProtocols</function>
+function returns the list of atoms stored in the <property>WM_PROTOCOLS</property> property
+on the specified window.
+These atoms describe window manager protocols in which the owner
+of this window is willing to participate.
+If the property exists, is of type ATOM, is of format 32,
+and the atom <property>WM_PROTOCOLS</property> can be interned,
+<function>XGetWMProtocols</function>
+sets the protocols_return argument to a list of atoms,
+sets the count_return argument to the number of elements in the list,
+and returns a nonzero status.
+Otherwise, it sets neither of the return arguments
+and returns a zero status.
+To release the list of atoms, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWMProtocols</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_COLORMAP_WINDOWS_Property">
+<title>Setting and Reading the WM_COLORMAP_WINDOWS Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_COLORMAP_WINDOWS Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_COLORMAP_WINDOWS</property> property for a given window.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_COLORMAP_WINDOWS</property> property, use
+<function>XSetWMColormapWindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMColormapWindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmcolormapwindows'>
+<funcprototype>
+ <funcdef>Status <function>XSetWMColormapWindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> *colormap_windows</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap_windows</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the list of windows.
+<!-- .ds Cn windows in the list -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMColormapWindows</function>
+function replaces the <property>WM_COLORMAP_WINDOWS</property> property on the specified
+window with the list of windows specified by the colormap_windows argument.
+If the property does not already exist,
+<function>XSetWMColormapWindows</function>
+sets the <property>WM_COLORMAP_WINDOWS</property> property on the specified
+window to the list of windows specified by the colormap_windows argument.
+The property is stored with a type of WINDOW and a format of 32.
+If it cannot intern the <property>WM_COLORMAP_WINDOWS</property> atom,
+<function>XSetWMColormapWindows</function>
+returns a zero status.
+Otherwise, it returns a nonzero status.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMColormapWindows</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_COLORMAP_WINDOWS</property> property, use
+<function>XGetWMColormapWindows</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMColormapWindows</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmcolormapwindows'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMColormapWindows</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>Window<parameter> **colormap_windows_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>colormap_windows_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of windows.
+<!-- .ds Cn windows in the list -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMColormapWindows</function>
+function returns the list of window identifiers stored
+in the <property>WM_COLORMAP_WINDOWS</property> property on the specified window.
+These identifiers indicate the colormaps that the window manager
+may need to install for this window.
+If the property exists, is of type WINDOW, is of format 32,
+and the atom <property>WM_COLORMAP_WINDOWS</property> can be interned,
+<function>XGetWMColormapWindows</function>
+sets the windows_return argument to a list of window identifiers,
+sets the count_return argument to the number of elements in the list,
+and returns a nonzero status.
+Otherwise, it sets neither of the return arguments
+and returns a zero status.
+To release the list of window identifiers, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetWMColormapWindows</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_ICON_SIZE_Property">
+<title>Setting and Reading the WM_ICON_SIZE Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_ICON_SIZE Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_ICON_SIZE</property> property for a given window.
+These functions use the
+<structname>XIconSize</structname>
+<indexterm><primary>XIconSize</primary></indexterm>
+structure, which is defined in the
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+header file.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To allocate an
+<structname>XIconSize</structname>
+structure, use
+<function>XAllocIconSize</function>.
+</para>
+
+<para>
+ XIconSize *XAllocIconSize()
+</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocIconSize</function>
+function allocates and returns a pointer to an
+<structname>XIconSize</structname>
+structure.
+Note that all fields in the
+<structname>XIconSize</structname>
+structure are initially set to zero.
+If insufficient memory is available,
+<function>XAllocIconSize</function>
+returns NULL.
+To free the memory allocated to this structure,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XIconSize</structname>
+structure contains:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<indexterm significance="preferred"><primary>XIconSize</primary></indexterm>
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ int min_width, min_height;
+ int max_width, max_height;
+ int width_inc, height_inc;
+} XIconSize;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The width_inc and height_inc members define an arithmetic progression of
+sizes (minimum to maximum) that represent the supported icon sizes.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a window's <property>WM_ICON_SIZE</property> property, use
+<function>XSetIconSizes</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetIconSizes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xseticonsizes'>
+<funcprototype>
+ <funcdef><function>XSetIconSizes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XIconSize<parameter> *size_list</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>size_list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of items in the size list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetIconSizes</function>
+function is used only by window managers to set the supported icon sizes.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetIconSizes</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a window's <property>WM_ICON_SIZE</property> property, use
+<function>XGetIconSizes</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetIconSizes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgeticonsizes'>
+<funcprototype>
+ <funcdef>Status <function>XGetIconSizes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XIconSize<parameter> **size_list_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>size_list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the size list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of items in the size list.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetIconSizes</function>
+function returns zero if a window manager has not set icon sizes;
+otherwise, it returns nonzero.
+<function>XGetIconSizes</function>
+should be called by an application that
+wants to find out what icon sizes would be most appreciated by the
+window manager under which the application is running.
+The application
+should then use
+<function>XSetWMHints</function>
+to supply the window manager with an icon pixmap or window in one of the
+supported sizes.
+To free the data allocated in size_list_return, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetIconSizes</function>
+can generate a
+<errorname>BadWindow</errorname>
+error.
+</para>
+</sect2>
+<sect2 id="Using_Window_Manager_Convenience_Functions">
+<title>Using Window Manager Convenience Functions</title>
+<!-- .XS -->
+<!-- (SN Using Window Manager Convenience Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<function>XmbSetWMProperties</function>
+function stores the standard set of window manager properties,
+with text properties in standard encodings
+for internationalized text communication.
+The standard window manager properties for a given window are
+<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_NORMAL_HINTS</property>, <property>WM_CLASS</property>,
+<property>WM_COMMAND</property>, <property>WM_CLIENT_MACHINE</property>, and <property>WM_LOCALE_NAME</property>.
+</para>
+<indexterm significance="preferred"><primary>XmbSetWMProperties</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmbsetwmproperties'>
+<funcprototype>
+ <funcdef>void <function>XmbSetWMProperties</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> *window_name</parameter></paramdef>
+ <paramdef>char<parameter> *icon_name</parameter></paramdef>
+ <paramdef>char<parameter> *argv[]</parameter></paramdef>
+ <paramdef>int<parameter> argc</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *normal_hints</parameter></paramdef>
+ <paramdef>XWMHints<parameter> *wm_hints</parameter></paramdef>
+ <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the icon name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application's argument list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>wm_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XWMHints</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XClassHint</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XmbSetWMProperties</function>
+convenience function provides a simple programming interface
+for setting those essential window properties that are used
+for communicating with other clients
+(particularly window and session managers).
+</para>
+<para>
+<!-- .LP -->
+If the window_name argument is non-NULL,
+<function>XmbSetWMProperties</function>
+sets the <property>WM_NAME</property> property.
+If the icon_name argument is non-NULL,
+<function>XmbSetWMProperties</function>
+sets the <property>WM_ICON_NAME</property> property.
+The window_name and icon_name arguments are null-terminated strings
+in the encoding of the current locale.
+If the arguments can be fully converted to the STRING encoding,
+the properties are created with type ``STRING'';
+otherwise, the arguments are converted to Compound Text,
+and the properties are created with type ``COMPOUND_TEXT''.
+</para>
+<para>
+<!-- .LP -->
+If the normal_hints argument is non-NULL,
+<function>XmbSetWMProperties</function>
+calls
+<function>XSetWMNormalHints</function>,
+which sets the <property>WM_NORMAL_HINTS</property> property
+(see <link linkend="Setting_and_Reading_the_WM_NORMAL_HINTS_Property">section 14.1.7</link>).
+If the wm_hints argument is non-NULL,
+<function>XmbSetWMProperties</function>
+calls
+<function>XSetWMHints</function>,
+which sets the <property>WM_HINTS</property> property
+(see <link linkend="Setting_and_Reading_the_WM_HINTS_Property">section 14.1.6</link>).
+</para>
+<para>
+<!-- .LP -->
+If the argv argument is non-NULL,
+<function>XmbSetWMProperties</function>
+sets the <property>WM_COMMAND</property> property from argv and argc.
+An argc of zero indicates a zero-length command.
+</para>
+<para>
+<!-- .LP -->
+The hostname of the machine is stored using
+<function>XSetWMClientMachine</function>
+(see <link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">section 14.2.2</link>).
+</para>
+<para>
+<!-- .LP -->
+If the class_hints argument is non-NULL,
+<function>XmbSetWMProperties</function>
+sets the <property>WM_CLASS</property> property.
+If the res_name member in the
+<structname>XClassHint</structname>
+structure is set to the NULL pointer and the RESOURCE_NAME
+environment variable is set,
+the value of the environment variable is substituted for res_name.
+If the res_name member is NULL,
+the environment variable is not set, and argv and argv[0] are set,
+then the value of argv[0], stripped of any directory prefixes,
+is substituted for res_name.
+</para>
+<para>
+<!-- .LP -->
+It is assumed that the supplied class_hints.res_name and argv,
+the RESOURCE_NAME environment variable, and the hostname of the machine
+are in the encoding of the locale announced for the LC_CTYPE category
+(on <acronym>POSIX</acronym>-compliant systems, the LC_CTYPE, else LANG environment variable).
+The corresponding <property>WM_CLASS</property>, <property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property> properties
+are typed according to the local host locale announcer.
+No encoding conversion is performed prior to storage in the properties.
+</para>
+<para>
+<!-- .LP -->
+For clients that need to process the property text in a locale,
+<function>XmbSetWMProperties</function>
+sets the <property>WM_LOCALE_NAME</property> property to be the name of the current locale.
+The name is assumed to be in the Host Portable Character Encoding
+and is converted to STRING for storage in the property.
+</para>
+<para>
+<!-- .LP -->
+<function>XmbSetWMProperties</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's standard window manager properties
+with strings in client-specified encodings, use
+<function>XSetWMProperties</function>.
+The standard window manager properties for a given window are
+<property>WM_NAME</property>, <property>WM_ICON_NAME</property>, <property>WM_HINTS</property>, <property>WM_NORMAL_HINTS</property>, <property>WM_CLASS</property>,
+<property>WM_COMMAND</property>, and <property>WM_CLIENT_MACHINE</property>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMProperties</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmproperties'>
+<funcprototype>
+ <funcdef>void <function>XSetWMProperties</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *window_name</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *icon_name</parameter></paramdef>
+ <paramdef>char<parameter> **argv</parameter></paramdef>
+ <paramdef>int<parameter> argc</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *normal_hints</parameter></paramdef>
+ <paramdef>XWMHints<parameter> *wm_hints</parameter></paramdef>
+ <paramdef>XClassHint<parameter> *class_hints</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>window_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>icon_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the icon name,
+which should be a null-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application's argument list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>normal_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>wm_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XWMHints</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class_hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XClassHint</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMProperties</function>
+convenience function provides a single programming interface
+for setting those essential window properties that are used
+for communicating with other clients (particularly window and session
+managers).
+</para>
+<para>
+<!-- .LP -->
+If the window_name argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetWMName</function>,
+which, in turn, sets the <property>WM_NAME</property> property
+(see <link linkend="Setting_and_Reading_the_WM_NAME_Property">section 14.1.4</link>).
+If the icon_name argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetWMIconName</function>,
+which sets the <property>WM_ICON_NAME</property> property
+(see <link linkend="Setting_and_Reading_the_WM_ICON_NAME_Property">section 14.1.5</link>).
+If the argv argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetCommand</function>,
+which sets the <property>WM_COMMAND</property> property
+(see <link linkend="Setting_and_Reading_the_WM_COMMAND_Property">section 14.2.1</link>).
+Note that an argc of zero is allowed to indicate a zero-length command.
+Note also that the hostname of this machine is stored using
+<function>XSetWMClientMachine</function>
+(see <link linkend="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">section 14.2.2</link>).
+</para>
+<para>
+<!-- .LP -->
+If the normal_hints argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetWMNormalHints</function>,
+which sets the <property>WM_NORMAL_HINTS</property> property
+(see <link linkend="Setting_and_Reading_the_WM_NORMAL_HINTS_Property">section 14.1.7</link>).
+If the wm_hints argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetWMHints</function>,
+which sets the <property>WM_HINTS</property> property
+(see <link linkend="Setting_and_Reading_the_WM_HINTS_Property">section 14.1.6</link>).
+</para>
+<para>
+<!-- .LP -->
+If the class_hints argument is non-NULL,
+<function>XSetWMProperties</function>
+calls
+<function>XSetClassHint</function>,
+which sets the <property>WM_CLASS</property> property
+(see <link linkend="Setting_and_Reading_the_WM_CLASS_Property">section 14.1.8</link>).
+If the res_name member in the
+<structname>XClassHint</structname>
+structure is set to the NULL pointer and the RESOURCE_NAME environment
+variable is set,
+then the value of the environment variable is substituted for res_name.
+If the res_name member is NULL,
+the environment variable is not set,
+and argv and argv[0] are set,
+then the value of argv[0], stripped of
+any directory prefixes, is substituted for res_name.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetWMProperties</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Client_to_Session_Manager_Communication">
+<title>Client to Session Manager Communication</title>
+<!-- .XS -->
+<!-- (SN Client to Session Manager Communication -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses how to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Set and read the <property>WM_COMMAND</property> property
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Set and read the <property>WM_CLIENT_MACHINE</property> property
+ </para>
+ </listitem>
+</itemizedlist>
+<sect2 id="Setting_and_Reading_the_WM_COMMAND_Property">
+<title>Setting and Reading the WM_COMMAND Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_COMMAND Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_COMMAND</property> property for a given window.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_COMMAND</property> property, use
+<function>XSetCommand</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetCommand</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetcommand'>
+<funcprototype>
+ <funcdef><function>XSetCommand</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> **argv</parameter></paramdef>
+ <paramdef>int<parameter> argc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application's argument list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetCommand</function>
+function sets the command and arguments used to invoke the
+application.
+(Typically, argv is the argv array of your main program.)
+If the strings are not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<function>XSetCommand</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_COMMAND</property> property, use
+<function>XGetCommand</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetCommand</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetcommand'>
+<funcprototype>
+ <funcdef>Status <function>XGetCommand</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>char<parameter> ***argv_return</parameter></paramdef>
+ <paramdef>int<parameter> *argc_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the application's argument list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of arguments returned.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetCommand</function>
+function reads the <property>WM_COMMAND</property> property from the specified window
+and returns a string list.
+If the <property>WM_COMMAND</property> property exists,
+it is of type STRING and format 8.
+If sufficient memory can be allocated to contain the string list,
+<function>XGetCommand</function>
+fills in the argv_return and argc_return arguments
+and returns a nonzero status.
+Otherwise, it returns a zero status.
+If the data returned by the server is in the Latin Portable Character Encoding,
+then the returned strings are in the Host Portable Character Encoding.
+Otherwise, the result is implementation-dependent.
+To free the memory allocated to the string list, use
+<function>XFreeStringList</function>.
+</para>
+</sect2>
+<sect2 id="Setting_and_Reading_the_WM_CLIENT_MACHINE_Property">
+<title>Setting and Reading the WM_CLIENT_MACHINE Property</title>
+<!-- .XS -->
+<!-- (SN Setting and Reading the WM_CLIENT_MACHINE Property -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and read
+the <property>WM_CLIENT_MACHINE</property> property for a given window.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set a window's <property>WM_CLIENT_MACHINE</property> property, use
+<function>XSetWMClientMachine</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetWMClientMachine</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetwmclientmachine'>
+<funcprototype>
+ <funcdef>void <function>XSetWMClientMachine</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XTextProperty</structname>
+structure to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetWMClientMachine</function>
+convenience function calls
+<function>XSetTextProperty</function>
+to set the <property>WM_CLIENT_MACHINE</property> property.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To read a window's <property>WM_CLIENT_MACHINE</property> property, use
+<function>XGetWMClientMachine</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetWMClientMachine</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetwmclientmachine'>
+<funcprototype>
+ <funcdef>Status <function>XGetWMClientMachine</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XTextProperty<parameter> *text_prop_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>text_prop_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XTextProperty</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetWMClientMachine</function>
+convenience function performs an
+<function>XGetTextProperty</function>
+on the <property>WM_CLIENT_MACHINE</property> property.
+It returns a nonzero status on success;
+otherwise, it returns a zero status.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Standard_Colormaps">
+<title>Standard Colormaps</title>
+<!-- .XS -->
+<!-- (SN Standard Colormaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Applications with color palettes, smooth-shaded drawings, or digitized
+images demand large numbers of colors.
+In addition, these applications often require an efficient mapping
+from color triples to pixel values that display the appropriate colors.
+</para>
+<para>
+<!-- .LP -->
+As an example, consider a three-dimensional display program that wants
+to draw a smoothly shaded sphere.
+At each pixel in the image of the sphere,
+the program computes the intensity and color of light
+reflected back to the viewer.
+The result of each computation is a triple of red, green, and blue (<acronym>RGB</acronym>)
+coefficients in the range 0.0 to 1.0.
+To draw the sphere, the program needs a colormap that provides a
+large range of uniformly distributed colors.
+The colormap should be arranged so that the program can
+convert its <acronym>RGB</acronym> triples into pixel values very quickly,
+because drawing the entire sphere requires many such
+conversions.
+</para>
+<para>
+<!-- .LP -->
+On many current workstations,
+the display is limited to 256 or fewer colors.
+Applications must allocate colors carefully,
+not only to make sure they cover the entire range they need
+but also to make use of as many of the available colors as possible.
+On a typical X display,
+many applications are active at once.
+Most workstations have only one hardware look-up table for colors,
+so only one application colormap can be installed at a given time.
+The application using the installed colormap is displayed correctly,
+and the other applications go technicolor and are
+displayed with false colors.
+</para>
+<para>
+<!-- .LP -->
+As another example, consider a user who is running an
+image processing program to display earth-resources data.
+The image processing program needs a colormap set up with 8 reds,
+8 greens, and 4 blues, for a total of 256 colors.
+Because some colors are already in use in the default colormap,
+the image processing program allocates and installs a new colormap.
+</para>
+<para>
+<!-- .LP -->
+The user decides to alter some of the colors in the image
+by invoking a color palette program to mix and choose colors.
+The color palette program also needs a
+colormap with eight reds, eight greens, and four blues, so just like
+the image processing program, it must allocate and
+install a new colormap.
+</para>
+<para>
+<!-- .LP -->
+Because only one colormap can be installed at a time,
+the color palette may be displayed incorrectly
+whenever the image processing program is active.
+Conversely, whenever the palette program is active,
+the image may be displayed incorrectly.
+The user can never match or compare colors in the palette and image.
+Contention for colormap resources can be reduced if applications
+with similar color needs share colormaps.
+</para>
+<para>
+<!-- .LP -->
+The image processing program and the color palette program
+could share the same colormap if there existed a convention that described
+how the colormap was set up.
+Whenever either program was active,
+both would be displayed correctly.
+</para>
+<para>
+<!-- .LP -->
+The standard colormap properties define a set of commonly used
+colormaps.
+Applications that share these colormaps and conventions display
+true colors more often and provide a better interface to the user.
+</para>
+<para>
+<!-- .LP -->
+Standard colormaps allow applications to share commonly used color
+resources.
+This allows many applications to be displayed in true colors
+simultaneously, even when each application needs an entirely filled
+colormap.
+</para>
+<para>
+<!-- .LP -->
+Several standard colormaps are described in this section.
+Usually, a window manager creates these colormaps.
+Applications should use the standard colormaps if they already exist.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To allocate an
+<structname>XStandardColormap</structname>
+structure, use
+<function>XAllocStandardColormap</function>.
+</para>
+
+<para>
+XStandardColormap *XAllocStandardColormap()
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAllocStandardColormap</function>
+function allocates and returns a pointer to an
+<structname>XStandardColormap</structname>
+structure.
+Note that all fields in the
+<structname>XStandardColormap</structname>
+structure are initially set to zero.
+If insufficient memory is available,
+<function>XAllocStandardColormap</function>
+returns NULL.
+To free the memory allocated to this structure,
+use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XStandardColormap</structname>
+structure contains:
+</para>
+<literallayout class="monospaced">
+/* Hints */
+
+#define ReeaseByFreeingColormap ((XID)1L)
+
+/* Values */
+
+typedef struct {
+ Colormap colormap;
+ unsigned long red_max;
+ unsigned long red_mult;
+ unsigned long green_max;
+ unsigned long green_mult;
+ unsigned long blue_max;
+ unsigned long blue_mult;
+ unsigned long base_pixel;
+ VisualID visualid;
+ XID killid;
+} XStandardColormap;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The colormap member is the colormap created by the
+<function>XCreateColormap</function>
+function.
+The red_max, green_max, and blue_max members give the maximum
+red, green, and blue values, respectively.
+Each color coefficient ranges from zero to its max, inclusive.
+For example,
+a common colormap allocation is 3/3/2 (3 planes for red, 3
+planes for green, and 2 planes for blue).
+This colormap would have red_max = 7, green_max = 7,
+and blue_max = 3.
+An alternate allocation that uses only 216 colors is red_max = 5,
+green_max = 5, and blue_max = 5.
+</para>
+<para>
+<!-- .LP -->
+The red_mult, green_mult, and blue_mult members give the
+scale factors used to compose a full pixel value.
+(See the discussion of the base_pixel members for further information.)
+For a 3/3/2 allocation, red_mult might be 32,
+green_mult might be 4, and blue_mult might be 1.
+For a 6-colors-each allocation, red_mult might be 36,
+green_mult might be 6, and blue_mult might be 1.
+</para>
+<para>
+<!-- .LP -->
+The base_pixel member gives the base pixel value used to
+compose a full pixel value.
+Usually, the base_pixel is obtained from a call to the
+<function>XAllocColorPlanes</function>
+function.
+Given integer red, green, and blue coefficients in their appropriate
+ranges, one then can compute a corresponding pixel value by
+using the following expression:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1.5i -->
+<!-- .ta .5i 1.5i -->
+(r * red_mult + g * green_mult + b * blue_mult + base_pixel) & 0xFFFFFFFF
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+For
+<symbol>GrayScale</symbol>
+colormaps,
+only the colormap, red_max, red_mult,
+and base_pixel members are defined.
+The other members are ignored.
+To compute a
+<symbol>GrayScale</symbol>
+pixel value, use the following expression:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .5i 1.5i -->
+<!-- .ta .5i 1.5i -->
+(gray * red_mult + base_pixel) & 0xFFFFFFFF
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Negative multipliers can be represented by converting the 2's
+complement representation of the multiplier into an unsigned long and
+storing the result in the appropriate _mult field.
+The step of masking by 0xFFFFFFFF effectively converts the resulting
+positive multiplier into a negative one.
+The masking step will take place automatically on many machine architectures,
+depending on the size of the integer type used to do the computation.
+</para>
+<para>
+<!-- .LP -->
+The visualid member gives the ID number of the visual from which the
+colormap was created.
+The killid member gives a resource ID that indicates whether
+the cells held by this standard colormap are to be released
+by freeing the colormap ID or by calling the
+<function>XKillClient</function>
+function on the indicated resource.
+(Note that this method is necessary for allocating out of an existing colormap.)
+</para>
+<para>
+<!-- .LP -->
+The properties containing the
+<structname>XStandardColormap</structname>
+information have
+the type RGB_COLOR_MAP.
+</para>
+<para>
+<!-- .LP -->
+The remainder of this section discusses standard colormap properties and atoms
+as well as how to manipulate standard colormaps.
+</para>
+<sect2 id="Standard_Colormap_Properties_and_Atoms">
+<title>Standard Colormap Properties and Atoms</title>
+<!-- .XS -->
+<!-- (SN Standard Colormap Properties and Atoms -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Standard Colormaps</primary></indexterm>
+<indexterm><primary>Colormaps</primary><secondary>standard</secondary></indexterm>
+Several standard colormaps are available.
+Each standard colormap is defined by a property,
+and each such property is identified by an atom.
+The following list names the atoms and describes the colormap
+associated with each one.
+The
+<filename class="headerfile"><X11/Xatom.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xatom.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xatom.h></filename></secondary></indexterm>
+header file contains the definitions for each of the following atoms,
+which are prefixed with XA_.
+</para>
+
+
+
+<variablelist>
+ <varlistentry>
+ <term>RGB_DEFAULT_MAP</term>
+ <listitem>
+ <para>
+This atom names a property.
+The value of the property is an array of
+<structname>XStandardColormap</structname>
+structures.
+Each entry in the array describes an <acronym>RGB</acronym> subset of the default color
+map for the Visual specified by visual_id.
+ </para>
+ <para>
+Some applications only need a few <acronym>RGB</acronym> colors and
+may be able to allocate them from the system default colormap.
+This is the ideal situation because the fewer colormaps that are
+active in the system the more applications are displayed
+with correct colors at all times.
+ </para>
+ <para>
+A typical allocation for the RGB_DEFAULT_MAP on 8-plane displays
+is 6 reds, 6 greens, and 6 blues.
+This gives 216 uniformly distributed colors
+(6 intensities of 36 different hues) and still leaves 40 elements
+of a 256-element colormap available for special-purpose colors
+for text, borders, and so on.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>RGB_BEST_MAP</term>
+ <listitem>
+ <para>
+This atom names a property. The value of the property is an
+<structname>XStandardColormap</structname>.
+ </para>
+ <para>
+The property defines the best <acronym>RGB</acronym> colormap available on
+the screen.
+(Of course, this is a subjective evaluation.)
+Many image processing and three-dimensional applications need to
+use all available colormap cells and to distribute as many
+perceptually distinct colors as possible over those cells.
+This implies that there may be more green values available than
+red, as well as more green or red than blue.
+ </para>
+ <para>
+For an 8-plane
+<symbol>PseudoColor</symbol>
+visual,
+RGB_BEST_MAP is likely to be a 3/3/2 allocation.
+For a 24-plane
+<symbol>DirectColor</symbol>
+visual,
+RGB_BEST_MAP is normally an 8/8/8 allocation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>RGB_RED_MAP,RGB_GREEN_MAP,RGB_BLUE_MAP</term>
+ <listitem>
+ <para>
+These atoms name properties.
+The value of each property is an
+<structname>XStandardColormap</structname>.
+ </para>
+ <para>
+The properties define all-red, all-green, and all-blue
+colormaps, respectively.
+These maps are used by applications that want to make color-separated
+images.
+For example, a user might generate a full-color image
+on an 8-plane display both by rendering an image three times
+(once with high color resolution in red, once with green,
+and once with blue) and by multiply exposing a single frame in a camera.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>RGB_GRAY_MAP</term>
+ <listitem>
+ <para>
+This atom names a property.
+The value of the property is an
+<structname>XStandardColormap</structname>.
+ </para>
+ <para>
+The property describes the best
+<symbol>GrayScale</symbol>
+colormap available on the screen.
+As previously mentioned,
+only the colormap, red_max, red_mult, and base_pixel members of the
+<structname>XStandardColormap</structname>
+structure are used for
+<symbol>GrayScale</symbol>
+colormaps.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect2>
+
+<sect2 id="Setting_and_Obtaining_Standard_Colormaps">
+<title>Setting and Obtaining Standard Colormaps</title>
+<!-- .XS -->
+<!-- (SN Setting and Obtaining Standard Colormaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to set and obtain an
+<structname>XStandardColormap</structname>
+structure.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To set an
+<structname>XStandardColormap</structname>
+structure, use
+<function>XSetRGBColormaps</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetRGBColormaps</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetrgbcolormaps'>
+<funcprototype>
+ <funcdef>void <function>XSetRGBColormaps</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XStandardColormap<parameter> *std_colormap</parameter></paramdef>
+ <paramdef>int<parameter> count</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>std_colormap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>XStandardColormap</structname>
+structure to be used.
+<!-- .ds Cn colormaps -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetRGBColormaps</function>
+function replaces the <acronym>RGB</acronym> colormap definition in the specified property
+on the named window.
+If the property does not already exist,
+<function>XSetRGBColormaps</function>
+sets the <acronym>RGB</acronym> colormap definition in the specified property
+on the named window.
+The property is stored with a type of RGB_COLOR_MAP and a format of 32.
+Note that it is the caller's responsibility to honor the <acronym>ICCCM</acronym>
+restriction that only RGB_DEFAULT_MAP contain more than one definition.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XSetRGBColormaps</function>
+function usually is only used by window or session managers.
+To create a standard colormap,
+follow this procedure:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Open a new connection to the same server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Grab the server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+See if the property is on the property list of the root window for the screen.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+If the desired property is not present:
+<!-- .RS -->
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Create a colormap (unless you are using the default colormap of the screen).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determine the color characteristics of the visual.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Allocate cells in the colormap (or create it with
+<symbol>AllocAll</symbol>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Call
+<function>XStoreColors</function>
+to store appropriate color values in the colormap.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Fill in the descriptive members in the
+<structname>XStandardColormap</structname>
+structure.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Attach the property to the root window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use
+<function>XSetCloseDownMode</function>
+to make the resource permanent.
+<!-- .RE -->
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Ungrab the server.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+<function>XSetRGBColormaps</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadAtom</errorname>,
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To obtain the
+<structname>XStandardColormap</structname>
+structure associated with the specified property, use
+<function>XGetRGBColormaps</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetRGBColormaps</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetrgbcolormaps'>
+<funcprototype>
+ <funcdef>Status <function>XGetRGBColormaps</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Window<parameter> w</parameter></paramdef>
+ <paramdef>XStandardColormap<parameter> **std_colormap_return</parameter></paramdef>
+ <paramdef>int<parameter> *count_return</parameter></paramdef>
+ <paramdef>Atom<parameter> property</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>w</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the window.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>std_colormap_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the
+<structname>XStandardColormap</structname>
+structure.
+<!-- .ds Cn colormaps -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>count_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of (Cn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>property</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the property name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetRGBColormaps</function>
+function returns the <acronym>RGB</acronym> colormap definitions stored
+in the specified property on the named window.
+If the property exists, is of type RGB_COLOR_MAP, is of format 32,
+and is long enough to contain a colormap definition,
+<function>XGetRGBColormaps</function>
+allocates and fills in space for the returned colormaps
+and returns a nonzero status.
+If the visualid is not present,
+<function>XGetRGBColormaps</function>
+assumes the default visual for the screen on which the window is located;
+if the killid is not present,
+<symbol>None</symbol>
+is assumed, which indicates that the resources cannot be released.
+Otherwise,
+none of the fields are set, and
+<function>XGetRGBColormaps</function>
+returns a zero status.
+Note that it is the caller's responsibility to honor the <acronym>ICCCM</acronym>
+restriction that only RGB_DEFAULT_MAP contain more than one definition.
+</para>
+<para>
+<!-- .LP -->
+<function>XGetRGBColormaps</function>
+can generate
+<errorname>BadAtom</errorname>
+and
+<errorname>BadWindow</errorname>
+errors.
+<!-- .bp -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH15.xml b/libX11/specs/libX11/CH15.xml index 3c4a29695..c012ea7d0 100644 --- a/libX11/specs/libX11/CH15.xml +++ b/libX11/specs/libX11/CH15.xml @@ -1,2483 +1,2483 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="resource_manager_functions"> -<title>Resource Manager Functions</title> -<!-- .sp 2 --> -<!-- .nr H1 15 --> -<!-- .nr H2 0 --> -<!-- .nr H3 0 --> -<!-- .nr H4 0 --> -<!-- .nr H5 0 --> -<!-- .na --> -<para> -<!-- .LP --> -<!-- .XS --> -<!-- Chapter 15: Resource Manager Functions --> -<!-- .XE --> -A program often needs a variety of options in the X environment -(for example, fonts, colors, icons, and cursors). -Specifying all of these options on the command line is awkward -because users may want to customize many aspects of the program -and need a convenient way to establish these customizations as -the default settings. -The resource manager is provided for this purpose. -Resource specifications are usually stored in human-readable files -and in server properties. -</para> -<para> -<!-- .LP --> -The resource manager is a database manager with a twist. -In most database systems, -you perform a query using an imprecise specification, -and you get back a set of records. -The resource manager, however, allows you to specify a large -set of values with an imprecise specification, to query the database -with a precise specification, and to get back only a single value. -This should be used by applications that need to know what the -user prefers for colors, fonts, and other resources. -It is this use as a database for dealing with X resources that -inspired the name "Resource Manager," -although the resource manager can be and is used in other ways. -</para> -<para> -<!-- .LP --> -For example, -a user of your application may want to specify -that all windows should have a blue background -but that all mail-reading windows should have a red background. -With well-engineered and coordinated applications, -a user can define this information using only two lines of specifications. -</para> -<para> -<!-- .LP --> -As an example of how the resource manager works, -consider a mail-reading application called xmh. -Assume that it is designed so that it uses a -complex window hierarchy all the way down to individual command buttons, -which may be actual small subwindows in some toolkits. -These are often called objects or widgets. -In such toolkit systems, -each user interface object can be composed of other objects -and can be assigned a name and a class. -Fully qualified names or classes can have arbitrary numbers of component names, -but a fully qualified name always has the same number of component names as a -fully qualified class. -This generally reflects the structure of the application as composed -of these objects, starting with the application itself. -</para> -<para> -<!-- .LP --> -For example, the xmh mail program has a name "xmh" and is one -of a class of "Mail" programs. -By convention, the first character of class components is capitalized, -and the first letter of name components is in lowercase. -Each name and class finally has an attribute -(for example, "foreground" or "font"). -If each window is properly assigned a name and class, -it is easy for the user to specify attributes of any portion -of the application. -</para> -<para> -<!-- .LP --> -At the top level, -the application might consist of a paned window (that is, a window divided -into several sections) named "toc". -One pane of the paned window is a button box window named "buttons" -and is filled with command buttons. -One of these command buttons is used to incorporate -new mail and has the name "incorporate". -This window has a fully qualified name, "xmh.toc.buttons.incorporate", -and a fully qualified class, "Xmh.Paned.Box.Command". -Its fully qualified name is the name of its parent, "xmh.toc.buttons", -followed by its name, "incorporate". -Its class is the class of its parent, "Xmh.Paned.Box", -followed by its particular class, "Command". -The fully qualified name of a resource is -the attribute's name appended to the object's fully qualified -name, and the fully qualified class is its class appended to the object's -class. -</para> -<para> -<!-- .LP --> -The incorporate button might need the following resources: -Title string, -Font, -Foreground color for its inactive state, -Background color for its inactive state, -Foreground color for its active state, and -Background color for its active state. -Each resource is considered -to be an attribute of the button and, as such, has a name and a class. -For example, the foreground color for the button in -its active state might be named "activeForeground", -and its class might be "Foreground". -</para> -<para> -<!-- .LP --> -When an application looks up a resource (for example, a color), -it passes the complete name and complete class of the resource -to a look-up routine. -The resource manager compares this complete specification -against the incomplete specifications of entries in the resource -database, finds the best match, and returns the corresponding -value for that entry. -</para> -<para> -<!-- .LP --> -The definitions for the resource manager are contained in -<filename class="headerfile"><X11/Xresource.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xresource.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xresource.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xresource.h></filename></secondary></indexterm> -</para> -<sect1 id="Resource_File_Syntax"> -<title>Resource File Syntax</title> -<!-- .XS --> -<!-- (SN Resource File Syntax --> -<!-- .XE --> -<para> -<!-- .LP --> -The syntax of a resource file is a sequence of resource lines -terminated by newline characters or the end of the file. -The syntax of an individual resource line is: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -<!-- .TA 1.5i 1.75i --> -<!-- .ta 1.5i 1.75i --> -ResourceLine = Comment | IncludeFile | ResourceSpec | <empty line> -Comment = "!" {<any character except null or newline>} -IncludeFile = "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace -FileName = <valid filename for operating system> -ResourceSpec = WhiteSpace ResourceName WhiteSpace ":" WhiteSpace Value -ResourceName = [Binding] {Component Binding} ComponentName -Binding = "." | "*" -WhiteSpace = {<space> | <horizontal tab>} -Component = "?" | ComponentName -ComponentName = NameChar {NameChar} -NameChar = "a"-"z" | "A"-"Z" | "0"-"9" | "_" | "-" -Value = {<any character except null or unescaped newline>} -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -Elements separated by vertical bar (|) are alternatives. -Curly braces ({......}) indicate zero or more repetitions -of the enclosed elements. -Square brackets ([......]) indicate that the enclosed element is optional. -Quotes ("......") are used around literal characters. -</para> -<para> -<!-- .LP --> -IncludeFile lines are interpreted by replacing the line with the -contents of the specified file. -The word "include" must be in lowercase. -The file name is interpreted relative to the directory of the file in -which the line occurs (for example, if the file name contains no -directory or contains a relative directory specification). -</para> -<para> -<!-- .LP --> -If a ResourceName contains a contiguous sequence of two or more Binding -characters, the sequence will be replaced with a single ".." character -if the sequence contains only ".." characters; -otherwise, the sequence will be replaced with a single "*" character. -</para> -<para> -<!-- .LP --> -A resource database never contains more than one entry for a given -ResourceName. If a resource file contains multiple lines with the -same ResourceName, the last line in the file is used. -</para> -<para> -<!-- .LP --> -Any white space characters before or after the name or colon in a ResourceSpec -are ignored. -To allow a Value to begin with white space, -the two-character sequence "\\<emphasis remap='I'>space</emphasis>" (backslash followed by space) -is recognized and replaced by a space character, -and the two-character sequence "\\<emphasis remap='I'>tab</emphasis>" -(backslash followed by horizontal tab) -is recognized and replaced by a horizontal tab character. -To allow a Value to contain embedded newline characters, -the two-character sequence "\\n" is recognized and replaced by a -newline character. -To allow a Value to be broken across multiple lines in a text file, -the two-character sequence "\\<emphasis remap='I'>newline</emphasis>" -(backslash followed by newline) is -recognized and removed from the value. -To allow a Value to contain arbitrary character codes, -the four-character sequence "\\<emphasis remap='I'>nnn</emphasis>", -where each <emphasis remap='I'>n</emphasis> is a digit character in the range of "0"-"7", -is recognized and replaced with a single byte that contains -the octal value specified by the sequence. -Finally, the two-character sequence "\newline" is recognized -and replaced with a single backslash. -</para> -<para> -<!-- .LP --> -As an example of these sequences, -the following resource line contains a value consisting of four -characters: a backslash, a null, a "z", and a newline: -<literallayout class="monospaced"> -magic.values: \\000\ -z\n -</literallayout> -</para> -</sect1> -<sect1 id="Resource_Manager_Matching_Rules"> -<title>Resource Manager Matching Rules</title> -<!-- .XS --> -<!-- (SN Resource Manager Matching Rules --> -<!-- .XE --> -<para> -<!-- .LP --> -The algorithm for determining which resource database entry -matches a given query is the heart of the resource manager. -All queries must fully specify the name and class of the desired resource -(use of the characters "*" and "?" is not permitted). -The library supports up to 100 components in a full name or class. -Resources are stored in the database with only partially specified -names and classes, using pattern matching constructs. -An asterisk (*) is a loose binding and is used to represent any number -of intervening components, including none. -A period (.) is a tight binding and is used to separate immediately -adjacent components. -A question mark (?) is used to match any single component name or class. -A database entry cannot end in a loose binding; -the final component (which cannot be the character "?") must be specified. -The lookup algorithm searches the database for the entry that most -closely matches (is most specific for) the full name and class being queried. -When more than one database entry matches the full name and class, -precedence rules are used to select just one. -</para> -<para> -<!-- .LP --> -The full name and class are scanned from left to right (from highest -level in the hierarchy to lowest), one component at a time. -At each level, the corresponding component and/or binding of each -matching entry is determined, and these matching components and -bindings are compared according to precedence rules. -Each of the rules is applied at each level before moving to the next level, -until a rule selects a single entry over all others. -The rules, in order of precedence, are: -</para> -<itemizedlist> - <listitem> - <para> -An entry that contains a matching component (whether name, class, -or the character "?") -takes precedence over entries that elide the level (that is, entries -that match the level in a loose binding). - </para> - </listitem> - <listitem> - <para> -An entry with a matching name takes precedence over both -entries with a matching class and entries that match using the character "?". -An entry with a matching class takes precedence over -entries that match using the character "?". - </para> - </listitem> - <listitem> - <para> -An entry preceded by a tight binding takes precedence over entries -preceded by a loose binding. - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -To illustrate these rules, -consider the following resource database entries: -<literallayout class="monospaced"> -<!-- .TA 2.5i 3.5i --> -<!-- .ta 2.5i 3.5i --> -xmh*Paned*activeForeground: red <emphasis remap='I'>(entry A)</emphasis> -*incorporate.Foreground: blue <emphasis remap='I'>(entry B)</emphasis> -xmh.toc*Command*activeForeground: green <emphasis remap='I'>(entry C)</emphasis> -xmh.toc*?.Foreground: white <emphasis remap='I'>(entry D)</emphasis> -xmh.toc*Command.activeForeground: black <emphasis remap='I'>(entry E)</emphasis> -</literallayout> -</para> -<para> -<!-- .LP --> -Consider a query for the resource: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA 3.5i --> -<!-- .ta 3.5i --> -xmh.toc.messagefunctions.incorporate.activeForeground <emphasis remap='I'>(name)</emphasis> -Xmh.Paned.Box.Command.Foreground <emphasis remap='I'>(class)</emphasis> -</literallayout> -</para> -<para> -<!-- .LP --> -At the first level (xmh, Xmh), rule 1 eliminates entry B. -At the second level (toc, Paned), rule 2 eliminates entry A. -At the third level (messagefunctions, Box), no entries are eliminated. -At the fourth level (incorporate, Command), rule 2 eliminates entry D. -At the fifth level (activeForeground, Foreground), rule 3 eliminates entry C. -</para> -</sect1> -<sect1 id="Quarks"> -<title>Quarks</title> -<!-- .XS --> -<!-- (SN Quarks --> -<!-- .XE --> -<para> -<!-- .LP --> -Most uses of the resource manager involve defining names, -classes, and representation types as string constants. -However, always referring to strings in the resource manager can be slow, -because it is so heavily used in some toolkits. -To solve this problem, -a shorthand for a string is used in place of the string -in many of the resource manager functions. -Simple comparisons can be performed rather than string comparisons. -The shorthand name for a string is called a quark and is the -type -<type>XrmQuark</type>. -On some occasions, -you may want to allocate a quark that has no string equivalent. -</para> -<para> -<!-- .LP --> -A quark is to a string what an atom is to a string in the server, -but its use is entirely local to your application. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate a new quark, use -<function>XrmUniqueQuark</function>. -</para> -<indexterm significance="preferred"><primary>XrmUniqueQuark</primary></indexterm> -<!-- .sM --> -<para>XrmQuark XrmUniqueQuark()</para> -<!-- .FN --> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmUniqueQuark</function> -function allocates a quark that is guaranteed not to represent any string that -is known to the resource manager. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Each name, class, and representation type is typedef'd as an -<type>XrmQuark</type>. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -typedef int XrmQuark, *XrmQuarkList; -typedef XrmQuark XrmName; -typedef XrmQuark XrmClass; -typedef XrmQuark XrmRepresentation; -#define NULLQUARK ((XrmQuark) 0) -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Lists are represented as null-terminated arrays of quarks. -The size of the array must be large enough for the number of components used. -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -typedef XrmQuarkList XrmNameList; -typedef XrmQuarkList XrmClassList; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To convert a string to a quark, use -<function>XrmStringToQuark</function> -or -<function>XrmPermStringToQuark</function>. -</para> -<literallayout class="monospaced"> -#define XrmStringToName(string) XrmStringToQuark(string) -#define XrmStringToClass(string) XrmStringToQuark(string) -#define XrmStringToRepresentation(string) XrmStringToQuark(string) -</literallayout> - -<indexterm significance="preferred"><primary>XrmStringToQuark</primary></indexterm> -<indexterm significance="preferred"><primary>XrmPermStringToQuark</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmstringtoquark'> -<funcprototype> - <funcdef>XrmQuark <function>XrmStringToQuark</function></funcdef> - <paramdef>char<parameter> *string</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Ql --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the string for which a quark(Ql is to be allocated. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -These functions can be used to convert from string to quark representation. -If the string is not in the Host Portable Character Encoding, -the conversion is implementation-dependent. -The string argument to -<function>XrmStringToQuark</function> -need not be permanently allocated storage. -<function>XrmPermStringToQuark</function> -is just like -<function>XrmStringToQuark</function>, -except that Xlib is permitted to assume the string argument is permanently -allocated, -and, hence, that it can be used as the value to be returned by -<function>XrmQuarkToString</function>. -</para> -<para> -<!-- .LP --> -For any given quark, if -<function>XrmStringToQuark</function> -returns a non-NULL value, -all future calls will return the same value (identical address). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To convert a quark to a string, use -<function>XrmQuarkToString</function>. -</para> - -<literallayout class="monospaced"> -#define XrmNameToString(name) XrmQuarkToString(name) -#define XrmClassToString(class) XrmQuarkToString(name) -#define XrmRepresentationToString(type) XrmQuarkToString(type) -</literallayout> -<indexterm significance="preferred"><primary>XrmQuarkToString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmquarktostring'> -<funcprototype> - <funcdef>char *<function>XrmQuarkToString</function></funcdef> - <paramdef>XrmQuark<parameter> quark</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>quark</emphasis> - </term> - <listitem> - <para> -Specifies the quark for which the equivalent string is desired. - </para> - </listitem> - </varlistentry> -</variablelist> -<!-- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --> -<para> -These functions can be used to convert from quark representation to string. -The string pointed to by the return value must not be modified or freed. -The returned string is byte-for-byte equal to the original -string passed to one of the string-to-quark routines. -If no string exists for that quark, -<function>XrmQuarkToString</function> -returns NULL. -For any given quark, if -<function>XrmQuarkToString</function> -returns a non-NULL value, -all future calls will return the same value (identical address). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To convert a string with one or more components to a quark list, use -<function>XrmStringToQuarkList</function>. -</para> - -<literallayout class="monospaced"> -#define XrmStringToNameList(str,name) XrmStringToQuarkList((str), (name)) -#define XrmStringToClassList(str,class) XrmStringToQuarkList((str), (class)) -</literallayout> - -<indexterm significance="preferred"><primary>XrmStringToQuarkList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmstringtoquarklist'> -<funcprototype> - <funcdef>void <function>XrmStringToQuarkList</function></funcdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>XrmQuarkList<parameter> quarks_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Ql \ list --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the string for which a quark(Ql is to be allocated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quarks_return</emphasis> - </term> - <listitem> - <para> -Returns the list of quarks. -The caller must allocate sufficient space for the quarks list before calling -<function>XrmStringToQuarkList</function>. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmStringToQuarkList</function> -function converts the null-terminated string (generally a fully qualified name) -to a list of quarks. -Note that the string must be in the valid ResourceName format -(see <link linkend="Resource_File_Syntax">section 15.1</link>). -If the string is not in the Host Portable Character Encoding, -the conversion is implementation-dependent. -</para> -<para> -<!-- .LP --> -A binding list is a list of type -<type>XrmBindingList</type> -and indicates if components of name or class lists are bound tightly or loosely -(that is, if wildcarding of intermediate components is specified). -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -typedef enum {XrmBindTightly, XrmBindLoosely} XrmBinding, *XrmBindingList; -</literallayout> -</para> -<para> -<!-- .LP --> -<constant>XrmBindTightly</constant> -indicates that a period separates the components, and -<constant>XrmBindLoosely</constant> -indicates that an asterisk separates the components. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To convert a string with one or more components to a binding list -and a quark list, use -<function>XrmStringToBindingQuarkList</function>. -</para> -<indexterm significance="preferred"><primary>XrmStringToBindingQuarkList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmstringtobindingquarklist'> -<funcprototype> - <funcdef><function>XrmStringToBindingQuarkList</function></funcdef> - <paramdef>char<parameter> *string</parameter></paramdef> - <paramdef>XrmBindingList<parameter> bindings_return</parameter></paramdef> - <paramdef>XrmQuarkList<parameter> quarks_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Ql \ list --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the string for which a quark(Ql is to be allocated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bindings_return</emphasis> - </term> - <listitem> - <para> -Returns the binding list. -The caller must allocate sufficient space for the binding list before calling -<function>XrmStringToBindingQuarkList</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quarks_return</emphasis> - </term> - <listitem> - <para> -Returns the list of quarks. -The caller must allocate sufficient space for the quarks list before calling -<function>XrmStringToBindingQuarkList</function>. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Component names in the list are separated by a period or -an asterisk character. -The string must be in the format of a valid ResourceName -(see <link linkend="Resource_File_Syntax">section 15.1</link>). -If the string does not start with a period or an asterisk, -a tight binding is assumed. -For example, the string ``*a.b*c'' becomes: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA .75i 1.5i 2.25i --> -<!-- .ta .75i 1.5i 2.25i --> -quarks: a b c -bindings: loose tight loose -</literallayout> -</para> -</sect1> -<sect1 id="Creating_and_Storing_Databases"> -<title>Creating and Storing Databases</title> -<!-- .XS --> -<!-- (SN Creating and Storing Databases --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XrmDatabase</primary></indexterm> -A resource database is an opaque type, -<type>XrmDatabase</type>. -Each database value is stored in an -<type>XrmValue</type> -structure. -This structure consists of a size, an address, and a representation type. -The size is specified in bytes. -The representation type is a way for you to store data tagged by some -application-defined type (for example, the strings ``font'' or ``color''). -It has nothing to do with the C data type or with its class. -The -<type>XrmValue</type> -structure is defined as: -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XrmValue</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -typedef struct { - unsigned int size; - XPointer addr; -} XrmValue, *XrmValuePtr; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To initialize the resource manager, use -<function>XrmInitialize</function>. -<indexterm significance="preferred"><primary>XrmInitialize</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrminitialize'> -<funcprototype> - <funcdef>void <function>XrmInitialize</function></funcdef> - <paramdef>void<parameter> XrmInitialize(\|)</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -To retrieve a database from disk, use -<function>XrmGetFileDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmGetFileDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmgetfiledatabase'> -<funcprototype> - <funcdef>XrmDatabase <function>XrmGetFileDatabase</function></funcdef> - <paramdef>char<parameter> *filename</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>filename</emphasis> - </term> - <listitem> - <para> -Specifies the resource database file name. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmGetFileDatabase</function> -function opens the specified file, -creates a new resource database, and loads it with the specifications -read in from the specified file. -The specified file should contain a sequence of entries in valid ResourceLine -format (see <link linkend="Resource_File_Syntax">section 15.1</link>); -the database that results from reading a file -with incorrect syntax is implementation-dependent. -The file is parsed in the current locale, -and the database is created in the current locale. -If it cannot open the specified file, -<function>XrmGetFileDatabase</function> -returns NULL. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store a copy of a database to disk, use -<function>XrmPutFileDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmPutFileDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmputfiledatabase'> -<funcprototype> - <funcdef>void <function>XrmPutFileDatabase</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> - <paramdef>char<parameter> *stored_db</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the database that is to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>stored_db</emphasis> - </term> - <listitem> - <para> -Specifies the file name for the stored database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmPutFileDatabase</function> -function stores a copy of the specified database in the specified file. -Text is written to the file as a sequence of entries in valid -ResourceLine format -(see <link linkend="Resource_File_Syntax">section 15.1</link>). -The file is written in the locale of the database. -Entries containing resource names that are not in the Host Portable Character -Encoding or containing values that are not in the encoding of the database -locale, are written in an implementation-dependent manner. -The order in which entries are written is implementation-dependent. -Entries with representation types other than ``String'' are ignored. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a pointer to the screen-independent resources of a display, use -<function>XResourceManagerString</function>. -</para> -<indexterm significance="preferred"><primary>XResourceManagerString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xresourcemanagerstring'> -<funcprototype> - <funcdef>char *<function>XResourceManagerString</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XResourceManagerString</function> -function returns the RESOURCE_MANAGER property from the server's root -window of screen zero, which was returned when the connection was opened using -<function>XOpenDisplay</function>. -The property is converted from type STRING to the current locale. -The conversion is identical to that produced by -<function>XmbTextPropertyToTextList</function> -for a single element STRING property. -The returned string is owned by Xlib and should not be freed by the client. -The property value must be in a format that is acceptable to -<function>XrmGetStringDatabase</function>. -If no property exists, NULL is returned. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a pointer to the screen-specific resources of a screen, use -<function>XScreenResourceString</function>. -</para> -<indexterm significance="preferred"><primary>XScreenResourceString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xscreenresourcestring'> -<funcprototype> - <funcdef>char *<function>XScreenResourceString</function></funcdef> - <paramdef>Screen<parameter> *screen</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the screen. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XScreenResourceString</function> -function returns the SCREEN_RESOURCES property from the root window of the -specified screen. -The property is converted from type STRING to the current locale. -The conversion is identical to that produced by -<function>XmbTextPropertyToTextList</function> -for a single element STRING property. -The property value must be in a format that is acceptable to -<function>XrmGetStringDatabase</function>. -If no property exists, NULL is returned. -The caller is responsible for freeing the returned string by using -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a database from a string, use -<function>XrmGetStringDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmGetStringDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmgetstringdatabase'> -<funcprototype> - <funcdef>XrmDatabase <function>XrmGetStringDatabase</function></funcdef> - <paramdef>char<parameter> *data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the database contents using a string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmGetStringDatabase</function> -function creates a new database and stores the resources specified -in the specified null-terminated string. -<function>XrmGetStringDatabase</function> -is similar to -<function>XrmGetFileDatabase</function> -except that it reads the information out of a string instead of out of a file. -The string should contain a sequence of entries in valid ResourceLine -format (see <link linkend="Resource_File_Syntax">section 15.1</link>) -terminated by a null character; -the database that results from using a string -with incorrect syntax is implementation-dependent. -The string is parsed in the current locale, -and the database is created in the current locale. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the locale name of a database, use -<function>XrmLocaleOfDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmLocaleOfDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmlocaleofdatabase'> -<funcprototype> - <funcdef>char *<function>XrmLocaleOfDatabase</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmLocaleOfDatabase</function> -function returns the name of the locale bound to the specified -database, as a null-terminated string. -The returned locale name string is owned by Xlib and should not be -modified or freed by the client. -Xlib is not permitted to free the string until the database is destroyed. -Until the string is freed, -it will not be modified by Xlib. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To destroy a resource database and free its allocated memory, use -<function>XrmDestroyDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmDestroyDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmdestroydatabase'> -<funcprototype> - <funcdef>void <function>XrmDestroyDatabase</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database is NULL, -<function>XrmDestroyDatabase</function> -returns immediately. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To associate a resource database with a display, use -<function>XrmSetDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmSetDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmsetdatabase'> -<funcprototype> - <funcdef>void <function>XrmSetDatabase</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmSetDatabase</function> -function associates the specified resource database (or NULL) -with the specified display. -The database previously associated with the display (if any) is not destroyed. -A client or toolkit may find this function convenient for retaining a database -once it is constructed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the resource database associated with a display, use -<function>XrmGetDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmGetDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmgetdatabase'> -<funcprototype> - <funcdef>XrmDatabase <function>XrmGetDatabase</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmGetDatabase</function> -function returns the database associated with the specified display. -It returns NULL if a database has not yet been set. -</para> -</sect1> -<sect1 id="Merging_Resource_Databases"> -<title>Merging Resource Databases</title> -<!-- .XS --> -<!-- (SN Merging Resource Databases --> -<!-- .XE --> -<para> -<!-- .LP --> -To merge the contents of a resource file into a database, use -<function>XrmCombineFileDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmCombineFileDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmcombinefiledatabase'> -<funcprototype> - <funcdef>Status <function>XrmCombineFileDatabase</function></funcdef> - <paramdef>char<parameter> *filename</parameter></paramdef> - <paramdef>XrmDatabase<parameter> *target_db</parameter></paramdef> - <paramdef>Bool<parameter> override</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>filename</emphasis> - </term> - <listitem> - <para> -Specifies the resource database file name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_db</emphasis> - </term> - <listitem> - <para> -Specifies the resource database into which the source -database is to be merged. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>override</emphasis> - </term> - <listitem> - <para> -Specifies whether source entries override target ones. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmCombineFileDatabase</function> -function merges the contents of a resource file into a database. -If the same specifier is used for an entry in both the file and -the database, -the entry in the file will replace the entry in the database -if override is -<symbol>True</symbol>; -otherwise, the entry in the file is discarded. -The file is parsed in the current locale. -If the file cannot be read, -a zero status is returned; -otherwise, a nonzero status is returned. -If target_db contains NULL, -<function>XrmCombineFileDatabase</function> -creates and returns a new database to it. -Otherwise, the database pointed to by target_db is not destroyed by the merge. -The database entries are merged without changing values or types, -regardless of the locale of the database. -The locale of the target database is not modified. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To merge the contents of one database into another database, use -<function>XrmCombineDatabase</function>. -</para> -<indexterm significance="preferred"><primary>XrmCombineDatabase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmcombinedatabase'> -<funcprototype> - <funcdef>void <function>XrmCombineDatabase</function></funcdef> - <paramdef>XrmDatabasesource_db,<parameter> *target_db</parameter></paramdef> - <paramdef>Bool<parameter> override</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>source_db</emphasis> - </term> - <listitem> - <para> -Specifies the resource database that is to be merged into the target database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_db</emphasis> - </term> - <listitem> - <para> -Specifies the resource database into which the source -database is to be merged. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>override</emphasis> - </term> - <listitem> - <para> -Specifies whether source entries override target ones. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmCombineDatabase</function> -function merges the contents of one database into another. -If the same specifier is used for an entry in both databases, -the entry in the source_db will replace the entry in the target_db -if override is -<symbol>True</symbol>; -otherwise, the entry in source_db is discarded. -If target_db contains NULL, -<function>XrmCombineDatabase</function> -simply stores source_db in it. -Otherwise, source_db is destroyed by the merge, but the database pointed -to by target_db is not destroyed. -The database entries are merged without changing values or types, -regardless of the locales of the databases. -The locale of the target database is not modified. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To merge the contents of one database into another database with override -semantics, use -<function>XrmMergeDatabases</function>. -</para> -<indexterm significance="preferred"><primary>XrmMergeDatabases</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmmergedatabases'> -<funcprototype> - <funcdef>void <function>XrmMergeDatabases</function></funcdef> - <paramdef>XrmDatabasesource_db,<parameter> *target_db</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>source_db</emphasis> - </term> - <listitem> - <para> -Specifies the resource database that is to be merged into the target database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>target_db</emphasis> - </term> - <listitem> - <para> -Specifies the resource database into which the source -database is to be merged. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Calling the -<function>XrmMergeDatabases</function> -function is equivalent to calling the -<function>XrmCombineDatabase</function> -function with an override argument of -<symbol>True</symbol>. -</para> -</sect1> -<sect1 id="Looking_Up_Resources"> -<title>Looking Up Resources</title> -<!-- .XS --> -<!-- (SN Looking Up Resources --> -<!-- .XE --> -<para> -<!-- .LP --> -To retrieve a resource from a resource database, use -<function>XrmGetResource</function>, -<function>XrmQGetResource</function>, -or -<function>XrmQGetSearchResource</function>. -</para> -<indexterm significance="preferred"><primary>XrmGetResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmgetresource'> -<funcprototype> - <funcdef>Bool <function>XrmGetResource</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> - <paramdef>char<parameter> *str_name</parameter></paramdef> - <paramdef>char<parameter> *str_class</parameter></paramdef> - <paramdef>char<parameter> **str_type_return</parameter></paramdef> - <paramdef>XrmValue<parameter> *value_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the database that is to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>str_name</emphasis> - </term> - <listitem> - <para> -Specifies the fully qualified name of the value being retrieved (as a string). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>str_class</emphasis> - </term> - <listitem> - <para> -Specifies the fully qualified class of the value being retrieved (as a string). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>str_type_return</emphasis> - </term> - <listitem> - <para> -Returns the representation type of the destination (as a string). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_return</emphasis> - </term> - <listitem> - <para> -Returns the value in the database. - </para> - </listitem> - </varlistentry> -</variablelist> -<indexterm significance="preferred"><primary>XrmQGetResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmqgetresource'> -<funcprototype> - <funcdef>Bool <function>XrmQGetResource</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> - <paramdef>XrmNameList<parameter> quark_name</parameter></paramdef> - <paramdef>XrmClassList<parameter> quark_class</parameter></paramdef> - <paramdef>XrmRepresentation<parameter> *quark_type_return</parameter></paramdef> - <paramdef>XrmValue<parameter> *value_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the database that is to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quark_name</emphasis> - </term> - <listitem> - <para> -Specifies the fully qualified name of the value being retrieved (as a quark). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quark_class</emphasis> - </term> - <listitem> - <para> -Specifies the fully qualified class of the value being retrieved (as a quark). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quark_type_return</emphasis> - </term> - <listitem> - <para> -Returns the representation type of the destination (as a quark). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_return</emphasis> - </term> - <listitem> - <para> -Returns the value in the database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmGetResource</function> -and -<function>XrmQGetResource</function> -functions retrieve a resource from the specified database. -Both take a fully qualified name/class pair, a destination -resource representation, and the address of a value -(size/address pair). -The value and returned type point into database memory; -therefore, you must not modify the data. -</para> -<para> -<!-- .LP --> -The database only frees or overwrites entries on -<function>XrmPutResource</function>, -<function>XrmQPutResource</function>, -or -<function>XrmMergeDatabases</function>. -A client that is not storing new values into the database or -is not merging the database should be safe using the address passed -back at any time until it exits. -If a resource was found, both -<function>XrmGetResource</function> -and -<function>XrmQGetResource</function> -return -<symbol>True</symbol>; -otherwise, they return -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -Most applications and toolkits do not make random probes -into a resource database to fetch resources. -The X toolkit access pattern for a resource database is quite stylized. -A series of from 1 to 20 probes is made with only the -last name/class differing in each probe. -The -<function>XrmGetResource</function> -function is at worst a -2<superscript><emphasis remap='I'>n</emphasis></superscript> algorithm, -where <emphasis remap='I'>n</emphasis> is the length of the name/class list. -This can be improved upon by the application programmer by prefetching a list -of database levels that might match the first part of a name/class list. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a list of database levels, use -<function>XrmQGetSearchList</function>. -</para> -<indexterm significance="preferred"><primary>XrmQGetSearchList</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmqgetsearchlist'> -<funcprototype> - <funcdef>Bool <function>XrmQGetSearchResource</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> - <paramdef>XrmNameList<parameter> names</parameter></paramdef> - <paramdef>XrmClassList<parameter> classes</parameter></paramdef> - <paramdef>XrmSearchList<parameter> list_return</parameter></paramdef> - <paramdef>int<parameter> list_length</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the database that is to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>names</emphasis> - </term> - <listitem> - <para> -Specifies a list of resource names. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>classes</emphasis> - </term> - <listitem> - <para> -Specifies a list of resource classes. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list_return</emphasis> - </term> - <listitem> - <para> -Returns a search list for further use. -The caller must allocate sufficient space for the list before calling -<function>XrmQGetSearchList</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list_length</emphasis> - </term> - <listitem> - <para> -Specifies the number of entries (not the byte size) allocated for list_return. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmQGetSearchList</function> -function takes a list of names and classes -and returns a list of database levels where a match might occur. -The returned list is in best-to-worst order and -uses the same algorithm as -<function>XrmGetResource</function> -for determining precedence. -If list_return was large enough for the search list, -<function>XrmQGetSearchList</function> -returns -<symbol>True</symbol>; -otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -The size of the search list that the caller must allocate is -dependent upon the number of levels and wildcards in the resource specifiers -that are stored in the database. -The worst case length is -3<superscript><emphasis remap='I'>n</emphasis></superscript>, -where <emphasis remap='I'>n</emphasis> is the number of name or class -components in names or classes. -</para> -<para> -<!-- .LP --> -When using -<function>XrmQGetSearchList</function> -followed by multiple probes for resources with a common name and class prefix, -only the common prefix should be specified in the name and class list to -<function>XrmQGetSearchList</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To search resource database levels for a given resource, use -<function>XrmQGetSearchResource</function>. -</para> -<indexterm significance="preferred"><primary>XrmQGetSearchResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmqgetsearchresource'> -<funcprototype> - <funcdef>Bool <function>XrmQGetSearchResource</function></funcdef> - <paramdef>XrmSearchList<parameter> list</parameter></paramdef> - <paramdef>XrmName<parameter> name</parameter></paramdef> - <paramdef>XrmClass<parameter> class</parameter></paramdef> - <paramdef>XrmRepresentation<parameter> *type_return</parameter></paramdef> - <paramdef>XrmValue<parameter> *value_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the search list returned by -<function>XrmQGetSearchList</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the resource name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class</emphasis> - </term> - <listitem> - <para> -Specifies the resource class. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>type_return</emphasis> - </term> - <listitem> - <para> -Returns data representation type. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value_return</emphasis> - </term> - <listitem> - <para> -Returns the value in the database. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmQGetSearchResource</function> -function searches the specified database levels for the resource -that is fully identified by the specified name and class. -The search stops with the first match. -<function>XrmQGetSearchResource</function> -returns -<symbol>True</symbol> -if the resource was found; -otherwise, it returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -A call to -<function>XrmQGetSearchList</function> -with a name and class list containing all but the last component -of a resource name followed by a call to -<function>XrmQGetSearchResource</function> -with the last component name and class returns the same database entry as -<function>XrmGetResource</function> -and -<function>XrmQGetResource</function> -with the fully qualified name and class. -</para> -</sect1> -<sect1 id="Storing_into_a_Resource_Database"> -<title>Storing into a Resource Database</title> -<!-- .XS --> -<!-- (SN Storing into a Resource Database --> -<!-- .XE --> -<para> -<!-- .LP --> -To store resources into the database, use -<function>XrmPutResource</function> -or -<function>XrmQPutResource</function>. -Both functions take a partial resource specification, a -representation type, and a value. -This value is copied into the specified database. -</para> -<!-- .LP --> -<!-- .sp --> -<indexterm significance="preferred"><primary>XrmPutResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmputresource'> -<funcprototype> - <funcdef>void <function>XrmPutResource</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>char<parameter> *specifier</parameter></paramdef> - <paramdef>char<parameter> *type</parameter></paramdef> - <paramdef>XrmValue<parameter> *value</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>specifier</emphasis> - </term> - <listitem> - <para> -Specifies a complete or partial specification of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>type</emphasis> - </term> - <listitem> - <para> -Specifies the type of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the value of the resource, which is specified as a string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database contains NULL, -<function>XrmPutResource</function> -creates a new database and returns a pointer to it. -<function>XrmPutResource</function> -is a convenience function that calls -<function>XrmStringToBindingQuarkList</function> -followed by: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -XrmQPutResource(database, bindings, quarks, XrmStringToQuark(type), value) -</literallayout> -If the specifier and type are not in the Host Portable Character Encoding, -the result is implementation-dependent. -The value is stored in the database without modification. -</para> -<!-- .LP --> -<!-- .sp --> -<indexterm significance="preferred"><primary>XrmQPutResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmqputresource'> -<funcprototype> - <funcdef>void <function>XrmQPutResource</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>XrmBindingList<parameter> bindings</parameter></paramdef> - <paramdef>XrmQuarkList<parameter> quarks</parameter></paramdef> - <paramdef>XrmRepresentation<parameter> type</parameter></paramdef> - <paramdef>XrmValue<parameter> *value</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bindings</emphasis> - </term> - <listitem> - <para> -Specifies a list of bindings. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quarks</emphasis> - </term> - <listitem> - <para> -Specifies the complete or partial name or the class list of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>type</emphasis> - </term> - <listitem> - <para> -Specifies the type of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the value of the resource, which is specified as a string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database contains NULL, -<function>XrmQPutResource</function> -creates a new database and returns a pointer to it. -If a resource entry with the identical bindings and quarks already -exists in the database, the previous type and value are replaced by the new -specified type and value. -The value is stored in the database without modification. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a resource that is specified as a string, use -<function>XrmPutStringResource</function>. -</para> -<indexterm significance="preferred"><primary>XrmPutStringResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmputstringresource'> -<funcprototype> - <funcdef>void <function>XrmPutStringResource</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>char<parameter> *specifier</parameter></paramdef> - <paramdef>char<parameter> *value</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>specifier</emphasis> - </term> - <listitem> - <para> -Specifies a complete or partial specification of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the value of the resource, which is specified as a string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database contains NULL, -<function>XrmPutStringResource</function> -creates a new database and returns a pointer to it. -<function>XrmPutStringResource</function> -adds a resource with the specified value to the specified database. -<function>XrmPutStringResource</function> -is a convenience function that first calls -<function>XrmStringToBindingQuarkList</function> -on the specifier and then calls -<function>XrmQPutResource</function>, -using a ``String'' representation type. -If the specifier is not in the Host Portable Character Encoding, -the result is implementation-dependent. -The value is stored in the database without modification. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a string resource using quarks as a specification, use -<function>XrmQPutStringResource</function>. -</para> -<indexterm significance="preferred"><primary>XrmQPutStringResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmqputstringresource'> -<funcprototype> - <funcdef>void <function>XrmQPutStringResource</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>XrmBindingList<parameter> bindings</parameter></paramdef> - <paramdef>XrmQuarkList<parameter> quarks</parameter></paramdef> - <paramdef>char<parameter> *value</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bindings</emphasis> - </term> - <listitem> - <para> -Specifies a list of bindings. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>quarks</emphasis> - </term> - <listitem> - <para> -Specifies the complete or partial name or the class list of the resource. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the value of the resource, which is specified as a string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database contains NULL, -<function>XrmQPutStringResource</function> -creates a new database and returns a pointer to it. -<function>XrmQPutStringResource</function> -is a convenience routine that constructs an -<type>XrmValue</type> -for the value string (by calling -<function>strlen</function> -to compute the size) and -then calls -<function>XrmQPutResource</function>, -using a ``String'' representation type. -The value is stored in the database without modification. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To add a single resource entry that is specified as a string that contains -both a name and a value, use -<function>XrmPutLineResource</function>. -</para> -<indexterm significance="preferred"><primary>XrmPutLineResource</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmputlineresource'> -<funcprototype> - <funcdef>void <function>XrmPutLineResource</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>char<parameter> *line</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>line</emphasis> - </term> - <listitem> - <para> -Specifies the resource name and value pair as a single string. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If database contains NULL, -<function>XrmPutLineResource</function> -creates a new database and returns a pointer to it. -<function>XrmPutLineResource</function> -adds a single resource entry to the specified database. -The line should be in valid ResourceLine format -(see <link linkend="Resource_File_Syntax">section 15.1</link>) -terminated by a newline or null character; -the database that results from using a string -with incorrect syntax is implementation-dependent. -The string is parsed in the locale of the database. -If the -<replaceable>ResourceName</replaceable> -is not in the Host Portable Character Encoding, -the result is implementation-dependent. -Note that comment lines are not stored. -</para> -</sect1> -<sect1 id="Enumerating_Database_Entries"> -<title>Enumerating Database Entries</title> -<!-- .XS --> -<!-- (SN Enumerating Database Entries --> -<!-- .XE --> -<para> -<!-- .LP --> -To enumerate the entries of a database, use -<function>XrmEnumerateDatabase</function>. -<indexterm significance="preferred"><primary>XrmEnumerateDatabase</primary></indexterm> -<!-- .sM --> -</para> - -<literallayout class="monospaced"> -#define XrmEnumAllLevels 0 -#define XrmEnumOneLevel 0 -</literallayout> - -<funcsynopsis id='xrmenumeratedatabase'> -<funcprototype> - <funcdef>Bool <function>XrmEnumerateDatabase</function></funcdef> - <paramdef>XrmDatabase<parameter> database</parameter></paramdef> - <paramdef>XrmNameList<parameter> name_prefix</parameter></paramdef> - <paramdef>XrmClassList<parameter> class_prefix</parameter></paramdef> - <paramdef>int<parameter> mode</parameter></paramdef> - <paramdef>Bool<parameter> (*proc)()</parameter></paramdef> - <paramdef>XPointer<parameter> arg</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name_prefix</emphasis> - </term> - <listitem> - <para> -Specifies the resource name prefix. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class_prefix</emphasis> - </term> - <listitem> - <para> -Specifies the resource class prefix. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mode</emphasis> - </term> - <listitem> - <para> -Specifies the number of levels to enumerate. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>proc</emphasis> - </term> - <listitem> - <para> -Specifies the procedure that is to be called for each matching entry. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>arg</emphasis> - </term> - <listitem> - <para> -Specifies the user-supplied argument that will be passed to the procedure. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmEnumerateDatabase</function> -function calls the specified procedure for each resource in the database -that would match some completion of the given name/class resource prefix. -The order in which resources are found is implementation-dependent. -If mode is -<symbol>XrmEnumOneLevel</symbol>, -a resource must match the given name/class prefix with -just a single name and class appended. If mode is -<symbol>XrmEnumAllLevels</symbol>, -the resource must match the given name/class prefix with one or more names and -classes appended. -If the procedure returns -<symbol>True</symbol>, -the enumeration terminates and the function returns -<symbol>True</symbol>. -If the procedure always returns -<symbol>False</symbol>, -all matching resources are enumerated and the function returns -<symbol>False</symbol>. -</para> -<para> -<!-- .LP --> -The procedure is called with the following arguments: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>database</emphasis>, <emphasis remap='I'>bindings</emphasis>, <emphasis remap='I'>quarks</emphasis>, <emphasis remap='I'>type</emphasis>, <emphasis remap='I'>value</emphasis>, <emphasis remap='I'>arg</emphasis>) - XrmDatabase *<emphasis remap='I'>database</emphasis>; - XrmBindingList <emphasis remap='I'>bindings</emphasis>; - XrmQuarkList <emphasis remap='I'>quarks</emphasis>; - XrmRepresentation *<emphasis remap='I'>type</emphasis>; - XrmValue *<emphasis remap='I'>value</emphasis>; - XPointer <emphasis remap='I'>arg</emphasis>; -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -The bindings and quarks lists are terminated by -<symbol>NULLQUARK</symbol>. -Note that pointers -to the database and type are passed, but these values should not be modified. -</para> -<para> -<!-- .LP --> -The procedure must not modify the database. -If Xlib has been initialized for threads, the procedure is called with -the database locked and the result of a call by the procedure to any -Xlib function using the same database is not defined. -</para> -</sect1> -<sect1 id="Parsing_Command_Line_Options"> -<title>Parsing Command Line Options</title> -<!-- .XS --> -<!-- (SN Parsing Command Line Options --> -<!-- .XE --> -<para> -<!-- .LP --> -The -<function>XrmParseCommand</function> -function can be used to parse the command line arguments to a program -and modify a resource database with selected entries from the command line. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XrmOptionKind</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef enum { - XrmoptionNoArg, /* Value is specified in XrmOptionDescRec.value */ - XrmoptionIsArg, /* Value is the option string itself */ - XrmoptionStickyArg, /* Value is characters immediately following option */ - XrmoptionSepArg, /* Value is next argument in argv */ - XrmoptionResArg, /* Resource and value in next argument in argv */ - XrmoptionSkipArg, /* Ignore this option and the next argument in argv */ - XrmoptionSkipLine, /* Ignore this option and the rest of argv */ - XrmoptionSkipNArgs /* Ignore this option and the next - \ \ \ XrmOptionDescRec.value arguments in argv */ -} XrmOptionKind; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -Note that -<constant>XrmoptionSkipArg</constant> -is equivalent to -<constant>XrmoptionSkipNArgs</constant> -with the -<structname>XrmOptionDescRec</structname>.<structfield>value</structfield> -field containing the value one. -Note also that the value zero for -<constant>XrmoptionSkipNArgs</constant> -indicates that only the option itself is to be skipped. -</para> -<para> -<!-- .LP --> -<indexterm significance="preferred"><primary>XrmOptionDescRec</primary></indexterm> -<!-- .sM --> -<literallayout class="monospaced"> -<!-- .TA .5i 2.5i --> -<!-- .ta .5i 2.5i --> -typedef struct { - char *option; /* Option specification string in argv */ - char *specifier; /* Binding and resource name (sans application name) */ - XrmOptionKind argKind; /* Which style of option it is */ - XPointer value; /* Value to provide if XrmoptionNoArg or - \ \ \ XrmoptionSkipNArgs */ -} XrmOptionDescRec, *XrmOptionDescList; -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To load a resource database from a C command line, use -<function>XrmParseCommand</function>. -</para> -<indexterm significance="preferred"><primary>XrmParseCommand</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrmparsecommand'> -<funcprototype> - <funcdef>void <function>XrmParseCommand</function></funcdef> - <paramdef>XrmDatabase<parameter> *database</parameter></paramdef> - <paramdef>XrmOptionDescList<parameter> table</parameter></paramdef> - <paramdef>int<parameter> table_count</parameter></paramdef> - <paramdef>char<parameter> *name</parameter></paramdef> - <paramdef>int<parameter> *argc_in_out</parameter></paramdef> - <paramdef>char<parameter> **argv_in_out</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>database</emphasis> - </term> - <listitem> - <para> -Specifies the resource database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>table</emphasis> - </term> - <listitem> - <para> -Specifies the table of command line arguments to be parsed. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>table_count</emphasis> - </term> - <listitem> - <para> -Specifies the number of entries in the table. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>name</emphasis> - </term> - <listitem> - <para> -Specifies the application name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argc_in_out</emphasis> - </term> - <listitem> - <para> -Specifies the number of arguments and returns the number of remaining arguments. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>argv_in_out</emphasis> - </term> - <listitem> - <para> -Specifies the command line arguments -and returns the remaining arguments. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XrmParseCommand</function> -function parses an (argc, argv) pair according to the specified option table, -loads recognized options into the specified database with type ``String,'' -and modifies the (argc, argv) pair to remove all recognized options. -If database contains NULL, -<function>XrmParseCommand</function> -creates a new database and returns a pointer to it. -Otherwise, entries are added to the database specified. -If a database is created, it is created in the current locale. -</para> -<para> -<!-- .LP --> -The specified table is used to parse the command line. -Recognized options in the table are removed from argv, -and entries are added to the specified resource database -in the order they occur in argv. -The table entries contain information on the option string, -the option name, the style of option, -and a value to provide if the option kind is -<constant>XrmoptionNoArg</constant>. -The option names are compared byte-for-byte to arguments in argv, -independent of any locale. -The resource values given in the table are stored in the resource database -without modification. -All resource database entries are created -using a ``String'' representation type. -The argc argument specifies the number of arguments in argv -and is set on return to the remaining number of arguments that were not parsed. -The name argument should be the name of your application -for use in building the database entry. -The name argument is prefixed to the resourceName in the option table -before storing a database entry. -The name argument is treated as a single component, even if it -has embedded periods. -No separating (binding) character is inserted, -so the table must contain either a period (.) or an asterisk (*) -as the first character in each resourceName entry. -To specify a more completely qualified resource name, -the resourceName entry can contain multiple components. -If the name argument and the resourceNames are not in the -Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -The following provides a sample option table: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -<!-- .TA 1.25i 3.25i 4.75i --> -<!-- .ta 1.25i 3.25i 4.75i --> -static XrmOptionDescRec opTable[] = { -{"-background", "*background", XrmoptionSepArg, (XPointer) NULL}, -{"-bd", "*borderColor", XrmoptionSepArg, (XPointer) NULL}, -{"-bg", "*background", XrmoptionSepArg, (XPointer) NULL}, -{"-borderwidth", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL}, -{"-bordercolor", "*borderColor", XrmoptionSepArg, (XPointer) NULL}, -{"-bw", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL}, -{"-display", ".display", XrmoptionSepArg, (XPointer) NULL}, -{"-fg", "*foreground", XrmoptionSepArg, (XPointer) NULL}, -{"-fn", "*font", XrmoptionSepArg, (XPointer) NULL}, -{"-font", "*font", XrmoptionSepArg, (XPointer) NULL}, -{"-foreground", "*foreground", XrmoptionSepArg, (XPointer) NULL}, -{"-geometry", ".TopLevelShell.geometry", XrmoptionSepArg, (XPointer) NULL}, -{"-iconic", ".TopLevelShell.iconic", XrmoptionNoArg, (XPointer) "on"}, -{"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, -{"-reverse", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"}, -{"-rv", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"}, -{"-synchronous", "*synchronous", XrmoptionNoArg, (XPointer) "on"}, -{"-title", ".TopLevelShell.title", XrmoptionSepArg, (XPointer) NULL}, -{"-xrm", NULL, XrmoptionResArg, (XPointer) NULL}, -}; -</literallayout> -</para> -<para> -<!-- .LP --> -In this table, if the -background (or -bg) option is used to set -background colors, the stored resource specifier matches all -resources of attribute background. -If the -borderwidth option is used, -the stored resource specifier applies only to border width -attributes of class TopLevelShell (that is, outer-most windows, including -pop-up windows). -If the -title option is used to set a window name, -only the topmost application windows receive the resource. -</para> -<para> -<!-- .LP --> -When parsing the command line, -any unique unambiguous abbreviation for an option name in the table is -considered a match for the option. -Note that uppercase and lowercase matter. -<!-- .bp --> - -</para> -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="resource_manager_functions">
+<title>Resource Manager Functions</title>
+<!-- .sp 2 -->
+<!-- .nr H1 15 -->
+<!-- .nr H2 0 -->
+<!-- .nr H3 0 -->
+<!-- .nr H4 0 -->
+<!-- .nr H5 0 -->
+<!-- .na -->
+<para>
+<!-- .LP -->
+<!-- .XS -->
+<!-- Chapter 15: Resource Manager Functions -->
+<!-- .XE -->
+A program often needs a variety of options in the X environment
+(for example, fonts, colors, icons, and cursors).
+Specifying all of these options on the command line is awkward
+because users may want to customize many aspects of the program
+and need a convenient way to establish these customizations as
+the default settings.
+The resource manager is provided for this purpose.
+Resource specifications are usually stored in human-readable files
+and in server properties.
+</para>
+<para>
+<!-- .LP -->
+The resource manager is a database manager with a twist.
+In most database systems,
+you perform a query using an imprecise specification,
+and you get back a set of records.
+The resource manager, however, allows you to specify a large
+set of values with an imprecise specification, to query the database
+with a precise specification, and to get back only a single value.
+This should be used by applications that need to know what the
+user prefers for colors, fonts, and other resources.
+It is this use as a database for dealing with X resources that
+inspired the name "Resource Manager,"
+although the resource manager can be and is used in other ways.
+</para>
+<para>
+<!-- .LP -->
+For example,
+a user of your application may want to specify
+that all windows should have a blue background
+but that all mail-reading windows should have a red background.
+With well-engineered and coordinated applications,
+a user can define this information using only two lines of specifications.
+</para>
+<para>
+<!-- .LP -->
+As an example of how the resource manager works,
+consider a mail-reading application called xmh.
+Assume that it is designed so that it uses a
+complex window hierarchy all the way down to individual command buttons,
+which may be actual small subwindows in some toolkits.
+These are often called objects or widgets.
+In such toolkit systems,
+each user interface object can be composed of other objects
+and can be assigned a name and a class.
+Fully qualified names or classes can have arbitrary numbers of component names,
+but a fully qualified name always has the same number of component names as a
+fully qualified class.
+This generally reflects the structure of the application as composed
+of these objects, starting with the application itself.
+</para>
+<para>
+<!-- .LP -->
+For example, the xmh mail program has a name "xmh" and is one
+of a class of "Mail" programs.
+By convention, the first character of class components is capitalized,
+and the first letter of name components is in lowercase.
+Each name and class finally has an attribute
+(for example, "foreground" or "font").
+If each window is properly assigned a name and class,
+it is easy for the user to specify attributes of any portion
+of the application.
+</para>
+<para>
+<!-- .LP -->
+At the top level,
+the application might consist of a paned window (that is, a window divided
+into several sections) named "toc".
+One pane of the paned window is a button box window named "buttons"
+and is filled with command buttons.
+One of these command buttons is used to incorporate
+new mail and has the name "incorporate".
+This window has a fully qualified name, "xmh.toc.buttons.incorporate",
+and a fully qualified class, "Xmh.Paned.Box.Command".
+Its fully qualified name is the name of its parent, "xmh.toc.buttons",
+followed by its name, "incorporate".
+Its class is the class of its parent, "Xmh.Paned.Box",
+followed by its particular class, "Command".
+The fully qualified name of a resource is
+the attribute's name appended to the object's fully qualified
+name, and the fully qualified class is its class appended to the object's
+class.
+</para>
+<para>
+<!-- .LP -->
+The incorporate button might need the following resources:
+Title string,
+Font,
+Foreground color for its inactive state,
+Background color for its inactive state,
+Foreground color for its active state, and
+Background color for its active state.
+Each resource is considered
+to be an attribute of the button and, as such, has a name and a class.
+For example, the foreground color for the button in
+its active state might be named "activeForeground",
+and its class might be "Foreground".
+</para>
+<para>
+<!-- .LP -->
+When an application looks up a resource (for example, a color),
+it passes the complete name and complete class of the resource
+to a look-up routine.
+The resource manager compares this complete specification
+against the incomplete specifications of entries in the resource
+database, finds the best match, and returns the corresponding
+value for that entry.
+</para>
+<para>
+<!-- .LP -->
+The definitions for the resource manager are contained in
+<filename class="headerfile"><X11/Xresource.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xresource.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xresource.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xresource.h></filename></secondary></indexterm>
+</para>
+<sect1 id="Resource_File_Syntax">
+<title>Resource File Syntax</title>
+<!-- .XS -->
+<!-- (SN Resource File Syntax -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The syntax of a resource file is a sequence of resource lines
+terminated by newline characters or the end of the file.
+The syntax of an individual resource line is:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+<!-- .TA 1.5i 1.75i -->
+<!-- .ta 1.5i 1.75i -->
+ResourceLine = Comment | IncludeFile | ResourceSpec | <empty line>
+Comment = "!" {<any character except null or newline>}
+IncludeFile = "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace
+FileName = <valid filename for operating system>
+ResourceSpec = WhiteSpace ResourceName WhiteSpace ":" WhiteSpace Value
+ResourceName = [Binding] {Component Binding} ComponentName
+Binding = "." | "*"
+WhiteSpace = {<space> | <horizontal tab>}
+Component = "?" | ComponentName
+ComponentName = NameChar {NameChar}
+NameChar = "a"-"z" | "A"-"Z" | "0"-"9" | "_" | "-"
+Value = {<any character except null or unescaped newline>}
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+Elements separated by vertical bar (|) are alternatives.
+Curly braces ({......}) indicate zero or more repetitions
+of the enclosed elements.
+Square brackets ([......]) indicate that the enclosed element is optional.
+Quotes ("......") are used around literal characters.
+</para>
+<para>
+<!-- .LP -->
+IncludeFile lines are interpreted by replacing the line with the
+contents of the specified file.
+The word "include" must be in lowercase.
+The file name is interpreted relative to the directory of the file in
+which the line occurs (for example, if the file name contains no
+directory or contains a relative directory specification).
+</para>
+<para>
+<!-- .LP -->
+If a ResourceName contains a contiguous sequence of two or more Binding
+characters, the sequence will be replaced with a single ".." character
+if the sequence contains only ".." characters;
+otherwise, the sequence will be replaced with a single "*" character.
+</para>
+<para>
+<!-- .LP -->
+A resource database never contains more than one entry for a given
+ResourceName. If a resource file contains multiple lines with the
+same ResourceName, the last line in the file is used.
+</para>
+<para>
+<!-- .LP -->
+Any white space characters before or after the name or colon in a ResourceSpec
+are ignored.
+To allow a Value to begin with white space,
+the two-character sequence "\\<emphasis remap='I'>space</emphasis>" (backslash followed by space)
+is recognized and replaced by a space character,
+and the two-character sequence "\\<emphasis remap='I'>tab</emphasis>"
+(backslash followed by horizontal tab)
+is recognized and replaced by a horizontal tab character.
+To allow a Value to contain embedded newline characters,
+the two-character sequence "\\n" is recognized and replaced by a
+newline character.
+To allow a Value to be broken across multiple lines in a text file,
+the two-character sequence "\\<emphasis remap='I'>newline</emphasis>"
+(backslash followed by newline) is
+recognized and removed from the value.
+To allow a Value to contain arbitrary character codes,
+the four-character sequence "\\<emphasis remap='I'>nnn</emphasis>",
+where each <emphasis remap='I'>n</emphasis> is a digit character in the range of "0"-"7",
+is recognized and replaced with a single byte that contains
+the octal value specified by the sequence.
+Finally, the two-character sequence "\newline" is recognized
+and replaced with a single backslash.
+</para>
+<para>
+<!-- .LP -->
+As an example of these sequences,
+the following resource line contains a value consisting of four
+characters: a backslash, a null, a "z", and a newline:
+<literallayout class="monospaced">
+magic.values: \\000\
+z\n
+</literallayout>
+</para>
+</sect1>
+<sect1 id="Resource_Manager_Matching_Rules">
+<title>Resource Manager Matching Rules</title>
+<!-- .XS -->
+<!-- (SN Resource Manager Matching Rules -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The algorithm for determining which resource database entry
+matches a given query is the heart of the resource manager.
+All queries must fully specify the name and class of the desired resource
+(use of the characters "*" and "?" is not permitted).
+The library supports up to 100 components in a full name or class.
+Resources are stored in the database with only partially specified
+names and classes, using pattern matching constructs.
+An asterisk (*) is a loose binding and is used to represent any number
+of intervening components, including none.
+A period (.) is a tight binding and is used to separate immediately
+adjacent components.
+A question mark (?) is used to match any single component name or class.
+A database entry cannot end in a loose binding;
+the final component (which cannot be the character "?") must be specified.
+The lookup algorithm searches the database for the entry that most
+closely matches (is most specific for) the full name and class being queried.
+When more than one database entry matches the full name and class,
+precedence rules are used to select just one.
+</para>
+<para>
+<!-- .LP -->
+The full name and class are scanned from left to right (from highest
+level in the hierarchy to lowest), one component at a time.
+At each level, the corresponding component and/or binding of each
+matching entry is determined, and these matching components and
+bindings are compared according to precedence rules.
+Each of the rules is applied at each level before moving to the next level,
+until a rule selects a single entry over all others.
+The rules, in order of precedence, are:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+An entry that contains a matching component (whether name, class,
+or the character "?")
+takes precedence over entries that elide the level (that is, entries
+that match the level in a loose binding).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An entry with a matching name takes precedence over both
+entries with a matching class and entries that match using the character "?".
+An entry with a matching class takes precedence over
+entries that match using the character "?".
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+An entry preceded by a tight binding takes precedence over entries
+preceded by a loose binding.
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+To illustrate these rules,
+consider the following resource database entries:
+<literallayout class="monospaced">
+<!-- .TA 2.5i 3.5i -->
+<!-- .ta 2.5i 3.5i -->
+xmh*Paned*activeForeground: red <emphasis remap='I'>(entry A)</emphasis>
+*incorporate.Foreground: blue <emphasis remap='I'>(entry B)</emphasis>
+xmh.toc*Command*activeForeground: green <emphasis remap='I'>(entry C)</emphasis>
+xmh.toc*?.Foreground: white <emphasis remap='I'>(entry D)</emphasis>
+xmh.toc*Command.activeForeground: black <emphasis remap='I'>(entry E)</emphasis>
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Consider a query for the resource:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA 3.5i -->
+<!-- .ta 3.5i -->
+xmh.toc.messagefunctions.incorporate.activeForeground <emphasis remap='I'>(name)</emphasis>
+Xmh.Paned.Box.Command.Foreground <emphasis remap='I'>(class)</emphasis>
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+At the first level (xmh, Xmh), rule 1 eliminates entry B.
+At the second level (toc, Paned), rule 2 eliminates entry A.
+At the third level (messagefunctions, Box), no entries are eliminated.
+At the fourth level (incorporate, Command), rule 2 eliminates entry D.
+At the fifth level (activeForeground, Foreground), rule 3 eliminates entry C.
+</para>
+</sect1>
+<sect1 id="Quarks">
+<title>Quarks</title>
+<!-- .XS -->
+<!-- (SN Quarks -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Most uses of the resource manager involve defining names,
+classes, and representation types as string constants.
+However, always referring to strings in the resource manager can be slow,
+because it is so heavily used in some toolkits.
+To solve this problem,
+a shorthand for a string is used in place of the string
+in many of the resource manager functions.
+Simple comparisons can be performed rather than string comparisons.
+The shorthand name for a string is called a quark and is the
+type
+<type>XrmQuark</type>.
+On some occasions,
+you may want to allocate a quark that has no string equivalent.
+</para>
+<para>
+<!-- .LP -->
+A quark is to a string what an atom is to a string in the server,
+but its use is entirely local to your application.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate a new quark, use
+<function>XrmUniqueQuark</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmUniqueQuark</primary></indexterm>
+<!-- .sM -->
+<para>XrmQuark XrmUniqueQuark()</para>
+<!-- .FN -->
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmUniqueQuark</function>
+function allocates a quark that is guaranteed not to represent any string that
+is known to the resource manager.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Each name, class, and representation type is typedef'd as an
+<type>XrmQuark</type>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+typedef int XrmQuark, *XrmQuarkList;
+typedef XrmQuark XrmName;
+typedef XrmQuark XrmClass;
+typedef XrmQuark XrmRepresentation;
+#define NULLQUARK ((XrmQuark) 0)
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Lists are represented as null-terminated arrays of quarks.
+The size of the array must be large enough for the number of components used.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+typedef XrmQuarkList XrmNameList;
+typedef XrmQuarkList XrmClassList;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To convert a string to a quark, use
+<function>XrmStringToQuark</function>
+or
+<function>XrmPermStringToQuark</function>.
+</para>
+<literallayout class="monospaced">
+#define XrmStringToName(string) XrmStringToQuark(string)
+#define XrmStringToClass(string) XrmStringToQuark(string)
+#define XrmStringToRepresentation(string) XrmStringToQuark(string)
+</literallayout>
+
+<indexterm significance="preferred"><primary>XrmStringToQuark</primary></indexterm>
+<indexterm significance="preferred"><primary>XrmPermStringToQuark</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmstringtoquark'>
+<funcprototype>
+ <funcdef>XrmQuark <function>XrmStringToQuark</function></funcdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Ql -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string for which a quark(Ql is to be allocated.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+These functions can be used to convert from string to quark representation.
+If the string is not in the Host Portable Character Encoding,
+the conversion is implementation-dependent.
+The string argument to
+<function>XrmStringToQuark</function>
+need not be permanently allocated storage.
+<function>XrmPermStringToQuark</function>
+is just like
+<function>XrmStringToQuark</function>,
+except that Xlib is permitted to assume the string argument is permanently
+allocated,
+and, hence, that it can be used as the value to be returned by
+<function>XrmQuarkToString</function>.
+</para>
+<para>
+<!-- .LP -->
+For any given quark, if
+<function>XrmStringToQuark</function>
+returns a non-NULL value,
+all future calls will return the same value (identical address).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To convert a quark to a string, use
+<function>XrmQuarkToString</function>.
+</para>
+
+<literallayout class="monospaced">
+#define XrmNameToString(name) XrmQuarkToString(name)
+#define XrmClassToString(class) XrmQuarkToString(name)
+#define XrmRepresentationToString(type) XrmQuarkToString(type)
+</literallayout>
+<indexterm significance="preferred"><primary>XrmQuarkToString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmquarktostring'>
+<funcprototype>
+ <funcdef>char *<function>XrmQuarkToString</function></funcdef>
+ <paramdef>XrmQuark<parameter> quark</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quark</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the quark for which the equivalent string is desired.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<!-- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -->
+<para>
+These functions can be used to convert from quark representation to string.
+The string pointed to by the return value must not be modified or freed.
+The returned string is byte-for-byte equal to the original
+string passed to one of the string-to-quark routines.
+If no string exists for that quark,
+<function>XrmQuarkToString</function>
+returns NULL.
+For any given quark, if
+<function>XrmQuarkToString</function>
+returns a non-NULL value,
+all future calls will return the same value (identical address).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To convert a string with one or more components to a quark list, use
+<function>XrmStringToQuarkList</function>.
+</para>
+
+<literallayout class="monospaced">
+#define XrmStringToNameList(str,name) XrmStringToQuarkList((str), (name))
+#define XrmStringToClassList(str,class) XrmStringToQuarkList((str), (class))
+</literallayout>
+
+<indexterm significance="preferred"><primary>XrmStringToQuarkList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmstringtoquarklist'>
+<funcprototype>
+ <funcdef>void <function>XrmStringToQuarkList</function></funcdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>XrmQuarkList<parameter> quarks_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Ql \ list -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string for which a quark(Ql is to be allocated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quarks_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of quarks.
+The caller must allocate sufficient space for the quarks list before calling
+<function>XrmStringToQuarkList</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmStringToQuarkList</function>
+function converts the null-terminated string (generally a fully qualified name)
+to a list of quarks.
+Note that the string must be in the valid ResourceName format
+(see <link linkend="Resource_File_Syntax">section 15.1</link>).
+If the string is not in the Host Portable Character Encoding,
+the conversion is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+A binding list is a list of type
+<type>XrmBindingList</type>
+and indicates if components of name or class lists are bound tightly or loosely
+(that is, if wildcarding of intermediate components is specified).
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+typedef enum {XrmBindTightly, XrmBindLoosely} XrmBinding, *XrmBindingList;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<constant>XrmBindTightly</constant>
+indicates that a period separates the components, and
+<constant>XrmBindLoosely</constant>
+indicates that an asterisk separates the components.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To convert a string with one or more components to a binding list
+and a quark list, use
+<function>XrmStringToBindingQuarkList</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmStringToBindingQuarkList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmstringtobindingquarklist'>
+<funcprototype>
+ <funcdef><function>XrmStringToBindingQuarkList</function></funcdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+ <paramdef>XrmBindingList<parameter> bindings_return</parameter></paramdef>
+ <paramdef>XrmQuarkList<parameter> quarks_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Ql \ list -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string for which a quark(Ql is to be allocated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bindings_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the binding list.
+The caller must allocate sufficient space for the binding list before calling
+<function>XrmStringToBindingQuarkList</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quarks_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the list of quarks.
+The caller must allocate sufficient space for the quarks list before calling
+<function>XrmStringToBindingQuarkList</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Component names in the list are separated by a period or
+an asterisk character.
+The string must be in the format of a valid ResourceName
+(see <link linkend="Resource_File_Syntax">section 15.1</link>).
+If the string does not start with a period or an asterisk,
+a tight binding is assumed.
+For example, the string ``*a.b*c'' becomes:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA .75i 1.5i 2.25i -->
+<!-- .ta .75i 1.5i 2.25i -->
+quarks: a b c
+bindings: loose tight loose
+</literallayout>
+</para>
+</sect1>
+<sect1 id="Creating_and_Storing_Databases">
+<title>Creating and Storing Databases</title>
+<!-- .XS -->
+<!-- (SN Creating and Storing Databases -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XrmDatabase</primary></indexterm>
+A resource database is an opaque type,
+<type>XrmDatabase</type>.
+Each database value is stored in an
+<type>XrmValue</type>
+structure.
+This structure consists of a size, an address, and a representation type.
+The size is specified in bytes.
+The representation type is a way for you to store data tagged by some
+application-defined type (for example, the strings ``font'' or ``color'').
+It has nothing to do with the C data type or with its class.
+The
+<type>XrmValue</type>
+structure is defined as:
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XrmValue</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+typedef struct {
+ unsigned int size;
+ XPointer addr;
+} XrmValue, *XrmValuePtr;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To initialize the resource manager, use
+<function>XrmInitialize</function>.
+<indexterm significance="preferred"><primary>XrmInitialize</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrminitialize'>
+<funcprototype>
+ <funcdef>void <function>XrmInitialize</function></funcdef>
+ <paramdef>void<parameter> XrmInitialize(\|)</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+To retrieve a database from disk, use
+<function>XrmGetFileDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmGetFileDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmgetfiledatabase'>
+<funcprototype>
+ <funcdef>XrmDatabase <function>XrmGetFileDatabase</function></funcdef>
+ <paramdef>char<parameter> *filename</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>filename</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database file name.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmGetFileDatabase</function>
+function opens the specified file,
+creates a new resource database, and loads it with the specifications
+read in from the specified file.
+The specified file should contain a sequence of entries in valid ResourceLine
+format (see <link linkend="Resource_File_Syntax">section 15.1</link>);
+the database that results from reading a file
+with incorrect syntax is implementation-dependent.
+The file is parsed in the current locale,
+and the database is created in the current locale.
+If it cannot open the specified file,
+<function>XrmGetFileDatabase</function>
+returns NULL.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store a copy of a database to disk, use
+<function>XrmPutFileDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmPutFileDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmputfiledatabase'>
+<funcprototype>
+ <funcdef>void <function>XrmPutFileDatabase</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+ <paramdef>char<parameter> *stored_db</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the database that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>stored_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the file name for the stored database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmPutFileDatabase</function>
+function stores a copy of the specified database in the specified file.
+Text is written to the file as a sequence of entries in valid
+ResourceLine format
+(see <link linkend="Resource_File_Syntax">section 15.1</link>).
+The file is written in the locale of the database.
+Entries containing resource names that are not in the Host Portable Character
+Encoding or containing values that are not in the encoding of the database
+locale, are written in an implementation-dependent manner.
+The order in which entries are written is implementation-dependent.
+Entries with representation types other than ``String'' are ignored.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a pointer to the screen-independent resources of a display, use
+<function>XResourceManagerString</function>.
+</para>
+<indexterm significance="preferred"><primary>XResourceManagerString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xresourcemanagerstring'>
+<funcprototype>
+ <funcdef>char *<function>XResourceManagerString</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XResourceManagerString</function>
+function returns the RESOURCE_MANAGER property from the server's root
+window of screen zero, which was returned when the connection was opened using
+<function>XOpenDisplay</function>.
+The property is converted from type STRING to the current locale.
+The conversion is identical to that produced by
+<function>XmbTextPropertyToTextList</function>
+for a single element STRING property.
+The returned string is owned by Xlib and should not be freed by the client.
+The property value must be in a format that is acceptable to
+<function>XrmGetStringDatabase</function>.
+If no property exists, NULL is returned.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a pointer to the screen-specific resources of a screen, use
+<function>XScreenResourceString</function>.
+</para>
+<indexterm significance="preferred"><primary>XScreenResourceString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xscreenresourcestring'>
+<funcprototype>
+ <funcdef>char *<function>XScreenResourceString</function></funcdef>
+ <paramdef>Screen<parameter> *screen</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XScreenResourceString</function>
+function returns the SCREEN_RESOURCES property from the root window of the
+specified screen.
+The property is converted from type STRING to the current locale.
+The conversion is identical to that produced by
+<function>XmbTextPropertyToTextList</function>
+for a single element STRING property.
+The property value must be in a format that is acceptable to
+<function>XrmGetStringDatabase</function>.
+If no property exists, NULL is returned.
+The caller is responsible for freeing the returned string by using
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a database from a string, use
+<function>XrmGetStringDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmGetStringDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmgetstringdatabase'>
+<funcprototype>
+ <funcdef>XrmDatabase <function>XrmGetStringDatabase</function></funcdef>
+ <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the database contents using a string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmGetStringDatabase</function>
+function creates a new database and stores the resources specified
+in the specified null-terminated string.
+<function>XrmGetStringDatabase</function>
+is similar to
+<function>XrmGetFileDatabase</function>
+except that it reads the information out of a string instead of out of a file.
+The string should contain a sequence of entries in valid ResourceLine
+format (see <link linkend="Resource_File_Syntax">section 15.1</link>)
+terminated by a null character;
+the database that results from using a string
+with incorrect syntax is implementation-dependent.
+The string is parsed in the current locale,
+and the database is created in the current locale.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the locale name of a database, use
+<function>XrmLocaleOfDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmLocaleOfDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmlocaleofdatabase'>
+<funcprototype>
+ <funcdef>char *<function>XrmLocaleOfDatabase</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmLocaleOfDatabase</function>
+function returns the name of the locale bound to the specified
+database, as a null-terminated string.
+The returned locale name string is owned by Xlib and should not be
+modified or freed by the client.
+Xlib is not permitted to free the string until the database is destroyed.
+Until the string is freed,
+it will not be modified by Xlib.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To destroy a resource database and free its allocated memory, use
+<function>XrmDestroyDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmDestroyDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmdestroydatabase'>
+<funcprototype>
+ <funcdef>void <function>XrmDestroyDatabase</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database is NULL,
+<function>XrmDestroyDatabase</function>
+returns immediately.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To associate a resource database with a display, use
+<function>XrmSetDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmSetDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmsetdatabase'>
+<funcprototype>
+ <funcdef>void <function>XrmSetDatabase</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmSetDatabase</function>
+function associates the specified resource database (or NULL)
+with the specified display.
+The database previously associated with the display (if any) is not destroyed.
+A client or toolkit may find this function convenient for retaining a database
+once it is constructed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the resource database associated with a display, use
+<function>XrmGetDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmGetDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmgetdatabase'>
+<funcprototype>
+ <funcdef>XrmDatabase <function>XrmGetDatabase</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmGetDatabase</function>
+function returns the database associated with the specified display.
+It returns NULL if a database has not yet been set.
+</para>
+</sect1>
+<sect1 id="Merging_Resource_Databases">
+<title>Merging Resource Databases</title>
+<!-- .XS -->
+<!-- (SN Merging Resource Databases -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To merge the contents of a resource file into a database, use
+<function>XrmCombineFileDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmCombineFileDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmcombinefiledatabase'>
+<funcprototype>
+ <funcdef>Status <function>XrmCombineFileDatabase</function></funcdef>
+ <paramdef>char<parameter> *filename</parameter></paramdef>
+ <paramdef>XrmDatabase<parameter> *target_db</parameter></paramdef>
+ <paramdef>Bool<parameter> override</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>filename</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database file name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database into which the source
+database is to be merged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>override</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies whether source entries override target ones.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmCombineFileDatabase</function>
+function merges the contents of a resource file into a database.
+If the same specifier is used for an entry in both the file and
+the database,
+the entry in the file will replace the entry in the database
+if override is
+<symbol>True</symbol>;
+otherwise, the entry in the file is discarded.
+The file is parsed in the current locale.
+If the file cannot be read,
+a zero status is returned;
+otherwise, a nonzero status is returned.
+If target_db contains NULL,
+<function>XrmCombineFileDatabase</function>
+creates and returns a new database to it.
+Otherwise, the database pointed to by target_db is not destroyed by the merge.
+The database entries are merged without changing values or types,
+regardless of the locale of the database.
+The locale of the target database is not modified.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To merge the contents of one database into another database, use
+<function>XrmCombineDatabase</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmCombineDatabase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmcombinedatabase'>
+<funcprototype>
+ <funcdef>void <function>XrmCombineDatabase</function></funcdef>
+ <paramdef>XrmDatabasesource_db,<parameter> *target_db</parameter></paramdef>
+ <paramdef>Bool<parameter> override</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>source_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database that is to be merged into the target database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database into which the source
+database is to be merged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>override</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies whether source entries override target ones.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmCombineDatabase</function>
+function merges the contents of one database into another.
+If the same specifier is used for an entry in both databases,
+the entry in the source_db will replace the entry in the target_db
+if override is
+<symbol>True</symbol>;
+otherwise, the entry in source_db is discarded.
+If target_db contains NULL,
+<function>XrmCombineDatabase</function>
+simply stores source_db in it.
+Otherwise, source_db is destroyed by the merge, but the database pointed
+to by target_db is not destroyed.
+The database entries are merged without changing values or types,
+regardless of the locales of the databases.
+The locale of the target database is not modified.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To merge the contents of one database into another database with override
+semantics, use
+<function>XrmMergeDatabases</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmMergeDatabases</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmmergedatabases'>
+<funcprototype>
+ <funcdef>void <function>XrmMergeDatabases</function></funcdef>
+ <paramdef>XrmDatabasesource_db,<parameter> *target_db</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>source_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database that is to be merged into the target database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>target_db</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database into which the source
+database is to be merged.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Calling the
+<function>XrmMergeDatabases</function>
+function is equivalent to calling the
+<function>XrmCombineDatabase</function>
+function with an override argument of
+<symbol>True</symbol>.
+</para>
+</sect1>
+<sect1 id="Looking_Up_Resources">
+<title>Looking Up Resources</title>
+<!-- .XS -->
+<!-- (SN Looking Up Resources -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To retrieve a resource from a resource database, use
+<function>XrmGetResource</function>,
+<function>XrmQGetResource</function>,
+or
+<function>XrmQGetSearchResource</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmGetResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmgetresource'>
+<funcprototype>
+ <funcdef>Bool <function>XrmGetResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+ <paramdef>char<parameter> *str_name</parameter></paramdef>
+ <paramdef>char<parameter> *str_class</parameter></paramdef>
+ <paramdef>char<parameter> **str_type_return</parameter></paramdef>
+ <paramdef>XrmValue<parameter> *value_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the database that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>str_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fully qualified name of the value being retrieved (as a string).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>str_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fully qualified class of the value being retrieved (as a string).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>str_type_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the representation type of the destination (as a string).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<indexterm significance="preferred"><primary>XrmQGetResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmqgetresource'>
+<funcprototype>
+ <funcdef>Bool <function>XrmQGetResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+ <paramdef>XrmNameList<parameter> quark_name</parameter></paramdef>
+ <paramdef>XrmClassList<parameter> quark_class</parameter></paramdef>
+ <paramdef>XrmRepresentation<parameter> *quark_type_return</parameter></paramdef>
+ <paramdef>XrmValue<parameter> *value_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the database that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quark_name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fully qualified name of the value being retrieved (as a quark).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quark_class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fully qualified class of the value being retrieved (as a quark).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quark_type_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the representation type of the destination (as a quark).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmGetResource</function>
+and
+<function>XrmQGetResource</function>
+functions retrieve a resource from the specified database.
+Both take a fully qualified name/class pair, a destination
+resource representation, and the address of a value
+(size/address pair).
+The value and returned type point into database memory;
+therefore, you must not modify the data.
+</para>
+<para>
+<!-- .LP -->
+The database only frees or overwrites entries on
+<function>XrmPutResource</function>,
+<function>XrmQPutResource</function>,
+or
+<function>XrmMergeDatabases</function>.
+A client that is not storing new values into the database or
+is not merging the database should be safe using the address passed
+back at any time until it exits.
+If a resource was found, both
+<function>XrmGetResource</function>
+and
+<function>XrmQGetResource</function>
+return
+<symbol>True</symbol>;
+otherwise, they return
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+Most applications and toolkits do not make random probes
+into a resource database to fetch resources.
+The X toolkit access pattern for a resource database is quite stylized.
+A series of from 1 to 20 probes is made with only the
+last name/class differing in each probe.
+The
+<function>XrmGetResource</function>
+function is at worst a
+2<superscript><emphasis remap='I'>n</emphasis></superscript> algorithm,
+where <emphasis remap='I'>n</emphasis> is the length of the name/class list.
+This can be improved upon by the application programmer by prefetching a list
+of database levels that might match the first part of a name/class list.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a list of database levels, use
+<function>XrmQGetSearchList</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmQGetSearchList</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmqgetsearchlist'>
+<funcprototype>
+ <funcdef>Bool <function>XrmQGetSearchResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+ <paramdef>XrmNameList<parameter> names</parameter></paramdef>
+ <paramdef>XrmClassList<parameter> classes</parameter></paramdef>
+ <paramdef>XrmSearchList<parameter> list_return</parameter></paramdef>
+ <paramdef>int<parameter> list_length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the database that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>names</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of resource names.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>classes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of resource classes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns a search list for further use.
+The caller must allocate sufficient space for the list before calling
+<function>XrmQGetSearchList</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list_length</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of entries (not the byte size) allocated for list_return.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmQGetSearchList</function>
+function takes a list of names and classes
+and returns a list of database levels where a match might occur.
+The returned list is in best-to-worst order and
+uses the same algorithm as
+<function>XrmGetResource</function>
+for determining precedence.
+If list_return was large enough for the search list,
+<function>XrmQGetSearchList</function>
+returns
+<symbol>True</symbol>;
+otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The size of the search list that the caller must allocate is
+dependent upon the number of levels and wildcards in the resource specifiers
+that are stored in the database.
+The worst case length is
+3<superscript><emphasis remap='I'>n</emphasis></superscript>,
+where <emphasis remap='I'>n</emphasis> is the number of name or class
+components in names or classes.
+</para>
+<para>
+<!-- .LP -->
+When using
+<function>XrmQGetSearchList</function>
+followed by multiple probes for resources with a common name and class prefix,
+only the common prefix should be specified in the name and class list to
+<function>XrmQGetSearchList</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To search resource database levels for a given resource, use
+<function>XrmQGetSearchResource</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmQGetSearchResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmqgetsearchresource'>
+<funcprototype>
+ <funcdef>Bool <function>XrmQGetSearchResource</function></funcdef>
+ <paramdef>XrmSearchList<parameter> list</parameter></paramdef>
+ <paramdef>XrmName<parameter> name</parameter></paramdef>
+ <paramdef>XrmClass<parameter> class</parameter></paramdef>
+ <paramdef>XrmRepresentation<parameter> *type_return</parameter></paramdef>
+ <paramdef>XrmValue<parameter> *value_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the search list returned by
+<function>XrmQGetSearchList</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource class.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>type_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns data representation type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the value in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmQGetSearchResource</function>
+function searches the specified database levels for the resource
+that is fully identified by the specified name and class.
+The search stops with the first match.
+<function>XrmQGetSearchResource</function>
+returns
+<symbol>True</symbol>
+if the resource was found;
+otherwise, it returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+A call to
+<function>XrmQGetSearchList</function>
+with a name and class list containing all but the last component
+of a resource name followed by a call to
+<function>XrmQGetSearchResource</function>
+with the last component name and class returns the same database entry as
+<function>XrmGetResource</function>
+and
+<function>XrmQGetResource</function>
+with the fully qualified name and class.
+</para>
+</sect1>
+<sect1 id="Storing_into_a_Resource_Database">
+<title>Storing into a Resource Database</title>
+<!-- .XS -->
+<!-- (SN Storing into a Resource Database -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To store resources into the database, use
+<function>XrmPutResource</function>
+or
+<function>XrmQPutResource</function>.
+Both functions take a partial resource specification, a
+representation type, and a value.
+This value is copied into the specified database.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm significance="preferred"><primary>XrmPutResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmputresource'>
+<funcprototype>
+ <funcdef>void <function>XrmPutResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>char<parameter> *specifier</parameter></paramdef>
+ <paramdef>char<parameter> *type</parameter></paramdef>
+ <paramdef>XrmValue<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>specifier</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a complete or partial specification of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the type of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the value of the resource, which is specified as a string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database contains NULL,
+<function>XrmPutResource</function>
+creates a new database and returns a pointer to it.
+<function>XrmPutResource</function>
+is a convenience function that calls
+<function>XrmStringToBindingQuarkList</function>
+followed by:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+XrmQPutResource(database, bindings, quarks, XrmStringToQuark(type), value)
+</literallayout>
+If the specifier and type are not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+The value is stored in the database without modification.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<indexterm significance="preferred"><primary>XrmQPutResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmqputresource'>
+<funcprototype>
+ <funcdef>void <function>XrmQPutResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>XrmBindingList<parameter> bindings</parameter></paramdef>
+ <paramdef>XrmQuarkList<parameter> quarks</parameter></paramdef>
+ <paramdef>XrmRepresentation<parameter> type</parameter></paramdef>
+ <paramdef>XrmValue<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bindings</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of bindings.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quarks</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the complete or partial name or the class list of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>type</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the type of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the value of the resource, which is specified as a string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database contains NULL,
+<function>XrmQPutResource</function>
+creates a new database and returns a pointer to it.
+If a resource entry with the identical bindings and quarks already
+exists in the database, the previous type and value are replaced by the new
+specified type and value.
+The value is stored in the database without modification.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a resource that is specified as a string, use
+<function>XrmPutStringResource</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmPutStringResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmputstringresource'>
+<funcprototype>
+ <funcdef>void <function>XrmPutStringResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>char<parameter> *specifier</parameter></paramdef>
+ <paramdef>char<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>specifier</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a complete or partial specification of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the value of the resource, which is specified as a string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database contains NULL,
+<function>XrmPutStringResource</function>
+creates a new database and returns a pointer to it.
+<function>XrmPutStringResource</function>
+adds a resource with the specified value to the specified database.
+<function>XrmPutStringResource</function>
+is a convenience function that first calls
+<function>XrmStringToBindingQuarkList</function>
+on the specifier and then calls
+<function>XrmQPutResource</function>,
+using a ``String'' representation type.
+If the specifier is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+The value is stored in the database without modification.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a string resource using quarks as a specification, use
+<function>XrmQPutStringResource</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmQPutStringResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmqputstringresource'>
+<funcprototype>
+ <funcdef>void <function>XrmQPutStringResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>XrmBindingList<parameter> bindings</parameter></paramdef>
+ <paramdef>XrmQuarkList<parameter> quarks</parameter></paramdef>
+ <paramdef>char<parameter> *value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bindings</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies a list of bindings.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>quarks</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the complete or partial name or the class list of the resource.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the value of the resource, which is specified as a string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database contains NULL,
+<function>XrmQPutStringResource</function>
+creates a new database and returns a pointer to it.
+<function>XrmQPutStringResource</function>
+is a convenience routine that constructs an
+<type>XrmValue</type>
+for the value string (by calling
+<function>strlen</function>
+to compute the size) and
+then calls
+<function>XrmQPutResource</function>,
+using a ``String'' representation type.
+The value is stored in the database without modification.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To add a single resource entry that is specified as a string that contains
+both a name and a value, use
+<function>XrmPutLineResource</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmPutLineResource</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmputlineresource'>
+<funcprototype>
+ <funcdef>void <function>XrmPutLineResource</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>char<parameter> *line</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>line</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource name and value pair as a single string.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If database contains NULL,
+<function>XrmPutLineResource</function>
+creates a new database and returns a pointer to it.
+<function>XrmPutLineResource</function>
+adds a single resource entry to the specified database.
+The line should be in valid ResourceLine format
+(see <link linkend="Resource_File_Syntax">section 15.1</link>)
+terminated by a newline or null character;
+the database that results from using a string
+with incorrect syntax is implementation-dependent.
+The string is parsed in the locale of the database.
+If the
+<replaceable>ResourceName</replaceable>
+is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+Note that comment lines are not stored.
+</para>
+</sect1>
+<sect1 id="Enumerating_Database_Entries">
+<title>Enumerating Database Entries</title>
+<!-- .XS -->
+<!-- (SN Enumerating Database Entries -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To enumerate the entries of a database, use
+<function>XrmEnumerateDatabase</function>.
+<indexterm significance="preferred"><primary>XrmEnumerateDatabase</primary></indexterm>
+<!-- .sM -->
+</para>
+
+<literallayout class="monospaced">
+#define XrmEnumAllLevels 0
+#define XrmEnumOneLevel 0
+</literallayout>
+
+<funcsynopsis id='xrmenumeratedatabase'>
+<funcprototype>
+ <funcdef>Bool <function>XrmEnumerateDatabase</function></funcdef>
+ <paramdef>XrmDatabase<parameter> database</parameter></paramdef>
+ <paramdef>XrmNameList<parameter> name_prefix</parameter></paramdef>
+ <paramdef>XrmClassList<parameter> class_prefix</parameter></paramdef>
+ <paramdef>int<parameter> mode</parameter></paramdef>
+ <paramdef>Bool<parameter> (*proc)()</parameter></paramdef>
+ <paramdef>XPointer<parameter> arg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name_prefix</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource name prefix.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class_prefix</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource class prefix.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of levels to enumerate.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>proc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the procedure that is to be called for each matching entry.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>arg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the user-supplied argument that will be passed to the procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmEnumerateDatabase</function>
+function calls the specified procedure for each resource in the database
+that would match some completion of the given name/class resource prefix.
+The order in which resources are found is implementation-dependent.
+If mode is
+<symbol>XrmEnumOneLevel</symbol>,
+a resource must match the given name/class prefix with
+just a single name and class appended. If mode is
+<symbol>XrmEnumAllLevels</symbol>,
+the resource must match the given name/class prefix with one or more names and
+classes appended.
+If the procedure returns
+<symbol>True</symbol>,
+the enumeration terminates and the function returns
+<symbol>True</symbol>.
+If the procedure always returns
+<symbol>False</symbol>,
+all matching resources are enumerated and the function returns
+<symbol>False</symbol>.
+</para>
+<para>
+<!-- .LP -->
+The procedure is called with the following arguments:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+(*<emphasis remap='I'>proc</emphasis>)(<emphasis remap='I'>database</emphasis>, <emphasis remap='I'>bindings</emphasis>, <emphasis remap='I'>quarks</emphasis>, <emphasis remap='I'>type</emphasis>, <emphasis remap='I'>value</emphasis>, <emphasis remap='I'>arg</emphasis>)
+ XrmDatabase *<emphasis remap='I'>database</emphasis>;
+ XrmBindingList <emphasis remap='I'>bindings</emphasis>;
+ XrmQuarkList <emphasis remap='I'>quarks</emphasis>;
+ XrmRepresentation *<emphasis remap='I'>type</emphasis>;
+ XrmValue *<emphasis remap='I'>value</emphasis>;
+ XPointer <emphasis remap='I'>arg</emphasis>;
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+The bindings and quarks lists are terminated by
+<symbol>NULLQUARK</symbol>.
+Note that pointers
+to the database and type are passed, but these values should not be modified.
+</para>
+<para>
+<!-- .LP -->
+The procedure must not modify the database.
+If Xlib has been initialized for threads, the procedure is called with
+the database locked and the result of a call by the procedure to any
+Xlib function using the same database is not defined.
+</para>
+</sect1>
+<sect1 id="Parsing_Command_Line_Options">
+<title>Parsing Command Line Options</title>
+<!-- .XS -->
+<!-- (SN Parsing Command Line Options -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The
+<function>XrmParseCommand</function>
+function can be used to parse the command line arguments to a program
+and modify a resource database with selected entries from the command line.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XrmOptionKind</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef enum {
+ XrmoptionNoArg, /* Value is specified in XrmOptionDescRec.value */
+ XrmoptionIsArg, /* Value is the option string itself */
+ XrmoptionStickyArg, /* Value is characters immediately following option */
+ XrmoptionSepArg, /* Value is next argument in argv */
+ XrmoptionResArg, /* Resource and value in next argument in argv */
+ XrmoptionSkipArg, /* Ignore this option and the next argument in argv */
+ XrmoptionSkipLine, /* Ignore this option and the rest of argv */
+ XrmoptionSkipNArgs /* Ignore this option and the next
+ \ \ \ XrmOptionDescRec.value arguments in argv */
+} XrmOptionKind;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Note that
+<constant>XrmoptionSkipArg</constant>
+is equivalent to
+<constant>XrmoptionSkipNArgs</constant>
+with the
+<structname>XrmOptionDescRec</structname>.<structfield>value</structfield>
+field containing the value one.
+Note also that the value zero for
+<constant>XrmoptionSkipNArgs</constant>
+indicates that only the option itself is to be skipped.
+</para>
+<para>
+<!-- .LP -->
+<indexterm significance="preferred"><primary>XrmOptionDescRec</primary></indexterm>
+<!-- .sM -->
+<literallayout class="monospaced">
+<!-- .TA .5i 2.5i -->
+<!-- .ta .5i 2.5i -->
+typedef struct {
+ char *option; /* Option specification string in argv */
+ char *specifier; /* Binding and resource name (sans application name) */
+ XrmOptionKind argKind; /* Which style of option it is */
+ XPointer value; /* Value to provide if XrmoptionNoArg or
+ \ \ \ XrmoptionSkipNArgs */
+} XrmOptionDescRec, *XrmOptionDescList;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To load a resource database from a C command line, use
+<function>XrmParseCommand</function>.
+</para>
+<indexterm significance="preferred"><primary>XrmParseCommand</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrmparsecommand'>
+<funcprototype>
+ <funcdef>void <function>XrmParseCommand</function></funcdef>
+ <paramdef>XrmDatabase<parameter> *database</parameter></paramdef>
+ <paramdef>XrmOptionDescList<parameter> table</parameter></paramdef>
+ <paramdef>int<parameter> table_count</parameter></paramdef>
+ <paramdef>char<parameter> *name</parameter></paramdef>
+ <paramdef>int<parameter> *argc_in_out</parameter></paramdef>
+ <paramdef>char<parameter> **argv_in_out</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>database</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the table of command line arguments to be parsed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>table_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of entries in the table.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>name</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argc_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of arguments and returns the number of remaining arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>argv_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the command line arguments
+and returns the remaining arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XrmParseCommand</function>
+function parses an (argc, argv) pair according to the specified option table,
+loads recognized options into the specified database with type ``String,''
+and modifies the (argc, argv) pair to remove all recognized options.
+If database contains NULL,
+<function>XrmParseCommand</function>
+creates a new database and returns a pointer to it.
+Otherwise, entries are added to the database specified.
+If a database is created, it is created in the current locale.
+</para>
+<para>
+<!-- .LP -->
+The specified table is used to parse the command line.
+Recognized options in the table are removed from argv,
+and entries are added to the specified resource database
+in the order they occur in argv.
+The table entries contain information on the option string,
+the option name, the style of option,
+and a value to provide if the option kind is
+<constant>XrmoptionNoArg</constant>.
+The option names are compared byte-for-byte to arguments in argv,
+independent of any locale.
+The resource values given in the table are stored in the resource database
+without modification.
+All resource database entries are created
+using a ``String'' representation type.
+The argc argument specifies the number of arguments in argv
+and is set on return to the remaining number of arguments that were not parsed.
+The name argument should be the name of your application
+for use in building the database entry.
+The name argument is prefixed to the resourceName in the option table
+before storing a database entry.
+The name argument is treated as a single component, even if it
+has embedded periods.
+No separating (binding) character is inserted,
+so the table must contain either a period (.) or an asterisk (*)
+as the first character in each resourceName entry.
+To specify a more completely qualified resource name,
+the resourceName entry can contain multiple components.
+If the name argument and the resourceNames are not in the
+Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+The following provides a sample option table:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+<!-- .TA 1.25i 3.25i 4.75i -->
+<!-- .ta 1.25i 3.25i 4.75i -->
+static XrmOptionDescRec opTable[] = {
+{"-background", "*background", XrmoptionSepArg, (XPointer) NULL},
+{"-bd", "*borderColor", XrmoptionSepArg, (XPointer) NULL},
+{"-bg", "*background", XrmoptionSepArg, (XPointer) NULL},
+{"-borderwidth", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL},
+{"-bordercolor", "*borderColor", XrmoptionSepArg, (XPointer) NULL},
+{"-bw", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL},
+{"-display", ".display", XrmoptionSepArg, (XPointer) NULL},
+{"-fg", "*foreground", XrmoptionSepArg, (XPointer) NULL},
+{"-fn", "*font", XrmoptionSepArg, (XPointer) NULL},
+{"-font", "*font", XrmoptionSepArg, (XPointer) NULL},
+{"-foreground", "*foreground", XrmoptionSepArg, (XPointer) NULL},
+{"-geometry", ".TopLevelShell.geometry", XrmoptionSepArg, (XPointer) NULL},
+{"-iconic", ".TopLevelShell.iconic", XrmoptionNoArg, (XPointer) "on"},
+{"-name", ".name", XrmoptionSepArg, (XPointer) NULL},
+{"-reverse", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"},
+{"-rv", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"},
+{"-synchronous", "*synchronous", XrmoptionNoArg, (XPointer) "on"},
+{"-title", ".TopLevelShell.title", XrmoptionSepArg, (XPointer) NULL},
+{"-xrm", NULL, XrmoptionResArg, (XPointer) NULL},
+};
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+In this table, if the -background (or -bg) option is used to set
+background colors, the stored resource specifier matches all
+resources of attribute background.
+If the -borderwidth option is used,
+the stored resource specifier applies only to border width
+attributes of class TopLevelShell (that is, outer-most windows, including
+pop-up windows).
+If the -title option is used to set a window name,
+only the topmost application windows receive the resource.
+</para>
+<para>
+<!-- .LP -->
+When parsing the command line,
+any unique unambiguous abbreviation for an option name in the table is
+considered a match for the option.
+Note that uppercase and lowercase matter.
+<!-- .bp -->
+
+</para>
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/CH16.xml b/libX11/specs/libX11/CH16.xml index 01f25d4b4..602668faf 100644 --- a/libX11/specs/libX11/CH16.xml +++ b/libX11/specs/libX11/CH16.xml @@ -1,4160 +1,4160 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<chapter id="application_utility_functions"> -<title>Application Utility Functions</title> -<!-- .sp 2 --> -<!-- .nr H1 16 --> -<!-- .nr H2 0 --> -<!-- .nr H3 0 --> -<!-- .nr H4 0 --> -<!-- .nr H5 0 --> -<!-- .na --> -<para> -<!-- .LP --> -<!-- .XS --> -<!-- Chapter 16: Application Utility Functions --> -<!-- .XE --> -Once you have initialized the X system, -you can use the Xlib utility functions to: -</para> -<itemizedlist> - <listitem> - <para> -Use keyboard utility functions - </para> - </listitem> - <listitem> - <para> -Use Latin-1 keyboard event functions - </para> - </listitem> - <listitem> - <para> -Allocate permanent storage - </para> - </listitem> - <listitem> - <para> -Parse the window geometry - </para> - </listitem> - <listitem> - <para> -Manipulate regions - </para> - </listitem> - <listitem> - <para> -Use cut buffers - </para> - </listitem> - <listitem> - <para> -Determine the appropriate visual type - </para> - </listitem> - <listitem> - <para> -Manipulate images - </para> - </listitem> - <listitem> - <para> -Manipulate bitmaps - </para> - </listitem> - <listitem> - <para> -Use the context manager - </para> - </listitem> -</itemizedlist> -<para> -<!-- .LP --> -As a group, -the functions discussed in this chapter provide the functionality that -is frequently needed and that spans toolkits. -Many of these functions do not generate actual protocol requests to the server. -</para> -<sect1 id="Using_Keyboard_Utility_Functions"> -<title>Using Keyboard Utility Functions</title> -<!-- .XS --> -<!-- (SN Using Keyboard Utility Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -This section discusses mapping between KeyCodes and KeySyms, -classifying KeySyms, and mapping between KeySyms and string names. -The first three functions in this section operate on a cached copy of the -server keyboard mapping. -The first four KeySyms for each KeyCode -are modified according to the rules given in section 12.7. -To obtain the untransformed KeySyms defined for a key, -use the functions described in section 12.7. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a KeySym for the KeyCode of an event, use -<function>XLookupKeysym</function>. -</para> -<indexterm significance="preferred"><primary>XLookupKeysym</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlookupkeysym'> -<funcprototype> - <funcdef>KeySym <function>XLookupKeysym</function></funcdef> - <paramdef>XKeyEvent<parameter> *key_event</parameter></paramdef> - <paramdef>int<parameter> index</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>key_event</emphasis> - </term> - <listitem> - <para> -Specifies the -<symbol>KeyPress</symbol> -or -<symbol>KeyRelease</symbol> -event. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>index</emphasis> - </term> - <listitem> - <para> -Specifies the index into the KeySyms list for the event's KeyCode. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLookupKeysym</function> -function uses a given keyboard event and the index you specified to return -the KeySym from the list that corresponds to the KeyCode member in the -<type>XKeyPressedEvent</type> -or -<type>XKeyReleasedEvent</type> -structure. -If no KeySym is defined for the KeyCode of the event, -<function>XLookupKeysym</function> -returns -<symbol>NoSymbol</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a KeySym for a specific KeyCode, use -<function>XKeycodeToKeysym</function>. -</para> -<indexterm significance="preferred"><primary>XKeycodeToKeysym</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xkeycodetokeysym'> -<funcprototype> - <funcdef>KeySym <function>XKeycodeToKeysym</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>KeyCode<parameter> keycode</parameter></paramdef> - <paramdef>int<parameter> index</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keycode</emphasis> - </term> - <listitem> - <para> -Specifies the KeyCode. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>index</emphasis> - </term> - <listitem> - <para> -Specifies the element of KeyCode vector. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XKeycodeToKeysym</function> -function uses internal Xlib tables -and returns the KeySym defined for the specified KeyCode and -the element of the KeyCode vector. -If no symbol is defined, -<function>XKeycodeToKeysym</function> -returns -<symbol>NoSymbol</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a KeyCode for a key having a specific KeySym, use -<function>XKeysymToKeycode</function>. -</para> -<indexterm significance="preferred"><primary>XKeysymToKeycode</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xkeysymtokeycode'> -<funcprototype> - <funcdef>KeyCode <function>XKeysymToKeycode</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>KeySym<parameter> keysym</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be searched for. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If the specified KeySym is not defined for any KeyCode, -<function>XKeysymToKeycode</function> -returns zero. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -The mapping between KeyCodes and KeySyms is cached internal to Xlib. -When this information is changed at the server, an Xlib function must -be called to refresh the cache. -To refresh the stored modifier and keymap information, use -<function>XRefreshKeyboardMapping</function>. -</para> -<indexterm significance="preferred"><primary>XRefreshKeyboardMapping</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrefreshkeyboardmapping'> -<funcprototype> - <funcdef><function>XRefreshKeyboardMapping</function></funcdef> - <paramdef>XMappingEvent<parameter> *event_map</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>event_map</emphasis> - </term> - <listitem> - <para> -Specifies the mapping event that is to be used. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRefreshKeyboardMapping</function> -function refreshes the stored modifier and keymap information. -You usually call this function when a -<symbol>MappingNotify</symbol> -event with a request member of -<symbol>MappingKeyboard</symbol> -or -<symbol>MappingModifier</symbol> -occurs. -The result is to update Xlib's knowledge of the keyboard. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the uppercase and lowercase forms of a KeySym, use -<function>XConvertCase</function>. -</para> -<indexterm significance="preferred"><primary>XConvertCase</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xconvertcase'> -<funcprototype> - <funcdef>void <function>XConvertCase</function></funcdef> - <paramdef>KeySym<parameter> keysym</parameter></paramdef> - <paramdef>KeySym<parameter> *lower_return</parameter></paramdef> - <paramdef>KeySym<parameter> *upper_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Fn converted --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>lower_return</emphasis> - </term> - <listitem> - <para> -Returns the lowercase form of keysym, or keysym. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>upper_return</emphasis> - </term> - <listitem> - <para> -Returns the uppercase form of keysym, or keysym. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XConvertCase</function> -function returns the uppercase and lowercase forms of the specified Keysym, -if the KeySym is subject to case conversion; -otherwise, the specified KeySym is returned to both lower_return and -upper_return. -Support for conversion of other than Latin and Cyrillic KeySyms is -implementation-dependent. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -KeySyms have string names as well as numeric codes. -To convert the name of the KeySym to the KeySym code, use -<function>XStringToKeysym</function>. -</para> -<indexterm significance="preferred"><primary>XStringToKeysym</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstringtokeysym'> -<funcprototype> - <funcdef>KeySym <function>XStringToKeysym</function></funcdef> - <paramdef>char<parameter> *string</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the name of the KeySym that is to be converted. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Standard KeySym names are obtained from -<filename class="headerfile"><X11/keysymdef.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/keysymdef.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm> -by removing the XK_ prefix from each name. -KeySyms that are not part of the Xlib standard also may be obtained -with this function. -The set of KeySyms that are available in this manner -and the mechanisms by which Xlib obtains them is implementation-dependent. -</para> -<para> -<!-- .LP --> -If the KeySym name is not in the Host Portable Character Encoding, -the result is implementation-dependent. -If the specified string does not match a valid KeySym, -<function>XStringToKeysym</function> -returns -<symbol>NoSymbol</symbol>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To convert a KeySym code to the name of the KeySym, use -<function>XKeysymToString</function>. -</para> -<indexterm significance="preferred"><primary>XKeysymToString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xkeysymtostring'> -<funcprototype> - <funcdef>char *<function>XKeysymToString</function></funcdef> - <paramdef>KeySym<parameter> keysym</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<!-- .ds Fn converted --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The returned string is in a static area and must not be modified. -The returned string is in the Host Portable Character Encoding. -If the specified KeySym is not defined, -<function>XKeysymToString</function> -returns a NULL. -</para> -<sect2 id="KeySym_Classification_Macros"> -<title>KeySym Classification Macros</title> -<!-- .XS --> -<!-- (SN KeySym Classification Macros --> -<!-- .XE --> -<para> -<!-- .LP --> -You may want to test if a KeySym is, for example, -on the keypad or on one of the function keys. -You can use KeySym macros to perform the following tests. -</para> -<para>IsCursorKey(<emphasis remap='I'>keysym</emphasis>)</para> -<!-- .FN --> -<!-- .ds Fn tested --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be tested. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsCursorKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a cursor key. -</para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<para>IsFunctionKey(<emphasis remap='I'>keysym</emphasis>)</para> -<!-- .FN --> -<!-- .ds Fn tested --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be tested. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsFunctionKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a function key. -</para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<para>IsKeypadKey(<emphasis remap='I'>keysym</emphasis>)</para> -<!-- .FN --> -<!-- .ds Fn tested --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsKeypadKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a standard keypad key. -</para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<para>IsPrivateKeypadKey(<emphasis remap='I'>keysym</emphasis>)</para> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsPrivateKeypadKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a vendor-private keypad key. -</para> - -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<para>IsMiscFunctionKey(<emphasis remap='I'>keysym</emphasis>)</para> -<!-- .FN --> -<!-- .ds Fn tested --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsMiscFunctionKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a miscellaneous function key. -</para> -<!-- .LP --> -<!-- .sp --> -<!-- .sM --> -<para>IsModifierKey(<emphasis remap='I'>keysym</emphasis>)</para> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be tested. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsModifierKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a modifier key. -</para> - -<para>IsPFKey(<emphasis remap='I'>keysym</emphasis>)</para> - -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be tested. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -<indexterm significance="preferred"><primary>IsPFKey</primary></indexterm> -Returns -<symbol>True</symbol> -if the specified KeySym is a PF key. -</para> -</sect2> -</sect1> -<sect1 id="Using_Latin_Keyboard_Event_Functions"> -<title>Using Latin-1 Keyboard Event Functions</title> -<!-- .XS --> -<!-- (SN Using Latin-1 Keyboard Event Functions --> -<!-- .XE --> -<para> -<!-- .LP --> -<link linkend="locales_and_internationalized_text_functions">Chapter 13</link> -describes internationalized text input facilities, -but sometimes it is expedient to write an application that -only deals with Latin-1 characters and ASCII controls, -so Xlib provides a simple function for that purpose. -<function>XLookupString</function> -handles the standard modifier semantics described in section 12.7. -This function does not use any of the input method facilities -described in chapter 13 and does not depend on the current locale. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To map a key event to an ISO Latin-1 string, use -<function>XLookupString</function>. -</para> -<indexterm significance="preferred"><primary>XLookupString</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xlookupstring'> -<funcprototype> - <funcdef>int <function>XLookupString</function></funcdef> - <paramdef>XKeyEvent<parameter> *event_struct</parameter></paramdef> - <paramdef>char<parameter> *buffer_return</parameter></paramdef> - <paramdef>int<parameter> bytes_buffer</parameter></paramdef> - <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef> - <paramdef>XComposeStatus<parameter> *status_in_out</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>event_struct</emphasis> - </term> - <listitem> - <para> -Specifies the key event structure to be used. -You can pass -<type>XKeyPressedEvent</type> -or -<type>XKeyReleasedEvent</type>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer_return</emphasis> - </term> - <listitem> - <para> -Returns the translated characters. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes_buffer</emphasis> - </term> - <listitem> - <para> -Specifies the length of the buffer. -No more than bytes_buffer of translation are returned. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysym_return</emphasis> - </term> - <listitem> - <para> -Returns the KeySym computed from the event if this argument is not NULL. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>status_in_out</emphasis> - </term> - <listitem> - <para> -Specifies or returns the -<structname>XComposeStatus</structname> -structure or NULL. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XLookupString</function> -function translates a key event to a KeySym and a string. -The KeySym is obtained by using the standard interpretation of the -<symbol>Shift</symbol>, -<symbol>Lock</symbol>, -group, and numlock modifiers as defined in the X Protocol specification. -If the KeySym has been rebound (see -<function>XRebindKeysym</function>), -the bound string will be stored in the buffer. -Otherwise, the KeySym is mapped, if possible, to an ISO Latin-1 character -or (if the Control modifier is on) to an ASCII control character, -and that character is stored in the buffer. -<function>XLookupString</function> -returns the number of characters that are stored in the buffer. -</para> -<para> -<!-- .LP --> -If present (non-NULL), -the -<structname>XComposeStatus</structname> -structure records the state, -which is private to Xlib, -that needs preservation across calls to -<function>XLookupString</function> -to implement compose processing. -The creation of -<structname>XComposeStatus</structname> -structures is implementation-dependent; -a portable program must pass NULL for this argument. -</para> -<para> -<!-- .LP --> -<function>XLookupString</function> -depends on the cached keyboard information mentioned in the -previous section, so it is necessary to use -<function>XRefreshKeyboardMapping</function> -to keep this information up-to-date. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To rebind the meaning of a KeySym for -<function>XLookupString</function>, -use -<function>XRebindKeysym</function>. -</para> -<indexterm significance="preferred"><primary>XRebindKeysym</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrebindkeysym'> -<funcprototype> - <funcdef><function>XRebindKeysym</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>KeySym<parameter> keysym</parameter></paramdef> - <paramdef>KeySym<parameter> list[ ]</parameter></paramdef> - <paramdef>int<parameter> mod_count</parameter></paramdef> - <paramdef>unsignedchar<parameter> *string</parameter></paramdef> - <paramdef>int<parameter> num_bytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Fn rebound --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>keysym</emphasis> - </term> - <listitem> - <para> -Specifies the KeySym that is to be (Fn. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>list</emphasis> - </term> - <listitem> - <para> -Specifies the KeySyms to be used as modifiers. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>mod_count</emphasis> - </term> - <listitem> - <para> -Specifies the number of modifiers in the modifier list. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>string</emphasis> - </term> - <listitem> - <para> -Specifies the string that is copied and will be returned by -<function>XLookupString</function>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>num_bytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the string argument. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRebindKeysym</function> -function can be used to rebind the meaning of a KeySym for the client. -It does not redefine any key in the X server but merely -provides an easy way for long strings to be attached to keys. -<function>XLookupString</function> -returns this string when the appropriate set of -modifier keys are pressed and when the KeySym would have been used for -the translation. -No text conversions are performed; -the client is responsible for supplying appropriately encoded strings. -Note that you can rebind a KeySym that may not exist. -</para> -</sect1> -<sect1 id="Allocating_Permanent_Storage"> -<title>Allocating Permanent Storage</title> -<!-- .XS --> -<!-- (SN Allocating Permanent Storage --> -<!-- .XE --> -<para> -<!-- .LP --> -To allocate some memory you will never give back, use -<function>Xpermalloc</function>. -<indexterm significance="preferred"><primary>Xpermalloc</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpermalloc'> -<funcprototype> - <funcdef>char *<function>Xpermalloc</function></funcdef> - <paramdef>unsignedint<parameter> size</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>Xpermalloc</function> -function allocates storage that can never be freed for the life of the -program. The memory is allocated with alignment for the C type double. -This function may provide some performance and space savings over -the standard operating system memory allocator. -</para> -</sect1> -<sect1 id="Parsing_the_Window_Geometry"> -<title>Parsing the Window Geometry</title> -<!-- .XS --> -<!-- (SN Parsing the Window Geometry --> -<!-- .XE --> -<para> -<!-- .LP --> -To parse standard window geometry strings, use -<function>XParseGeometry</function>. -<indexterm><primary>Window</primary><secondary>determining location</secondary></indexterm> -<indexterm significance="preferred"><primary>XParseGeometry</primary></indexterm> -</para> -<!-- .LP --> -<!-- .sM --> -<funcsynopsis id='xparsegeometry'> -<funcprototype> - <funcdef>int <function>XParseGeometry</function></funcdef> - <paramdef>char<parameter> *parsestring</parameter></paramdef> - <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>parsestring</emphasis> - </term> - <listitem> - <para> -Specifies the string you want to parse. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_return</emphasis> - </term> - <listitem> - <para> -Return the x and y offsets. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height determined. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -By convention, -X applications use a standard string to indicate window size and placement. -<function>XParseGeometry</function> -makes it easier to conform to this standard because it allows you -to parse the standard window geometry. -Specifically, this function lets you parse strings of the form: -</para> -<para> -<!-- .LP --> -<!-- .\" Start marker code here --> -<literallayout class="monospaced"> -[=][<<emphasis remap='I'>width</emphasis>>{xX}<<emphasis remap='I'>height</emphasis>>][{+-}<<emphasis remap='I'>xoffset</emphasis>>{+-}<<emphasis remap='I'>yoffset</emphasis>>] -</literallayout> -<!-- .\" End marker code here --> -</para> -<para> -<!-- .LP --> -The fields map into the arguments associated with this function. -(Items enclosed in < > are integers, items in [ ] are optional, and -items enclosed in { } indicate ``choose one of.'' -Note that the brackets should not appear in the actual string.) -If the string is not in the Host Portable Character Encoding, -the result is implementation-dependent. -</para> -<para> -<!-- .LP --> -The -<function>XParseGeometry</function> -function returns a bitmask that indicates which of the four values (width, -height, xoffset, and yoffset) were actually found in the string -and whether the x and y values are negative. -By convention, −0 is not equal to +0, because the user needs to -be able to say ``position the window relative to the right or bottom edge.'' -For each value found, the corresponding argument is updated. -For each value not found, the argument is left unchanged. -The bits are represented by -<symbol>XValue</symbol>, -<symbol>YValue</symbol>, -<symbol>WidthValue</symbol>, -<symbol>HeightValue</symbol>, -<symbol>XNegative</symbol>, -or -<symbol>YNegative</symbol> -and are defined in -<filename class="headerfile"><X11/Xutil.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -They will be set whenever one of the values is defined -or one of the signs is set. -</para> -<para> -<!-- .LP --> -If the function returns either the -<symbol>XValue</symbol> -or -<symbol>YValue</symbol> -flag, -you should place the window at the requested position. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To construct a window's geometry information, use -<function>XWMGeometry</function>. -</para> -<indexterm significance="preferred"><primary>XWMGeometry</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwmgeometry'> -<funcprototype> - <funcdef>int <function>XWMGeometry</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen</parameter></paramdef> - <paramdef>char<parameter> *user_geom</parameter></paramdef> - <paramdef>char<parameter> *def_geom</parameter></paramdef> - <paramdef>unsignedint<parameter> bwidth</parameter></paramdef> - <paramdef>XSizeHints<parameter> *hints</parameter></paramdef> - <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef> - <paramdef>int<parameter> *width_return</parameter></paramdef> - <paramdef>int<parameter> *height_return</parameter></paramdef> - <paramdef>int<parameter> *gravity_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>user_geom</emphasis> - </term> - <listitem> - <para> -Specifies the user-specified geometry or NULL. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>def_geom</emphasis> - </term> - <listitem> - <para> -Specifies the application's default geometry or NULL. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bwidth</emphasis> - </term> - <listitem> - <para> -Specifies the border width. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>hints</emphasis> - </term> - <listitem> - <para> -Specifies the size hints for the window in its normal state. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_return</emphasis> - </term> - <listitem> - <para> -Return the x and y offsets. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height determined. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gravity_return</emphasis> - </term> - <listitem> - <para> -Returns the window gravity. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XWMGeometry</function> -function combines any geometry information (given in the format used by -<function>XParseGeometry</function>) -specified by the user and by the calling program with size hints -(usually the ones to be stored in <property>WM_NORMAL_HINTS</property>) and returns the position, -size, and gravity -(<symbol>NorthWestGravity</symbol>, -<symbol>NorthEastGravity</symbol>, -<symbol>SouthEastGravity</symbol>, -or -<symbol>SouthWestGravity</symbol>) -that describe the window. -If the base size is not set in the -<structname>XSizeHints</structname> -structure, -the minimum size is used if set. -Otherwise, a base size of zero is assumed. -If no minimum size is set in the hints structure, -the base size is used. -A mask (in the form returned by -<function>XParseGeometry</function>) -that describes which values came from the user specification -and whether or not the position coordinates are relative -to the right and bottom edges is returned. -Note that these coordinates will have already been accounted for -in the x_return and y_return values. -</para> -<para> -<!-- .LP --> -Note that invalid geometry specifications can cause a width or height -of zero to be returned. -The caller may pass the address of the hints win_gravity field -as gravity_return to update the hints directly. -</para> -</sect1> - -<sect1 id="Manipulating_Regions"> -<title>Manipulating Regions</title> -<!-- .XS --> -<!-- (SN Manipulating Regions --> -<!-- .XE --> -<para> -Regions are arbitrary sets of pixel locations. -Xlib provides functions for manipulating regions. -The opaque type -<structname>Region</structname> -is defined in -<filename class="headerfile"><X11/Xutil.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -Xlib provides functions that you can use to manipulate regions. -This section discusses how to: -</para> - -<itemizedlist> - <listitem> - <para> -Create, copy, or destroy regions - </para> - </listitem> - <listitem> - <para> -Move or shrink regions - </para> - </listitem> - <listitem> - <para> -Compute with regions - </para> - </listitem> - <listitem> - <para> -Determine if regions are empty or equal - </para> - </listitem> - <listitem> - <para> -Locate a point or rectangle in a region - </para> - </listitem> -</itemizedlist> - -<sect2 id="Creating_Copying_or_Destroying_Regions"> -<title>Creating, Copying, or Destroying Regions</title> -<!-- .XS --> -<!-- (SN Creating, Copying, or Destroying Regions --> -<!-- .XE --> -<para> -<!-- .LP --> -To create a new empty region, use -<function>XCreateRegion</function>. -</para> -<para>Region XCreateRegion()</para> - -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To generate a region from a polygon, use -<function>XPolygonRegion</function>. -</para> -<indexterm significance="preferred"><primary>XPolygonRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpolygonregion'> -<funcprototype> - <funcdef>Region <function>XPolygonRegion</function></funcdef> - <paramdef>XPoint<parameter> points[]</parameter></paramdef> - <paramdef>int<parameter> n</parameter></paramdef> - <paramdef>int<parameter> fill_rule</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>points</emphasis> - </term> - <listitem> - <para> -Specifies an array of points. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>n</emphasis> - </term> - <listitem> - <para> -Specifies the number of points in the polygon. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fill_rule</emphasis> - </term> - <listitem> - <para> -Specifies the fill-rule you want to set for the specified GC. -You can pass -<symbol>EvenOddRule</symbol> -or -<symbol>WindingRule</symbol>. - </para> - </listitem> - </varlistentry> -</variablelist> - -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPolygonRegion</function> -function returns a region for the polygon defined by the points array. -For an explanation of fill_rule, -see -<function>XCreateGC</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set the clip-mask of a GC to a region, use -<function>XSetRegion</function>. -</para> -<indexterm significance="preferred"><primary>XSetRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsetregion'> -<funcprototype> - <funcdef><function>XSetRegion</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>GC<parameter> gc</parameter></paramdef> - <paramdef>Region<parameter> r</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>gc</emphasis> - </term> - <listitem> - <para> -Specifies the GC. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSetRegion</function> -function sets the clip-mask in the GC to the specified region. -The region is specified relative to the drawable's origin. -The resulting GC clip origin is implementation-dependent. -Once it is set in the GC, -the region can be destroyed. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To deallocate the storage associated with a specified region, use -<function>XDestroyRegion</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroyregion'> -<funcprototype> - <funcdef><function>XDestroyRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect2> -<sect2 id="Moving_or_Shrinking_Regions"> -<title>Moving or Shrinking Regions</title> -<!-- .XS --> -<!-- (SN Moving or Shrinking Regions --> -<!-- .XE --> -<para> -<!-- .LP --> -To move a region by a specified amount, use -<function>XOffsetRegion</function>. -</para> -<indexterm significance="preferred"><primary>XOffsetRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xoffsetregion'> -<funcprototype> - <funcdef><function>XOffsetRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> - <paramdef>intdx,<parameter> dy</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. -<!-- .ds Dy move --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dx</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dy</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates, -which define the amount you want to (Dy the specified region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To reduce a region by a specified amount, use -<function>XShrinkRegion</function>. -</para> -<indexterm significance="preferred"><primary>XShrinkRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xshrinkregion'> -<funcprototype> - <funcdef><function>XShrinkRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> - <paramdef>intdx,<parameter> dy</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. -<!-- .ds Dy shrink --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dx</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dy</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates, -which define the amount you want to (Dy the specified region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Positive values shrink the size of the region, -and negative values expand the region. -</para> -</sect2> -<sect2 id="Computing_with_Regions"> -<title>Computing with Regions</title> -<!-- .XS --> -<!-- (SN Computing with Regions --> -<!-- .XE --> -<para> -<!-- .LP --> -<!-- .sp --> -To generate the smallest rectangle enclosing a region, use -<function>XClipBox</function>. -</para> -<indexterm significance="preferred"><primary>XClipBox</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xclipbox'> -<funcprototype> - <funcdef><function>XClipBox</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> - <paramdef>XRectangle<parameter> *rect_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rect_return</emphasis> - </term> - <listitem> - <para> -Returns the smallest enclosing rectangle. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XClipBox</function> -function returns the smallest rectangle enclosing the specified region. -<!-- .sp --> -</para> -<para> -<!-- .LP --> -To compute the intersection of two regions, use -<function>XIntersectRegion</function>. -</para> -<indexterm significance="preferred"><primary>XIntersectRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xintersectregion'> -<funcprototype> - <funcdef><function>XIntersectRegion</function></funcdef> - <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>sra</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>srb</emphasis> - </term> - <listitem> - <para> -Specify the two regions with which you want to perform the computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dr_return</emphasis> - </term> - <listitem> - <para> -Returns the result of the computation. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To compute the union of two regions, use -<function>XUnionRegion</function>. -</para> -<indexterm significance="preferred"><primary>XUnionRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunionregion'> -<funcprototype> - <funcdef><function>XUnionRegion</function></funcdef> - <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>sra</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>srb</emphasis> - </term> - <listitem> - <para> -Specify the two regions with which you want to perform the computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dr_return</emphasis> - </term> - <listitem> - <para> -Returns the result of the computation. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -<!-- .sp --> -To create a union of a source region and a rectangle, use -<function>XUnionRectWithRegion</function>. -</para> -<indexterm significance="preferred"><primary>XUnionRectWithRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xunionrectwithregion'> -<funcprototype> - <funcdef><function>XUnionRectWithRegion</function></funcdef> - <paramdef>XRectangle<parameter> *rectangle</parameter></paramdef> - <paramdef>Region<parameter> src_region</parameter></paramdef> - <paramdef>Region<parameter> dest_region_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>rectangle</emphasis> - </term> - <listitem> - <para> -Specifies the rectangle. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>src_region</emphasis> - </term> - <listitem> - <para> -Specifies the source region to be used. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dest_region_return</emphasis> - </term> - <listitem> - <para> -Returns the destination region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XUnionRectWithRegion</function> -function updates the destination region from a union of the specified rectangle -and the specified source region. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To subtract two regions, use -<function>XSubtractRegion</function>. -</para> -<indexterm significance="preferred"><primary>XSubtractRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsubtractregion'> -<funcprototype> - <funcdef><function>XSubtractRegion</function></funcdef> - <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>sra</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>srb</emphasis> - </term> - <listitem> - <para> -Specify the two regions with which you want to perform the computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dr_return</emphasis> - </term> - <listitem> - <para> -Returns the result of the computation. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSubtractRegion</function> -function subtracts srb from sra and stores the results in dr_return. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To calculate the difference between the union and intersection -of two regions, use -<function>XXorRegion</function>. -</para> -<indexterm significance="preferred"><primary>XXorRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xxorregion'> -<funcprototype> - <funcdef><function>XXorRegion</function></funcdef> - <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>sra</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>srb</emphasis> - </term> - <listitem> - <para> -Specify the two regions with which you want to perform the computation. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>dr_return</emphasis> - </term> - <listitem> - <para> -Returns the result of the computation. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -</para> -</sect2> -<sect2 id="Determining_if_Regions_Are_Empty_or_Equal"> -<title>Determining if Regions Are Empty or Equal</title> -<!-- .XS --> -<!-- (SN Determining if Regions Are Empty or Equal --> -<!-- .XE --> -<para> -<!-- .LP --> -To determine if the specified region is empty, use -<function>XEmptyRegion</function>. -</para> -<indexterm significance="preferred"><primary>XEmptyRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xemptyregion'> -<funcprototype> - <funcdef>Bool <function>XEmptyRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XEmptyRegion</function> -function returns -<symbol>True</symbol> -if the region is empty. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To determine if two regions have the same offset, size, and shape, use -<function>XEqualRegion</function>. -</para> -<indexterm significance="preferred"><primary>XEqualRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xequalregion'> -<funcprototype> - <funcdef>Bool <function>XEqualRegion</function></funcdef> - <paramdef>Regionr1,<parameter> r2</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r1</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>r2</emphasis> - </term> - <listitem> - <para> -Specify the two regions. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XEqualRegion</function> -function returns -<symbol>True</symbol> -if the two regions have the same offset, size, and shape. -</para> -</sect2> -<sect2 id="Locating_a_Point_or_a_Rectangle_in_a_Region"> -<title>Locating a Point or a Rectangle in a Region</title> -<!-- .XS --> -<!-- (SN Locating a Point or a Rectangle in a Region --> -<!-- .XE --> -<para> -<!-- .LP --> -To determine if a specified point resides in a specified region, use -<function>XPointInRegion</function>. -</para> -<indexterm significance="preferred"><primary>XPointInRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xpointinregion'> -<funcprototype> - <funcdef>Bool <function>XPointInRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. -<!-- .ds Xy , which define the point --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPointInRegion</function> -function returns -<symbol>True</symbol> -if the point (x, y) is contained in the region r. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To determine if a specified rectangle is inside a region, use -<function>XRectInRegion</function>. -</para> -<indexterm significance="preferred"><primary>XRectInRegion</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrectinregion'> -<funcprototype> - <funcdef>int <function>XRectInRegion</function></funcdef> - <paramdef>Region<parameter> r</parameter></paramdef> - <paramdef>intx,<parameter> y</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>r</emphasis> - </term> - <listitem> - <para> -Specifies the region. -<!-- .ds Xy , which define the coordinates of the upper-left corner of the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates(Xy. -<!-- .ds Wh , which define the rectangle --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height(Wh. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRectInRegion</function> -function returns -<symbol>RectangleIn</symbol> -if the rectangle is entirely in the specified region, -<symbol>RectangleOut</symbol> -if the rectangle is entirely out of the specified region, -and -<symbol>RectanglePart</symbol> -if the rectangle is partially in the specified region. -</para> -</sect2> -</sect1> -<sect1 id="Using_Cut_Buffers"> -<title>Using Cut Buffers</title> -<!-- .XS --> -<!-- (SN Using Cut Buffers --> -<!-- .XE --> -<para> -<!-- .LP --> -<indexterm><primary>Cut Buffers</primary></indexterm> -Xlib provides functions to manipulate cut buffers, -a very simple form of cut-and-paste inter-client communication. -Selections are a much more powerful and useful mechanism for -interchanging data between client -(see <link linkend="Selections">section 4.5</link>) -and generally should be used instead of cut buffers. -</para> -<para> -<!-- .LP --> -Cut buffers are implemented as properties on the first root window -of the display. -The buffers can only contain text, in the STRING encoding. -The text encoding is not changed by Xlib when fetching or storing. -Eight buffers are provided -and can be accessed as a ring or as explicit buffers (numbered 0 through 7). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store data in cut buffer 0, use -<function>XStoreBytes</function>. -</para> -<indexterm significance="preferred"><primary>XStoreBytes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorebytes'> -<funcprototype> - <funcdef><function>XStoreBytes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *bytes</parameter></paramdef> - <paramdef>int<parameter> nbytes</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes</emphasis> - </term> - <listitem> - <para> -Specifies the bytes, which are not necessarily ASCII or null-terminated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes to be stored. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The data can have embedded null characters -and need not be null-terminated. -The cut buffer's contents can be retrieved later by -any client calling -<function>XFetchBytes</function>. -</para> -<para> -<!-- .LP --> -<function>XStoreBytes</function> -can generate a -<errorname>BadAlloc</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To store data in a specified cut buffer, use -<function>XStoreBuffer</function>. -</para> -<indexterm significance="preferred"><primary>XStoreBuffer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xstorebuffer'> -<funcprototype> - <funcdef><function>XStoreBuffer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *bytes</parameter></paramdef> - <paramdef>int<parameter> nbytes</parameter></paramdef> - <paramdef>int<parameter> buffer</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes</emphasis> - </term> - <listitem> - <para> -Specifies the bytes, which are not necessarily ASCII or null-terminated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes to be stored. -<!-- .ds Fn in which you want to store the bytes --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer</emphasis> - </term> - <listitem> - <para> -Specifies the buffer (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If an invalid buffer is specified, the call has no effect. -The data can have embedded null characters -and need not be null-terminated. -</para> -<para> -<!-- .LP --> -<function>XStoreBuffer</function> -can generate a -<errorname>BadAlloc</errorname> -error. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return data from cut buffer 0, use -<function>XFetchBytes</function>. -</para> -<indexterm significance="preferred"><primary>XFetchBytes</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfetchbytes'> -<funcprototype> - <funcdef>char *<function>XFetchBytes</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *nbytes_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes_return</emphasis> - </term> - <listitem> - <para> -Returns the number of bytes in the buffer. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFetchBytes</function> -function -returns the number of bytes in the nbytes_return argument, -if the buffer contains data. -Otherwise, the function -returns NULL and sets nbytes to 0. -The appropriate amount of storage is allocated and the pointer returned. -The client must free this storage when finished with it by calling -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To return data from a specified cut buffer, use -<function>XFetchBuffer</function>. -</para> -<indexterm significance="preferred"><primary>XFetchBuffer</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfetchbuffer'> -<funcprototype> - <funcdef>char *<function>XFetchBuffer</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> *nbytes_return</parameter></paramdef> - <paramdef>int<parameter> buffer</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nbytes_return</emphasis> - </term> - <listitem> - <para> -Returns the number of bytes in the buffer. -<!-- .ds Fn from which you want the stored data returned --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>buffer</emphasis> - </term> - <listitem> - <para> -Specifies the buffer (Fn. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XFetchBuffer</function> -function returns zero to the nbytes_return argument -if there is no data in the buffer or if an invalid -buffer is specified. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To rotate the cut buffers, use -<function>XRotateBuffers</function>. -</para> -<indexterm significance="preferred"><primary>XRotateBuffers</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xrotatebuffers'> -<funcprototype> - <funcdef><function>XRotateBuffers</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> rotate</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rotate</emphasis> - </term> - <listitem> - <para> -Specifies how much to rotate the cut buffers. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XRotateBuffers</function> -function rotates the cut -buffers, such that buffer 0 becomes buffer n, -buffer 1 becomes n + 1 mod 8, and so on. -This cut buffer numbering is global to the display. -Note that -<function>XRotateBuffers</function> -generates -<errorname>BadMatch</errorname> -errors if any of the eight buffers have not been created. -</para> -</sect1> -<sect1 id="Determining_the_Appropriate_Visual_Type"> -<title>Determining the Appropriate Visual Type</title> -<!-- .XS --> -<!-- (SN Determining the Appropriate Visual Type --> -<!-- .XE --> -<para> -<!-- .LP --> -A single display can support multiple screens. -Each screen can have several different visual types supported -at different depths. -You can use the functions described in this section to determine -which visual to use for your application. -</para> -<para> -<!-- .LP --> -The functions in this section use the visual information masks and the -<structname>XVisualInfo</structname> -structure, -which is defined in -<filename class="headerfile"><X11/Xutil.h></filename> -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -and contains: -<!-- .sM --> -</para> -<!-- .LP --> -<literallayout class="monospaced"> - -/* Visual information mask bits */ - - -#define VisualNoMask 0x0 -#define VisualIDMask 0x1 -#define VisualScreenMask 0x2 -#define VisualDepthMask 0x4 -#define VisualClassMask 0x8 -#define VisualRedMaskMask 0x10 -#define VisualGreenMaskMask 0x20 -#define VisualBlueMaskMask 0x40 -#define VisualColormapSizeMask 0x80 -#define VisualBitsPerRGBMask 0x100 -#define VisualAllMask 0x1FF - -</literallayout> - -<literallayout class="monospaced"> -<!-- .TA .5i 3i --> -<!-- .ta .5i 3i --> -/* Values */ - -typedef struct { - Visual *visual; - VisualID visualid; - int screen; - unsigned int depth; - int class; - unsigned long red_mask; - unsigned long green_mask; - unsigned long blue_mask; - int colormap_size; - int bits_per_rgb; -} XVisualInfo; -</literallayout> - -<para> -<!-- .LP --> -<!-- .eM --> -To obtain a list of visual information structures that match a specified -template, use -<function>XGetVisualInfo</function>. -</para> -<indexterm significance="preferred"><primary>XGetVisualInfo</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetvisualinfo'> -<funcprototype> - <funcdef>XVisualInfo *<function>XGetVisualInfo</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>long<parameter> vinfo_mask</parameter></paramdef> - <paramdef>XVisualInfo<parameter> *vinfo_template</parameter></paramdef> - <paramdef>int<parameter> *nitems_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vinfo_mask</emphasis> - </term> - <listitem> - <para> -Specifies the visual mask value. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vinfo_template</emphasis> - </term> - <listitem> - <para> -Specifies the visual attributes that are to be used in matching the visual -structures. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>nitems_return</emphasis> - </term> - <listitem> - <para> -Returns the number of matching visual structures. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetVisualInfo</function> -function returns a list of visual structures that have attributes -equal to the attributes specified by vinfo_template. -If no visual structures match the template using the specified vinfo_mask, -<function>XGetVisualInfo</function> -returns a NULL. -To free the data returned by this function, use -<function>XFree</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain the visual information that matches the specified depth and -class of the screen, use -<function>XMatchVisualInfo</function>. -</para> -<indexterm significance="preferred"><primary>XMatchVisualInfo</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xmatchvisualinfo'> -<funcprototype> - <funcdef>Status <function>XMatchVisualInfo</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>int<parameter> screen</parameter></paramdef> - <paramdef>int<parameter> depth</parameter></paramdef> - <paramdef>int<parameter> class</parameter></paramdef> - <paramdef>XVisualInfo<parameter> *vinfo_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>screen</emphasis> - </term> - <listitem> - <para> -Specifies the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth</emphasis> - </term> - <listitem> - <para> -Specifies the depth of the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>class</emphasis> - </term> - <listitem> - <para> -Specifies the class of the screen. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>vinfo_return</emphasis> - </term> - <listitem> - <para> -Returns the matched visual information. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XMatchVisualInfo</function> -function returns the visual information for a visual that matches the specified -depth and class for a screen. -Because multiple visuals that match the specified depth and class can exist, -the exact visual chosen is undefined. -If a visual is found, -<function>XMatchVisualInfo</function> -returns nonzero and the information on the visual to vinfo_return. -Otherwise, when a visual is not found, -<function>XMatchVisualInfo</function> -returns zero. -</para> -</sect1> -<sect1 id="Manipulating_Images"> -<title>Manipulating Images</title> -<!-- .XS --> -<!-- (SN Manipulating Images --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides several functions that perform basic operations on images. -All operations on images are defined using an -<structname>XImage</structname> -structure, -as defined in -<filename class="headerfile"><X11/Xlib.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm> -Because the number of different types of image formats can be very large, -this hides details of image storage properly from applications. -</para> -<para> -<!-- .LP --> -This section describes the functions for generic operations on images. -Manufacturers can provide very fast implementations of these for the -formats frequently encountered on their hardware. -These functions are neither sufficient nor desirable to use for general image -processing. -Rather, they are here to provide minimal functions on screen format -images. -The basic operations for getting and putting images are -<function>XGetImage</function> -and -<function>XPutImage</function>. -</para> -<para> -<!-- .LP --> -Note that no functions have been defined, as yet, to read and write images -to and from disk files. -</para> -<para> -<!-- .LP --> -The -<structname>XImage</structname> -structure describes an image as it exists in the client's memory. -The user can request that some of the members such as height, width, -and xoffset be changed when the image is sent to the server. -Note that bytes_per_line in concert with offset can be used to -extract a subset of the image. -Other members (for example, byte order, bitmap_unit, and so forth) -are characteristics of both the image and the server. -If these members -differ between the image and the server, -<function>XPutImage</function> -makes the appropriate conversions. -The first byte of the first line of -plane n must be located at the address (data + (n * height * bytes_per_line)). -For a description of the -<structname>XImage</structname> -structure, -see <link linkend="Transferring_Images_between_Client_and_Server">section 8.7</link>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To allocate an -<structname>XImage</structname> -structure and initialize it with image format values from a display, use -<function>XCreateImage</function>. -</para> -<indexterm significance="preferred"><primary>XCreateImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreateimage'> -<funcprototype> - <funcdef>XImage *<function>XCreateImage</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Visual<parameter> *visual</parameter></paramdef> - <paramdef>unsignedint<parameter> depth</parameter></paramdef> - <paramdef>int<parameter> format</parameter></paramdef> - <paramdef>int<parameter> offset</parameter></paramdef> - <paramdef>char<parameter> *data</parameter></paramdef> - <paramdef>unsignedint<parameter> width</parameter></paramdef> - <paramdef>unsignedint<parameter> height</parameter></paramdef> - <paramdef>int<parameter> bitmap_pad</parameter></paramdef> - <paramdef>int<parameter> bytes_per_line</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>visual</emphasis> - </term> - <listitem> - <para> -Specifies the -<structname>Visual</structname> -structure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth</emphasis> - </term> - <listitem> - <para> -Specifies the depth of the image. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>format</emphasis> - </term> - <listitem> - <para> -Specifies the format for the image. -You can pass -<symbol>XYBitmap</symbol>, -<symbol>XYPixmap</symbol>, -or -<symbol>ZPixmap</symbol>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>offset</emphasis> - </term> - <listitem> - <para> -Specifies the number of pixels to ignore at the beginning of the scanline. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the image data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -Specifies the width of the image, in pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specifies the height of the image, in pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bitmap_pad</emphasis> - </term> - <listitem> - <para> -Specifies the quantum of a scanline (8, 16, or 32). -In other words, the start of one scanline is separated in client memory from -the start of the next scanline by an integer multiple of this many bits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bytes_per_line</emphasis> - </term> - <listitem> - <para> -Specifies the number of bytes in the client image between -the start of one scanline and the start of the next. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateImage</function> -function allocates the memory needed for an -<structname>XImage</structname> -structure for the -specified display but does not allocate space for the image itself. -Rather, it initializes the structure byte-order, bit-order, and bitmap-unit -values from the display and returns a pointer to the -<structname>XImage</structname> -structure. -The red, green, and blue mask values are defined for Z format images only -and are derived from the -<structname>Visual</structname> -structure passed in. -Other values also are passed in. -The offset permits the rapid displaying of the image without requiring each -scanline to be shifted into position. -If you pass a zero value in bytes_per_line, -Xlib assumes that the scanlines are contiguous -in memory and calculates the value of bytes_per_line itself. -</para> -<para> -<!-- .LP --> -Note that when the image is created using -<function>XCreateImage</function>, -<function>XGetImage</function>, -or -<function>XSubImage</function>, -the destroy procedure that the -<function>XDestroyImage</function> -function calls frees both the image structure -and the data pointed to by the image structure. -</para> -<para> -<!-- .LP --> -The basic functions used to get a pixel, set a pixel, create a subimage, -and add a constant value to an image are defined in the image object. -The functions in this section are really macro invocations of the functions -in the image object and are defined in -<filename class="headerfile"><X11/Xutil.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To obtain a pixel value in an image, use -<function>XGetPixel</function>. -</para> -<indexterm significance="preferred"><primary>XGetPixel</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xgetpixel'> -<funcprototype> - <funcdef>unsigned long <function>XGetPixel</function></funcdef> - <paramdef>XImage<parameter> *ximage</parameter></paramdef> - <paramdef>int<parameter> x</parameter></paramdef> - <paramdef>int<parameter> y</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XGetPixel</function> -function returns the specified pixel from the named image. -The pixel value is returned in normalized format (that is, -the least significant byte of the long is the least significant byte -of the pixel). -The image must contain the x and y coordinates. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To set a pixel value in an image, use -<function>XPutPixel</function>. -</para> -<indexterm significance="preferred"><primary>XPutPixel</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xputpixel'> -<funcprototype> - <funcdef><function>XPutPixel</function></funcdef> - <paramdef>XImage<parameter> *ximage</parameter></paramdef> - <paramdef>int<parameter> x</parameter></paramdef> - <paramdef>int<parameter> y</parameter></paramdef> - <paramdef>unsignedlong<parameter> pixel</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>pixel</emphasis> - </term> - <listitem> - <para> -Specifies the new pixel value. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XPutPixel</function> -function overwrites the pixel in the named image with the specified pixel value. -The input pixel value must be in normalized format -(that is, the least significant byte of the long is the least significant -byte of the pixel). -The image must contain the x and y coordinates. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a subimage, use -<function>XSubImage</function>. -</para> -<indexterm significance="preferred"><primary>XSubImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsubimage'> -<funcprototype> - <funcdef>XImage *<function>XSubImage</function></funcdef> - <paramdef>XImage<parameter> *ximage</parameter></paramdef> - <paramdef>int<parameter> x</parameter></paramdef> - <paramdef>int<parameter> y</parameter></paramdef> - <paramdef>unsignedint<parameter> subimage_width</parameter></paramdef> - <paramdef>unsignedint<parameter> subimage_height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y</emphasis> - </term> - <listitem> - <para> -Specify the x and y coordinates. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>subimage_width</emphasis> - </term> - <listitem> - <para> -Specifies the width of the new subimage, in pixels. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>subimage_height</emphasis> - </term> - <listitem> - <para> -Specifies the height of the new subimage, in pixels. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XSubImage</function> -function creates a new image that is a subsection of an existing one. -It allocates the memory necessary for the new -<structname>XImage</structname> -structure -and returns a pointer to the new image. -The data is copied from the source image, -and the image must contain the rectangle defined by x, y, subimage_width, -and subimage_height. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To increment each pixel in an image by a constant value, use -<function>XAddPixel</function>. -</para> -<indexterm significance="preferred"><primary>XAddPixel</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xaddpixel'> -<funcprototype> - <funcdef><function>XAddPixel</function></funcdef> - <paramdef>XImage<parameter> *ximage</parameter></paramdef> - <paramdef>long<parameter> value</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>value</emphasis> - </term> - <listitem> - <para> -Specifies the constant value that is to be added. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XAddPixel</function> -function adds a constant value to every pixel in an image. -It is useful when you have a base pixel value from allocating -color resources and need to manipulate the image to that form. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To deallocate the memory allocated in a previous call to -<function>XCreateImage</function>, -use -<function>XDestroyImage</function>. -</para> -<indexterm significance="preferred"><primary>XDestroyImage</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdestroyimage'> -<funcprototype> - <funcdef><function>XDestroyImage</function></funcdef> - <paramdef>XImage *<parameter>ximage</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>ximage</emphasis> - </term> - <listitem> - <para> -Specifies the image. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDestroyImage</function> -function deallocates the memory associated with the -<structname>XImage</structname> -structure. -</para> -<para> -<!-- .LP --> -Note that when the image is created using -<function>XCreateImage</function>, -<function>XGetImage</function>, -or -<function>XSubImage</function>, -the destroy procedure that this macro calls -frees both the image structure and the data pointed to by the image structure. -</para> -</sect1> -<sect1 id="Manipulating_Bitmaps"> -<title>Manipulating Bitmaps</title> -<!-- .XS --> -<!-- (SN Manipulating Bitmaps --> -<!-- .XE --> -<para> -<!-- .LP --> -Xlib provides functions that you can use to read a bitmap from a file, -save a bitmap to a file, or create a bitmap. -This section describes those functions that transfer bitmaps to and -from the client's file system, thus allowing their reuse in a later -connection (for example, from an entirely different client or to a -different display or server). -</para> -<para> -<!-- .LP --> -The X version 11 bitmap file format is: -</para> -<para> -<!-- .LP --> -<!-- .sM --> -<literallayout class="monospaced"> -#define <emphasis remap='I'>name</emphasis>_width <emphasis remap='I'>width</emphasis> -#define <emphasis remap='I'>name</emphasis>_height <emphasis remap='I'>height</emphasis> -#define <emphasis remap='I'>name</emphasis>_x_hot <emphasis remap='I'>x</emphasis> -#define <emphasis remap='I'>name</emphasis>_y_hot <emphasis remap='I'>y</emphasis> -static unsigned char <emphasis remap='I'>name</emphasis>_bits[] = { 0x<emphasis remap='I'>NN</emphasis>,... } -</literallayout> -</para> -<para> -<!-- .LP --> -<!-- .eM --> -The lines for the variables ending with _x_hot and _y_hot suffixes are optional -because they are present only if a hotspot has been defined for this bitmap. -The lines for the other variables are required. -The word ``unsigned'' is optional; -that is, the type of the _bits array can be ``char'' or ``unsigned char''. -The _bits array must be large enough to contain the size bitmap. -The bitmap unit is 8. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a bitmap from a file and store it in a pixmap, use -<function>XReadBitmapFile</function>. -</para> -<indexterm significance="preferred"><primary>XReadBitmapFile</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xreadbitmapfile'> -<funcprototype> - <funcdef>int <function>XReadBitmapFile</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>char<parameter> *filename</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> - <paramdef>Pixmap<parameter> *bitmap_return</parameter></paramdef> - <paramdef>int*x_hot_return,<parameter> *y_hot_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Dr \ that indicates the screen --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable(Dr. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>filename</emphasis> - </term> - <listitem> - <para> -Specifies the file name to use. -The format of the file name is operating-system dependent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height values of the read in bitmap file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bitmap_return</emphasis> - </term> - <listitem> - <para> -Returns the bitmap that is created. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_hot_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_hot_return</emphasis> - </term> - <listitem> - <para> -Return the hotspot coordinates. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XReadBitmapFile</function> -function reads in a file containing a bitmap. -The file is parsed in the encoding of the current locale. -The ability to read other than the standard format -is implementation-dependent. -If the file cannot be opened, -<function>XReadBitmapFile</function> -returns -<returnvalue>BitmapOpenFailed</returnvalue>. -If the file can be opened but does not contain valid bitmap data, -it returns -<returnvalue>BitmapFileInvalid</returnvalue>. -If insufficient working storage is allocated, -it returns -<returnvalue>BitmapNoMemory</returnvalue>. -If the file is readable and valid, -it returns -<returnvalue>BitmapSuccess</returnvalue>. -</para> -<para> -<!-- .LP --> -<function>XReadBitmapFile</function> -returns the bitmap's height and width, as read -from the file, to width_return and height_return. -It then creates a pixmap of the appropriate size, -reads the bitmap data from the file into the pixmap, -and assigns the pixmap to the caller's variable bitmap. -The caller must free the bitmap using -<function>XFreePixmap</function> -when finished. -If <emphasis remap='I'>name</emphasis>_x_hot and <emphasis remap='I'>name</emphasis>_y_hot exist, -<function>XReadBitmapFile</function> -returns them to x_hot_return and y_hot_return; -otherwise, it returns −1,−1. -</para> -<para> -<!-- .LP --> -<function>XReadBitmapFile</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadDrawable</errorname>, -and -<errorname>BadGC</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To read a bitmap from a file and return it as data, use -<function>XReadBitmapFileData</function>. -</para> -<indexterm significance="preferred"><primary>XReadBitmapFileData</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xreadbitmapfiledata'> -<funcprototype> - <funcdef>int <function>XReadBitmapFileData</function></funcdef> - <paramdef>char<parameter> *filename</parameter></paramdef> - <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef> - <paramdef>unsignedchar<parameter> *data_return</parameter></paramdef> - <paramdef>int*x_hot_return,<parameter> *y_hot_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>filename</emphasis> - </term> - <listitem> - <para> -Specifies the file name to use. -The format of the file name is operating-system dependent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height_return</emphasis> - </term> - <listitem> - <para> -Return the width and height values of the read in bitmap file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Returns the bitmap data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_hot_return</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_hot_return</emphasis> - </term> - <listitem> - <para> -Return the hotspot coordinates. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XReadBitmapFileData</function> -function reads in a file containing a bitmap, in the same manner as -<function>XReadBitmapFile</function>, -but returns the data directly rather than creating a pixmap in the server. -The bitmap data is returned in data_return; the client must free this -storage when finished with it by calling -<function>XFree</function>. -The status and other return values are the same as for -<function>XReadBitmapFile</function>. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To write out a bitmap from a pixmap to a file, use -<function>XWriteBitmapFile</function>. -</para> -<indexterm significance="preferred"><primary>XWriteBitmapFile</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xwritebitmapfile'> -<funcprototype> - <funcdef>int <function>XWriteBitmapFile</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>char<parameter> *filename</parameter></paramdef> - <paramdef>Pixmap<parameter> bitmap</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>intx_hot,<parameter> y_hot</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>filename</emphasis> - </term> - <listitem> - <para> -Specifies the file name to use. -The format of the file name is operating-system dependent. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bitmap</emphasis> - </term> - <listitem> - <para> -Specifies the bitmap. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>x_hot</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>y_hot</emphasis> - </term> - <listitem> - <para> -Specify where to place the hotspot coordinates (or −1,−1 if none are present) -in the file. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XWriteBitmapFile</function> -function writes a bitmap out to a file in the X Version 11 format. -The name used in the output file is derived from the file name -by deleting the directory prefix. -The file is written in the encoding of the current locale. -If the file cannot be opened for writing, -it returns -<returnvalue>BitmapOpenFailed</returnvalue>. -If insufficient memory is allocated, -<function>XWriteBitmapFile</function> -returns -<returnvalue>BitmapNoMemory</returnvalue>; -otherwise, on no error, -it returns -<returnvalue>BitmapSuccess</returnvalue>. -If x_hot and y_hot are not −1, −1, -<function>XWriteBitmapFile</function> -writes them out as the hotspot coordinates for the bitmap. -</para> -<para> -<!-- .LP --> -<function>XWriteBitmapFile</function> -can generate -<errorname>BadDrawable</errorname> -and -<errorname>BadMatch</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a pixmap and then store bitmap-format data into it, use -<function>XCreatePixmapFromBitmapData</function>. -</para> -<indexterm significance="preferred"><primary>XCreatePixmapFromBitmapData</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatepixmapfrombitmapdata'> -<funcprototype> - <funcdef>Pixmap <function>XCreatePixmapFromBitmapData</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>char<parameter> *data</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> - <paramdef>unsignedlongfg,<parameter> bg</parameter></paramdef> - <paramdef>unsignedint<parameter> depth</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Dr \ that indicates the screen --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable(Dr. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the data in bitmap format. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>fg</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>bg</emphasis> - </term> - <listitem> - <para> -Specify the foreground and background pixel values to use. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>depth</emphasis> - </term> - <listitem> - <para> -Specifies the depth of the pixmap. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreatePixmapFromBitmapData</function> -function creates a pixmap of the given depth and then does a bitmap-format -<function>XPutImage</function> -of the data into it. -The depth must be supported by the screen of the specified drawable, -or a -<errorname>BadMatch</errorname> -error results. -</para> -<para> -<!-- .LP --> -<function>XCreatePixmapFromBitmapData</function> -can generate -<errorname>BadAlloc</errorname>, -<errorname>BadDrawable</errorname>, -<errorname>BadGC</errorname>, -and -<errorname>BadValue</errorname> -errors. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To include a bitmap written out by -<function>XWriteBitmapFile</function> -<indexterm><primary>XWriteBitmapFile</primary></indexterm> -in a program directly, as opposed to reading it in every time at run time, use -<function>XCreateBitmapFromData</function>. -</para> -<indexterm significance="preferred"><primary>XCreateBitmapFromData</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xcreatebitmapfromdata'> -<funcprototype> - <funcdef>Pixmap <function>XCreateBitmapFromData</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>Drawable<parameter> d</parameter></paramdef> - <paramdef>char<parameter> *data</parameter></paramdef> - <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. -<!-- .ds Dr \ that indicates the screen --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>d</emphasis> - </term> - <listitem> - <para> -Specifies the drawable(Dr. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the location of the bitmap data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>width</emphasis> - </term> - <listitem> - <para> -<!-- .br --> -<!-- .ns --> - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>height</emphasis> - </term> - <listitem> - <para> -Specify the width and height. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XCreateBitmapFromData</function> -function allows you to include in your C program (using -<code>#include</code>) -a bitmap file that was written out by -<function>XWriteBitmapFile</function> -(X version 11 format only) without reading in the bitmap file. -The following example creates a gray bitmap: -</para> -<para> -<!-- .LP --> -<literallayout class="monospaced"> -#include "gray.bitmap" -<!-- .sp 6p --> -Pixmap bitmap; -bitmap = XCreateBitmapFromData(display, window, gray_bits, gray_width, gray_height); -</literallayout> -</para> -<para> -<!-- .LP --> -If insufficient working storage was allocated, -<function>XCreateBitmapFromData</function> -returns -<symbol>None</symbol>. -It is your responsibility to free the -bitmap using -<function>XFreePixmap</function> -when finished. -</para> -<para> -<!-- .LP --> -<function>XCreateBitmapFromData</function> -can generate -<errorname>BadAlloc</errorname> -and -<errorname>BadGC</errorname> -errors. -</para> -</sect1> -<sect1 id="Using_the_Context_Manager"> -<title>Using the Context Manager</title> -<!-- .XS --> -<!-- (SN Using the Context Manager --> -<!-- .XE --> -<para> -<!-- .LP --> -The context manager provides a way of associating data with an X resource ID -(mostly typically a window) in your program. -Note that this is local to your program; -the data is not stored in the server on a property list. -Any amount of data in any number of pieces can be associated with a -resource ID, -and each piece of data has a type associated with it. -The context manager requires knowledge of the resource ID -and type to store or retrieve data. -</para> -<para> -<!-- .LP --> -Essentially, the context manager can be viewed as a two-dimensional, -sparse array: one dimension is subscripted by the X resource ID -and the other by a context type field. -Each entry in the array contains a pointer to the data. -Xlib provides context management functions with which you can -save data values, get data values, delete entries, and create a unique -context type. -The symbols used are in -<filename class="headerfile"><X11/Xutil.h></filename>. -<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm> -<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm> -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To save a data value that corresponds to a resource ID and context type, use -<function>XSaveContext</function>. -</para> -<indexterm significance="preferred"><primary>XSaveContext</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xsavecontext'> -<funcprototype> - <funcdef>int <function>XSaveContext</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> rid</parameter></paramdef> - <paramdef>XContext<parameter> context</parameter></paramdef> - <paramdef>XPointer<parameter> data</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rid</emphasis> - </term> - <listitem> - <para> -Specifies the resource ID with which the data is associated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>context</emphasis> - </term> - <listitem> - <para> -Specifies the context type to which the data belongs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data</emphasis> - </term> - <listitem> - <para> -Specifies the data to be associated with the window and type. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -If an entry with the specified resource ID and type already exists, -<function>XSaveContext</function> -overrides it with the specified context. -The -<function>XSaveContext</function> -function returns a nonzero error code if an error has occurred -and zero otherwise. -Possible errors are -<symbol>XCNOMEM</symbol> -(out of memory). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To get the data associated with a resource ID and type, use -<function>XFindContext</function>. -</para> -<indexterm significance="preferred"><primary>XFindContext</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xfindcontext'> -<funcprototype> - <funcdef>int <function>XFindContext</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> rid</parameter></paramdef> - <paramdef>XContext<parameter> context</parameter></paramdef> - <paramdef>XPointer<parameter> *data_return</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rid</emphasis> - </term> - <listitem> - <para> -Specifies the resource ID with which the data is associated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>context</emphasis> - </term> - <listitem> - <para> -Specifies the context type to which the data belongs. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>data_return</emphasis> - </term> - <listitem> - <para> -Returns the data. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -Because it is a return value, -the data is a pointer. -The -<function>XFindContext</function> -function returns a nonzero error code if an error has occurred -and zero otherwise. -Possible errors are -<symbol>XCNOENT</symbol> -(context-not-found). -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To delete an entry for a given resource ID and type, use -<function>XDeleteContext</function>. -</para> -<indexterm significance="preferred"><primary>XDeleteContext</primary></indexterm> -<!-- .sM --> -<funcsynopsis id='xdeletecontext'> -<funcprototype> - <funcdef>int <function>XDeleteContext</function></funcdef> - <paramdef>Display<parameter> *display</parameter></paramdef> - <paramdef>XID<parameter> rid</parameter></paramdef> - <paramdef>XContext<parameter> context</parameter></paramdef> -</funcprototype> -</funcsynopsis> -<!-- .FN --> -<variablelist> - <varlistentry> - <term> - <emphasis remap='I'>display</emphasis> - </term> - <listitem> - <para> -Specifies the connection to the X server. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>rid</emphasis> - </term> - <listitem> - <para> -Specifies the resource ID with which the data is associated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <emphasis remap='I'>context</emphasis> - </term> - <listitem> - <para> -Specifies the context type to which the data belongs. - </para> - </listitem> - </varlistentry> -</variablelist> -<para> -<!-- .LP --> -<!-- .eM --> -The -<function>XDeleteContext</function> -function deletes the entry for the given resource ID -and type from the data structure. -This function returns the same error codes that -<function>XFindContext</function> -returns if called with the same arguments. -<function>XDeleteContext</function> -does not free the data whose address was saved. -</para> -<para> -<!-- .LP --> -<!-- .sp --> -To create a unique context type that may be used in subsequent calls to -<function>XSaveContext</function> -and -<function>XFindContext</function>, -use -<function>XUniqueContext</function>. -</para> -<para>XContext XuniqueContext()</para> - -</sect1> -</chapter> +<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+<chapter id="application_utility_functions">
+<title>Application Utility Functions</title>
+<!-- .sp 2 -->
+<!-- .nr H1 16 -->
+<!-- .nr H2 0 -->
+<!-- .nr H3 0 -->
+<!-- .nr H4 0 -->
+<!-- .nr H5 0 -->
+<!-- .na -->
+<para>
+<!-- .LP -->
+<!-- .XS -->
+<!-- Chapter 16: Application Utility Functions -->
+<!-- .XE -->
+Once you have initialized the X system,
+you can use the Xlib utility functions to:
+</para>
+<itemizedlist>
+ <listitem>
+ <para>
+Use keyboard utility functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use Latin-1 keyboard event functions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Allocate permanent storage
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Parse the window geometry
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Manipulate regions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use cut buffers
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determine the appropriate visual type
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Manipulate images
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Manipulate bitmaps
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Use the context manager
+ </para>
+ </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+As a group,
+the functions discussed in this chapter provide the functionality that
+is frequently needed and that spans toolkits.
+Many of these functions do not generate actual protocol requests to the server.
+</para>
+<sect1 id="Using_Keyboard_Utility_Functions">
+<title>Using Keyboard Utility Functions</title>
+<!-- .XS -->
+<!-- (SN Using Keyboard Utility Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+This section discusses mapping between KeyCodes and KeySyms,
+classifying KeySyms, and mapping between KeySyms and string names.
+The first three functions in this section operate on a cached copy of the
+server keyboard mapping.
+The first four KeySyms for each KeyCode
+are modified according to the rules given in section 12.7.
+To obtain the untransformed KeySyms defined for a key,
+use the functions described in section 12.7.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a KeySym for the KeyCode of an event, use
+<function>XLookupKeysym</function>.
+</para>
+<indexterm significance="preferred"><primary>XLookupKeysym</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlookupkeysym'>
+<funcprototype>
+ <funcdef>KeySym <function>XLookupKeysym</function></funcdef>
+ <paramdef>XKeyEvent<parameter> *key_event</parameter></paramdef>
+ <paramdef>int<parameter> index</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>key_event</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<symbol>KeyPress</symbol>
+or
+<symbol>KeyRelease</symbol>
+event.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>index</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the index into the KeySyms list for the event's KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLookupKeysym</function>
+function uses a given keyboard event and the index you specified to return
+the KeySym from the list that corresponds to the KeyCode member in the
+<type>XKeyPressedEvent</type>
+or
+<type>XKeyReleasedEvent</type>
+structure.
+If no KeySym is defined for the KeyCode of the event,
+<function>XLookupKeysym</function>
+returns
+<symbol>NoSymbol</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a KeySym for a specific KeyCode, use
+<function>XKeycodeToKeysym</function>.
+</para>
+<indexterm significance="preferred"><primary>XKeycodeToKeysym</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xkeycodetokeysym'>
+<funcprototype>
+ <funcdef>KeySym <function>XKeycodeToKeysym</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>KeyCode<parameter> keycode</parameter></paramdef>
+ <paramdef>int<parameter> index</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keycode</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeyCode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>index</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the element of KeyCode vector.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XKeycodeToKeysym</function>
+function uses internal Xlib tables
+and returns the KeySym defined for the specified KeyCode and
+the element of the KeyCode vector.
+If no symbol is defined,
+<function>XKeycodeToKeysym</function>
+returns
+<symbol>NoSymbol</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a KeyCode for a key having a specific KeySym, use
+<function>XKeysymToKeycode</function>.
+</para>
+<indexterm significance="preferred"><primary>XKeysymToKeycode</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xkeysymtokeycode'>
+<funcprototype>
+ <funcdef>KeyCode <function>XKeysymToKeycode</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>KeySym<parameter> keysym</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be searched for.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If the specified KeySym is not defined for any KeyCode,
+<function>XKeysymToKeycode</function>
+returns zero.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+The mapping between KeyCodes and KeySyms is cached internal to Xlib.
+When this information is changed at the server, an Xlib function must
+be called to refresh the cache.
+To refresh the stored modifier and keymap information, use
+<function>XRefreshKeyboardMapping</function>.
+</para>
+<indexterm significance="preferred"><primary>XRefreshKeyboardMapping</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrefreshkeyboardmapping'>
+<funcprototype>
+ <funcdef><function>XRefreshKeyboardMapping</function></funcdef>
+ <paramdef>XMappingEvent<parameter> *event_map</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_map</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the mapping event that is to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRefreshKeyboardMapping</function>
+function refreshes the stored modifier and keymap information.
+You usually call this function when a
+<symbol>MappingNotify</symbol>
+event with a request member of
+<symbol>MappingKeyboard</symbol>
+or
+<symbol>MappingModifier</symbol>
+occurs.
+The result is to update Xlib's knowledge of the keyboard.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the uppercase and lowercase forms of a KeySym, use
+<function>XConvertCase</function>.
+</para>
+<indexterm significance="preferred"><primary>XConvertCase</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xconvertcase'>
+<funcprototype>
+ <funcdef>void <function>XConvertCase</function></funcdef>
+ <paramdef>KeySym<parameter> keysym</parameter></paramdef>
+ <paramdef>KeySym<parameter> *lower_return</parameter></paramdef>
+ <paramdef>KeySym<parameter> *upper_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Fn converted -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>lower_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the lowercase form of keysym, or keysym.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>upper_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the uppercase form of keysym, or keysym.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XConvertCase</function>
+function returns the uppercase and lowercase forms of the specified Keysym,
+if the KeySym is subject to case conversion;
+otherwise, the specified KeySym is returned to both lower_return and
+upper_return.
+Support for conversion of other than Latin and Cyrillic KeySyms is
+implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+KeySyms have string names as well as numeric codes.
+To convert the name of the KeySym to the KeySym code, use
+<function>XStringToKeysym</function>.
+</para>
+<indexterm significance="preferred"><primary>XStringToKeysym</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstringtokeysym'>
+<funcprototype>
+ <funcdef>KeySym <function>XStringToKeysym</function></funcdef>
+ <paramdef>char<parameter> *string</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the name of the KeySym that is to be converted.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Standard KeySym names are obtained from
+<filename class="headerfile"><X11/keysymdef.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/keysymdef.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/keysymdef.h></filename></secondary></indexterm>
+by removing the XK_ prefix from each name.
+KeySyms that are not part of the Xlib standard also may be obtained
+with this function.
+The set of KeySyms that are available in this manner
+and the mechanisms by which Xlib obtains them is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+If the KeySym name is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+If the specified string does not match a valid KeySym,
+<function>XStringToKeysym</function>
+returns
+<symbol>NoSymbol</symbol>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To convert a KeySym code to the name of the KeySym, use
+<function>XKeysymToString</function>.
+</para>
+<indexterm significance="preferred"><primary>XKeysymToString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xkeysymtostring'>
+<funcprototype>
+ <funcdef>char *<function>XKeysymToString</function></funcdef>
+ <paramdef>KeySym<parameter> keysym</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<!-- .ds Fn converted -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The returned string is in a static area and must not be modified.
+The returned string is in the Host Portable Character Encoding.
+If the specified KeySym is not defined,
+<function>XKeysymToString</function>
+returns a NULL.
+</para>
+<sect2 id="KeySym_Classification_Macros">
+<title>KeySym Classification Macros</title>
+<!-- .XS -->
+<!-- (SN KeySym Classification Macros -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+You may want to test if a KeySym is, for example,
+on the keypad or on one of the function keys.
+You can use KeySym macros to perform the following tests.
+</para>
+<para>IsCursorKey(<emphasis remap='I'>keysym</emphasis>)</para>
+<!-- .FN -->
+<!-- .ds Fn tested -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be tested.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsCursorKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a cursor key.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<para>IsFunctionKey(<emphasis remap='I'>keysym</emphasis>)</para>
+<!-- .FN -->
+<!-- .ds Fn tested -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be tested.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsFunctionKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a function key.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<para>IsKeypadKey(<emphasis remap='I'>keysym</emphasis>)</para>
+<!-- .FN -->
+<!-- .ds Fn tested -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsKeypadKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a standard keypad key.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<para>IsPrivateKeypadKey(<emphasis remap='I'>keysym</emphasis>)</para>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsPrivateKeypadKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a vendor-private keypad key.
+</para>
+
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<para>IsMiscFunctionKey(<emphasis remap='I'>keysym</emphasis>)</para>
+<!-- .FN -->
+<!-- .ds Fn tested -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsMiscFunctionKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a miscellaneous function key.
+</para>
+<!-- .LP -->
+<!-- .sp -->
+<!-- .sM -->
+<para>IsModifierKey(<emphasis remap='I'>keysym</emphasis>)</para>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be tested.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsModifierKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a modifier key.
+</para>
+
+<para>IsPFKey(<emphasis remap='I'>keysym</emphasis>)</para>
+
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be tested.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<indexterm significance="preferred"><primary>IsPFKey</primary></indexterm>
+Returns
+<symbol>True</symbol>
+if the specified KeySym is a PF key.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Using_Latin_Keyboard_Event_Functions">
+<title>Using Latin-1 Keyboard Event Functions</title>
+<!-- .XS -->
+<!-- (SN Using Latin-1 Keyboard Event Functions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<link linkend="locales_and_internationalized_text_functions">Chapter 13</link>
+describes internationalized text input facilities,
+but sometimes it is expedient to write an application that
+only deals with Latin-1 characters and ASCII controls,
+so Xlib provides a simple function for that purpose.
+<function>XLookupString</function>
+handles the standard modifier semantics described in section 12.7.
+This function does not use any of the input method facilities
+described in chapter 13 and does not depend on the current locale.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To map a key event to an ISO Latin-1 string, use
+<function>XLookupString</function>.
+</para>
+<indexterm significance="preferred"><primary>XLookupString</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xlookupstring'>
+<funcprototype>
+ <funcdef>int <function>XLookupString</function></funcdef>
+ <paramdef>XKeyEvent<parameter> *event_struct</parameter></paramdef>
+ <paramdef>char<parameter> *buffer_return</parameter></paramdef>
+ <paramdef>int<parameter> bytes_buffer</parameter></paramdef>
+ <paramdef>KeySym<parameter> *keysym_return</parameter></paramdef>
+ <paramdef>XComposeStatus<parameter> *status_in_out</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>event_struct</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the key event structure to be used.
+You can pass
+<type>XKeyPressedEvent</type>
+or
+<type>XKeyReleasedEvent</type>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the translated characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes_buffer</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the length of the buffer.
+No more than bytes_buffer of translation are returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the KeySym computed from the event if this argument is not NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>status_in_out</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies or returns the
+<structname>XComposeStatus</structname>
+structure or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XLookupString</function>
+function translates a key event to a KeySym and a string.
+The KeySym is obtained by using the standard interpretation of the
+<symbol>Shift</symbol>,
+<symbol>Lock</symbol>,
+group, and numlock modifiers as defined in the X Protocol specification.
+If the KeySym has been rebound (see
+<function>XRebindKeysym</function>),
+the bound string will be stored in the buffer.
+Otherwise, the KeySym is mapped, if possible, to an ISO Latin-1 character
+or (if the Control modifier is on) to an ASCII control character,
+and that character is stored in the buffer.
+<function>XLookupString</function>
+returns the number of characters that are stored in the buffer.
+</para>
+<para>
+<!-- .LP -->
+If present (non-NULL),
+the
+<structname>XComposeStatus</structname>
+structure records the state,
+which is private to Xlib,
+that needs preservation across calls to
+<function>XLookupString</function>
+to implement compose processing.
+The creation of
+<structname>XComposeStatus</structname>
+structures is implementation-dependent;
+a portable program must pass NULL for this argument.
+</para>
+<para>
+<!-- .LP -->
+<function>XLookupString</function>
+depends on the cached keyboard information mentioned in the
+previous section, so it is necessary to use
+<function>XRefreshKeyboardMapping</function>
+to keep this information up-to-date.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To rebind the meaning of a KeySym for
+<function>XLookupString</function>,
+use
+<function>XRebindKeysym</function>.
+</para>
+<indexterm significance="preferred"><primary>XRebindKeysym</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrebindkeysym'>
+<funcprototype>
+ <funcdef><function>XRebindKeysym</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>KeySym<parameter> keysym</parameter></paramdef>
+ <paramdef>KeySym<parameter> list[ ]</parameter></paramdef>
+ <paramdef>int<parameter> mod_count</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> *string</parameter></paramdef>
+ <paramdef>int<parameter> num_bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Fn rebound -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>keysym</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySym that is to be (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>list</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the KeySyms to be used as modifiers.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>mod_count</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of modifiers in the modifier list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>string</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string that is copied and will be returned by
+<function>XLookupString</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>num_bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the string argument.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRebindKeysym</function>
+function can be used to rebind the meaning of a KeySym for the client.
+It does not redefine any key in the X server but merely
+provides an easy way for long strings to be attached to keys.
+<function>XLookupString</function>
+returns this string when the appropriate set of
+modifier keys are pressed and when the KeySym would have been used for
+the translation.
+No text conversions are performed;
+the client is responsible for supplying appropriately encoded strings.
+Note that you can rebind a KeySym that may not exist.
+</para>
+</sect1>
+<sect1 id="Allocating_Permanent_Storage">
+<title>Allocating Permanent Storage</title>
+<!-- .XS -->
+<!-- (SN Allocating Permanent Storage -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To allocate some memory you will never give back, use
+<function>Xpermalloc</function>.
+<indexterm significance="preferred"><primary>Xpermalloc</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpermalloc'>
+<funcprototype>
+ <funcdef>char *<function>Xpermalloc</function></funcdef>
+ <paramdef>unsignedint<parameter> size</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>Xpermalloc</function>
+function allocates storage that can never be freed for the life of the
+program. The memory is allocated with alignment for the C type double.
+This function may provide some performance and space savings over
+the standard operating system memory allocator.
+</para>
+</sect1>
+<sect1 id="Parsing_the_Window_Geometry">
+<title>Parsing the Window Geometry</title>
+<!-- .XS -->
+<!-- (SN Parsing the Window Geometry -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To parse standard window geometry strings, use
+<function>XParseGeometry</function>.
+<indexterm><primary>Window</primary><secondary>determining location</secondary></indexterm>
+<indexterm significance="preferred"><primary>XParseGeometry</primary></indexterm>
+</para>
+<!-- .LP -->
+<!-- .sM -->
+<funcsynopsis id='xparsegeometry'>
+<funcprototype>
+ <funcdef>int <function>XParseGeometry</function></funcdef>
+ <paramdef>char<parameter> *parsestring</parameter></paramdef>
+ <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>parsestring</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the string you want to parse.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the x and y offsets.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height determined.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+By convention,
+X applications use a standard string to indicate window size and placement.
+<function>XParseGeometry</function>
+makes it easier to conform to this standard because it allows you
+to parse the standard window geometry.
+Specifically, this function lets you parse strings of the form:
+</para>
+<para>
+<!-- .LP -->
+<!-- .\" Start marker code here -->
+<literallayout class="monospaced">
+[=][<<emphasis remap='I'>width</emphasis>>{xX}<<emphasis remap='I'>height</emphasis>>][{+-}<<emphasis remap='I'>xoffset</emphasis>>{+-}<<emphasis remap='I'>yoffset</emphasis>>]
+</literallayout>
+<!-- .\" End marker code here -->
+</para>
+<para>
+<!-- .LP -->
+The fields map into the arguments associated with this function.
+(Items enclosed in < > are integers, items in [ ] are optional, and
+items enclosed in { } indicate ``choose one of.''
+Note that the brackets should not appear in the actual string.)
+If the string is not in the Host Portable Character Encoding,
+the result is implementation-dependent.
+</para>
+<para>
+<!-- .LP -->
+The
+<function>XParseGeometry</function>
+function returns a bitmask that indicates which of the four values (width,
+height, xoffset, and yoffset) were actually found in the string
+and whether the x and y values are negative.
+By convention, −0 is not equal to +0, because the user needs to
+be able to say ``position the window relative to the right or bottom edge.''
+For each value found, the corresponding argument is updated.
+For each value not found, the argument is left unchanged.
+The bits are represented by
+<symbol>XValue</symbol>,
+<symbol>YValue</symbol>,
+<symbol>WidthValue</symbol>,
+<symbol>HeightValue</symbol>,
+<symbol>XNegative</symbol>,
+or
+<symbol>YNegative</symbol>
+and are defined in
+<filename class="headerfile"><X11/Xutil.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+They will be set whenever one of the values is defined
+or one of the signs is set.
+</para>
+<para>
+<!-- .LP -->
+If the function returns either the
+<symbol>XValue</symbol>
+or
+<symbol>YValue</symbol>
+flag,
+you should place the window at the requested position.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To construct a window's geometry information, use
+<function>XWMGeometry</function>.
+</para>
+<indexterm significance="preferred"><primary>XWMGeometry</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwmgeometry'>
+<funcprototype>
+ <funcdef>int <function>XWMGeometry</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen</parameter></paramdef>
+ <paramdef>char<parameter> *user_geom</parameter></paramdef>
+ <paramdef>char<parameter> *def_geom</parameter></paramdef>
+ <paramdef>unsignedint<parameter> bwidth</parameter></paramdef>
+ <paramdef>XSizeHints<parameter> *hints</parameter></paramdef>
+ <paramdef>int*x_return,<parameter> *y_return</parameter></paramdef>
+ <paramdef>int<parameter> *width_return</parameter></paramdef>
+ <paramdef>int<parameter> *height_return</parameter></paramdef>
+ <paramdef>int<parameter> *gravity_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>user_geom</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the user-specified geometry or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>def_geom</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the application's default geometry or NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bwidth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the border width.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>hints</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the size hints for the window in its normal state.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the x and y offsets.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height determined.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gravity_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the window gravity.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XWMGeometry</function>
+function combines any geometry information (given in the format used by
+<function>XParseGeometry</function>)
+specified by the user and by the calling program with size hints
+(usually the ones to be stored in <property>WM_NORMAL_HINTS</property>) and returns the position,
+size, and gravity
+(<symbol>NorthWestGravity</symbol>,
+<symbol>NorthEastGravity</symbol>,
+<symbol>SouthEastGravity</symbol>,
+or
+<symbol>SouthWestGravity</symbol>)
+that describe the window.
+If the base size is not set in the
+<structname>XSizeHints</structname>
+structure,
+the minimum size is used if set.
+Otherwise, a base size of zero is assumed.
+If no minimum size is set in the hints structure,
+the base size is used.
+A mask (in the form returned by
+<function>XParseGeometry</function>)
+that describes which values came from the user specification
+and whether or not the position coordinates are relative
+to the right and bottom edges is returned.
+Note that these coordinates will have already been accounted for
+in the x_return and y_return values.
+</para>
+<para>
+<!-- .LP -->
+Note that invalid geometry specifications can cause a width or height
+of zero to be returned.
+The caller may pass the address of the hints win_gravity field
+as gravity_return to update the hints directly.
+</para>
+</sect1>
+
+<sect1 id="Manipulating_Regions">
+<title>Manipulating Regions</title>
+<!-- .XS -->
+<!-- (SN Manipulating Regions -->
+<!-- .XE -->
+<para>
+Regions are arbitrary sets of pixel locations.
+Xlib provides functions for manipulating regions.
+The opaque type
+<structname>Region</structname>
+is defined in
+<filename class="headerfile"><X11/Xutil.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+Xlib provides functions that you can use to manipulate regions.
+This section discusses how to:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+Create, copy, or destroy regions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Move or shrink regions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Compute with regions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Determine if regions are empty or equal
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Locate a point or rectangle in a region
+ </para>
+ </listitem>
+</itemizedlist>
+
+<sect2 id="Creating_Copying_or_Destroying_Regions">
+<title>Creating, Copying, or Destroying Regions</title>
+<!-- .XS -->
+<!-- (SN Creating, Copying, or Destroying Regions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To create a new empty region, use
+<function>XCreateRegion</function>.
+</para>
+<para>Region XCreateRegion()</para>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To generate a region from a polygon, use
+<function>XPolygonRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XPolygonRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpolygonregion'>
+<funcprototype>
+ <funcdef>Region <function>XPolygonRegion</function></funcdef>
+ <paramdef>XPoint<parameter> points[]</parameter></paramdef>
+ <paramdef>int<parameter> n</parameter></paramdef>
+ <paramdef>int<parameter> fill_rule</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>points</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies an array of points.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>n</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of points in the polygon.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fill_rule</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the fill-rule you want to set for the specified GC.
+You can pass
+<symbol>EvenOddRule</symbol>
+or
+<symbol>WindingRule</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPolygonRegion</function>
+function returns a region for the polygon defined by the points array.
+For an explanation of fill_rule,
+see
+<function>XCreateGC</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set the clip-mask of a GC to a region, use
+<function>XSetRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XSetRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsetregion'>
+<funcprototype>
+ <funcdef><function>XSetRegion</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>GC<parameter> gc</parameter></paramdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>gc</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the GC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSetRegion</function>
+function sets the clip-mask in the GC to the specified region.
+The region is specified relative to the drawable's origin.
+The resulting GC clip origin is implementation-dependent.
+Once it is set in the GC,
+the region can be destroyed.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To deallocate the storage associated with a specified region, use
+<function>XDestroyRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroyregion'>
+<funcprototype>
+ <funcdef><function>XDestroyRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect2>
+<sect2 id="Moving_or_Shrinking_Regions">
+<title>Moving or Shrinking Regions</title>
+<!-- .XS -->
+<!-- (SN Moving or Shrinking Regions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To move a region by a specified amount, use
+<function>XOffsetRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XOffsetRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xoffsetregion'>
+<funcprototype>
+ <funcdef><function>XOffsetRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+ <paramdef>intdx,<parameter> dy</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+<!-- .ds Dy move -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dx</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dy</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates,
+which define the amount you want to (Dy the specified region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To reduce a region by a specified amount, use
+<function>XShrinkRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XShrinkRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xshrinkregion'>
+<funcprototype>
+ <funcdef><function>XShrinkRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+ <paramdef>intdx,<parameter> dy</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+<!-- .ds Dy shrink -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dx</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dy</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates,
+which define the amount you want to (Dy the specified region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Positive values shrink the size of the region,
+and negative values expand the region.
+</para>
+</sect2>
+<sect2 id="Computing_with_Regions">
+<title>Computing with Regions</title>
+<!-- .XS -->
+<!-- (SN Computing with Regions -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To generate the smallest rectangle enclosing a region, use
+<function>XClipBox</function>.
+</para>
+<indexterm significance="preferred"><primary>XClipBox</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xclipbox'>
+<funcprototype>
+ <funcdef><function>XClipBox</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+ <paramdef>XRectangle<parameter> *rect_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rect_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the smallest enclosing rectangle.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XClipBox</function>
+function returns the smallest rectangle enclosing the specified region.
+<!-- .sp -->
+</para>
+<para>
+<!-- .LP -->
+To compute the intersection of two regions, use
+<function>XIntersectRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XIntersectRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xintersectregion'>
+<funcprototype>
+ <funcdef><function>XIntersectRegion</function></funcdef>
+ <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>sra</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>srb</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the two regions with which you want to perform the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dr_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the result of the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To compute the union of two regions, use
+<function>XUnionRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnionRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunionregion'>
+<funcprototype>
+ <funcdef><function>XUnionRegion</function></funcdef>
+ <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>sra</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>srb</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the two regions with which you want to perform the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dr_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the result of the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+<!-- .sp -->
+To create a union of a source region and a rectangle, use
+<function>XUnionRectWithRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XUnionRectWithRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xunionrectwithregion'>
+<funcprototype>
+ <funcdef><function>XUnionRectWithRegion</function></funcdef>
+ <paramdef>XRectangle<parameter> *rectangle</parameter></paramdef>
+ <paramdef>Region<parameter> src_region</parameter></paramdef>
+ <paramdef>Region<parameter> dest_region_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rectangle</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the rectangle.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>src_region</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the source region to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dest_region_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the destination region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XUnionRectWithRegion</function>
+function updates the destination region from a union of the specified rectangle
+and the specified source region.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To subtract two regions, use
+<function>XSubtractRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XSubtractRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsubtractregion'>
+<funcprototype>
+ <funcdef><function>XSubtractRegion</function></funcdef>
+ <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>sra</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>srb</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the two regions with which you want to perform the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dr_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the result of the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSubtractRegion</function>
+function subtracts srb from sra and stores the results in dr_return.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To calculate the difference between the union and intersection
+of two regions, use
+<function>XXorRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XXorRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xxorregion'>
+<funcprototype>
+ <funcdef><function>XXorRegion</function></funcdef>
+ <paramdef>Regionsra,srb,<parameter> dr_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>sra</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>srb</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the two regions with which you want to perform the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>dr_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the result of the computation.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+</para>
+</sect2>
+<sect2 id="Determining_if_Regions_Are_Empty_or_Equal">
+<title>Determining if Regions Are Empty or Equal</title>
+<!-- .XS -->
+<!-- (SN Determining if Regions Are Empty or Equal -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To determine if the specified region is empty, use
+<function>XEmptyRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XEmptyRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xemptyregion'>
+<funcprototype>
+ <funcdef>Bool <function>XEmptyRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XEmptyRegion</function>
+function returns
+<symbol>True</symbol>
+if the region is empty.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To determine if two regions have the same offset, size, and shape, use
+<function>XEqualRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XEqualRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xequalregion'>
+<funcprototype>
+ <funcdef>Bool <function>XEqualRegion</function></funcdef>
+ <paramdef>Regionr1,<parameter> r2</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r1</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r2</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the two regions.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XEqualRegion</function>
+function returns
+<symbol>True</symbol>
+if the two regions have the same offset, size, and shape.
+</para>
+</sect2>
+<sect2 id="Locating_a_Point_or_a_Rectangle_in_a_Region">
+<title>Locating a Point or a Rectangle in a Region</title>
+<!-- .XS -->
+<!-- (SN Locating a Point or a Rectangle in a Region -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+To determine if a specified point resides in a specified region, use
+<function>XPointInRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XPointInRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xpointinregion'>
+<funcprototype>
+ <funcdef>Bool <function>XPointInRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+<!-- .ds Xy , which define the point -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPointInRegion</function>
+function returns
+<symbol>True</symbol>
+if the point (x, y) is contained in the region r.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To determine if a specified rectangle is inside a region, use
+<function>XRectInRegion</function>.
+</para>
+<indexterm significance="preferred"><primary>XRectInRegion</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrectinregion'>
+<funcprototype>
+ <funcdef>int <function>XRectInRegion</function></funcdef>
+ <paramdef>Region<parameter> r</parameter></paramdef>
+ <paramdef>intx,<parameter> y</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>r</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the region.
+<!-- .ds Xy , which define the coordinates of the upper-left corner of the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates(Xy.
+<!-- .ds Wh , which define the rectangle -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height(Wh.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRectInRegion</function>
+function returns
+<symbol>RectangleIn</symbol>
+if the rectangle is entirely in the specified region,
+<symbol>RectangleOut</symbol>
+if the rectangle is entirely out of the specified region,
+and
+<symbol>RectanglePart</symbol>
+if the rectangle is partially in the specified region.
+</para>
+</sect2>
+</sect1>
+<sect1 id="Using_Cut_Buffers">
+<title>Using Cut Buffers</title>
+<!-- .XS -->
+<!-- (SN Using Cut Buffers -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+<indexterm><primary>Cut Buffers</primary></indexterm>
+Xlib provides functions to manipulate cut buffers,
+a very simple form of cut-and-paste inter-client communication.
+Selections are a much more powerful and useful mechanism for
+interchanging data between client
+(see <link linkend="Selections">section 4.5</link>)
+and generally should be used instead of cut buffers.
+</para>
+<para>
+<!-- .LP -->
+Cut buffers are implemented as properties on the first root window
+of the display.
+The buffers can only contain text, in the STRING encoding.
+The text encoding is not changed by Xlib when fetching or storing.
+Eight buffers are provided
+and can be accessed as a ring or as explicit buffers (numbered 0 through 7).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store data in cut buffer 0, use
+<function>XStoreBytes</function>.
+</para>
+<indexterm significance="preferred"><primary>XStoreBytes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorebytes'>
+<funcprototype>
+ <funcdef><function>XStoreBytes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *bytes</parameter></paramdef>
+ <paramdef>int<parameter> nbytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the bytes, which are not necessarily ASCII or null-terminated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes to be stored.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The data can have embedded null characters
+and need not be null-terminated.
+The cut buffer's contents can be retrieved later by
+any client calling
+<function>XFetchBytes</function>.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreBytes</function>
+can generate a
+<errorname>BadAlloc</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To store data in a specified cut buffer, use
+<function>XStoreBuffer</function>.
+</para>
+<indexterm significance="preferred"><primary>XStoreBuffer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xstorebuffer'>
+<funcprototype>
+ <funcdef><function>XStoreBuffer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *bytes</parameter></paramdef>
+ <paramdef>int<parameter> nbytes</parameter></paramdef>
+ <paramdef>int<parameter> buffer</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the bytes, which are not necessarily ASCII or null-terminated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes to be stored.
+<!-- .ds Fn in which you want to store the bytes -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If an invalid buffer is specified, the call has no effect.
+The data can have embedded null characters
+and need not be null-terminated.
+</para>
+<para>
+<!-- .LP -->
+<function>XStoreBuffer</function>
+can generate a
+<errorname>BadAlloc</errorname>
+error.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return data from cut buffer 0, use
+<function>XFetchBytes</function>.
+</para>
+<indexterm significance="preferred"><primary>XFetchBytes</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfetchbytes'>
+<funcprototype>
+ <funcdef>char *<function>XFetchBytes</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *nbytes_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of bytes in the buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFetchBytes</function>
+function
+returns the number of bytes in the nbytes_return argument,
+if the buffer contains data.
+Otherwise, the function
+returns NULL and sets nbytes to 0.
+The appropriate amount of storage is allocated and the pointer returned.
+The client must free this storage when finished with it by calling
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To return data from a specified cut buffer, use
+<function>XFetchBuffer</function>.
+</para>
+<indexterm significance="preferred"><primary>XFetchBuffer</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfetchbuffer'>
+<funcprototype>
+ <funcdef>char *<function>XFetchBuffer</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> *nbytes_return</parameter></paramdef>
+ <paramdef>int<parameter> buffer</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nbytes_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of bytes in the buffer.
+<!-- .ds Fn from which you want the stored data returned -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>buffer</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the buffer (Fn.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XFetchBuffer</function>
+function returns zero to the nbytes_return argument
+if there is no data in the buffer or if an invalid
+buffer is specified.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To rotate the cut buffers, use
+<function>XRotateBuffers</function>.
+</para>
+<indexterm significance="preferred"><primary>XRotateBuffers</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xrotatebuffers'>
+<funcprototype>
+ <funcdef><function>XRotateBuffers</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> rotate</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rotate</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies how much to rotate the cut buffers.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XRotateBuffers</function>
+function rotates the cut
+buffers, such that buffer 0 becomes buffer n,
+buffer 1 becomes n + 1 mod 8, and so on.
+This cut buffer numbering is global to the display.
+Note that
+<function>XRotateBuffers</function>
+generates
+<errorname>BadMatch</errorname>
+errors if any of the eight buffers have not been created.
+</para>
+</sect1>
+<sect1 id="Determining_the_Appropriate_Visual_Type">
+<title>Determining the Appropriate Visual Type</title>
+<!-- .XS -->
+<!-- (SN Determining the Appropriate Visual Type -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+A single display can support multiple screens.
+Each screen can have several different visual types supported
+at different depths.
+You can use the functions described in this section to determine
+which visual to use for your application.
+</para>
+<para>
+<!-- .LP -->
+The functions in this section use the visual information masks and the
+<structname>XVisualInfo</structname>
+structure,
+which is defined in
+<filename class="headerfile"><X11/Xutil.h></filename>
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+and contains:
+<!-- .sM -->
+</para>
+<!-- .LP -->
+<literallayout class="monospaced">
+
+/* Visual information mask bits */
+
+
+#define VisualNoMask 0x0
+#define VisualIDMask 0x1
+#define VisualScreenMask 0x2
+#define VisualDepthMask 0x4
+#define VisualClassMask 0x8
+#define VisualRedMaskMask 0x10
+#define VisualGreenMaskMask 0x20
+#define VisualBlueMaskMask 0x40
+#define VisualColormapSizeMask 0x80
+#define VisualBitsPerRGBMask 0x100
+#define VisualAllMask 0x1FF
+
+</literallayout>
+
+<literallayout class="monospaced">
+<!-- .TA .5i 3i -->
+<!-- .ta .5i 3i -->
+/* Values */
+
+typedef struct {
+ Visual *visual;
+ VisualID visualid;
+ int screen;
+ unsigned int depth;
+ int class;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int colormap_size;
+ int bits_per_rgb;
+} XVisualInfo;
+</literallayout>
+
+<para>
+<!-- .LP -->
+<!-- .eM -->
+To obtain a list of visual information structures that match a specified
+template, use
+<function>XGetVisualInfo</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetVisualInfo</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetvisualinfo'>
+<funcprototype>
+ <funcdef>XVisualInfo *<function>XGetVisualInfo</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>long<parameter> vinfo_mask</parameter></paramdef>
+ <paramdef>XVisualInfo<parameter> *vinfo_template</parameter></paramdef>
+ <paramdef>int<parameter> *nitems_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vinfo_mask</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the visual mask value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vinfo_template</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the visual attributes that are to be used in matching the visual
+structures.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>nitems_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the number of matching visual structures.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetVisualInfo</function>
+function returns a list of visual structures that have attributes
+equal to the attributes specified by vinfo_template.
+If no visual structures match the template using the specified vinfo_mask,
+<function>XGetVisualInfo</function>
+returns a NULL.
+To free the data returned by this function, use
+<function>XFree</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain the visual information that matches the specified depth and
+class of the screen, use
+<function>XMatchVisualInfo</function>.
+</para>
+<indexterm significance="preferred"><primary>XMatchVisualInfo</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xmatchvisualinfo'>
+<funcprototype>
+ <funcdef>Status <function>XMatchVisualInfo</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>int<parameter> screen</parameter></paramdef>
+ <paramdef>int<parameter> depth</parameter></paramdef>
+ <paramdef>int<parameter> class</parameter></paramdef>
+ <paramdef>XVisualInfo<parameter> *vinfo_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>screen</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the depth of the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>class</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the class of the screen.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>vinfo_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the matched visual information.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XMatchVisualInfo</function>
+function returns the visual information for a visual that matches the specified
+depth and class for a screen.
+Because multiple visuals that match the specified depth and class can exist,
+the exact visual chosen is undefined.
+If a visual is found,
+<function>XMatchVisualInfo</function>
+returns nonzero and the information on the visual to vinfo_return.
+Otherwise, when a visual is not found,
+<function>XMatchVisualInfo</function>
+returns zero.
+</para>
+</sect1>
+<sect1 id="Manipulating_Images">
+<title>Manipulating Images</title>
+<!-- .XS -->
+<!-- (SN Manipulating Images -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides several functions that perform basic operations on images.
+All operations on images are defined using an
+<structname>XImage</structname>
+structure,
+as defined in
+<filename class="headerfile"><X11/Xlib.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xlib.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xlib.h></filename></secondary></indexterm>
+Because the number of different types of image formats can be very large,
+this hides details of image storage properly from applications.
+</para>
+<para>
+<!-- .LP -->
+This section describes the functions for generic operations on images.
+Manufacturers can provide very fast implementations of these for the
+formats frequently encountered on their hardware.
+These functions are neither sufficient nor desirable to use for general image
+processing.
+Rather, they are here to provide minimal functions on screen format
+images.
+The basic operations for getting and putting images are
+<function>XGetImage</function>
+and
+<function>XPutImage</function>.
+</para>
+<para>
+<!-- .LP -->
+Note that no functions have been defined, as yet, to read and write images
+to and from disk files.
+</para>
+<para>
+<!-- .LP -->
+The
+<structname>XImage</structname>
+structure describes an image as it exists in the client's memory.
+The user can request that some of the members such as height, width,
+and xoffset be changed when the image is sent to the server.
+Note that bytes_per_line in concert with offset can be used to
+extract a subset of the image.
+Other members (for example, byte order, bitmap_unit, and so forth)
+are characteristics of both the image and the server.
+If these members
+differ between the image and the server,
+<function>XPutImage</function>
+makes the appropriate conversions.
+The first byte of the first line of
+plane n must be located at the address (data + (n * height * bytes_per_line)).
+For a description of the
+<structname>XImage</structname>
+structure,
+see <link linkend="Transferring_Images_between_Client_and_Server">section 8.7</link>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To allocate an
+<structname>XImage</structname>
+structure and initialize it with image format values from a display, use
+<function>XCreateImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreateimage'>
+<funcprototype>
+ <funcdef>XImage *<function>XCreateImage</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Visual<parameter> *visual</parameter></paramdef>
+ <paramdef>unsignedint<parameter> depth</parameter></paramdef>
+ <paramdef>int<parameter> format</parameter></paramdef>
+ <paramdef>int<parameter> offset</parameter></paramdef>
+ <paramdef>char<parameter> *data</parameter></paramdef>
+ <paramdef>unsignedint<parameter> width</parameter></paramdef>
+ <paramdef>unsignedint<parameter> height</parameter></paramdef>
+ <paramdef>int<parameter> bitmap_pad</parameter></paramdef>
+ <paramdef>int<parameter> bytes_per_line</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>visual</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the
+<structname>Visual</structname>
+structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the depth of the image.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>format</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the format for the image.
+You can pass
+<symbol>XYBitmap</symbol>,
+<symbol>XYPixmap</symbol>,
+or
+<symbol>ZPixmap</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>offset</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of pixels to ignore at the beginning of the scanline.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the width of the image, in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the height of the image, in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bitmap_pad</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the quantum of a scanline (8, 16, or 32).
+In other words, the start of one scanline is separated in client memory from
+the start of the next scanline by an integer multiple of this many bits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bytes_per_line</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the number of bytes in the client image between
+the start of one scanline and the start of the next.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateImage</function>
+function allocates the memory needed for an
+<structname>XImage</structname>
+structure for the
+specified display but does not allocate space for the image itself.
+Rather, it initializes the structure byte-order, bit-order, and bitmap-unit
+values from the display and returns a pointer to the
+<structname>XImage</structname>
+structure.
+The red, green, and blue mask values are defined for Z format images only
+and are derived from the
+<structname>Visual</structname>
+structure passed in.
+Other values also are passed in.
+The offset permits the rapid displaying of the image without requiring each
+scanline to be shifted into position.
+If you pass a zero value in bytes_per_line,
+Xlib assumes that the scanlines are contiguous
+in memory and calculates the value of bytes_per_line itself.
+</para>
+<para>
+<!-- .LP -->
+Note that when the image is created using
+<function>XCreateImage</function>,
+<function>XGetImage</function>,
+or
+<function>XSubImage</function>,
+the destroy procedure that the
+<function>XDestroyImage</function>
+function calls frees both the image structure
+and the data pointed to by the image structure.
+</para>
+<para>
+<!-- .LP -->
+The basic functions used to get a pixel, set a pixel, create a subimage,
+and add a constant value to an image are defined in the image object.
+The functions in this section are really macro invocations of the functions
+in the image object and are defined in
+<filename class="headerfile"><X11/Xutil.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To obtain a pixel value in an image, use
+<function>XGetPixel</function>.
+</para>
+<indexterm significance="preferred"><primary>XGetPixel</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xgetpixel'>
+<funcprototype>
+ <funcdef>unsigned long <function>XGetPixel</function></funcdef>
+ <paramdef>XImage<parameter> *ximage</parameter></paramdef>
+ <paramdef>int<parameter> x</parameter></paramdef>
+ <paramdef>int<parameter> y</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XGetPixel</function>
+function returns the specified pixel from the named image.
+The pixel value is returned in normalized format (that is,
+the least significant byte of the long is the least significant byte
+of the pixel).
+The image must contain the x and y coordinates.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To set a pixel value in an image, use
+<function>XPutPixel</function>.
+</para>
+<indexterm significance="preferred"><primary>XPutPixel</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xputpixel'>
+<funcprototype>
+ <funcdef><function>XPutPixel</function></funcdef>
+ <paramdef>XImage<parameter> *ximage</parameter></paramdef>
+ <paramdef>int<parameter> x</parameter></paramdef>
+ <paramdef>int<parameter> y</parameter></paramdef>
+ <paramdef>unsignedlong<parameter> pixel</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>pixel</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the new pixel value.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XPutPixel</function>
+function overwrites the pixel in the named image with the specified pixel value.
+The input pixel value must be in normalized format
+(that is, the least significant byte of the long is the least significant
+byte of the pixel).
+The image must contain the x and y coordinates.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a subimage, use
+<function>XSubImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XSubImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsubimage'>
+<funcprototype>
+ <funcdef>XImage *<function>XSubImage</function></funcdef>
+ <paramdef>XImage<parameter> *ximage</parameter></paramdef>
+ <paramdef>int<parameter> x</parameter></paramdef>
+ <paramdef>int<parameter> y</parameter></paramdef>
+ <paramdef>unsignedint<parameter> subimage_width</parameter></paramdef>
+ <paramdef>unsignedint<parameter> subimage_height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the x and y coordinates.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>subimage_width</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the width of the new subimage, in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>subimage_height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the height of the new subimage, in pixels.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XSubImage</function>
+function creates a new image that is a subsection of an existing one.
+It allocates the memory necessary for the new
+<structname>XImage</structname>
+structure
+and returns a pointer to the new image.
+The data is copied from the source image,
+and the image must contain the rectangle defined by x, y, subimage_width,
+and subimage_height.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To increment each pixel in an image by a constant value, use
+<function>XAddPixel</function>.
+</para>
+<indexterm significance="preferred"><primary>XAddPixel</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xaddpixel'>
+<funcprototype>
+ <funcdef><function>XAddPixel</function></funcdef>
+ <paramdef>XImage<parameter> *ximage</parameter></paramdef>
+ <paramdef>long<parameter> value</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>value</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the constant value that is to be added.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XAddPixel</function>
+function adds a constant value to every pixel in an image.
+It is useful when you have a base pixel value from allocating
+color resources and need to manipulate the image to that form.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To deallocate the memory allocated in a previous call to
+<function>XCreateImage</function>,
+use
+<function>XDestroyImage</function>.
+</para>
+<indexterm significance="preferred"><primary>XDestroyImage</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdestroyimage'>
+<funcprototype>
+ <funcdef><function>XDestroyImage</function></funcdef>
+ <paramdef>XImage *<parameter>ximage</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>ximage</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the image.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDestroyImage</function>
+function deallocates the memory associated with the
+<structname>XImage</structname>
+structure.
+</para>
+<para>
+<!-- .LP -->
+Note that when the image is created using
+<function>XCreateImage</function>,
+<function>XGetImage</function>,
+or
+<function>XSubImage</function>,
+the destroy procedure that this macro calls
+frees both the image structure and the data pointed to by the image structure.
+</para>
+</sect1>
+<sect1 id="Manipulating_Bitmaps">
+<title>Manipulating Bitmaps</title>
+<!-- .XS -->
+<!-- (SN Manipulating Bitmaps -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+Xlib provides functions that you can use to read a bitmap from a file,
+save a bitmap to a file, or create a bitmap.
+This section describes those functions that transfer bitmaps to and
+from the client's file system, thus allowing their reuse in a later
+connection (for example, from an entirely different client or to a
+different display or server).
+</para>
+<para>
+<!-- .LP -->
+The X version 11 bitmap file format is:
+</para>
+<para>
+<!-- .LP -->
+<!-- .sM -->
+<literallayout class="monospaced">
+#define <emphasis remap='I'>name</emphasis>_width <emphasis remap='I'>width</emphasis>
+#define <emphasis remap='I'>name</emphasis>_height <emphasis remap='I'>height</emphasis>
+#define <emphasis remap='I'>name</emphasis>_x_hot <emphasis remap='I'>x</emphasis>
+#define <emphasis remap='I'>name</emphasis>_y_hot <emphasis remap='I'>y</emphasis>
+static unsigned char <emphasis remap='I'>name</emphasis>_bits[] = { 0x<emphasis remap='I'>NN</emphasis>,... }
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The lines for the variables ending with _x_hot and _y_hot suffixes are optional
+because they are present only if a hotspot has been defined for this bitmap.
+The lines for the other variables are required.
+The word ``unsigned'' is optional;
+that is, the type of the _bits array can be ``char'' or ``unsigned char''.
+The _bits array must be large enough to contain the size bitmap.
+The bitmap unit is 8.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a bitmap from a file and store it in a pixmap, use
+<function>XReadBitmapFile</function>.
+</para>
+<indexterm significance="preferred"><primary>XReadBitmapFile</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xreadbitmapfile'>
+<funcprototype>
+ <funcdef>int <function>XReadBitmapFile</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>char<parameter> *filename</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+ <paramdef>Pixmap<parameter> *bitmap_return</parameter></paramdef>
+ <paramdef>int*x_hot_return,<parameter> *y_hot_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Dr \ that indicates the screen -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable(Dr.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>filename</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the file name to use.
+The format of the file name is operating-system dependent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height values of the read in bitmap file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bitmap_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the bitmap that is created.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_hot_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_hot_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the hotspot coordinates.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XReadBitmapFile</function>
+function reads in a file containing a bitmap.
+The file is parsed in the encoding of the current locale.
+The ability to read other than the standard format
+is implementation-dependent.
+If the file cannot be opened,
+<function>XReadBitmapFile</function>
+returns
+<returnvalue>BitmapOpenFailed</returnvalue>.
+If the file can be opened but does not contain valid bitmap data,
+it returns
+<returnvalue>BitmapFileInvalid</returnvalue>.
+If insufficient working storage is allocated,
+it returns
+<returnvalue>BitmapNoMemory</returnvalue>.
+If the file is readable and valid,
+it returns
+<returnvalue>BitmapSuccess</returnvalue>.
+</para>
+<para>
+<!-- .LP -->
+<function>XReadBitmapFile</function>
+returns the bitmap's height and width, as read
+from the file, to width_return and height_return.
+It then creates a pixmap of the appropriate size,
+reads the bitmap data from the file into the pixmap,
+and assigns the pixmap to the caller's variable bitmap.
+The caller must free the bitmap using
+<function>XFreePixmap</function>
+when finished.
+If <emphasis remap='I'>name</emphasis>_x_hot and <emphasis remap='I'>name</emphasis>_y_hot exist,
+<function>XReadBitmapFile</function>
+returns them to x_hot_return and y_hot_return;
+otherwise, it returns −1,−1.
+</para>
+<para>
+<!-- .LP -->
+<function>XReadBitmapFile</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadDrawable</errorname>,
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To read a bitmap from a file and return it as data, use
+<function>XReadBitmapFileData</function>.
+</para>
+<indexterm significance="preferred"><primary>XReadBitmapFileData</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xreadbitmapfiledata'>
+<funcprototype>
+ <funcdef>int <function>XReadBitmapFileData</function></funcdef>
+ <paramdef>char<parameter> *filename</parameter></paramdef>
+ <paramdef>unsignedint*width_return,<parameter> *height_return</parameter></paramdef>
+ <paramdef>unsignedchar<parameter> *data_return</parameter></paramdef>
+ <paramdef>int*x_hot_return,<parameter> *y_hot_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>filename</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the file name to use.
+The format of the file name is operating-system dependent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the width and height values of the read in bitmap file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the bitmap data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_hot_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_hot_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Return the hotspot coordinates.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XReadBitmapFileData</function>
+function reads in a file containing a bitmap, in the same manner as
+<function>XReadBitmapFile</function>,
+but returns the data directly rather than creating a pixmap in the server.
+The bitmap data is returned in data_return; the client must free this
+storage when finished with it by calling
+<function>XFree</function>.
+The status and other return values are the same as for
+<function>XReadBitmapFile</function>.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To write out a bitmap from a pixmap to a file, use
+<function>XWriteBitmapFile</function>.
+</para>
+<indexterm significance="preferred"><primary>XWriteBitmapFile</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xwritebitmapfile'>
+<funcprototype>
+ <funcdef>int <function>XWriteBitmapFile</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>char<parameter> *filename</parameter></paramdef>
+ <paramdef>Pixmap<parameter> bitmap</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>intx_hot,<parameter> y_hot</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>filename</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the file name to use.
+The format of the file name is operating-system dependent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bitmap</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the bitmap.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>x_hot</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>y_hot</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify where to place the hotspot coordinates (or −1,−1 if none are present)
+in the file.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XWriteBitmapFile</function>
+function writes a bitmap out to a file in the X Version 11 format.
+The name used in the output file is derived from the file name
+by deleting the directory prefix.
+The file is written in the encoding of the current locale.
+If the file cannot be opened for writing,
+it returns
+<returnvalue>BitmapOpenFailed</returnvalue>.
+If insufficient memory is allocated,
+<function>XWriteBitmapFile</function>
+returns
+<returnvalue>BitmapNoMemory</returnvalue>;
+otherwise, on no error,
+it returns
+<returnvalue>BitmapSuccess</returnvalue>.
+If x_hot and y_hot are not −1, −1,
+<function>XWriteBitmapFile</function>
+writes them out as the hotspot coordinates for the bitmap.
+</para>
+<para>
+<!-- .LP -->
+<function>XWriteBitmapFile</function>
+can generate
+<errorname>BadDrawable</errorname>
+and
+<errorname>BadMatch</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a pixmap and then store bitmap-format data into it, use
+<function>XCreatePixmapFromBitmapData</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreatePixmapFromBitmapData</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatepixmapfrombitmapdata'>
+<funcprototype>
+ <funcdef>Pixmap <function>XCreatePixmapFromBitmapData</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>char<parameter> *data</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+ <paramdef>unsignedlongfg,<parameter> bg</parameter></paramdef>
+ <paramdef>unsignedint<parameter> depth</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Dr \ that indicates the screen -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable(Dr.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data in bitmap format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>fg</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>bg</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the foreground and background pixel values to use.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>depth</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the depth of the pixmap.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreatePixmapFromBitmapData</function>
+function creates a pixmap of the given depth and then does a bitmap-format
+<function>XPutImage</function>
+of the data into it.
+The depth must be supported by the screen of the specified drawable,
+or a
+<errorname>BadMatch</errorname>
+error results.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreatePixmapFromBitmapData</function>
+can generate
+<errorname>BadAlloc</errorname>,
+<errorname>BadDrawable</errorname>,
+<errorname>BadGC</errorname>,
+and
+<errorname>BadValue</errorname>
+errors.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To include a bitmap written out by
+<function>XWriteBitmapFile</function>
+<indexterm><primary>XWriteBitmapFile</primary></indexterm>
+in a program directly, as opposed to reading it in every time at run time, use
+<function>XCreateBitmapFromData</function>.
+</para>
+<indexterm significance="preferred"><primary>XCreateBitmapFromData</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xcreatebitmapfromdata'>
+<funcprototype>
+ <funcdef>Pixmap <function>XCreateBitmapFromData</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>Drawable<parameter> d</parameter></paramdef>
+ <paramdef>char<parameter> *data</parameter></paramdef>
+ <paramdef>unsignedintwidth,<parameter> height</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+<!-- .ds Dr \ that indicates the screen -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>d</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the drawable(Dr.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the location of the bitmap data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>width</emphasis>
+ </term>
+ <listitem>
+ <para>
+<!-- .br -->
+<!-- .ns -->
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>height</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specify the width and height.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XCreateBitmapFromData</function>
+function allows you to include in your C program (using
+<code>#include</code>)
+a bitmap file that was written out by
+<function>XWriteBitmapFile</function>
+(X version 11 format only) without reading in the bitmap file.
+The following example creates a gray bitmap:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+#include "gray.bitmap"
+<!-- .sp 6p -->
+Pixmap bitmap;
+bitmap = XCreateBitmapFromData(display, window, gray_bits, gray_width, gray_height);
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+If insufficient working storage was allocated,
+<function>XCreateBitmapFromData</function>
+returns
+<symbol>None</symbol>.
+It is your responsibility to free the
+bitmap using
+<function>XFreePixmap</function>
+when finished.
+</para>
+<para>
+<!-- .LP -->
+<function>XCreateBitmapFromData</function>
+can generate
+<errorname>BadAlloc</errorname>
+and
+<errorname>BadGC</errorname>
+errors.
+</para>
+</sect1>
+<sect1 id="Using_the_Context_Manager">
+<title>Using the Context Manager</title>
+<!-- .XS -->
+<!-- (SN Using the Context Manager -->
+<!-- .XE -->
+<para>
+<!-- .LP -->
+The context manager provides a way of associating data with an X resource ID
+(mostly typically a window) in your program.
+Note that this is local to your program;
+the data is not stored in the server on a property list.
+Any amount of data in any number of pieces can be associated with a
+resource ID,
+and each piece of data has a type associated with it.
+The context manager requires knowledge of the resource ID
+and type to store or retrieve data.
+</para>
+<para>
+<!-- .LP -->
+Essentially, the context manager can be viewed as a two-dimensional,
+sparse array: one dimension is subscripted by the X resource ID
+and the other by a context type field.
+Each entry in the array contains a pointer to the data.
+Xlib provides context management functions with which you can
+save data values, get data values, delete entries, and create a unique
+context type.
+The symbols used are in
+<filename class="headerfile"><X11/Xutil.h></filename>.
+<indexterm type="file"><primary><filename class="headerfile">X11/Xutil.h</filename></primary></indexterm>
+<indexterm><primary>Files</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+<indexterm><primary>Headers</primary><secondary><filename class="headerfile"><X11/Xutil.h></filename></secondary></indexterm>
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To save a data value that corresponds to a resource ID and context type, use
+<function>XSaveContext</function>.
+</para>
+<indexterm significance="preferred"><primary>XSaveContext</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xsavecontext'>
+<funcprototype>
+ <funcdef>int <function>XSaveContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> rid</parameter></paramdef>
+ <paramdef>XContext<parameter> context</parameter></paramdef>
+ <paramdef>XPointer<parameter> data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rid</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource ID with which the data is associated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>context</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the context type to which the data belongs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the data to be associated with the window and type.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+If an entry with the specified resource ID and type already exists,
+<function>XSaveContext</function>
+overrides it with the specified context.
+The
+<function>XSaveContext</function>
+function returns a nonzero error code if an error has occurred
+and zero otherwise.
+Possible errors are
+<symbol>XCNOMEM</symbol>
+(out of memory).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To get the data associated with a resource ID and type, use
+<function>XFindContext</function>.
+</para>
+<indexterm significance="preferred"><primary>XFindContext</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xfindcontext'>
+<funcprototype>
+ <funcdef>int <function>XFindContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> rid</parameter></paramdef>
+ <paramdef>XContext<parameter> context</parameter></paramdef>
+ <paramdef>XPointer<parameter> *data_return</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rid</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource ID with which the data is associated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>context</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the context type to which the data belongs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>data_return</emphasis>
+ </term>
+ <listitem>
+ <para>
+Returns the data.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+Because it is a return value,
+the data is a pointer.
+The
+<function>XFindContext</function>
+function returns a nonzero error code if an error has occurred
+and zero otherwise.
+Possible errors are
+<symbol>XCNOENT</symbol>
+(context-not-found).
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To delete an entry for a given resource ID and type, use
+<function>XDeleteContext</function>.
+</para>
+<indexterm significance="preferred"><primary>XDeleteContext</primary></indexterm>
+<!-- .sM -->
+<funcsynopsis id='xdeletecontext'>
+<funcprototype>
+ <funcdef>int <function>XDeleteContext</function></funcdef>
+ <paramdef>Display<parameter> *display</parameter></paramdef>
+ <paramdef>XID<parameter> rid</parameter></paramdef>
+ <paramdef>XContext<parameter> context</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+<!-- .FN -->
+<variablelist>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>display</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the connection to the X server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>rid</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the resource ID with which the data is associated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <emphasis remap='I'>context</emphasis>
+ </term>
+ <listitem>
+ <para>
+Specifies the context type to which the data belongs.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+<para>
+<!-- .LP -->
+<!-- .eM -->
+The
+<function>XDeleteContext</function>
+function deletes the entry for the given resource ID
+and type from the data structure.
+This function returns the same error codes that
+<function>XFindContext</function>
+returns if called with the same arguments.
+<function>XDeleteContext</function>
+does not free the data whose address was saved.
+</para>
+<para>
+<!-- .LP -->
+<!-- .sp -->
+To create a unique context type that may be used in subsequent calls to
+<function>XSaveContext</function>
+and
+<function>XFindContext</function>,
+use
+<function>XUniqueContext</function>.
+</para>
+<para>XContext XuniqueContext()</para>
+
+</sect1>
+</chapter>
diff --git a/libX11/specs/libX11/Makefile.am b/libX11/specs/libX11/Makefile.am index b87e568cd..f91320c09 100644 --- a/libX11/specs/libX11/Makefile.am +++ b/libX11/specs/libX11/Makefile.am @@ -1,38 +1,38 @@ - -if ENABLE_SPECS - -# Main DocBook/XML files (DOCTYPE book) -docbook = libX11.xml - -# Included chapters, appendix, images -chapters = \ - AppA.xml \ - AppB.xml \ - AppC.xml \ - AppD.xml \ - CH01.xml \ - CH02.xml \ - CH03.xml \ - CH04.xml \ - CH05.xml \ - CH06.xml \ - CH07.xml \ - CH08.xml \ - CH09.xml \ - CH10.xml \ - CH11.xml \ - CH12.xml \ - CH13.xml \ - CH14.xml \ - CH15.xml \ - CH16.xml \ - credits.xml \ - glossary.xml - -# The location where the DocBook/XML files and their generated formats are installed -shelfdir = $(docdir)/libX11 - -# Generate DocBook/XML output formats with or without stylesheets -include $(top_srcdir)/docbook.am - -endif ENABLE_SPECS +
+if ENABLE_SPECS
+
+# Main DocBook/XML files (DOCTYPE book)
+docbook = libX11.xml
+
+# Included chapters, appendix, images
+chapters = \
+ AppA.xml \
+ AppB.xml \
+ AppC.xml \
+ AppD.xml \
+ CH01.xml \
+ CH02.xml \
+ CH03.xml \
+ CH04.xml \
+ CH05.xml \
+ CH06.xml \
+ CH07.xml \
+ CH08.xml \
+ CH09.xml \
+ CH10.xml \
+ CH11.xml \
+ CH12.xml \
+ CH13.xml \
+ CH14.xml \
+ CH15.xml \
+ CH16.xml \
+ credits.xml \
+ glossary.xml
+
+# The location where the DocBook/XML files and their generated formats are installed
+shelfdir = $(docdir)/libX11
+
+# Generate DocBook/XML output formats with or without stylesheets
+include $(top_srcdir)/docbook.am
+
+endif ENABLE_SPECS
diff --git a/libX11/src/ConvSel.c b/libX11/src/ConvSel.c index fb6e8e338..2dece58b5 100644 --- a/libX11/src/ConvSel.c +++ b/libX11/src/ConvSel.c @@ -49,5 +49,5 @@ XConvertSelection( req->time = time; UnlockDisplay(dpy); SyncHandle(); - return 1; + return Success; } diff --git a/libX11/src/CrGlCur.c b/libX11/src/CrGlCur.c index 460660f81..4f332836b 100644 --- a/libX11/src/CrGlCur.c +++ b/libX11/src/CrGlCur.c @@ -1,260 +1,270 @@ -/* - -Copyright 1986, 1998 The Open Group - -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. - -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 -OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" - -#ifdef USE_DYNAMIC_XCURSOR - -#ifdef __UNIXOS2__ -#define RTLD_LAZY 1 -#define LIBXCURSOR "Xcursor.dll" -#endif -#include <stdio.h> -#include <string.h> -#if defined(hpux) -#include <dl.h> -#else -#include <dlfcn.h> -#endif -#include "Cr.h" - -#ifdef __CYGWIN__ -#define LIBXCURSOR "cygXcursor-1.dll" -#endif - -#if defined(hpux) -typedef shl_t XModuleType; -#else -typedef void *XModuleType; -#endif - -#ifndef LIBXCURSOR -#define LIBXCURSOR "libXcursor.so.1" -#endif - -static char libraryName[] = LIBXCURSOR; - -static XModuleType -open_library (void) -{ - char *library = libraryName; - char *dot; - XModuleType module; - for (;;) - { -#if defined(hpux) - module = shl_load(library, BIND_DEFERRED, 0L); -#else - module = dlopen(library, RTLD_LAZY); -#endif - if (module) - return module; - dot = strrchr (library, '.'); - if (!dot) - break; - *dot = '\0'; - } - return NULL; -} - -static void * -fetch_symbol (XModuleType module, const char *under_symbol) -{ - void *result = NULL; - const char *symbol = under_symbol + 1; -#if defined(hpux) - int getsyms_cnt, i; - struct shl_symbol *symbols; - - getsyms_cnt = shl_getsymbols(module, TYPE_PROCEDURE, - EXPORT_SYMBOLS, malloc, &symbols); - - for(i=0; i<getsyms_cnt; i++) { - if(!strcmp(symbols[i].name, symbol)) { - result = symbols[i].value; - break; - } - } - - if(getsyms_cnt > 0) { - free(symbols); - } -#else - result = dlsym (module, symbol); - if (!result) - result = dlsym (module, under_symbol); -#endif - return result; -} - -typedef void (*NoticeCreateBitmapFunc) (Display *dpy, - Pixmap pid, - unsigned int width, - unsigned int height); - -typedef void (*NoticePutBitmapFunc) (Display *dpy, - Drawable draw, - XImage *image); - -typedef Cursor (*TryShapeBitmapCursorFunc) (Display *dpy, - Pixmap source, - Pixmap mask, - XColor *foreground, - XColor *background, - unsigned int x, - unsigned int y); - -typedef Cursor (*TryShapeCursorFunc) (Display *dpy, - Font source_font, - Font mask_font, - unsigned int source_char, - unsigned int mask_char, - XColor _Xconst *foreground, - XColor _Xconst *background); - -static XModuleType _XcursorModule; -static Bool _XcursorModuleTried; - -#define GetFunc(type,name,ret) {\ - static Bool been_here; \ - static type staticFunc; \ - \ - _XLockMutex (_Xglobal_lock); \ - if (!been_here) \ - { \ - been_here = True; \ - if (!_XcursorModuleTried) \ - { \ - _XcursorModuleTried = True; \ - _XcursorModule = open_library (); \ - } \ - if (_XcursorModule) \ - staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \ - } \ - ret = staticFunc; \ - _XUnlockMutex (_Xglobal_lock); \ -} - -static Cursor -_XTryShapeCursor (Display *dpy, - Font source_font, - Font mask_font, - unsigned int source_char, - unsigned int mask_char, - XColor _Xconst *foreground, - XColor _Xconst *background) -{ - TryShapeCursorFunc func; - - GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func); - if (func) - return (*func) (dpy, source_font, mask_font, source_char, mask_char, - foreground, background); - return None; -} - -void -_XNoticeCreateBitmap (Display *dpy, - Pixmap pid, - unsigned int width, - unsigned int height) -{ - NoticeCreateBitmapFunc func; - - GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func); - if (func) - (*func) (dpy, pid, width, height); -} - -void -_XNoticePutBitmap (Display *dpy, - Drawable draw, - XImage *image) -{ - NoticePutBitmapFunc func; - - GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func); - if (func) - (*func) (dpy, draw, image); -} - -Cursor -_XTryShapeBitmapCursor (Display *dpy, - Pixmap source, - Pixmap mask, - XColor *foreground, - XColor *background, - unsigned int x, - unsigned int y) -{ - TryShapeBitmapCursorFunc func; - - GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func); - if (func) - return (*func) (dpy, source, mask, foreground, background, x, y); - return None; -} -#endif - -Cursor XCreateGlyphCursor( - register Display *dpy, - Font source_font, - Font mask_font, - unsigned int source_char, - unsigned int mask_char, - XColor _Xconst *foreground, - XColor _Xconst *background) -{ - Cursor cid; - register xCreateGlyphCursorReq *req; - -#ifdef USE_DYNAMIC_XCURSOR - cid = _XTryShapeCursor (dpy, source_font, mask_font, - source_char, mask_char, foreground, background); - if (cid) - return cid; -#endif - LockDisplay(dpy); - GetReq(CreateGlyphCursor, req); - cid = req->cid = XAllocID(dpy); - req->source = source_font; - req->mask = mask_font; - req->sourceChar = source_char; - req->maskChar = mask_char; - req->foreRed = foreground->red; - req->foreGreen = foreground->green; - req->foreBlue = foreground->blue; - req->backRed = background->red; - req->backGreen = background->green; - req->backBlue = background->blue; - UnlockDisplay(dpy); - SyncHandle(); - return (cid); -} - +/*
+
+Copyright 1986, 1998 The Open Group
+
+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.
+
+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
+OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+
+#ifdef USE_DYNAMIC_XCURSOR
+
+#ifdef __UNIXOS2__
+#define RTLD_LAZY 1
+#define LIBXCURSOR "Xcursor.dll"
+#endif
+#include <stdio.h>
+#include <string.h>
+#if defined(hpux)
+#include <dl.h>
+#else
+#include <dlfcn.h>
+#endif
+#include "Cr.h"
+
+#ifdef __CYGWIN__
+#define LIBXCURSOR "cygXcursor-1.dll"
+#endif
+
+#if defined(hpux)
+typedef shl_t XModuleType;
+#else
+#ifdef _MSC_VER
+#include <X11/XWindows.h>
+typedef HANDLE XModuleType;
+#define dlsym GetProcAddress
+#else
+typedef void *XModuleType;
+#endif
+#endif
+
+#ifndef LIBXCURSOR
+#define LIBXCURSOR "libXcursor.so.1"
+#endif
+
+static char libraryName[] = LIBXCURSOR;
+
+static XModuleType
+open_library (void)
+{
+ char *library = libraryName;
+ char *dot;
+ XModuleType module;
+ for (;;)
+ {
+#if defined(hpux)
+ module = shl_load(library, BIND_DEFERRED, 0L);
+#else
+#ifdef _MSC_VER
+ module = LoadLibrary(library);
+#else
+ module = dlopen(library, RTLD_LAZY);
+#endif
+#endif
+ if (module)
+ return module;
+ dot = strrchr (library, '.');
+ if (!dot)
+ break;
+ *dot = '\0';
+ }
+ return NULL;
+}
+
+static void *
+fetch_symbol (XModuleType module, const char *under_symbol)
+{
+ void *result = NULL;
+ const char *symbol = under_symbol + 1;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+
+ getsyms_cnt = shl_getsymbols(module, TYPE_PROCEDURE,
+ EXPORT_SYMBOLS, malloc, &symbols);
+
+ for(i=0; i<getsyms_cnt; i++) {
+ if(!strcmp(symbols[i].name, symbol)) {
+ result = symbols[i].value;
+ break;
+ }
+ }
+
+ if(getsyms_cnt > 0) {
+ free(symbols);
+ }
+#else
+ result = dlsym (module, symbol);
+ if (!result)
+ result = dlsym (module, under_symbol);
+#endif
+ return result;
+}
+
+typedef void (*NoticeCreateBitmapFunc) (Display *dpy,
+ Pixmap pid,
+ unsigned int width,
+ unsigned int height);
+
+typedef void (*NoticePutBitmapFunc) (Display *dpy,
+ Drawable draw,
+ XImage *image);
+
+typedef Cursor (*TryShapeBitmapCursorFunc) (Display *dpy,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground,
+ XColor *background,
+ unsigned int x,
+ unsigned int y);
+
+typedef Cursor (*TryShapeCursorFunc) (Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background);
+
+static XModuleType _XcursorModule;
+static Bool _XcursorModuleTried;
+
+#define GetFunc(type,name,ret) {\
+ static Bool been_here; \
+ static type staticFunc; \
+ \
+ _XLockMutex (_Xglobal_lock); \
+ if (!been_here) \
+ { \
+ been_here = True; \
+ if (!_XcursorModuleTried) \
+ { \
+ _XcursorModuleTried = True; \
+ _XcursorModule = open_library (); \
+ } \
+ if (_XcursorModule) \
+ staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \
+ } \
+ ret = staticFunc; \
+ _XUnlockMutex (_Xglobal_lock); \
+}
+
+static Cursor
+_XTryShapeCursor (Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background)
+{
+ TryShapeCursorFunc func;
+
+ GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func);
+ if (func)
+ return (*func) (dpy, source_font, mask_font, source_char, mask_char,
+ foreground, background);
+ return None;
+}
+
+void
+_XNoticeCreateBitmap (Display *dpy,
+ Pixmap pid,
+ unsigned int width,
+ unsigned int height)
+{
+ NoticeCreateBitmapFunc func;
+
+ GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func);
+ if (func)
+ (*func) (dpy, pid, width, height);
+}
+
+void
+_XNoticePutBitmap (Display *dpy,
+ Drawable draw,
+ XImage *image)
+{
+ NoticePutBitmapFunc func;
+
+ GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func);
+ if (func)
+ (*func) (dpy, draw, image);
+}
+
+Cursor
+_XTryShapeBitmapCursor (Display *dpy,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground,
+ XColor *background,
+ unsigned int x,
+ unsigned int y)
+{
+ TryShapeBitmapCursorFunc func;
+
+ GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func);
+ if (func)
+ return (*func) (dpy, source, mask, foreground, background, x, y);
+ return None;
+}
+#endif
+
+Cursor XCreateGlyphCursor(
+ register Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background)
+{
+ Cursor cid;
+ register xCreateGlyphCursorReq *req;
+
+#ifdef USE_DYNAMIC_XCURSOR
+ cid = _XTryShapeCursor (dpy, source_font, mask_font,
+ source_char, mask_char, foreground, background);
+ if (cid)
+ return cid;
+#endif
+ LockDisplay(dpy);
+ GetReq(CreateGlyphCursor, req);
+ cid = req->cid = XAllocID(dpy);
+ req->source = source_font;
+ req->mask = mask_font;
+ req->sourceChar = source_char;
+ req->maskChar = mask_char;
+ req->foreRed = foreground->red;
+ req->foreGreen = foreground->green;
+ req->foreBlue = foreground->blue;
+ req->backRed = background->red;
+ req->backGreen = background->green;
+ req->backBlue = background->blue;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return (cid);
+}
+
diff --git a/libX11/src/FSWrap.c b/libX11/src/FSWrap.c index 45a2c34e3..d97c39504 100644 --- a/libX11/src/FSWrap.c +++ b/libX11/src/FSWrap.c @@ -1,262 +1,262 @@ - -/* - * Copyright 1991 by the Open Software Foundation - * Copyright 1993 by the TOSHIBA Corp. - * - * 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 Open Software Foundation - * not be used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. Open Software - * Foundation makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN 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. - * - * M. Collins OSF - * - * Katsuhisa Yano TOSHIBA Corp. - */ - -/* - -Copyright 1991, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include <ctype.h> -#include <X11/Xos.h> - - -#define XMAXLIST 256 - -char ** -_XParseBaseFontNameList( - char *str, - int *num) -{ - char *plist[XMAXLIST]; - char **list; - char *ptr, *psave; - - *num = 0; - if (!str || !*str) { - return (char **)NULL; - } - while (*str && isspace(*str)) - str++; - if (!*str) - return (char **)NULL; - - if (!(ptr = strdup(str))) { - return (char **)NULL; - } - - psave = ptr; - /* somebody who specifies more than XMAXLIST basefontnames will lose */ - while (*num < (sizeof plist / sizeof plist[0])) { - char *back; - - plist[*num] = ptr; - if ((ptr = strchr(ptr, ','))) { - back = ptr; - } else { - back = plist[*num] + strlen(plist[*num]); - } - while (isspace(*(back - 1))) - back--; - *back = '\0'; - (*num)++; - if (!ptr) - break; - ptr++; - while (*ptr && isspace(*ptr)) - ptr++; - if (!*ptr) - break; - } - if (!(list = (char **) Xmalloc((unsigned)sizeof(char *) * (*num + 1)))) { - Xfree(psave); - return (char **)NULL; - } - memcpy((char *)list, (char *)plist, sizeof(char *) * (*num)); - *(list + *num) = NULL; - - return list; -} - -static char ** -copy_string_list( - char **string_list, - int list_count) -{ - char **string_list_ret, **list_src, **list_dst, *dst; - int length, count; - - if (string_list == NULL || list_count == 0) - return (char **) NULL; - - string_list_ret = (char **) Xmalloc(sizeof(char *) * list_count); - if (string_list_ret == NULL) - return (char **) NULL; - - list_src = string_list; - count = list_count; - for (length = 0; count-- > 0; list_src++) - length += strlen(*list_src) + 1; - - dst = (char *) Xmalloc(length); - if (dst == NULL) { - Xfree(string_list_ret); - return (char **) NULL; - } - - list_src = string_list; - count = list_count; - list_dst = string_list_ret; - for ( ; count-- > 0; list_src++) { - strcpy(dst, *list_src); - *list_dst++ = dst; - dst += strlen(dst) + 1; - } - - return string_list_ret; -} - -XFontSet -XCreateFontSet ( - Display *dpy, - _Xconst char *base_font_name_list, - char ***missing_charset_list, - int *missing_charset_count, - char **def_string) -{ - XOM om; - XOC oc; - XOMCharSetList *list; - - *missing_charset_list = NULL; - *missing_charset_count = 0; - - om = XOpenOM(dpy, NULL, NULL, NULL); - if (om == NULL) - return (XFontSet) NULL; - - if ((oc = XCreateOC(om, XNBaseFontName, base_font_name_list, NULL))) { - list = &oc->core.missing_list; - oc->core.om_automatic = True; - } else - list = &om->core.required_charset; - - *missing_charset_list = copy_string_list(list->charset_list, - list->charset_count); - *missing_charset_count = list->charset_count; - - if (list->charset_list && *missing_charset_list == NULL) - oc = NULL; - - if (oc && def_string) { - *def_string = oc->core.default_string; - if (!*def_string) - *def_string = ""; - } - - if (oc == NULL) - XCloseOM(om); - - return (XFontSet) oc; -} - -int -XFontsOfFontSet( - XFontSet font_set, - XFontStruct ***font_struct_list, - char ***font_name_list) -{ - *font_name_list = font_set->core.font_info.font_name_list; - *font_struct_list = font_set->core.font_info.font_struct_list; - return font_set->core.font_info.num_font; -} - -char * -XBaseFontNameListOfFontSet(XFontSet font_set) -{ - return font_set->core.base_name_list; -} - -char * -XLocaleOfFontSet(XFontSet font_set) -{ - return font_set->core.om->core.lcd->core->name; -} - -Bool -XContextDependentDrawing(XFontSet font_set) -{ - return font_set->core.om->core.context_dependent; -} - -Bool -XDirectionalDependentDrawing(XFontSet font_set) -{ - return font_set->core.om->core.directional_dependent; -} - -Bool -XContextualDrawing(XFontSet font_set) -{ - return font_set->core.om->core.contextual_drawing; -} - -XFontSetExtents * -XExtentsOfFontSet(XFontSet font_set) -{ - if (!font_set) - return NULL; - return &font_set->core.font_set_extents; -} - -void -XFreeFontSet( - Display *dpy, - XFontSet font_set) -{ - XCloseOM(font_set->core.om); -} +
+/*
+ * Copyright 1991 by the Open Software Foundation
+ * Copyright 1993 by the TOSHIBA Corp.
+ *
+ * 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 Open Software Foundation
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Open Software
+ * Foundation makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN 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.
+ *
+ * M. Collins OSF
+ *
+ * Katsuhisa Yano TOSHIBA Corp.
+ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include <ctype.h>
+#include <X11/Xos.h>
+#include <unistd.h>
+
+#define XMAXLIST 256
+
+char **
+_XParseBaseFontNameList(
+ char *str,
+ int *num)
+{
+ char *plist[XMAXLIST];
+ char **list;
+ char *ptr, *psave;
+
+ *num = 0;
+ if (!str || !*str) {
+ return (char **)NULL;
+ }
+ while (*str && isspace(*str))
+ str++;
+ if (!*str)
+ return (char **)NULL;
+
+ if (!(ptr = strdup(str))) {
+ return (char **)NULL;
+ }
+
+ psave = ptr;
+ /* somebody who specifies more than XMAXLIST basefontnames will lose */
+ while (*num < (sizeof plist / sizeof plist[0])) {
+ char *back;
+
+ plist[*num] = ptr;
+ if ((ptr = strchr(ptr, ','))) {
+ back = ptr;
+ } else {
+ back = plist[*num] + strlen(plist[*num]);
+ }
+ while (isspace(*(back - 1)))
+ back--;
+ *back = '\0';
+ (*num)++;
+ if (!ptr)
+ break;
+ ptr++;
+ while (*ptr && isspace(*ptr))
+ ptr++;
+ if (!*ptr)
+ break;
+ }
+ if (!(list = (char **) Xmalloc((unsigned)sizeof(char *) * (*num + 1)))) {
+ Xfree(psave);
+ return (char **)NULL;
+ }
+ memcpy((char *)list, (char *)plist, sizeof(char *) * (*num));
+ *(list + *num) = NULL;
+
+ return list;
+}
+
+static char **
+copy_string_list(
+ char **string_list,
+ int list_count)
+{
+ char **string_list_ret, **list_src, **list_dst, *dst;
+ int length, count;
+
+ if (string_list == NULL || list_count == 0)
+ return (char **) NULL;
+
+ string_list_ret = (char **) Xmalloc(sizeof(char *) * list_count);
+ if (string_list_ret == NULL)
+ return (char **) NULL;
+
+ list_src = string_list;
+ count = list_count;
+ for (length = 0; count-- > 0; list_src++)
+ length += strlen(*list_src) + 1;
+
+ dst = (char *) Xmalloc(length);
+ if (dst == NULL) {
+ Xfree(string_list_ret);
+ return (char **) NULL;
+ }
+
+ list_src = string_list;
+ count = list_count;
+ list_dst = string_list_ret;
+ for ( ; count-- > 0; list_src++) {
+ strcpy(dst, *list_src);
+ *list_dst++ = dst;
+ dst += strlen(dst) + 1;
+ }
+
+ return string_list_ret;
+}
+
+XFontSet
+XCreateFontSet (
+ Display *dpy,
+ _Xconst char *base_font_name_list,
+ char ***missing_charset_list,
+ int *missing_charset_count,
+ char **def_string)
+{
+ XOM om;
+ XOC oc;
+ XOMCharSetList *list;
+
+ *missing_charset_list = NULL;
+ *missing_charset_count = 0;
+
+ om = XOpenOM(dpy, NULL, NULL, NULL);
+ if (om == NULL)
+ return (XFontSet) NULL;
+
+ if ((oc = XCreateOC(om, XNBaseFontName, base_font_name_list, NULL))) {
+ list = &oc->core.missing_list;
+ oc->core.om_automatic = True;
+ } else
+ list = &om->core.required_charset;
+
+ *missing_charset_list = copy_string_list(list->charset_list,
+ list->charset_count);
+ *missing_charset_count = list->charset_count;
+
+ if (list->charset_list && *missing_charset_list == NULL)
+ oc = NULL;
+
+ if (oc && def_string) {
+ *def_string = oc->core.default_string;
+ if (!*def_string)
+ *def_string = "";
+ }
+
+ if (oc == NULL)
+ XCloseOM(om);
+
+ return (XFontSet) oc;
+}
+
+int
+XFontsOfFontSet(
+ XFontSet font_set,
+ XFontStruct ***font_struct_list,
+ char ***font_name_list)
+{
+ *font_name_list = font_set->core.font_info.font_name_list;
+ *font_struct_list = font_set->core.font_info.font_struct_list;
+ return font_set->core.font_info.num_font;
+}
+
+char *
+XBaseFontNameListOfFontSet(XFontSet font_set)
+{
+ return font_set->core.base_name_list;
+}
+
+char *
+XLocaleOfFontSet(XFontSet font_set)
+{
+ return font_set->core.om->core.lcd->core->name;
+}
+
+Bool
+XContextDependentDrawing(XFontSet font_set)
+{
+ return font_set->core.om->core.context_dependent;
+}
+
+Bool
+XDirectionalDependentDrawing(XFontSet font_set)
+{
+ return font_set->core.om->core.directional_dependent;
+}
+
+Bool
+XContextualDrawing(XFontSet font_set)
+{
+ return font_set->core.om->core.contextual_drawing;
+}
+
+XFontSetExtents *
+XExtentsOfFontSet(XFontSet font_set)
+{
+ if (!font_set)
+ return NULL;
+ return &font_set->core.font_set_extents;
+}
+
+void
+XFreeFontSet(
+ Display *dpy,
+ XFontSet font_set)
+{
+ XCloseOM(font_set->core.om);
+}
diff --git a/libX11/src/GetDflt.c b/libX11/src/GetDflt.c index dfda1c64d..0443e2d1a 100644 --- a/libX11/src/GetDflt.c +++ b/libX11/src/GetDflt.c @@ -160,9 +160,13 @@ InitDefaults( * ~/.Xdefaults. Next, if there is an XENVIRONMENT environment variable, * then load that file. */ - + if (dpy->xdefaults == NULL) { + #ifdef _MSC_VER + const char *slashDotXdefaults = ".Xdefaults"; + #else const char *slashDotXdefaults = "/.Xdefaults"; + #endif (void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaults) - 1); (void) strcat (fname, slashDotXdefaults); @@ -172,7 +176,11 @@ InitDefaults( } if (!(xenv = getenv ("XENVIRONMENT"))) { + #ifdef _MSC_VER + const char *slashDotXdefaultsDash = ".Xdefaults-"; + #else const char *slashDotXdefaultsDash = "/.Xdefaults-"; + #endif int len; (void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaultsDash) - 1); diff --git a/libX11/src/InitExt.c b/libX11/src/InitExt.c index 19515ccd0..f14da412c 100644 --- a/libX11/src/InitExt.c +++ b/libX11/src/InitExt.c @@ -1,409 +1,410 @@ -/* - -Copyright 1987, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xlibint.h> -#include <X11/Xos.h> -#include <stdio.h> - -/* - * This routine is used to link a extension in so it will be called - * at appropriate times. - */ - -XExtCodes *XInitExtension ( - Display *dpy, - _Xconst char *name) -{ - XExtCodes codes; /* temp. place for extension information. */ - register _XExtension *ext;/* need a place to build it all */ - if (!XQueryExtension(dpy, name, - &codes.major_opcode, &codes.first_event, - &codes.first_error)) return (NULL); - - LockDisplay (dpy); - if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) || - ! (ext->name = strdup(name))) { - if (ext) Xfree((char *) ext); - UnlockDisplay(dpy); - return (XExtCodes *) NULL; - } - codes.extension = dpy->ext_number++; - ext->codes = codes; - - /* chain it onto the display list */ - ext->next = dpy->ext_procs; - dpy->ext_procs = ext; - UnlockDisplay (dpy); - - return (&ext->codes); /* tell him which extension */ -} - -XExtCodes *XAddExtension (Display *dpy) -{ - register _XExtension *ext; - - LockDisplay (dpy); - if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension)))) { - UnlockDisplay(dpy); - return (XExtCodes *) NULL; - } - ext->codes.extension = dpy->ext_number++; - - /* chain it onto the display list */ - ext->next = dpy->ext_procs; - dpy->ext_procs = ext; - UnlockDisplay (dpy); - - return (&ext->codes); /* tell him which extension */ -} - -static _XExtension *XLookupExtension ( - register Display *dpy, /* display */ - register int extension) /* extension number */ -{ - register _XExtension *ext; - for (ext = dpy->ext_procs; ext; ext = ext->next) - if (ext->codes.extension == extension) return (ext); - return (NULL); -} - -XExtData **XEHeadOfExtensionList(XEDataObject object) -{ - return *(XExtData ***)&object; -} - -int -XAddToExtensionList( - XExtData **structure, - XExtData *ext_data) -{ - ext_data->next = *structure; - *structure = ext_data; - return 1; -} - -XExtData *XFindOnExtensionList( - XExtData **structure, - int number) -{ - XExtData *ext; - - ext = *structure; - while (ext && (ext->number != number)) - ext = ext->next; - return ext; -} - -/* - * Routines to hang procs on the extension structure. - */ -CreateGCType XESetCreateGC( - Display *dpy, /* display */ - int extension, /* extension number */ - CreateGCType proc) /* routine to call when GC created */ -{ - register _XExtension *e; /* for lookup of extension */ - register CreateGCType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->create_GC; - e->create_GC = proc; - UnlockDisplay(dpy); - return (CreateGCType)oldproc; -} - -CopyGCType XESetCopyGC( - Display *dpy, /* display */ - int extension, /* extension number */ - CopyGCType proc) /* routine to call when GC copied */ -{ - register _XExtension *e; /* for lookup of extension */ - register CopyGCType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->copy_GC; - e->copy_GC = proc; - UnlockDisplay(dpy); - return (CopyGCType)oldproc; -} - -FlushGCType XESetFlushGC( - Display *dpy, /* display */ - int extension, /* extension number */ - FlushGCType proc) /* routine to call when GC copied */ -{ - register _XExtension *e; /* for lookup of extension */ - register FlushGCType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->flush_GC; - e->flush_GC = proc; - UnlockDisplay(dpy); - return (FlushGCType)oldproc; -} - -FreeGCType XESetFreeGC( - Display *dpy, /* display */ - int extension, /* extension number */ - FreeGCType proc) /* routine to call when GC freed */ -{ - register _XExtension *e; /* for lookup of extension */ - register FreeGCType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->free_GC; - e->free_GC = proc; - UnlockDisplay(dpy); - return (FreeGCType)oldproc; -} - -CreateFontType XESetCreateFont( - Display *dpy, /* display */ - int extension, /* extension number */ - CreateFontType proc) /* routine to call when font created */ -{ - register _XExtension *e; /* for lookup of extension */ - register CreateFontType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->create_Font; - e->create_Font = proc; - UnlockDisplay(dpy); - return (CreateFontType)oldproc; -} - -FreeFontType XESetFreeFont( - Display *dpy, /* display */ - int extension, /* extension number */ - FreeFontType proc) /* routine to call when font freed */ -{ - register _XExtension *e; /* for lookup of extension */ - register FreeFontType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->free_Font; - e->free_Font = proc; - UnlockDisplay(dpy); - return (FreeFontType)oldproc; -} - -CloseDisplayType XESetCloseDisplay( - Display *dpy, /* display */ - int extension, /* extension number */ - CloseDisplayType proc) /* routine to call when display closed */ -{ - register _XExtension *e; /* for lookup of extension */ - register CloseDisplayType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->close_display; - e->close_display = proc; - UnlockDisplay(dpy); - return (CloseDisplayType)oldproc; -} - -typedef Bool (*WireToEventType) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ -); - -WireToEventType XESetWireToEvent( - Display *dpy, /* display */ - int event_number, /* event routine to replace */ - WireToEventType proc) /* routine to call when converting event */ -{ - register WireToEventType oldproc; - if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent; - LockDisplay (dpy); - oldproc = dpy->event_vec[event_number]; - dpy->event_vec[event_number] = proc; - UnlockDisplay (dpy); - return (WireToEventType)oldproc; -} - -typedef Bool (*WireToEventCookieType) ( - Display* /* display */, - XGenericEventCookie* /* re */, - xEvent* /* event */ -); - -WireToEventCookieType XESetWireToEventCookie( - Display *dpy, /* display */ - int extension, /* extension major opcode */ - WireToEventCookieType proc /* routine to call for generic events */ - ) -{ - WireToEventCookieType oldproc; - if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie; - LockDisplay (dpy); - oldproc = dpy->generic_event_vec[extension & 0x7F]; - dpy->generic_event_vec[extension & 0x7F] = proc; - UnlockDisplay (dpy); - return (WireToEventCookieType)oldproc; -} - -typedef Bool (*CopyEventCookieType) ( - Display* /* display */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ -); - -CopyEventCookieType XESetCopyEventCookie( - Display *dpy, /* display */ - int extension, /* extension major opcode */ - CopyEventCookieType proc /* routine to copy generic events */ - ) -{ - CopyEventCookieType oldproc; - if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie; - LockDisplay (dpy); - oldproc = dpy->generic_event_copy_vec[extension & 0x7F]; - dpy->generic_event_copy_vec[extension & 0x7F] = proc; - UnlockDisplay (dpy); - return (CopyEventCookieType)oldproc; -} - - -typedef Status (*EventToWireType) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ -); - -EventToWireType XESetEventToWire( - Display *dpy, /* display */ - int event_number, /* event routine to replace */ - EventToWireType proc) /* routine to call when converting event */ -{ - register EventToWireType oldproc; - if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent; - LockDisplay (dpy); - oldproc = dpy->wire_vec[event_number]; - dpy->wire_vec[event_number] = proc; - UnlockDisplay(dpy); - return (EventToWireType)oldproc; -} - -typedef Bool (*WireToErrorType) ( - Display* /* display */, - XErrorEvent* /* he */, - xError* /* we */ -); - -WireToErrorType XESetWireToError( - Display *dpy, /* display */ - int error_number, /* error routine to replace */ - WireToErrorType proc) /* routine to call when converting error */ -{ - register WireToErrorType oldproc = NULL; - if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError; - LockDisplay (dpy); - if (!dpy->error_vec) { - int i; - dpy->error_vec = Xmalloc(256 * sizeof(oldproc)); - for (i = 1; i < 256; i++) - dpy->error_vec[i] = _XDefaultWireError; - } - if (dpy->error_vec) { - oldproc = dpy->error_vec[error_number]; - dpy->error_vec[error_number] = proc; - } - UnlockDisplay (dpy); - return (WireToErrorType)oldproc; -} - -ErrorType XESetError( - Display *dpy, /* display */ - int extension, /* extension number */ - ErrorType proc) /* routine to call when X error happens */ -{ - register _XExtension *e; /* for lookup of extension */ - register ErrorType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->error; - e->error = proc; - UnlockDisplay(dpy); - return (ErrorType)oldproc; -} - -ErrorStringType XESetErrorString( - Display *dpy, /* display */ - int extension, /* extension number */ - ErrorStringType proc) /* routine to call when I/O error happens */ -{ - register _XExtension *e; /* for lookup of extension */ - register ErrorStringType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->error_string; - e->error_string = proc; - UnlockDisplay(dpy); - return (ErrorStringType)oldproc; -} - -PrintErrorType XESetPrintErrorValues( - Display *dpy, /* display */ - int extension, /* extension number */ - PrintErrorType proc) /* routine to call to print */ -{ - register _XExtension *e; /* for lookup of extension */ - register PrintErrorType oldproc; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->error_values; - e->error_values = proc; - UnlockDisplay(dpy); - return (PrintErrorType)oldproc; -} - -BeforeFlushType XESetBeforeFlush( - Display *dpy, /* display */ - int extension, /* extension number */ - BeforeFlushType proc) /* routine to call on flush */ -{ - register _XExtension *e; /* for lookup of extension */ - register BeforeFlushType oldproc; - register _XExtension *ext; - if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); - LockDisplay(dpy); - oldproc = e->before_flush; - e->before_flush = proc; - for (ext = dpy->flushes; ext && ext != e; ext = ext->next) - ; - if (!ext) { - e->next_flush = dpy->flushes; - dpy->flushes = e; - } - UnlockDisplay(dpy); - return (BeforeFlushType)oldproc; -} +/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xlibint.h>
+#include <X11/Xos.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*
+ * This routine is used to link a extension in so it will be called
+ * at appropriate times.
+ */
+
+XExtCodes *XInitExtension (
+ Display *dpy,
+ _Xconst char *name)
+{
+ XExtCodes codes; /* temp. place for extension information. */
+ register _XExtension *ext;/* need a place to build it all */
+ if (!XQueryExtension(dpy, name,
+ &codes.major_opcode, &codes.first_event,
+ &codes.first_error)) return (NULL);
+
+ LockDisplay (dpy);
+ if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) ||
+ ! (ext->name = strdup(name))) {
+ if (ext) Xfree((char *) ext);
+ UnlockDisplay(dpy);
+ return (XExtCodes *) NULL;
+ }
+ codes.extension = dpy->ext_number++;
+ ext->codes = codes;
+
+ /* chain it onto the display list */
+ ext->next = dpy->ext_procs;
+ dpy->ext_procs = ext;
+ UnlockDisplay (dpy);
+
+ return (&ext->codes); /* tell him which extension */
+}
+
+XExtCodes *XAddExtension (Display *dpy)
+{
+ register _XExtension *ext;
+
+ LockDisplay (dpy);
+ if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension)))) {
+ UnlockDisplay(dpy);
+ return (XExtCodes *) NULL;
+ }
+ ext->codes.extension = dpy->ext_number++;
+
+ /* chain it onto the display list */
+ ext->next = dpy->ext_procs;
+ dpy->ext_procs = ext;
+ UnlockDisplay (dpy);
+
+ return (&ext->codes); /* tell him which extension */
+}
+
+static _XExtension *XLookupExtension (
+ register Display *dpy, /* display */
+ register int extension) /* extension number */
+{
+ register _XExtension *ext;
+ for (ext = dpy->ext_procs; ext; ext = ext->next)
+ if (ext->codes.extension == extension) return (ext);
+ return (NULL);
+}
+
+XExtData **XEHeadOfExtensionList(XEDataObject object)
+{
+ return *(XExtData ***)&object;
+}
+
+int
+XAddToExtensionList(
+ XExtData **structure,
+ XExtData *ext_data)
+{
+ ext_data->next = *structure;
+ *structure = ext_data;
+ return 1;
+}
+
+XExtData *XFindOnExtensionList(
+ XExtData **structure,
+ int number)
+{
+ XExtData *ext;
+
+ ext = *structure;
+ while (ext && (ext->number != number))
+ ext = ext->next;
+ return ext;
+}
+
+/*
+ * Routines to hang procs on the extension structure.
+ */
+CreateGCType XESetCreateGC(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ CreateGCType proc) /* routine to call when GC created */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register CreateGCType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->create_GC;
+ e->create_GC = proc;
+ UnlockDisplay(dpy);
+ return (CreateGCType)oldproc;
+}
+
+CopyGCType XESetCopyGC(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ CopyGCType proc) /* routine to call when GC copied */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register CopyGCType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->copy_GC;
+ e->copy_GC = proc;
+ UnlockDisplay(dpy);
+ return (CopyGCType)oldproc;
+}
+
+FlushGCType XESetFlushGC(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ FlushGCType proc) /* routine to call when GC copied */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register FlushGCType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->flush_GC;
+ e->flush_GC = proc;
+ UnlockDisplay(dpy);
+ return (FlushGCType)oldproc;
+}
+
+FreeGCType XESetFreeGC(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ FreeGCType proc) /* routine to call when GC freed */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register FreeGCType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->free_GC;
+ e->free_GC = proc;
+ UnlockDisplay(dpy);
+ return (FreeGCType)oldproc;
+}
+
+CreateFontType XESetCreateFont(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ CreateFontType proc) /* routine to call when font created */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register CreateFontType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->create_Font;
+ e->create_Font = proc;
+ UnlockDisplay(dpy);
+ return (CreateFontType)oldproc;
+}
+
+FreeFontType XESetFreeFont(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ FreeFontType proc) /* routine to call when font freed */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register FreeFontType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->free_Font;
+ e->free_Font = proc;
+ UnlockDisplay(dpy);
+ return (FreeFontType)oldproc;
+}
+
+CloseDisplayType XESetCloseDisplay(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ CloseDisplayType proc) /* routine to call when display closed */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register CloseDisplayType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->close_display;
+ e->close_display = proc;
+ UnlockDisplay(dpy);
+ return (CloseDisplayType)oldproc;
+}
+
+typedef Bool (*WireToEventType) (
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+);
+
+WireToEventType XESetWireToEvent(
+ Display *dpy, /* display */
+ int event_number, /* event routine to replace */
+ WireToEventType proc) /* routine to call when converting event */
+{
+ register WireToEventType oldproc;
+ if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent;
+ LockDisplay (dpy);
+ oldproc = dpy->event_vec[event_number];
+ dpy->event_vec[event_number] = proc;
+ UnlockDisplay (dpy);
+ return (WireToEventType)oldproc;
+}
+
+typedef Bool (*WireToEventCookieType) (
+ Display* /* display */,
+ XGenericEventCookie* /* re */,
+ xEvent* /* event */
+);
+
+WireToEventCookieType XESetWireToEventCookie(
+ Display *dpy, /* display */
+ int extension, /* extension major opcode */
+ WireToEventCookieType proc /* routine to call for generic events */
+ )
+{
+ WireToEventCookieType oldproc;
+ if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie;
+ LockDisplay (dpy);
+ oldproc = dpy->generic_event_vec[extension & 0x7F];
+ dpy->generic_event_vec[extension & 0x7F] = proc;
+ UnlockDisplay (dpy);
+ return (WireToEventCookieType)oldproc;
+}
+
+typedef Bool (*CopyEventCookieType) (
+ Display* /* display */,
+ XGenericEventCookie* /* in */,
+ XGenericEventCookie* /* out */
+);
+
+CopyEventCookieType XESetCopyEventCookie(
+ Display *dpy, /* display */
+ int extension, /* extension major opcode */
+ CopyEventCookieType proc /* routine to copy generic events */
+ )
+{
+ CopyEventCookieType oldproc;
+ if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie;
+ LockDisplay (dpy);
+ oldproc = dpy->generic_event_copy_vec[extension & 0x7F];
+ dpy->generic_event_copy_vec[extension & 0x7F] = proc;
+ UnlockDisplay (dpy);
+ return (CopyEventCookieType)oldproc;
+}
+
+
+typedef Status (*EventToWireType) (
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+);
+
+EventToWireType XESetEventToWire(
+ Display *dpy, /* display */
+ int event_number, /* event routine to replace */
+ EventToWireType proc) /* routine to call when converting event */
+{
+ register EventToWireType oldproc;
+ if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent;
+ LockDisplay (dpy);
+ oldproc = dpy->wire_vec[event_number];
+ dpy->wire_vec[event_number] = proc;
+ UnlockDisplay(dpy);
+ return (EventToWireType)oldproc;
+}
+
+typedef Bool (*WireToErrorType) (
+ Display* /* display */,
+ XErrorEvent* /* he */,
+ xError* /* we */
+);
+
+WireToErrorType XESetWireToError(
+ Display *dpy, /* display */
+ int error_number, /* error routine to replace */
+ WireToErrorType proc) /* routine to call when converting error */
+{
+ register WireToErrorType oldproc = NULL;
+ if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError;
+ LockDisplay (dpy);
+ if (!dpy->error_vec) {
+ int i;
+ dpy->error_vec = Xmalloc(256 * sizeof(oldproc));
+ for (i = 1; i < 256; i++)
+ dpy->error_vec[i] = _XDefaultWireError;
+ }
+ if (dpy->error_vec) {
+ oldproc = dpy->error_vec[error_number];
+ dpy->error_vec[error_number] = proc;
+ }
+ UnlockDisplay (dpy);
+ return (WireToErrorType)oldproc;
+}
+
+ErrorType XESetError(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ ErrorType proc) /* routine to call when X error happens */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register ErrorType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->error;
+ e->error = proc;
+ UnlockDisplay(dpy);
+ return (ErrorType)oldproc;
+}
+
+ErrorStringType XESetErrorString(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ ErrorStringType proc) /* routine to call when I/O error happens */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register ErrorStringType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->error_string;
+ e->error_string = proc;
+ UnlockDisplay(dpy);
+ return (ErrorStringType)oldproc;
+}
+
+PrintErrorType XESetPrintErrorValues(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ PrintErrorType proc) /* routine to call to print */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register PrintErrorType oldproc;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->error_values;
+ e->error_values = proc;
+ UnlockDisplay(dpy);
+ return (PrintErrorType)oldproc;
+}
+
+BeforeFlushType XESetBeforeFlush(
+ Display *dpy, /* display */
+ int extension, /* extension number */
+ BeforeFlushType proc) /* routine to call on flush */
+{
+ register _XExtension *e; /* for lookup of extension */
+ register BeforeFlushType oldproc;
+ register _XExtension *ext;
+ if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
+ LockDisplay(dpy);
+ oldproc = e->before_flush;
+ e->before_flush = proc;
+ for (ext = dpy->flushes; ext && ext != e; ext = ext->next)
+ ;
+ if (!ext) {
+ e->next_flush = dpy->flushes;
+ dpy->flushes = e;
+ }
+ UnlockDisplay(dpy);
+ return (BeforeFlushType)oldproc;
+}
diff --git a/libX11/src/KeyBind.c b/libX11/src/KeyBind.c index 221cedd8c..82d85fbe7 100644 --- a/libX11/src/KeyBind.c +++ b/libX11/src/KeyBind.c @@ -1,1078 +1,1078 @@ -/* - -Copyright 1985, 1987, 1998 The Open Group - -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. - -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 -OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -/* Beware, here be monsters (still under construction... - JG */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xlibint.h> -#include <X11/Xutil.h> -#define XK_MISCELLANY -#define XK_LATIN1 -#define XK_LATIN2 -#define XK_LATIN3 -#define XK_LATIN4 -#define XK_LATIN8 -#define XK_LATIN9 -#define XK_CYRILLIC -#define XK_GREEK -#define XK_ARMENIAN -#define XK_CAUCASUS -#define XK_VIETNAMESE -#define XK_XKB_KEYS -#define XK_SINHALA -#include <X11/keysymdef.h> -#include <stdio.h> - -#ifdef USE_OWN_COMPOSE -#include "imComp.h" - -#endif - -#include "Xresource.h" -#include "Key.h" - -#ifdef XKB -#include "XKBlib.h" -#include "XKBlibint.h" -#define XKeycodeToKeysym _XKeycodeToKeysym -#define XKeysymToKeycode _XKeysymToKeycode -#define XLookupKeysym _XLookupKeysym -#define XRefreshKeyboardMapping _XRefreshKeyboardMapping -#define XLookupString _XLookupString -/* XKBBind.c */ -#else -#define XkbKeysymToModifiers _XKeysymToModifiers -#endif - -#define AllMods (ShiftMask|LockMask|ControlMask| \ - Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) - -static void -ComputeMaskFromKeytrans( - Display *dpy, - register struct _XKeytrans *p); - -struct _XKeytrans { - struct _XKeytrans *next;/* next on list */ - char *string; /* string to return when the time comes */ - int len; /* length of string (since NULL is legit)*/ - KeySym key; /* keysym rebound */ - unsigned int state; /* modifier state */ - KeySym *modifiers; /* modifier keysyms you want */ - int mlen; /* length of modifier list */ -}; - -static KeySym -KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col) -{ - register int per = dpy->keysyms_per_keycode; - register KeySym *syms; - KeySym lsym, usym; - - if ((col < 0) || ((col >= per) && (col > 3)) || - ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) - return NoSymbol; - - syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; - if (col < 4) { - if (col > 1) { - while ((per > 2) && (syms[per - 1] == NoSymbol)) - per--; - if (per < 3) - col -= 2; - } - if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) { - XConvertCase(syms[col&~1], &lsym, &usym); - if (!(col & 1)) - return lsym; - else if (usym == lsym) - return NoSymbol; - else - return usym; - } - } - return syms[col]; -} - -KeySym -XKeycodeToKeysym(Display *dpy, -#if NeedWidePrototypes - unsigned int kc, -#else - KeyCode kc, -#endif - int col) -{ - if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) - return NoSymbol; - return KeyCodetoKeySym(dpy, kc, col); -} - -KeyCode -XKeysymToKeycode( - Display *dpy, - KeySym ks) -{ - register int i, j; - - if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) - return (KeyCode) 0; - for (j = 0; j < dpy->keysyms_per_keycode; j++) { - for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { - if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks) - return i; - } - } - return 0; -} - -KeySym -XLookupKeysym( - register XKeyEvent *event, - int col) -{ - if ((! event->display->keysyms) && (! _XKeyInitialize(event->display))) - return NoSymbol; - return KeyCodetoKeySym(event->display, event->keycode, col); -} - -static void -ResetModMap( - Display *dpy) -{ - register XModifierKeymap *map; - register int i, j, n; - KeySym sym; - register struct _XKeytrans *p; - - map = dpy->modifiermap; - /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock, - * else if any contains Shift_Lock, then interpret as Shift_Lock, - * else ignore Lock altogether. - */ - dpy->lock_meaning = NoSymbol; - /* Lock modifiers are in the second row of the matrix */ - n = 2 * map->max_keypermod; - for (i = map->max_keypermod; i < n; i++) { - for (j = 0; j < dpy->keysyms_per_keycode; j++) { - sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); - if (sym == XK_Caps_Lock) { - dpy->lock_meaning = XK_Caps_Lock; - break; - } else if (sym == XK_Shift_Lock) { - dpy->lock_meaning = XK_Shift_Lock; - } - else if (sym == XK_ISO_Lock) { - dpy->lock_meaning = XK_Caps_Lock; - break; - } - } - } - /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */ - dpy->mode_switch = 0; - dpy->num_lock = 0; - n *= 4; - for (i = 3*map->max_keypermod; i < n; i++) { - for (j = 0; j < dpy->keysyms_per_keycode; j++) { - sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); - if (sym == XK_Mode_switch) - dpy->mode_switch |= 1 << (i / map->max_keypermod); - if (sym == XK_Num_Lock) - dpy->num_lock |= 1 << (i / map->max_keypermod); - } - } - for (p = dpy->key_bindings; p; p = p->next) - ComputeMaskFromKeytrans(dpy, p); -} - -static int -InitModMap( - Display *dpy) -{ - register XModifierKeymap *map; - - if (! (map = XGetModifierMapping(dpy))) - return 0; - LockDisplay(dpy); - if (dpy->modifiermap) - XFreeModifiermap(dpy->modifiermap); - dpy->modifiermap = map; - dpy->free_funcs->modifiermap = XFreeModifiermap; - if (dpy->keysyms) - ResetModMap(dpy); - UnlockDisplay(dpy); - return 1; -} - -int -XRefreshKeyboardMapping(register XMappingEvent *event) -{ - - if(event->request == MappingKeyboard) { - /* XXX should really only refresh what is necessary - * for now, make initialize test fail - */ - LockDisplay(event->display); - if (event->display->keysyms) { - Xfree ((char *)event->display->keysyms); - event->display->keysyms = NULL; - } - UnlockDisplay(event->display); - } - if(event->request == MappingModifier) { - LockDisplay(event->display); - if (event->display->modifiermap) { - XFreeModifiermap(event->display->modifiermap); - event->display->modifiermap = NULL; - } - UnlockDisplay(event->display); - /* go ahead and get it now, since initialize test may not fail */ - if (event->display->keysyms) - (void) InitModMap(event->display); - } - return 1; -} - -int -_XKeyInitialize( - Display *dpy) -{ - int per, n; - KeySym *keysyms; - - /* - * lets go get the keysyms from the server. - */ - if (!dpy->keysyms) { - n = dpy->max_keycode - dpy->min_keycode + 1; - keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode, - n, &per); - /* keysyms may be NULL */ - if (! keysyms) return 0; - - LockDisplay(dpy); - if (dpy->keysyms) - Xfree ((char *)dpy->keysyms); - dpy->keysyms = keysyms; - dpy->keysyms_per_keycode = per; - if (dpy->modifiermap) - ResetModMap(dpy); - UnlockDisplay(dpy); - } - if (!dpy->modifiermap) - return InitModMap(dpy); - return 1; -} - -static void -UCSConvertCase( register unsigned code, - KeySym *lower, - KeySym *upper ) -{ - /* Case conversion for UCS, as in Unicode Data version 4.0.0 */ - /* NB: Only converts simple one-to-one mappings. */ - - /* Tables are used where they take less space than */ - /* the code to work out the mappings. Zero values mean */ - /* undefined code points. */ - - static unsigned short const IPAExt_upper_mapping[] = { /* part only */ - 0x0181, 0x0186, 0x0255, 0x0189, 0x018A, - 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F, - 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, - 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C, - 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277, - 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, - 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287, - 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F, - 0x0290, 0x0291, 0x01B7 - }; - - static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */ - 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, - 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F, - 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197, - 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F, - 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7, - 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF, - 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7, - 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7, - 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7, - 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA - }; - - static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */ - 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, - 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, - 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, - 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, - 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, - 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, - 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, - 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, - 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, - 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC - }; - - static unsigned short const Greek_upper_mapping[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, - 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387, - 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F, - 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A, - 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000, - 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7, - 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE, - 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6, - 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE, - 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7, - 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000 - }; - - static unsigned short const Greek_lower_mapping[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, - 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387, - 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, - 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, - 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, - 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, - 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, - 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, - 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8, - 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000 - }; - - static unsigned short const GreekExt_lower_mapping[] = { - 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, - 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, - 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, - 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, - 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, - 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, - 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, - 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, - 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, - 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, - 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, - 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57, - 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, - 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, - 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, - 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000, - 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, - 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, - 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, - 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, - 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, - 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, - 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, - 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF, - 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, - 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, - 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, - 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, - 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, - 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, - 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, - 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000 - }; - - static unsigned short const GreekExt_upper_mapping[] = { - 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, - 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, - 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, - 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, - 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, - 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, - 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, - 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, - 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, - 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, - 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F, - 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, - 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, - 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, - 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, - 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000, - 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, - 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, - 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, - 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, - 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, - 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, - 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, - 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF, - 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, - 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF, - 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, - 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, - 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7, - 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF, - 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, - 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000 - }; - - *lower = code; - *upper = code; - - /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */ - if (code <= 0x00ff) { - if (code >= 0x0041 && code <= 0x005a) /* A-Z */ - *lower += 0x20; - else if (code >= 0x0061 && code <= 0x007a) /* a-z */ - *upper -= 0x20; - else if ( (code >= 0x00c0 && code <= 0x00d6) || - (code >= 0x00d8 && code <= 0x00de) ) - *lower += 0x20; - else if ( (code >= 0x00e0 && code <= 0x00f6) || - (code >= 0x00f8 && code <= 0x00fe) ) - *upper -= 0x20; - else if (code == 0x00ff) /* y with diaeresis */ - *upper = 0x0178; - else if (code == 0x00b5) /* micro sign */ - *upper = 0x039c; - return; - } - - /* Latin Extended-A, U+0100 to U+017F */ - if (code >= 0x0100 && code <= 0x017f) { - if ( (code >= 0x0100 && code <= 0x012f) || - (code >= 0x0132 && code <= 0x0137) || - (code >= 0x014a && code <= 0x0177) ) { - *upper = code & ~1; - *lower = code | 1; - } - else if ( (code >= 0x0139 && code <= 0x0148) || - (code >= 0x0179 && code <= 0x017e) ) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - else if (code == 0x0130) - *lower = 0x0069; - else if (code == 0x0131) - *upper = 0x0049; - else if (code == 0x0178) - *lower = 0x00ff; - else if (code == 0x017f) - *upper = 0x0053; - return; - } - - /* Latin Extended-B, U+0180 to U+024F */ - if (code >= 0x0180 && code <= 0x024f) { - if (code >= 0x01cd && code <= 0x01dc) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - else if ( (code >= 0x01de && code <= 0x01ef) || - (code >= 0x01f4 && code <= 0x01f5) || - (code >= 0x01f8 && code <= 0x021f) || - (code >= 0x0222 && code <= 0x0233) ) { - *lower |= 1; - *upper &= ~1; - } - else if (code >= 0x0180 && code <= 0x01cc) { - *lower = LatinExtB_lower_mapping[code - 0x0180]; - *upper = LatinExtB_upper_mapping[code - 0x0180]; - } - else if (code == 0x01dd) - *upper = 0x018e; - else if (code == 0x01f1 || code == 0x01f2) { - *lower = 0x01f3; - *upper = 0x01f1; - } - else if (code == 0x01f3) - *upper = 0x01f1; - else if (code == 0x01f6) - *lower = 0x0195; - else if (code == 0x01f7) - *lower = 0x01bf; - else if (code == 0x0220) - *lower = 0x019e; - return; - } - - /* IPA Extensions, U+0250 to U+02AF */ - if (code >= 0x0253 && code <= 0x0292) { - *upper = IPAExt_upper_mapping[code - 0x0253]; - } - - /* Combining Diacritical Marks, U+0300 to U+036F */ - if (code == 0x0345) { - *upper = 0x0399; - } - - /* Greek and Coptic, U+0370 to U+03FF */ - if (code >= 0x0370 && code <= 0x03ff) { - *lower = Greek_lower_mapping[code - 0x0370]; - *upper = Greek_upper_mapping[code - 0x0370]; - if (*upper == 0) - *upper = code; - if (*lower == 0) - *lower = code; - } - - /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */ - if ( (code >= 0x0400 && code <= 0x04ff) || - (code >= 0x0500 && code <= 0x052f) ) { - if (code >= 0x0400 && code <= 0x040f) - *lower += 0x50; - else if (code >= 0x0410 && code <= 0x042f) - *lower += 0x20; - else if (code >= 0x0430 && code <= 0x044f) - *upper -= 0x20; - else if (code >= 0x0450 && code <= 0x045f) - *upper -= 0x50; - else if ( (code >= 0x0460 && code <= 0x0481) || - (code >= 0x048a && code <= 0x04bf) || - (code >= 0x04d0 && code <= 0x04f5) || - (code >= 0x04f8 && code <= 0x04f9) || - (code >= 0x0500 && code <= 0x050f) ) { - *upper &= ~1; - *lower |= 1; - } - else if (code >= 0x04c1 && code <= 0x04ce) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - } - - /* Armenian, U+0530 to U+058F */ - if (code >= 0x0530 && code <= 0x058f) { - if (code >= 0x0531 && code <= 0x0556) - *lower += 0x30; - else if (code >=0x0561 && code <= 0x0586) - *upper -= 0x30; - } - - /* Latin Extended Additional, U+1E00 to U+1EFF */ - if (code >= 0x1e00 && code <= 0x1eff) { - if ( (code >= 0x1e00 && code <= 0x1e95) || - (code >= 0x1ea0 && code <= 0x1ef9) ) { - *upper &= ~1; - *lower |= 1; - } - else if (code == 0x1e9b) - *upper = 0x1e60; - } - - /* Greek Extended, U+1F00 to U+1FFF */ - if (code >= 0x1f00 && code <= 0x1fff) { - *lower = GreekExt_lower_mapping[code - 0x1f00]; - *upper = GreekExt_upper_mapping[code - 0x1f00]; - if (*upper == 0) - *upper = code; - if (*lower == 0) - *lower = code; - } - - /* Letterlike Symbols, U+2100 to U+214F */ - if (code >= 0x2100 && code <= 0x214f) { - switch (code) { - case 0x2126: *lower = 0x03c9; break; - case 0x212a: *lower = 0x006b; break; - case 0x212b: *lower = 0x00e5; break; - } - } - /* Number Forms, U+2150 to U+218F */ - else if (code >= 0x2160 && code <= 0x216f) - *lower += 0x10; - else if (code >= 0x2170 && code <= 0x217f) - *upper -= 0x10; - /* Enclosed Alphanumerics, U+2460 to U+24FF */ - else if (code >= 0x24b6 && code <= 0x24cf) - *lower += 0x1a; - else if (code >= 0x24d0 && code <= 0x24e9) - *upper -= 0x1a; - /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */ - else if (code >= 0xff21 && code <= 0xff3a) - *lower += 0x20; - else if (code >= 0xff41 && code <= 0xff5a) - *upper -= 0x20; - /* Deseret, U+10400 to U+104FF */ - else if (code >= 0x10400 && code <= 0x10427) - *lower += 0x28; - else if (code >= 0x10428 && code <= 0x1044f) - *upper -= 0x28; -} - -void -XConvertCase( - register KeySym sym, - KeySym *lower, - KeySym *upper) -{ - /* Latin 1 keysym */ - if (sym < 0x100) { - UCSConvertCase(sym, lower, upper); - return; - } - - /* Unicode keysym */ - if ((sym & 0xff000000) == 0x01000000) { - UCSConvertCase((sym & 0x00ffffff), lower, upper); - *upper |= 0x01000000; - *lower |= 0x01000000; - return; - } - - /* Legacy keysym */ - - *lower = sym; - *upper = sym; - - switch(sym >> 8) { - 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 0x13: /* Latin 9 */ - if (sym == XK_OE) - *lower = XK_oe; - else if (sym == XK_oe) - *upper = XK_OE; - else if (sym == XK_Ydiaeresis) - *lower = XK_ydiaeresis; - break; - } -} - -int -_XTranslateKey( register Display *dpy, - KeyCode keycode, - register unsigned int modifiers, - unsigned int *modifiers_return, - KeySym *keysym_return) -{ - int per; - register KeySym *syms; - KeySym sym, lsym, usym; - - if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) - return 0; - *modifiers_return = ((ShiftMask|LockMask) - | dpy->mode_switch | dpy->num_lock); - if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) - { - *keysym_return = NoSymbol; - return 1; - } - per = dpy->keysyms_per_keycode; - syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; - while ((per > 2) && (syms[per - 1] == NoSymbol)) - per--; - if ((per > 2) && (modifiers & dpy->mode_switch)) { - syms += 2; - per -= 2; - } - if ((modifiers & dpy->num_lock) && - (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) { - if ((modifiers & ShiftMask) || - ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock))) - *keysym_return = syms[0]; - else - *keysym_return = syms[1]; - } else if (!(modifiers & ShiftMask) && - (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) { - if ((per == 1) || (syms[1] == NoSymbol)) - XConvertCase(syms[0], keysym_return, &usym); - else - *keysym_return = syms[0]; - } else if (!(modifiers & LockMask) || - (dpy->lock_meaning != XK_Caps_Lock)) { - if ((per == 1) || ((usym = syms[1]) == NoSymbol)) - XConvertCase(syms[0], &lsym, &usym); - *keysym_return = usym; - } else { - if ((per == 1) || ((sym = syms[1]) == NoSymbol)) - sym = syms[0]; - XConvertCase(sym, &lsym, &usym); - if (!(modifiers & ShiftMask) && (sym != syms[0]) && - ((sym != usym) || (lsym == usym))) - XConvertCase(syms[0], &lsym, &usym); - *keysym_return = usym; - } - if (*keysym_return == XK_VoidSymbol) - *keysym_return = NoSymbol; - return 1; -} - -int -_XTranslateKeySym( - Display *dpy, - register KeySym symbol, - unsigned int modifiers, - char *buffer, - int nbytes) -{ - register struct _XKeytrans *p; - int length; - unsigned long hiBytes; - register unsigned char c; - - if (!symbol) - return 0; - /* see if symbol rebound, if so, return that string. */ - for (p = dpy->key_bindings; p; p = p->next) { - if (((modifiers & AllMods) == p->state) && (symbol == p->key)) { - length = p->len; - if (length > nbytes) length = nbytes; - memcpy (buffer, p->string, length); - return length; - } - } - /* try to convert to Latin-1, handling control */ - hiBytes = symbol >> 8; - if (!(nbytes && - ((hiBytes == 0) || - ((hiBytes == 0xFF) && - (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) || - (symbol == XK_Return) || - (symbol == XK_Escape) || - (symbol == XK_KP_Space) || - (symbol == XK_KP_Tab) || - (symbol == XK_KP_Enter) || - ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) || - (symbol == XK_KP_Equal) || - (symbol == XK_Delete)))))) - return 0; - - /* if X keysym, convert to ascii by grabbing low 7 bits */ - if (symbol == XK_KP_Space) - c = XK_space & 0x7F; /* patch encoding botch */ - else if (hiBytes == 0xFF) - c = symbol & 0x7F; - else - c = symbol & 0xFF; - /* only apply Control key if it makes sense, else ignore it */ - if (modifiers & ControlMask) { - if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; - else if (c == '2') c = '\000'; - else if (c >= '3' && c <= '7') c -= ('3' - '\033'); - else if (c == '8') c = '\177'; - else if (c == '/') c = '_' & 0x1F; - } - buffer[0] = c; - return 1; -} - -/*ARGSUSED*/ -int -XLookupString ( - register XKeyEvent *event, - char *buffer, /* buffer */ - int nbytes, /* space in buffer for characters */ - KeySym *keysym, - XComposeStatus *status) /* not implemented */ -{ - unsigned int modifiers; - KeySym symbol; - - if (! _XTranslateKey(event->display, event->keycode, event->state, - &modifiers, &symbol)) - return 0; - -#ifdef USE_OWN_COMPOSE - if ( status ) { - static int been_here= 0; - if ( !been_here ) { - XimCompInitTables(); - been_here = 1; - } - if ( !XimCompLegalStatus(status) ) { - status->compose_ptr = NULL; - status->chars_matched = 0; - } - if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) || - XimCompIsComposeKey(symbol,event->keycode,status) ) { - XimCompRtrn rtrn; - switch (XimCompProcessSym(status,symbol,&rtrn)) { - case XIM_COMP_IGNORE: - break; - case XIM_COMP_IN_PROGRESS: - if ( keysym!=NULL ) - *keysym = NoSymbol; - return 0; - case XIM_COMP_FAIL: - { - int n = 0, len= 0; - for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { - if ( nbytes-len > 0 ) { - len+= _XTranslateKeySym(event->display,rtrn.sym[n], - event->state, - buffer+len,nbytes-len); - } - } - if ( keysym!=NULL ) { - if ( n==1 ) *keysym = rtrn.sym[0]; - else *keysym = NoSymbol; - } - return len; - } - case XIM_COMP_SUCCEED: - { - int len,n = 0; - - symbol = rtrn.matchSym; - if ( keysym!=NULL ) *keysym = symbol; - if ( rtrn.str[0]!='\0' ) { - strncpy(buffer,rtrn.str,nbytes-1); - buffer[nbytes-1]= '\0'; - len = strlen(buffer); - } - else { - len = _XTranslateKeySym(event->display,symbol, - event->state, - buffer,nbytes); - } - for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) { - if ( nbytes-len > 0 ) { - len+= _XTranslateKeySym(event->display,rtrn.sym[n], - event->state, - buffer+len,nbytes-len); - } - } - return len; - } - } - } - } -#endif - - if (keysym) - *keysym = symbol; - /* arguable whether to use (event->state & ~modifiers) here */ - return _XTranslateKeySym(event->display, symbol, event->state, - buffer, nbytes); -} - -static void -_XFreeKeyBindings( - Display *dpy) -{ - register struct _XKeytrans *p, *np; - - for (p = dpy->key_bindings; p; p = np) { - np = p->next; - Xfree(p->string); - Xfree((char *)p->modifiers); - Xfree((char *)p); - } -} - -int -XRebindKeysym ( - Display *dpy, - KeySym keysym, - KeySym *mlist, - int nm, /* number of modifiers in mlist */ - _Xconst unsigned char *str, - int nbytes) -{ - register struct _XKeytrans *tmp, *p; - int nb; - - if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) - return 0; - LockDisplay(dpy); - tmp = dpy->key_bindings; - nb = sizeof(KeySym) * nm; - - if ((! (p = (struct _XKeytrans *) Xcalloc( 1, sizeof(struct _XKeytrans)))) || - ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) && - (nbytes > 0)) || - ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) && - (nb > 0))) { - if (p) { - if (p->string) Xfree(p->string); - if (p->modifiers) Xfree((char *) p->modifiers); - Xfree((char *) p); - } - UnlockDisplay(dpy); - return 0; - } - - dpy->key_bindings = p; - dpy->free_funcs->key_bindings = _XFreeKeyBindings; - p->next = tmp; /* chain onto list */ - memcpy (p->string, (char *) str, nbytes); - p->len = nbytes; - memcpy ((char *) p->modifiers, (char *) mlist, nb); - p->key = keysym; - p->mlen = nm; - ComputeMaskFromKeytrans(dpy, p); - UnlockDisplay(dpy); - return 0; -} - -unsigned -_XKeysymToModifiers( - Display *dpy, - KeySym ks) -{ - CARD8 code,mods; - register KeySym *kmax; - register KeySym *k; - register XModifierKeymap *m; - - if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) - return 0; - kmax = dpy->keysyms + - (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; - k = dpy->keysyms; - m = dpy->modifiermap; - mods= 0; - while (k<kmax) { - if (*k == ks ) { - register int j = m->max_keypermod<<3; - - code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode); - - while (--j >= 0) { - if (code == m->modifiermap[j]) - mods|= (1<<(j/m->max_keypermod)); - } - } - k++; - } - return mods; -} - -/* - * given a list of modifiers, computes the mask necessary for later matching. - * This routine must lookup the key in the Keymap and then search to see - * what modifier it is bound to, if any. Sets the AnyModifier bit if it - * can't map some keysym to a modifier. - */ -static void -ComputeMaskFromKeytrans( - Display *dpy, - register struct _XKeytrans *p) -{ - register int i; - - p->state = AnyModifier; - for (i = 0; i < p->mlen; i++) { - p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); - } - p->state &= AllMods; -} +/*
+
+Copyright 1985, 1987, 1998 The Open Group
+
+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.
+
+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
+OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+/* Beware, here be monsters (still under construction... - JG */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_LATIN2
+#define XK_LATIN3
+#define XK_LATIN4
+#define XK_LATIN8
+#define XK_LATIN9
+#define XK_CYRILLIC
+#define XK_GREEK
+#define XK_ARMENIAN
+#define XK_CAUCASUS
+#define XK_VIETNAMESE
+#define XK_XKB_KEYS
+#define XK_SINHALA
+#include <X11/keysymdef.h>
+#include <stdio.h>
+
+#ifdef USE_OWN_COMPOSE
+#include "imComp.h"
+
+#endif
+
+#include "Xresource.h"
+#include "Key.h"
+
+#ifdef XKB
+#include "XKBlib.h"
+#include "XKBlibint.h"
+#define XKeycodeToKeysym _XKeycodeToKeysym
+#define XKeysymToKeycode _XKeysymToKeycode
+#define XLookupKeysym _XLookupKeysym
+#define XRefreshKeyboardMapping _XRefreshKeyboardMapping
+#define XLookupString _XLookupString
+/* XKBBind.c */
+#else
+#define XkbKeysymToModifiers _XKeysymToModifiers
+#endif
+
+#define AllMods (ShiftMask|LockMask|ControlMask| \
+ Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
+
+static void
+ComputeMaskFromKeytrans(
+ Display *dpy,
+ register struct _XKeytrans *p);
+
+struct _XKeytrans {
+ struct _XKeytrans *next;/* next on list */
+ char *string; /* string to return when the time comes */
+ int len; /* length of string (since NULL is legit)*/
+ KeySym key; /* keysym rebound */
+ unsigned int state; /* modifier state */
+ KeySym *modifiers; /* modifier keysyms you want */
+ int mlen; /* length of modifier list */
+};
+
+static KeySym
+KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
+{
+ register int per = dpy->keysyms_per_keycode;
+ register KeySym *syms;
+ KeySym lsym, usym;
+
+ if ((col < 0) || ((col >= per) && (col > 3)) ||
+ ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
+ return NoSymbol;
+
+ syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
+ if (col < 4) {
+ if (col > 1) {
+ while ((per > 2) && (syms[per - 1] == NoSymbol))
+ per--;
+ if (per < 3)
+ col -= 2;
+ }
+ if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
+ XConvertCase(syms[col&~1], &lsym, &usym);
+ if (!(col & 1))
+ return lsym;
+ else if (usym == lsym)
+ return NoSymbol;
+ else
+ return usym;
+ }
+ }
+ return syms[col];
+}
+
+KeySym
+XKeycodeToKeysym(Display *dpy,
+#if NeedWidePrototypes
+ unsigned int kc,
+#else
+ KeyCode kc,
+#endif
+ int col)
+{
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return NoSymbol;
+ return KeyCodetoKeySym(dpy, kc, col);
+}
+
+KeyCode
+XKeysymToKeycode(
+ Display *dpy,
+ KeySym ks)
+{
+ register int i, j;
+
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return (KeyCode) 0;
+ for (j = 0; j < dpy->keysyms_per_keycode; j++) {
+ for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
+ if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks)
+ return i;
+ }
+ }
+ return 0;
+}
+
+KeySym
+XLookupKeysym(
+ register XKeyEvent *event,
+ int col)
+{
+ if ((! event->display->keysyms) && (! _XKeyInitialize(event->display)))
+ return NoSymbol;
+ return KeyCodetoKeySym(event->display, event->keycode, col);
+}
+
+static void
+ResetModMap(
+ Display *dpy)
+{
+ register XModifierKeymap *map;
+ register int i, j, n;
+ KeySym sym;
+ register struct _XKeytrans *p;
+
+ map = dpy->modifiermap;
+ /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock,
+ * else if any contains Shift_Lock, then interpret as Shift_Lock,
+ * else ignore Lock altogether.
+ */
+ dpy->lock_meaning = NoSymbol;
+ /* Lock modifiers are in the second row of the matrix */
+ n = 2 * map->max_keypermod;
+ for (i = map->max_keypermod; i < n; i++) {
+ for (j = 0; j < dpy->keysyms_per_keycode; j++) {
+ sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
+ if (sym == XK_Caps_Lock) {
+ dpy->lock_meaning = XK_Caps_Lock;
+ break;
+ } else if (sym == XK_Shift_Lock) {
+ dpy->lock_meaning = XK_Shift_Lock;
+ }
+ else if (sym == XK_ISO_Lock) {
+ dpy->lock_meaning = XK_Caps_Lock;
+ break;
+ }
+ }
+ }
+ /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
+ dpy->mode_switch = 0;
+ dpy->num_lock = 0;
+ n *= 4;
+ for (i = 3*map->max_keypermod; i < n; i++) {
+ for (j = 0; j < dpy->keysyms_per_keycode; j++) {
+ sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
+ if (sym == XK_Mode_switch)
+ dpy->mode_switch |= 1 << (i / map->max_keypermod);
+ if (sym == XK_Num_Lock)
+ dpy->num_lock |= 1 << (i / map->max_keypermod);
+ }
+ }
+ for (p = dpy->key_bindings; p; p = p->next)
+ ComputeMaskFromKeytrans(dpy, p);
+}
+
+static int
+InitModMap(
+ Display *dpy)
+{
+ register XModifierKeymap *map;
+
+ if (! (map = XGetModifierMapping(dpy)))
+ return 0;
+ LockDisplay(dpy);
+ if (dpy->modifiermap)
+ XFreeModifiermap(dpy->modifiermap);
+ dpy->modifiermap = map;
+ dpy->free_funcs->modifiermap = XFreeModifiermap;
+ if (dpy->keysyms)
+ ResetModMap(dpy);
+ UnlockDisplay(dpy);
+ return 1;
+}
+
+int
+XRefreshKeyboardMapping(register XMappingEvent *event)
+{
+
+ if(event->request == MappingKeyboard) {
+ /* XXX should really only refresh what is necessary
+ * for now, make initialize test fail
+ */
+ LockDisplay(event->display);
+ if (event->display->keysyms) {
+ Xfree ((char *)event->display->keysyms);
+ event->display->keysyms = NULL;
+ }
+ UnlockDisplay(event->display);
+ }
+ if(event->request == MappingModifier) {
+ LockDisplay(event->display);
+ if (event->display->modifiermap) {
+ XFreeModifiermap(event->display->modifiermap);
+ event->display->modifiermap = NULL;
+ }
+ UnlockDisplay(event->display);
+ /* go ahead and get it now, since initialize test may not fail */
+ if (event->display->keysyms)
+ (void) InitModMap(event->display);
+ }
+ return 1;
+}
+
+int
+_XKeyInitialize(
+ Display *dpy)
+{
+ int per, n;
+ KeySym *keysyms;
+
+ /*
+ * lets go get the keysyms from the server.
+ */
+ if (!dpy->keysyms) {
+ n = dpy->max_keycode - dpy->min_keycode + 1;
+ keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode,
+ n, &per);
+ /* keysyms may be NULL */
+ if (! keysyms) return 0;
+
+ LockDisplay(dpy);
+ if (dpy->keysyms)
+ Xfree ((char *)dpy->keysyms);
+ dpy->keysyms = keysyms;
+ dpy->keysyms_per_keycode = per;
+ if (dpy->modifiermap)
+ ResetModMap(dpy);
+ UnlockDisplay(dpy);
+ }
+ if (!dpy->modifiermap)
+ return InitModMap(dpy);
+ return 1;
+}
+
+static void
+UCSConvertCase( register unsigned code,
+ KeySym *lower,
+ KeySym *upper )
+{
+ /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
+ /* NB: Only converts simple one-to-one mappings. */
+
+ /* Tables are used where they take less space than */
+ /* the code to work out the mappings. Zero values mean */
+ /* undefined code points. */
+
+ static unsigned short const IPAExt_upper_mapping[] = { /* part only */
+ 0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
+ 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
+ 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
+ 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
+ 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
+ 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
+ 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
+ 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
+ 0x0290, 0x0291, 0x01B7
+ };
+
+ static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */
+ 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
+ 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
+ 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
+ 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
+ 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
+ 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
+ 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
+ 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
+ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
+ 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
+ };
+
+ static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */
+ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
+ 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
+ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
+ 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
+ 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
+ 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
+ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
+ 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
+ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
+ 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
+ };
+
+ static unsigned short const Greek_upper_mapping[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
+ 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
+ 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
+ 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
+ 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
+ 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
+ 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
+ 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
+ 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ static unsigned short const Greek_lower_mapping[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
+ 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
+ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
+ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
+ 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
+ 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
+ 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
+ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
+ 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ static unsigned short const GreekExt_lower_mapping[] = {
+ 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
+ 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
+ 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
+ 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
+ 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
+ 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
+ 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
+ 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
+ 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
+ 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
+ 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
+ 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
+ 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
+ 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
+ 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
+ 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
+ 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
+ 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
+ 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
+ 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
+ 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
+ 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
+ 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
+ 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
+ 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
+ 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
+ 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
+ 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
+ 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
+ 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
+ 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
+ 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
+ };
+
+ static unsigned short const GreekExt_upper_mapping[] = {
+ 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
+ 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
+ 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
+ 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
+ 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
+ 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
+ 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
+ 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
+ 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
+ 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
+ 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
+ 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
+ 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
+ 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
+ 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
+ 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
+ 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
+ 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
+ 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
+ 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
+ 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
+ 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
+ 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
+ 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
+ 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
+ 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
+ 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
+ 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
+ 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
+ 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
+ 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
+ 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
+ };
+
+ *lower = code;
+ *upper = code;
+
+ /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
+ if (code <= 0x00ff) {
+ if (code >= 0x0041 && code <= 0x005a) /* A-Z */
+ *lower += 0x20;
+ else if (code >= 0x0061 && code <= 0x007a) /* a-z */
+ *upper -= 0x20;
+ else if ( (code >= 0x00c0 && code <= 0x00d6) ||
+ (code >= 0x00d8 && code <= 0x00de) )
+ *lower += 0x20;
+ else if ( (code >= 0x00e0 && code <= 0x00f6) ||
+ (code >= 0x00f8 && code <= 0x00fe) )
+ *upper -= 0x20;
+ else if (code == 0x00ff) /* y with diaeresis */
+ *upper = 0x0178;
+ else if (code == 0x00b5) /* micro sign */
+ *upper = 0x039c;
+ return;
+ }
+
+ /* Latin Extended-A, U+0100 to U+017F */
+ if (code >= 0x0100 && code <= 0x017f) {
+ if ( (code >= 0x0100 && code <= 0x012f) ||
+ (code >= 0x0132 && code <= 0x0137) ||
+ (code >= 0x014a && code <= 0x0177) ) {
+ *upper = code & ~1;
+ *lower = code | 1;
+ }
+ else if ( (code >= 0x0139 && code <= 0x0148) ||
+ (code >= 0x0179 && code <= 0x017e) ) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ else if (code == 0x0130)
+ *lower = 0x0069;
+ else if (code == 0x0131)
+ *upper = 0x0049;
+ else if (code == 0x0178)
+ *lower = 0x00ff;
+ else if (code == 0x017f)
+ *upper = 0x0053;
+ return;
+ }
+
+ /* Latin Extended-B, U+0180 to U+024F */
+ if (code >= 0x0180 && code <= 0x024f) {
+ if (code >= 0x01cd && code <= 0x01dc) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ else if ( (code >= 0x01de && code <= 0x01ef) ||
+ (code >= 0x01f4 && code <= 0x01f5) ||
+ (code >= 0x01f8 && code <= 0x021f) ||
+ (code >= 0x0222 && code <= 0x0233) ) {
+ *lower |= 1;
+ *upper &= ~1;
+ }
+ else if (code >= 0x0180 && code <= 0x01cc) {
+ *lower = LatinExtB_lower_mapping[code - 0x0180];
+ *upper = LatinExtB_upper_mapping[code - 0x0180];
+ }
+ else if (code == 0x01dd)
+ *upper = 0x018e;
+ else if (code == 0x01f1 || code == 0x01f2) {
+ *lower = 0x01f3;
+ *upper = 0x01f1;
+ }
+ else if (code == 0x01f3)
+ *upper = 0x01f1;
+ else if (code == 0x01f6)
+ *lower = 0x0195;
+ else if (code == 0x01f7)
+ *lower = 0x01bf;
+ else if (code == 0x0220)
+ *lower = 0x019e;
+ return;
+ }
+
+ /* IPA Extensions, U+0250 to U+02AF */
+ if (code >= 0x0253 && code <= 0x0292) {
+ *upper = IPAExt_upper_mapping[code - 0x0253];
+ }
+
+ /* Combining Diacritical Marks, U+0300 to U+036F */
+ if (code == 0x0345) {
+ *upper = 0x0399;
+ }
+
+ /* Greek and Coptic, U+0370 to U+03FF */
+ if (code >= 0x0370 && code <= 0x03ff) {
+ *lower = Greek_lower_mapping[code - 0x0370];
+ *upper = Greek_upper_mapping[code - 0x0370];
+ if (*upper == 0)
+ *upper = code;
+ if (*lower == 0)
+ *lower = code;
+ }
+
+ /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
+ if ( (code >= 0x0400 && code <= 0x04ff) ||
+ (code >= 0x0500 && code <= 0x052f) ) {
+ if (code >= 0x0400 && code <= 0x040f)
+ *lower += 0x50;
+ else if (code >= 0x0410 && code <= 0x042f)
+ *lower += 0x20;
+ else if (code >= 0x0430 && code <= 0x044f)
+ *upper -= 0x20;
+ else if (code >= 0x0450 && code <= 0x045f)
+ *upper -= 0x50;
+ else if ( (code >= 0x0460 && code <= 0x0481) ||
+ (code >= 0x048a && code <= 0x04bf) ||
+ (code >= 0x04d0 && code <= 0x04f5) ||
+ (code >= 0x04f8 && code <= 0x04f9) ||
+ (code >= 0x0500 && code <= 0x050f) ) {
+ *upper &= ~1;
+ *lower |= 1;
+ }
+ else if (code >= 0x04c1 && code <= 0x04ce) {
+ if (code & 1)
+ *lower += 1;
+ else
+ *upper -= 1;
+ }
+ }
+
+ /* Armenian, U+0530 to U+058F */
+ if (code >= 0x0530 && code <= 0x058f) {
+ if (code >= 0x0531 && code <= 0x0556)
+ *lower += 0x30;
+ else if (code >=0x0561 && code <= 0x0586)
+ *upper -= 0x30;
+ }
+
+ /* Latin Extended Additional, U+1E00 to U+1EFF */
+ if (code >= 0x1e00 && code <= 0x1eff) {
+ if ( (code >= 0x1e00 && code <= 0x1e95) ||
+ (code >= 0x1ea0 && code <= 0x1ef9) ) {
+ *upper &= ~1;
+ *lower |= 1;
+ }
+ else if (code == 0x1e9b)
+ *upper = 0x1e60;
+ }
+
+ /* Greek Extended, U+1F00 to U+1FFF */
+ if (code >= 0x1f00 && code <= 0x1fff) {
+ *lower = GreekExt_lower_mapping[code - 0x1f00];
+ *upper = GreekExt_upper_mapping[code - 0x1f00];
+ if (*upper == 0)
+ *upper = code;
+ if (*lower == 0)
+ *lower = code;
+ }
+
+ /* Letterlike Symbols, U+2100 to U+214F */
+ if (code >= 0x2100 && code <= 0x214f) {
+ switch (code) {
+ case 0x2126: *lower = 0x03c9; break;
+ case 0x212a: *lower = 0x006b; break;
+ case 0x212b: *lower = 0x00e5; break;
+ }
+ }
+ /* Number Forms, U+2150 to U+218F */
+ else if (code >= 0x2160 && code <= 0x216f)
+ *lower += 0x10;
+ else if (code >= 0x2170 && code <= 0x217f)
+ *upper -= 0x10;
+ /* Enclosed Alphanumerics, U+2460 to U+24FF */
+ else if (code >= 0x24b6 && code <= 0x24cf)
+ *lower += 0x1a;
+ else if (code >= 0x24d0 && code <= 0x24e9)
+ *upper -= 0x1a;
+ /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
+ else if (code >= 0xff21 && code <= 0xff3a)
+ *lower += 0x20;
+ else if (code >= 0xff41 && code <= 0xff5a)
+ *upper -= 0x20;
+ /* Deseret, U+10400 to U+104FF */
+ else if (code >= 0x10400 && code <= 0x10427)
+ *lower += 0x28;
+ else if (code >= 0x10428 && code <= 0x1044f)
+ *upper -= 0x28;
+}
+
+void
+XConvertCase(
+ register KeySym sym,
+ KeySym *lower,
+ KeySym *upper)
+{
+ /* Latin 1 keysym */
+ if (sym < 0x100) {
+ UCSConvertCase(sym, lower, upper);
+ return;
+ }
+
+ /* Unicode keysym */
+ if ((sym & 0xff000000) == 0x01000000) {
+ UCSConvertCase((sym & 0x00ffffff), lower, upper);
+ *upper |= 0x01000000;
+ *lower |= 0x01000000;
+ return;
+ }
+
+ /* Legacy keysym */
+
+ *lower = sym;
+ *upper = sym;
+
+ switch(sym >> 8) {
+ 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 0x13: /* Latin 9 */
+ if (sym == XK_OE)
+ *lower = XK_oe;
+ else if (sym == XK_oe)
+ *upper = XK_OE;
+ else if (sym == XK_Ydiaeresis)
+ *lower = XK_ydiaeresis;
+ break;
+ }
+}
+
+int
+_XTranslateKey( register Display *dpy,
+ KeyCode keycode,
+ register unsigned int modifiers,
+ unsigned int *modifiers_return,
+ KeySym *keysym_return)
+{
+ int per;
+ register KeySym *syms;
+ KeySym sym, lsym, usym;
+
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return 0;
+ *modifiers_return = ((ShiftMask|LockMask)
+ | dpy->mode_switch | dpy->num_lock);
+ if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
+ {
+ *keysym_return = NoSymbol;
+ return 1;
+ }
+ per = dpy->keysyms_per_keycode;
+ syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
+ while ((per > 2) && (syms[per - 1] == NoSymbol))
+ per--;
+ if ((per > 2) && (modifiers & dpy->mode_switch)) {
+ syms += 2;
+ per -= 2;
+ }
+ if ((modifiers & dpy->num_lock) &&
+ (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
+ if ((modifiers & ShiftMask) ||
+ ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
+ *keysym_return = syms[0];
+ else
+ *keysym_return = syms[1];
+ } else if (!(modifiers & ShiftMask) &&
+ (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
+ if ((per == 1) || (syms[1] == NoSymbol))
+ XConvertCase(syms[0], keysym_return, &usym);
+ else
+ *keysym_return = syms[0];
+ } else if (!(modifiers & LockMask) ||
+ (dpy->lock_meaning != XK_Caps_Lock)) {
+ if ((per == 1) || ((usym = syms[1]) == NoSymbol))
+ XConvertCase(syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ } else {
+ if ((per == 1) || ((sym = syms[1]) == NoSymbol))
+ sym = syms[0];
+ XConvertCase(sym, &lsym, &usym);
+ if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
+ ((sym != usym) || (lsym == usym)))
+ XConvertCase(syms[0], &lsym, &usym);
+ *keysym_return = usym;
+ }
+ if (*keysym_return == XK_VoidSymbol)
+ *keysym_return = NoSymbol;
+ return 1;
+}
+
+int
+_XTranslateKeySym(
+ Display *dpy,
+ register KeySym symbol,
+ unsigned int modifiers,
+ char *buffer,
+ int nbytes)
+{
+ register struct _XKeytrans *p;
+ int length;
+ unsigned long hiBytes;
+ register unsigned char c;
+
+ if (!symbol)
+ return 0;
+ /* see if symbol rebound, if so, return that string. */
+ for (p = dpy->key_bindings; p; p = p->next) {
+ if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
+ length = p->len;
+ if (length > nbytes) length = nbytes;
+ memcpy (buffer, p->string, length);
+ return length;
+ }
+ }
+ /* try to convert to Latin-1, handling control */
+ hiBytes = symbol >> 8;
+ if (!(nbytes &&
+ ((hiBytes == 0) ||
+ ((hiBytes == 0xFF) &&
+ (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
+ (symbol == XK_Return) ||
+ (symbol == XK_Escape) ||
+ (symbol == XK_KP_Space) ||
+ (symbol == XK_KP_Tab) ||
+ (symbol == XK_KP_Enter) ||
+ ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
+ (symbol == XK_KP_Equal) ||
+ (symbol == XK_Delete))))))
+ return 0;
+
+ /* if X keysym, convert to ascii by grabbing low 7 bits */
+ if (symbol == XK_KP_Space)
+ c = XK_space & 0x7F; /* patch encoding botch */
+ else if (hiBytes == 0xFF)
+ c = symbol & 0x7F;
+ else
+ c = symbol & 0xFF;
+ /* only apply Control key if it makes sense, else ignore it */
+ if (modifiers & ControlMask) {
+ if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
+ else if (c == '2') c = '\000';
+ else if (c >= '3' && c <= '7') c -= ('3' - '\033');
+ else if (c == '8') c = '\177';
+ else if (c == '/') c = '_' & 0x1F;
+ }
+ buffer[0] = c;
+ return 1;
+}
+
+/*ARGSUSED*/
+int
+XLookupString (
+ register XKeyEvent *event,
+ char *buffer, /* buffer */
+ int nbytes, /* space in buffer for characters */
+ KeySym *keysym,
+ XComposeStatus *status) /* not implemented */
+{
+ unsigned int modifiers;
+ KeySym symbol;
+
+ if (! _XTranslateKey(event->display, event->keycode, event->state,
+ &modifiers, &symbol))
+ return 0;
+
+#ifdef USE_OWN_COMPOSE
+ if ( status ) {
+ static int been_here= 0;
+ if ( !been_here ) {
+ XimCompInitTables();
+ been_here = 1;
+ }
+ if ( !XimCompLegalStatus(status) ) {
+ status->compose_ptr = NULL;
+ status->chars_matched = 0;
+ }
+ if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
+ XimCompIsComposeKey(symbol,event->keycode,status) ) {
+ XimCompRtrn rtrn;
+ switch (XimCompProcessSym(status,symbol,&rtrn)) {
+ case XIM_COMP_IGNORE:
+ break;
+ case XIM_COMP_IN_PROGRESS:
+ if ( keysym!=NULL )
+ *keysym = NoSymbol;
+ return 0;
+ case XIM_COMP_FAIL:
+ {
+ int n = 0, len= 0;
+ for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
+ if ( nbytes-len > 0 ) {
+ len+= _XTranslateKeySym(event->display,rtrn.sym[n],
+ event->state,
+ buffer+len,nbytes-len);
+ }
+ }
+ if ( keysym!=NULL ) {
+ if ( n==1 ) *keysym = rtrn.sym[0];
+ else *keysym = NoSymbol;
+ }
+ return len;
+ }
+ case XIM_COMP_SUCCEED:
+ {
+ int len,n = 0;
+
+ symbol = rtrn.matchSym;
+ if ( keysym!=NULL ) *keysym = symbol;
+ if ( rtrn.str[0]!='\0' ) {
+ strncpy(buffer,rtrn.str,nbytes-1);
+ buffer[nbytes-1]= '\0';
+ len = strlen(buffer);
+ }
+ else {
+ len = _XTranslateKeySym(event->display,symbol,
+ event->state,
+ buffer,nbytes);
+ }
+ for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
+ if ( nbytes-len > 0 ) {
+ len+= _XTranslateKeySym(event->display,rtrn.sym[n],
+ event->state,
+ buffer+len,nbytes-len);
+ }
+ }
+ return len;
+ }
+ }
+ }
+ }
+#endif
+
+ if (keysym)
+ *keysym = symbol;
+ /* arguable whether to use (event->state & ~modifiers) here */
+ return _XTranslateKeySym(event->display, symbol, event->state,
+ buffer, nbytes);
+}
+
+static void
+_XFreeKeyBindings(
+ Display *dpy)
+{
+ register struct _XKeytrans *p, *np;
+
+ for (p = dpy->key_bindings; p; p = np) {
+ np = p->next;
+ Xfree(p->string);
+ Xfree((char *)p->modifiers);
+ Xfree((char *)p);
+ }
+}
+
+int
+XRebindKeysym (
+ Display *dpy,
+ KeySym keysym,
+ KeySym *mlist,
+ int nm, /* number of modifiers in mlist */
+ _Xconst unsigned char *str,
+ int nbytes)
+{
+ register struct _XKeytrans *tmp, *p;
+ int nb;
+
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return 0;
+ LockDisplay(dpy);
+ tmp = dpy->key_bindings;
+ nb = sizeof(KeySym) * nm;
+
+ if ((! (p = (struct _XKeytrans *) Xcalloc( 1, sizeof(struct _XKeytrans)))) ||
+ ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) &&
+ (nbytes > 0)) ||
+ ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) &&
+ (nb > 0))) {
+ if (p) {
+ if (p->string) Xfree(p->string);
+ if (p->modifiers) Xfree((char *) p->modifiers);
+ Xfree((char *) p);
+ }
+ UnlockDisplay(dpy);
+ return 0;
+ }
+
+ dpy->key_bindings = p;
+ dpy->free_funcs->key_bindings = _XFreeKeyBindings;
+ p->next = tmp; /* chain onto list */
+ memcpy (p->string, (char *) str, nbytes);
+ p->len = nbytes;
+ memcpy ((char *) p->modifiers, (char *) mlist, nb);
+ p->key = keysym;
+ p->mlen = nm;
+ ComputeMaskFromKeytrans(dpy, p);
+ UnlockDisplay(dpy);
+ return 0;
+}
+
+unsigned
+_XKeysymToModifiers(
+ Display *dpy,
+ KeySym ks)
+{
+ CARD8 code,mods;
+ register KeySym *kmax;
+ register KeySym *k;
+ register XModifierKeymap *m;
+
+ if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
+ return 0;
+ kmax = dpy->keysyms +
+ (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
+ k = dpy->keysyms;
+ m = dpy->modifiermap;
+ mods= 0;
+ while (k<kmax) {
+ if (*k == ks ) {
+ register int j = m->max_keypermod<<3;
+
+ code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode);
+
+ while (--j >= 0) {
+ if (code == m->modifiermap[j])
+ mods|= (1<<(j/m->max_keypermod));
+ }
+ }
+ k++;
+ }
+ return mods;
+}
+
+/*
+ * given a list of modifiers, computes the mask necessary for later matching.
+ * This routine must lookup the key in the Keymap and then search to see
+ * what modifier it is bound to, if any. Sets the AnyModifier bit if it
+ * can't map some keysym to a modifier.
+ */
+static void
+ComputeMaskFromKeytrans(
+ Display *dpy,
+ register struct _XKeytrans *p)
+{
+ register int i;
+
+ p->state = AnyModifier;
+ for (i = 0; i < p->mlen; i++) {
+ p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
+ }
+ p->state &= AllMods;
+}
diff --git a/libX11/src/Makefile.am b/libX11/src/Makefile.am index 71e02e71b..ecf4a99aa 100644 --- a/libX11/src/Makefile.am +++ b/libX11/src/Makefile.am @@ -1,425 +1,425 @@ -if XKB -XKB_SUBDIRS = xkb -endif -SUBDIRS = util xcms xlibi18n $(XKB_SUBDIRS) - -lib_LTLIBRARIES = libX11.la libX11-xcb.la - -BUILT_SOURCES=ks_tables.h -CLEANFILES=ks_tables.h ks_tables_h - -AM_CPPFLAGS= \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/include/X11 \ - -I$(top_builddir)/include \ - -I$(top_builddir)/include/X11 \ - -I$(top_srcdir)/src/xcms \ - -I$(top_srcdir)/src/xkb \ - -I$(top_srcdir)/src/xlibi18n \ - -D_BSD_SOURCE -DX11_t -DTRANS_CLIENT - -AM_CFLAGS= \ - $(X11_CFLAGS) \ - $(BIGFONT_CFLAGS) \ - $(XMALLOC_ZERO_CFLAGS) \ - $(CWARNFLAGS) - -# -# =============================== I18N ============================= -# - -I18N_LIBS = \ - xlibi18n/libi18n.la - -# -# =============================== XCMS ============================= -# - -XCMS_LIBS = \ - xcms/libxcms.la - -# -# =============================== XKB ============================== -# - -XKB_LIBS = \ - xkb/libxkb.la - -# -# =============================== XLIB ============================= -# - -libX11_la_SOURCES = \ - AllCells.c \ - AllowEv.c \ - AllPlanes.c \ - AutoRep.c \ - Backgnd.c \ - BdrWidth.c \ - Bell.c \ - Border.c \ - ChAccCon.c \ - ChActPGb.c \ - ChClMode.c \ - ChCmap.c \ - ChGC.c \ - ChKeyCon.c \ - ChkIfEv.c \ - ChkMaskEv.c \ - ChkTypEv.c \ - ChkTypWEv.c \ - ChkWinEv.c \ - ChPntCon.c \ - ChProp.c \ - ChSaveSet.c \ - ChWAttrs.c \ - ChWindow.c \ - CirWin.c \ - CirWinDn.c \ - CirWinUp.c \ - ClDisplay.c \ - ClearArea.c \ - Clear.c \ - Cmap.h \ - ConfWind.c \ - Context.c \ - ConvSel.c \ - CopyArea.c \ - CopyCmap.c \ - CopyGC.c \ - CopyPlane.c \ - CrBFData.c \ - CrCmap.c \ - CrCursor.c \ - CrGC.c \ - CrGlCur.c \ - Cr.h \ - CrPFBData.c \ - CrPixmap.c \ - CrWindow.c \ - Cursor.c \ - DefCursor.c \ - DelProp.c \ - Depths.c \ - DestSubs.c \ - DestWind.c \ - DisName.c \ - DrArc.c \ - DrArcs.c \ - DrLine.c \ - DrLines.c \ - DrPoint.c \ - DrPoints.c \ - DrRect.c \ - DrRects.c \ - DrSegs.c \ - ErrDes.c \ - ErrHndlr.c \ - evtomask.c \ - EvToWire.c \ - FetchName.c \ - FillArc.c \ - FillArcs.c \ - FillPoly.c \ - FillRct.c \ - FillRcts.c \ - FilterEv.c \ - Flush.c \ - Font.c \ - FontInfo.c \ - FontNames.c \ - FreeCmap.c \ - FreeCols.c \ - FreeCurs.c \ - FreeEData.c \ - FreeEventData.c \ - FreeGC.c \ - FreePix.c \ - FSSaver.c \ - FSWrap.c \ - GCMisc.c \ - Geom.c \ - GetAtomNm.c \ - GetColor.c \ - GetDflt.c \ - GetEventData.c \ - GetFPath.c \ - GetFProp.c \ - GetGCVals.c \ - GetGeom.c \ - GetHColor.c \ - GetHints.c \ - GetIFocus.c \ - GetImage.c \ - GetKCnt.c \ - GetMoEv.c \ - GetNrmHint.c \ - GetPCnt.c \ - GetPntMap.c \ - GetProp.c \ - GetRGBCMap.c \ - GetSOwner.c \ - GetSSaver.c \ - GetStCmap.c \ - GetTxtProp.c \ - GetWAttrs.c \ - GetWMCMapW.c \ - GetWMProto.c \ - globals.c \ - GrButton.c \ - GrKeybd.c \ - GrKey.c \ - GrPointer.c \ - GrServer.c \ - Host.c \ - Iconify.c \ - IfEvent.c \ - imConv.c \ - ImText16.c \ - ImText.c \ - ImUtil.c \ - InitExt.c \ - InsCmap.c \ - IntAtom.c \ - KeyBind.c \ - Key.h \ - KeysymStr.c \ - KillCl.c \ - LiHosts.c \ - LiICmaps.c \ - LiProps.c \ - ListExt.c \ - LoadFont.c \ - LockDis.c \ - locking.c \ - locking.h \ - LookupCol.c \ - LowerWin.c \ - Macros.c \ - MapRaised.c \ - MapSubs.c \ - MapWindow.c \ - MaskEvent.c \ - Misc.c \ - ModMap.c \ - MoveWin.c \ - NextEvent.c \ - OCWrap.c \ - OMWrap.c \ - OpenDis.c \ - ParseCmd.c \ - ParseCol.c \ - ParseGeom.c \ - PeekEvent.c \ - PeekIfEv.c \ - Pending.c \ - PixFormats.c \ - PmapBgnd.c \ - PmapBord.c \ - poly.h \ - PolyReg.c \ - PolyTxt16.c \ - PolyTxt.c \ - PropAlloc.c \ - PutBEvent.c \ - PutImage.c \ - Quarks.c \ - QuBest.c \ - QuColor.c \ - QuColors.c \ - QuCurShp.c \ - QuExt.c \ - QuKeybd.c \ - QuPntr.c \ - QuStipShp.c \ - QuTextE16.c \ - QuTextExt.c \ - QuTileShp.c \ - QuTree.c \ - RaiseWin.c \ - RdBitF.c \ - RecolorC.c \ - ReconfWin.c \ - ReconfWM.c \ - Region.c \ - RegstFlt.c \ - RepWindow.c \ - RestackWs.c \ - RotProp.c \ - ScrResStr.c \ - SelInput.c \ - SendEvent.c \ - SetBack.c \ - SetClMask.c \ - SetClOrig.c \ - SetCRects.c \ - SetDashes.c \ - SetFont.c \ - SetFore.c \ - SetFPath.c \ - SetFunc.c \ - SetHints.c \ - SetIFocus.c \ - SetLocale.c \ - SetLStyle.c \ - SetNrmHint.c \ - SetPMask.c \ - SetPntMap.c \ - SetRGBCMap.c \ - SetSOwner.c \ - SetSSaver.c \ - SetState.c \ - SetStCmap.c \ - SetStip.c \ - SetTile.c \ - SetTSOrig.c \ - SetTxtProp.c \ - SetWMCMapW.c \ - SetWMProto.c \ - StBytes.c \ - StColor.c \ - StColors.c \ - StName.c \ - StNColor.c \ - StrKeysym.c \ - StrToText.c \ - Sync.c \ - Synchro.c \ - Text16.c \ - Text.c \ - TextExt16.c \ - TextExt.c \ - TextToStr.c \ - TrCoords.c \ - UndefCurs.c \ - UngrabBut.c \ - UngrabKbd.c \ - UngrabKey.c \ - UngrabPtr.c \ - UngrabSvr.c \ - UninsCmap.c \ - UnldFont.c \ - UnmapSubs.c \ - UnmapWin.c \ - utlist.h \ - VisUtil.c \ - WarpPtr.c \ - Window.c \ - WinEvent.c \ - Withdraw.c \ - WMGeom.c \ - WMProps.c \ - WrBitF.c \ - Xatomtype.h \ - xcb_disp.c \ - xcb_io.c \ - Xintatom.h \ - Xintconn.h \ - XlibAsync.c \ - XlibInt.c \ - Xprivate.h \ - XomGeneric.h \ - Xresinternal.h \ - Xrm.c \ - Xxcbint.h - -# -# ========================= Extra stuff ============================ -# - -if OS2 -libX11_la_SOURCES+=os2Stubs.c -endif OS2 - -if UDC -libX11_la_SOURCES+=udcInf.c -endif - -if THRSTUBS -libX11_la_SOURCES+=UIThrStubs.c -endif - -x11datadir = @X11_DATADIR@ -x11data_DATA = XErrorDB - -EXTRA_DIST = \ - $(x11data_DATA) \ - os2Stubs.c \ - udcInf.c \ - UIThrStubs.c - -libX11_xcb_la_SOURCES = x11_xcb.c Xxcbint.h -libX11_xcb_la_LDFLAGS = -version-number 1:0:0 -no-undefined -libX11_xcb_la_LIBADD = libX11.la - -# -# Figure out which sub-libraries to link into Xlib -# - -if XLOCALE -USE_I18N_LIBS = $(I18N_LIBS) -endif - -if XCMS -USE_XCMS_LIBS = $(XCMS_LIBS) -endif - -if XKB -USE_XKB_LIBS = $(XKB_LIBS) -endif - -libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined - -libX11_la_LIBADD = \ - $(USE_I18N_LIBS) \ - $(USE_XCMS_LIBS) \ - $(USE_XKB_LIBS) \ - $(X11_LIBS) - -preprocess: $(patsubst %.c,%.ii,$(libX11_la_SOURCES)) -.c.ii: - $(COMPILE) -E -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -if LINT -# Check source code with tools like lint & sparse - -ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) - -lint: $(BUILT_SOURCES) - for f in $(libX11_la_SOURCES) ; do \ - $(LINT) $(ALL_LINT_FLAGS) $$f ; \ - done - @for subdir in $(SUBDIRS) ; do \ - echo "Making $@ in src/$$subdir"; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) lint) ; \ - done -endif LINT - -if MAKE_LINT_LIB -lintlibdir = $(libdir) - -lintlib_DATA = $(LINTLIB) - -lintlib_src = $(libX11_la_SOURCES) xcms/*.c xkb/*.c - -CLEANFILES += $(lintlib_DATA) - -$(LINTLIB): $(libX11_la_SOURCES) - $(AM_V_GEN)$(LINT) -y -oX11 -x $(ALL_LINT_FLAGS) $(lintlib_src) -endif MAKE_LINT_LIB - -# -# Building ks_tables.h requires the makekeys utility -# - -KEYSYMDEFS=@KEYSYMDEFS@ - -ks_tables.h: $(KEYSYMDEFS) $(top_builddir)/src/util/makekeys$(EXEEXT) - $(top_builddir)/src/util/makekeys $(KEYSYMDEFS) > ks_tables_h - mv ks_tables_h $@ - -$(top_builddir)/src/util/makekeys$(EXEEXT): force - cd util && $(MAKE) - -force: +if XKB
+XKB_SUBDIRS = xkb
+endif
+SUBDIRS = util xcms xlibi18n $(XKB_SUBDIRS)
+
+lib_LTLIBRARIES = libX11.la libX11-xcb.la
+
+BUILT_SOURCES=ks_tables.h
+CLEANFILES=ks_tables.h ks_tables_h
+
+AM_CPPFLAGS= \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/include/X11 \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/include/X11 \
+ -I$(top_srcdir)/src/xcms \
+ -I$(top_srcdir)/src/xkb \
+ -I$(top_srcdir)/src/xlibi18n \
+ -D_BSD_SOURCE -DX11_t -DTRANS_CLIENT
+
+AM_CFLAGS= \
+ $(X11_CFLAGS) \
+ $(BIGFONT_CFLAGS) \
+ $(XMALLOC_ZERO_CFLAGS) \
+ $(CWARNFLAGS)
+
+#
+# =============================== I18N =============================
+#
+
+I18N_LIBS = \
+ xlibi18n/libi18n.la
+
+#
+# =============================== XCMS =============================
+#
+
+XCMS_LIBS = \
+ xcms/libxcms.la
+
+#
+# =============================== XKB ==============================
+#
+
+XKB_LIBS = \
+ xkb/libxkb.la
+
+#
+# =============================== XLIB =============================
+#
+
+libX11_la_SOURCES = \
+ AllCells.c \
+ AllowEv.c \
+ AllPlanes.c \
+ AutoRep.c \
+ Backgnd.c \
+ BdrWidth.c \
+ Bell.c \
+ Border.c \
+ ChAccCon.c \
+ ChActPGb.c \
+ ChClMode.c \
+ ChCmap.c \
+ ChGC.c \
+ ChKeyCon.c \
+ ChkIfEv.c \
+ ChkMaskEv.c \
+ ChkTypEv.c \
+ ChkTypWEv.c \
+ ChkWinEv.c \
+ ChPntCon.c \
+ ChProp.c \
+ ChSaveSet.c \
+ ChWAttrs.c \
+ ChWindow.c \
+ CirWin.c \
+ CirWinDn.c \
+ CirWinUp.c \
+ ClDisplay.c \
+ ClearArea.c \
+ Clear.c \
+ Cmap.h \
+ ConfWind.c \
+ Context.c \
+ ConvSel.c \
+ CopyArea.c \
+ CopyCmap.c \
+ CopyGC.c \
+ CopyPlane.c \
+ CrBFData.c \
+ CrCmap.c \
+ CrCursor.c \
+ CrGC.c \
+ CrGlCur.c \
+ Cr.h \
+ CrPFBData.c \
+ CrPixmap.c \
+ CrWindow.c \
+ Cursor.c \
+ DefCursor.c \
+ DelProp.c \
+ Depths.c \
+ DestSubs.c \
+ DestWind.c \
+ DisName.c \
+ DrArc.c \
+ DrArcs.c \
+ DrLine.c \
+ DrLines.c \
+ DrPoint.c \
+ DrPoints.c \
+ DrRect.c \
+ DrRects.c \
+ DrSegs.c \
+ ErrDes.c \
+ ErrHndlr.c \
+ evtomask.c \
+ EvToWire.c \
+ FetchName.c \
+ FillArc.c \
+ FillArcs.c \
+ FillPoly.c \
+ FillRct.c \
+ FillRcts.c \
+ FilterEv.c \
+ Flush.c \
+ Font.c \
+ FontInfo.c \
+ FontNames.c \
+ FreeCmap.c \
+ FreeCols.c \
+ FreeCurs.c \
+ FreeEData.c \
+ FreeEventData.c \
+ FreeGC.c \
+ FreePix.c \
+ FSSaver.c \
+ FSWrap.c \
+ GCMisc.c \
+ Geom.c \
+ GetAtomNm.c \
+ GetColor.c \
+ GetDflt.c \
+ GetEventData.c \
+ GetFPath.c \
+ GetFProp.c \
+ GetGCVals.c \
+ GetGeom.c \
+ GetHColor.c \
+ GetHints.c \
+ GetIFocus.c \
+ GetImage.c \
+ GetKCnt.c \
+ GetMoEv.c \
+ GetNrmHint.c \
+ GetPCnt.c \
+ GetPntMap.c \
+ GetProp.c \
+ GetRGBCMap.c \
+ GetSOwner.c \
+ GetSSaver.c \
+ GetStCmap.c \
+ GetTxtProp.c \
+ GetWAttrs.c \
+ GetWMCMapW.c \
+ GetWMProto.c \
+ globals.c \
+ GrButton.c \
+ GrKeybd.c \
+ GrKey.c \
+ GrPointer.c \
+ GrServer.c \
+ Host.c \
+ Iconify.c \
+ IfEvent.c \
+ imConv.c \
+ ImText16.c \
+ ImText.c \
+ ImUtil.c \
+ InitExt.c \
+ InsCmap.c \
+ IntAtom.c \
+ KeyBind.c \
+ Key.h \
+ KeysymStr.c \
+ KillCl.c \
+ LiHosts.c \
+ LiICmaps.c \
+ LiProps.c \
+ ListExt.c \
+ LoadFont.c \
+ LockDis.c \
+ locking.c \
+ locking.h \
+ LookupCol.c \
+ LowerWin.c \
+ Macros.c \
+ MapRaised.c \
+ MapSubs.c \
+ MapWindow.c \
+ MaskEvent.c \
+ Misc.c \
+ ModMap.c \
+ MoveWin.c \
+ NextEvent.c \
+ OCWrap.c \
+ OMWrap.c \
+ OpenDis.c \
+ ParseCmd.c \
+ ParseCol.c \
+ ParseGeom.c \
+ PeekEvent.c \
+ PeekIfEv.c \
+ Pending.c \
+ PixFormats.c \
+ PmapBgnd.c \
+ PmapBord.c \
+ poly.h \
+ PolyReg.c \
+ PolyTxt16.c \
+ PolyTxt.c \
+ PropAlloc.c \
+ PutBEvent.c \
+ PutImage.c \
+ Quarks.c \
+ QuBest.c \
+ QuColor.c \
+ QuColors.c \
+ QuCurShp.c \
+ QuExt.c \
+ QuKeybd.c \
+ QuPntr.c \
+ QuStipShp.c \
+ QuTextE16.c \
+ QuTextExt.c \
+ QuTileShp.c \
+ QuTree.c \
+ RaiseWin.c \
+ RdBitF.c \
+ RecolorC.c \
+ ReconfWin.c \
+ ReconfWM.c \
+ Region.c \
+ RegstFlt.c \
+ RepWindow.c \
+ RestackWs.c \
+ RotProp.c \
+ ScrResStr.c \
+ SelInput.c \
+ SendEvent.c \
+ SetBack.c \
+ SetClMask.c \
+ SetClOrig.c \
+ SetCRects.c \
+ SetDashes.c \
+ SetFont.c \
+ SetFore.c \
+ SetFPath.c \
+ SetFunc.c \
+ SetHints.c \
+ SetIFocus.c \
+ SetLocale.c \
+ SetLStyle.c \
+ SetNrmHint.c \
+ SetPMask.c \
+ SetPntMap.c \
+ SetRGBCMap.c \
+ SetSOwner.c \
+ SetSSaver.c \
+ SetState.c \
+ SetStCmap.c \
+ SetStip.c \
+ SetTile.c \
+ SetTSOrig.c \
+ SetTxtProp.c \
+ SetWMCMapW.c \
+ SetWMProto.c \
+ StBytes.c \
+ StColor.c \
+ StColors.c \
+ StName.c \
+ StNColor.c \
+ StrKeysym.c \
+ StrToText.c \
+ Sync.c \
+ Synchro.c \
+ Text16.c \
+ Text.c \
+ TextExt16.c \
+ TextExt.c \
+ TextToStr.c \
+ TrCoords.c \
+ UndefCurs.c \
+ UngrabBut.c \
+ UngrabKbd.c \
+ UngrabKey.c \
+ UngrabPtr.c \
+ UngrabSvr.c \
+ UninsCmap.c \
+ UnldFont.c \
+ UnmapSubs.c \
+ UnmapWin.c \
+ utlist.h \
+ VisUtil.c \
+ WarpPtr.c \
+ Window.c \
+ WinEvent.c \
+ Withdraw.c \
+ WMGeom.c \
+ WMProps.c \
+ WrBitF.c \
+ Xatomtype.h \
+ xcb_disp.c \
+ xcb_io.c \
+ Xintatom.h \
+ Xintconn.h \
+ XlibAsync.c \
+ XlibInt.c \
+ Xprivate.h \
+ XomGeneric.h \
+ Xresinternal.h \
+ Xrm.c \
+ Xxcbint.h
+
+#
+# ========================= Extra stuff ============================
+#
+
+if OS2
+libX11_la_SOURCES+=os2Stubs.c
+endif OS2
+
+if UDC
+libX11_la_SOURCES+=udcInf.c
+endif
+
+if THRSTUBS
+libX11_la_SOURCES+=UIThrStubs.c
+endif
+
+x11datadir = @X11_DATADIR@
+x11data_DATA = XErrorDB
+
+EXTRA_DIST = \
+ $(x11data_DATA) \
+ os2Stubs.c \
+ udcInf.c \
+ UIThrStubs.c
+
+libX11_xcb_la_SOURCES = x11_xcb.c Xxcbint.h
+libX11_xcb_la_LDFLAGS = -version-number 1:0:0 -no-undefined
+libX11_xcb_la_LIBADD = libX11.la
+
+#
+# Figure out which sub-libraries to link into Xlib
+#
+
+if XLOCALE
+USE_I18N_LIBS = $(I18N_LIBS)
+endif
+
+if XCMS
+USE_XCMS_LIBS = $(XCMS_LIBS)
+endif
+
+if XKB
+USE_XKB_LIBS = $(XKB_LIBS)
+endif
+
+libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined
+
+libX11_la_LIBADD = \
+ $(USE_I18N_LIBS) \
+ $(USE_XCMS_LIBS) \
+ $(USE_XKB_LIBS) \
+ $(X11_LIBS)
+
+preprocess: $(patsubst %.c,%.ii,$(libX11_la_SOURCES))
+.c.ii:
+ $(COMPILE) -E -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+if LINT
+# Check source code with tools like lint & sparse
+
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
+
+lint: $(BUILT_SOURCES)
+ for f in $(libX11_la_SOURCES) ; do \
+ $(LINT) $(ALL_LINT_FLAGS) $$f ; \
+ done
+ @for subdir in $(SUBDIRS) ; do \
+ echo "Making $@ in src/$$subdir"; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) lint) ; \
+ done
+endif LINT
+
+if MAKE_LINT_LIB
+lintlibdir = $(libdir)
+
+lintlib_DATA = $(LINTLIB)
+
+lintlib_src = $(libX11_la_SOURCES) xcms/*.c xkb/*.c
+
+CLEANFILES += $(lintlib_DATA)
+
+$(LINTLIB): $(libX11_la_SOURCES)
+ $(AM_V_GEN)$(LINT) -y -oX11 -x $(ALL_LINT_FLAGS) $(lintlib_src)
+endif MAKE_LINT_LIB
+
+#
+# Building ks_tables.h requires the makekeys utility
+#
+
+KEYSYMDEFS=@KEYSYMDEFS@
+
+ks_tables.h: $(KEYSYMDEFS) $(top_builddir)/src/util/makekeys$(EXEEXT)
+ $(top_builddir)/src/util/makekeys $(KEYSYMDEFS) > ks_tables_h
+ mv ks_tables_h $@
+
+$(top_builddir)/src/util/makekeys$(EXEEXT): force
+ cd util && $(MAKE)
+
+force:
diff --git a/libX11/src/OpenDis.c b/libX11/src/OpenDis.c index 0b779b0ad..e5336a847 100644 --- a/libX11/src/OpenDis.c +++ b/libX11/src/OpenDis.c @@ -32,6 +32,7 @@ in this Software without prior written authorization from The Open Group. #include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <stdio.h>
+#include <unistd.h>
#include "Xintconn.h"
#ifdef XKB
diff --git a/libX11/src/Quarks.c b/libX11/src/Quarks.c index 7a704b101..aa64392f6 100644 --- a/libX11/src/Quarks.c +++ b/libX11/src/Quarks.c @@ -1,413 +1,413 @@ - -/*********************************************************** -Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL 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. - -******************************************************************/ -/* - -Copyright 1987, 1988, 1990, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include <X11/Xresource.h> -#include "Xresinternal.h" - -/* Not cost effective, at least for vanilla MIT clients */ -/* #define PERMQ */ - -#ifdef PERMQ -typedef unsigned char Bits; -#endif -typedef unsigned long Entry; /* dont confuse with EntryRec from Xintatom.h */ - -static XrmQuark nextQuark = 1; /* next available quark number */ -static unsigned long quarkMask = 0; -static Entry zero = 0; -static Entry *quarkTable = &zero; /* crock */ -static unsigned long quarkRehash; -static XrmString **stringTable = NULL; -#ifdef PERMQ -static Bits **permTable = NULL; -#endif -static XrmQuark nextUniq = -1; /* next quark from XrmUniqueQuark */ - -#define QUANTUMSHIFT 8 -#define QUANTUMMASK ((1 << QUANTUMSHIFT) - 1) -#define CHUNKPER 8 -#define CHUNKMASK ((CHUNKPER << QUANTUMSHIFT) - 1) - -#define LARGEQUARK ((Entry)0x80000000L) -#define QUARKSHIFT 18 -#define QUARKMASK ((LARGEQUARK - 1) >> QUARKSHIFT) -#define XSIGMASK ((1L << QUARKSHIFT) - 1) - -#define STRQUANTSIZE (sizeof(XrmString) * (QUANTUMMASK + 1)) -#ifdef PERMQ -#define QUANTSIZE (STRQUANTSIZE + \ - (sizeof(Bits) * ((QUANTUMMASK + 1) >> 3)) -#else -#define QUANTSIZE STRQUANTSIZE -#endif - -#define HASH(sig) ((sig) & quarkMask) -#define REHASHVAL(sig) ((((sig) % quarkRehash) + 2) | 1) -#define REHASH(idx,rehash) ((idx + rehash) & quarkMask) -#define NAME(q) stringTable[(q) >> QUANTUMSHIFT][(q) & QUANTUMMASK] -#ifdef PERMQ -#define BYTEREF(q) permTable[(q) >> QUANTUMSHIFT][((q) & QUANTUMMASK) >> 3] -#define ISPERM(q) (BYTEREF(q) & (1 << ((q) & 7))) -#define SETPERM(q) BYTEREF(q) |= (1 << ((q) & 7)) -#define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7)) -#endif - -/* Permanent memory allocation */ - -#define WALIGN sizeof(unsigned long) -#define DALIGN sizeof(double) - -#define NEVERFREETABLESIZE ((8192-12) & ~(DALIGN-1)) -static char *neverFreeTable = NULL; -static int neverFreeTableSize = 0; - -static char *permalloc(unsigned int length) -{ - char *ret; - - if (neverFreeTableSize < length) { - if (length >= NEVERFREETABLESIZE) - return Xmalloc(length); - if (! (ret = Xmalloc(NEVERFREETABLESIZE))) - return (char *) NULL; - neverFreeTableSize = NEVERFREETABLESIZE; - neverFreeTable = ret; - } - ret = neverFreeTable; - neverFreeTable += length; - neverFreeTableSize -= length; - return(ret); -} - -#ifndef WORD64 -typedef struct {char a; double b;} TestType1; -typedef struct {char a; unsigned long b;} TestType2; -#endif - -#ifdef XTHREADS -static char *_Xpermalloc(unsigned int length); - -char *Xpermalloc(unsigned int length) -{ - char *p; - - _XLockMutex(_Xglobal_lock); - p = _Xpermalloc(length); - _XUnlockMutex(_Xglobal_lock); - return p; -} -#define Xpermalloc _Xpermalloc - -static -#endif /* XTHREADS */ -char *Xpermalloc(unsigned int length) -{ - int i; - - if (neverFreeTableSize && length < NEVERFREETABLESIZE) { -#ifndef WORD64 - if ((sizeof(TestType1) != - (sizeof(TestType2) - sizeof(unsigned long) + sizeof(double))) && - !(length & (DALIGN-1)) && - ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (DALIGN-1)))) { - neverFreeTableSize -= DALIGN - i; - neverFreeTable += DALIGN - i; - } else -#endif - if ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (WALIGN-1))) { - neverFreeTableSize -= WALIGN - i; - neverFreeTable += WALIGN - i; - } - } - return permalloc(length); -} - -static Bool -ExpandQuarkTable(void) -{ - unsigned long oldmask, newmask; - register char c, *s; - register Entry *oldentries, *entries; - register Entry entry; - register int oldidx, newidx, rehash; - Signature sig; - XrmQuark q; - - oldentries = quarkTable; - if ((oldmask = quarkMask)) - newmask = (oldmask << 1) + 1; - else { - if (!stringTable) { - stringTable = (XrmString **)Xmalloc(sizeof(XrmString *) * - CHUNKPER); - if (!stringTable) - return False; - stringTable[0] = (XrmString *)NULL; - } -#ifdef PERMQ - if (!permTable) - permTable = (Bits **)Xmalloc(sizeof(Bits *) * CHUNKPER); - if (!permTable) - return False; -#endif - stringTable[0] = (XrmString *)Xpermalloc(QUANTSIZE); - if (!stringTable[0]) - return False; -#ifdef PERMQ - permTable[0] = (Bits *)((char *)stringTable[0] + STRQUANTSIZE); -#endif - newmask = 0x1ff; - } - entries = Xcalloc(newmask + 1, sizeof(Entry)); - if (!entries) - return False; - quarkTable = entries; - quarkMask = newmask; - quarkRehash = quarkMask - 2; - for (oldidx = 0; oldidx <= oldmask; oldidx++) { - if ((entry = oldentries[oldidx])) { - if (entry & LARGEQUARK) - q = entry & (LARGEQUARK-1); - else - q = (entry >> QUARKSHIFT) & QUARKMASK; - for (sig = 0, s = NAME(q); (c = *s++); ) - sig = (sig << 1) + c; - newidx = HASH(sig); - if (entries[newidx]) { - rehash = REHASHVAL(sig); - do { - newidx = REHASH(newidx, rehash); - } while (entries[newidx]); - } - entries[newidx] = entry; - } - } - if (oldmask) - Xfree((char *)oldentries); - return True; -} - -XrmQuark -_XrmInternalStringToQuark( - register _Xconst char *name, register int len, register Signature sig, - Bool permstring) -{ - register XrmQuark q; - register Entry entry; - register int idx, rehash; - register int i; - register char *s1, *s2; - char *new; - - rehash = 0; - idx = HASH(sig); - _XLockMutex(_Xglobal_lock); - while ((entry = quarkTable[idx])) { - if (entry & LARGEQUARK) - q = entry & (LARGEQUARK-1); - else { - if ((entry - sig) & XSIGMASK) - goto nomatch; - q = (entry >> QUARKSHIFT) & QUARKMASK; - } - for (i = len, s1 = (char *)name, s2 = NAME(q); --i >= 0; ) { - if (*s1++ != *s2++) - goto nomatch; - } - if (*s2) { -nomatch: if (!rehash) - rehash = REHASHVAL(sig); - idx = REHASH(idx, rehash); - continue; - } -#ifdef PERMQ - if (permstring && !ISPERM(q)) { - Xfree(NAME(q)); - NAME(q) = (char *)name; - SETPERM(q); - } -#endif - _XUnlockMutex(_Xglobal_lock); - return q; - } - if (nextUniq == nextQuark) - goto fail; - if ((nextQuark + (nextQuark >> 2)) > quarkMask) { - if (!ExpandQuarkTable()) - goto fail; - _XUnlockMutex(_Xglobal_lock); - return _XrmInternalStringToQuark(name, len, sig, permstring); - } - q = nextQuark; - if (!(q & QUANTUMMASK)) { - if (!(q & CHUNKMASK)) { - if (!(new = Xrealloc((char *)stringTable, - sizeof(XrmString *) * - ((q >> QUANTUMSHIFT) + CHUNKPER)))) - goto fail; - stringTable = (XrmString **)new; -#ifdef PERMQ - if (!(new = Xrealloc((char *)permTable, - sizeof(Bits *) * - ((q >> QUANTUMSHIFT) + CHUNKPER)))) - goto fail; - permTable = (Bits **)new; -#endif - } - new = Xpermalloc(QUANTSIZE); - if (!new) - goto fail; - stringTable[q >> QUANTUMSHIFT] = (XrmString *)new; -#ifdef PERMQ - permTable[q >> QUANTUMSHIFT] = (Bits *)(new + STRQUANTSIZE); -#endif - } - if (!permstring) { - s2 = (char *)name; -#ifdef PERMQ - name = Xmalloc(len+1); -#else - name = permalloc(len+1); -#endif - if (!name) - goto fail; - for (i = len, s1 = (char *)name; --i >= 0; ) - *s1++ = *s2++; - *s1++ = '\0'; -#ifdef PERMQ - CLEARPERM(q); - } - else { - SETPERM(q); -#endif - } - NAME(q) = (char *)name; - if (q <= QUARKMASK) - entry = (q << QUARKSHIFT) | (sig & XSIGMASK); - else - entry = q | LARGEQUARK; - quarkTable[idx] = entry; - nextQuark++; - _XUnlockMutex(_Xglobal_lock); - return q; - fail: - _XUnlockMutex(_Xglobal_lock); - return NULLQUARK; -} - -XrmQuark -XrmStringToQuark( - _Xconst char *name) -{ - register char c, *tname; - register Signature sig = 0; - - if (!name) - return (NULLQUARK); - - for (tname = (char *)name; (c = *tname++); ) - sig = (sig << 1) + c; - - return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, False); -} - -XrmQuark -XrmPermStringToQuark( - _Xconst char *name) -{ - register char c, *tname; - register Signature sig = 0; - - if (!name) - return (NULLQUARK); - - for (tname = (char *)name; (c = *tname++); ) - sig = (sig << 1) + c; - - return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, True); -} - -XrmQuark XrmUniqueQuark(void) -{ - XrmQuark q; - - _XLockMutex(_Xglobal_lock); - if (nextUniq == nextQuark) - q = NULLQUARK; - else - q = nextUniq--; - _XUnlockMutex(_Xglobal_lock); - return q; -} - -XrmString XrmQuarkToString(register XrmQuark quark) -{ - XrmString s; - - _XLockMutex(_Xglobal_lock); - if (quark <= 0 || quark >= nextQuark) - s = NULLSTRING; - else { -#ifdef PERMQ - /* We have to mark the quark as permanent, since the caller might hold - * onto the string pointer forver. - */ - SETPERM(quark); -#endif - s = NAME(quark); - } - _XUnlockMutex(_Xglobal_lock); - return s; -} +
+/***********************************************************
+Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard,
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/*
+
+Copyright 1987, 1988, 1990, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <X11/Xresource.h>
+#include "Xresinternal.h"
+
+/* Not cost effective, at least for vanilla MIT clients */
+/* #define PERMQ */
+
+#ifdef PERMQ
+typedef unsigned char Bits;
+#endif
+typedef unsigned long Entry; /* dont confuse with EntryRec from Xintatom.h */
+
+static XrmQuark nextQuark = 1; /* next available quark number */
+static unsigned long quarkMask = 0;
+static Entry zero = 0;
+static Entry *quarkTable = &zero; /* crock */
+static unsigned long quarkRehash;
+static XrmString **stringTable = NULL;
+#ifdef PERMQ
+static Bits **permTable = NULL;
+#endif
+static XrmQuark nextUniq = -1; /* next quark from XrmUniqueQuark */
+
+#define QUANTUMSHIFT 8
+#define QUANTUMMASK ((1 << QUANTUMSHIFT) - 1)
+#define CHUNKPER 8
+#define CHUNKMASK ((CHUNKPER << QUANTUMSHIFT) - 1)
+
+#define LARGEQUARK ((Entry)0x80000000L)
+#define QUARKSHIFT 18
+#define QUARKMASK ((LARGEQUARK - 1) >> QUARKSHIFT)
+#define XSIGMASK ((1L << QUARKSHIFT) - 1)
+
+#define STRQUANTSIZE (sizeof(XrmString) * (QUANTUMMASK + 1))
+#ifdef PERMQ
+#define QUANTSIZE (STRQUANTSIZE + \
+ (sizeof(Bits) * ((QUANTUMMASK + 1) >> 3))
+#else
+#define QUANTSIZE STRQUANTSIZE
+#endif
+
+#define HASH(sig) ((sig) & quarkMask)
+#define REHASHVAL(sig) ((((sig) % quarkRehash) + 2) | 1)
+#define REHASH(idx,rehash) ((idx + rehash) & quarkMask)
+#define NAME(q) stringTable[(q) >> QUANTUMSHIFT][(q) & QUANTUMMASK]
+#ifdef PERMQ
+#define BYTEREF(q) permTable[(q) >> QUANTUMSHIFT][((q) & QUANTUMMASK) >> 3]
+#define ISPERM(q) (BYTEREF(q) & (1 << ((q) & 7)))
+#define SETPERM(q) BYTEREF(q) |= (1 << ((q) & 7))
+#define CLEARPERM(q) BYTEREF(q) &= ~(1 << ((q) & 7))
+#endif
+
+/* Permanent memory allocation */
+
+#define WALIGN sizeof(unsigned long)
+#define DALIGN sizeof(double)
+
+#define NEVERFREETABLESIZE ((8192-12) & ~(DALIGN-1))
+static char *neverFreeTable = NULL;
+static int neverFreeTableSize = 0;
+
+static char *permalloc(unsigned int length)
+{
+ char *ret;
+
+ if (neverFreeTableSize < length) {
+ if (length >= NEVERFREETABLESIZE)
+ return Xmalloc(length);
+ if (! (ret = Xmalloc(NEVERFREETABLESIZE)))
+ return (char *) NULL;
+ neverFreeTableSize = NEVERFREETABLESIZE;
+ neverFreeTable = ret;
+ }
+ ret = neverFreeTable;
+ neverFreeTable += length;
+ neverFreeTableSize -= length;
+ return(ret);
+}
+
+#ifndef WORD64
+typedef struct {char a; double b;} TestType1;
+typedef struct {char a; unsigned long b;} TestType2;
+#endif
+
+#ifdef XTHREADS
+static char *_Xpermalloc(unsigned int length);
+
+char *Xpermalloc(unsigned int length)
+{
+ char *p;
+
+ _XLockMutex(_Xglobal_lock);
+ p = _Xpermalloc(length);
+ _XUnlockMutex(_Xglobal_lock);
+ return p;
+}
+#define Xpermalloc _Xpermalloc
+
+static
+#endif /* XTHREADS */
+char *Xpermalloc(unsigned int length)
+{
+ int i;
+
+ if (neverFreeTableSize && length < NEVERFREETABLESIZE) {
+#ifndef WORD64
+ if ((sizeof(TestType1) !=
+ (sizeof(TestType2) - sizeof(unsigned long) + sizeof(double))) &&
+ !(length & (DALIGN-1)) &&
+ ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (DALIGN-1)))) {
+ neverFreeTableSize -= DALIGN - i;
+ neverFreeTable += DALIGN - i;
+ } else
+#endif
+ if ((i = (NEVERFREETABLESIZE - neverFreeTableSize) & (WALIGN-1))) {
+ neverFreeTableSize -= WALIGN - i;
+ neverFreeTable += WALIGN - i;
+ }
+ }
+ return permalloc(length);
+}
+
+static Bool
+ExpandQuarkTable(void)
+{
+ unsigned long oldmask, newmask;
+ register char c, *s;
+ register Entry *oldentries, *entries;
+ register Entry entry;
+ register int oldidx, newidx, rehash;
+ Signature sig;
+ XrmQuark q;
+
+ oldentries = quarkTable;
+ if ((oldmask = quarkMask))
+ newmask = (oldmask << 1) + 1;
+ else {
+ if (!stringTable) {
+ stringTable = (XrmString **)Xmalloc(sizeof(XrmString *) *
+ CHUNKPER);
+ if (!stringTable)
+ return False;
+ stringTable[0] = (XrmString *)NULL;
+ }
+#ifdef PERMQ
+ if (!permTable)
+ permTable = (Bits **)Xmalloc(sizeof(Bits *) * CHUNKPER);
+ if (!permTable)
+ return False;
+#endif
+ stringTable[0] = (XrmString *)Xpermalloc(QUANTSIZE);
+ if (!stringTable[0])
+ return False;
+#ifdef PERMQ
+ permTable[0] = (Bits *)((char *)stringTable[0] + STRQUANTSIZE);
+#endif
+ newmask = 0x1ff;
+ }
+ entries = Xcalloc(newmask + 1, sizeof(Entry));
+ if (!entries)
+ return False;
+ quarkTable = entries;
+ quarkMask = newmask;
+ quarkRehash = quarkMask - 2;
+ for (oldidx = 0; oldidx <= oldmask; oldidx++) {
+ if ((entry = oldentries[oldidx])) {
+ if (entry & LARGEQUARK)
+ q = entry & (LARGEQUARK-1);
+ else
+ q = (entry >> QUARKSHIFT) & QUARKMASK;
+ for (sig = 0, s = NAME(q); (c = *s++); )
+ sig = (sig << 1) + c;
+ newidx = HASH(sig);
+ if (entries[newidx]) {
+ rehash = REHASHVAL(sig);
+ do {
+ newidx = REHASH(newidx, rehash);
+ } while (entries[newidx]);
+ }
+ entries[newidx] = entry;
+ }
+ }
+ if (oldmask)
+ Xfree((char *)oldentries);
+ return True;
+}
+
+XrmQuark
+_XrmInternalStringToQuark(
+ register _Xconst char *name, register int len, register Signature sig,
+ Bool permstring)
+{
+ register XrmQuark q;
+ register Entry entry;
+ register int idx, rehash;
+ register int i;
+ register char *s1, *s2;
+ char *new;
+
+ rehash = 0;
+ idx = HASH(sig);
+ _XLockMutex(_Xglobal_lock);
+ while ((entry = quarkTable[idx])) {
+ if (entry & LARGEQUARK)
+ q = entry & (LARGEQUARK-1);
+ else {
+ if ((entry - sig) & XSIGMASK)
+ goto nomatch;
+ q = (entry >> QUARKSHIFT) & QUARKMASK;
+ }
+ for (i = len, s1 = (char *)name, s2 = NAME(q); --i >= 0; ) {
+ if (*s1++ != *s2++)
+ goto nomatch;
+ }
+ if (*s2) {
+nomatch: if (!rehash)
+ rehash = REHASHVAL(sig);
+ idx = REHASH(idx, rehash);
+ continue;
+ }
+#ifdef PERMQ
+ if (permstring && !ISPERM(q)) {
+ Xfree(NAME(q));
+ NAME(q) = (char *)name;
+ SETPERM(q);
+ }
+#endif
+ _XUnlockMutex(_Xglobal_lock);
+ return q;
+ }
+ if (nextUniq == nextQuark)
+ goto fail;
+ if ((nextQuark + (nextQuark >> 2)) > quarkMask) {
+ if (!ExpandQuarkTable())
+ goto fail;
+ _XUnlockMutex(_Xglobal_lock);
+ return _XrmInternalStringToQuark(name, len, sig, permstring);
+ }
+ q = nextQuark;
+ if (!(q & QUANTUMMASK)) {
+ if (!(q & CHUNKMASK)) {
+ if (!(new = Xrealloc((char *)stringTable,
+ sizeof(XrmString *) *
+ ((q >> QUANTUMSHIFT) + CHUNKPER))))
+ goto fail;
+ stringTable = (XrmString **)new;
+#ifdef PERMQ
+ if (!(new = Xrealloc((char *)permTable,
+ sizeof(Bits *) *
+ ((q >> QUANTUMSHIFT) + CHUNKPER))))
+ goto fail;
+ permTable = (Bits **)new;
+#endif
+ }
+ new = Xpermalloc(QUANTSIZE);
+ if (!new)
+ goto fail;
+ stringTable[q >> QUANTUMSHIFT] = (XrmString *)new;
+#ifdef PERMQ
+ permTable[q >> QUANTUMSHIFT] = (Bits *)(new + STRQUANTSIZE);
+#endif
+ }
+ if (!permstring) {
+ s2 = (char *)name;
+#ifdef PERMQ
+ name = Xmalloc(len+1);
+#else
+ name = permalloc(len+1);
+#endif
+ if (!name)
+ goto fail;
+ for (i = len, s1 = (char *)name; --i >= 0; )
+ *s1++ = *s2++;
+ *s1++ = '\0';
+#ifdef PERMQ
+ CLEARPERM(q);
+ }
+ else {
+ SETPERM(q);
+#endif
+ }
+ NAME(q) = (char *)name;
+ if (q <= QUARKMASK)
+ entry = (q << QUARKSHIFT) | (sig & XSIGMASK);
+ else
+ entry = q | LARGEQUARK;
+ quarkTable[idx] = entry;
+ nextQuark++;
+ _XUnlockMutex(_Xglobal_lock);
+ return q;
+ fail:
+ _XUnlockMutex(_Xglobal_lock);
+ return NULLQUARK;
+}
+
+XrmQuark
+XrmStringToQuark(
+ _Xconst char *name)
+{
+ register char c, *tname;
+ register Signature sig = 0;
+
+ if (!name)
+ return (NULLQUARK);
+
+ for (tname = (char *)name; (c = *tname++); )
+ sig = (sig << 1) + c;
+
+ return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, False);
+}
+
+XrmQuark
+XrmPermStringToQuark(
+ _Xconst char *name)
+{
+ register char c, *tname;
+ register Signature sig = 0;
+
+ if (!name)
+ return (NULLQUARK);
+
+ for (tname = (char *)name; (c = *tname++); )
+ sig = (sig << 1) + c;
+
+ return _XrmInternalStringToQuark(name, tname-(char *)name-1, sig, True);
+}
+
+XrmQuark XrmUniqueQuark(void)
+{
+ XrmQuark q;
+
+ _XLockMutex(_Xglobal_lock);
+ if (nextUniq == nextQuark)
+ q = NULLQUARK;
+ else
+ q = nextUniq--;
+ _XUnlockMutex(_Xglobal_lock);
+ return q;
+}
+
+XrmString XrmQuarkToString(register XrmQuark quark)
+{
+ XrmString s;
+
+ _XLockMutex(_Xglobal_lock);
+ if (quark <= 0 || quark >= nextQuark)
+ s = NULLSTRING;
+ else {
+#ifdef PERMQ
+ /* We have to mark the quark as permanent, since the caller might hold
+ * onto the string pointer forver.
+ */
+ SETPERM(quark);
+#endif
+ s = NAME(quark);
+ }
+ _XUnlockMutex(_Xglobal_lock);
+ return s;
+}
diff --git a/libX11/src/RdBitF.c b/libX11/src/RdBitF.c index ab7d800d3..6b920c609 100644 --- a/libX11/src/RdBitF.c +++ b/libX11/src/RdBitF.c @@ -1,261 +1,262 @@ -/* - -Copyright 1987, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -/* - * Code to read bitmaps from disk files. Interprets - * data from X10 and X11 bitmap files and creates - * Pixmap representations of files. Returns Pixmap - * ID and specifics about image. - * - * Modified for speedup by Jim Becker, changed image - * data parsing logic (removed some fscanf()s). - * Aug 5, 1988 - * - * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them - * that way (but don't use common source code so that people can have one - * without the other). - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include <X11/Xos.h> -#include "Xutil.h" -#include <stdio.h> -#include <ctype.h> - - -#define MAX_SIZE 255 - -/* shared data for the image read/parse logic */ -static const short hexTable[256] = { - ['0'] = 0, ['1'] = 1, - ['2'] = 2, ['3'] = 3, - ['4'] = 4, ['5'] = 5, - ['6'] = 6, ['7'] = 7, - ['8'] = 8, ['9'] = 9, - ['A'] = 10, ['B'] = 11, - ['C'] = 12, ['D'] = 13, - ['E'] = 14, ['F'] = 15, - ['a'] = 10, ['b'] = 11, - ['c'] = 12, ['d'] = 13, - ['e'] = 14, ['f'] = 15, - - [' '] = -1, [','] = -1, - ['}'] = -1, ['\n'] = -1, - ['\t'] = -1 -}; - -/* - * read next hex value in the input stream, return -1 if EOF - */ -static int -NextInt ( - FILE *fstream) -{ - int ch; - int value = 0; - int gotone = 0; - int done = 0; - - /* loop, accumulate hex value until find delimiter */ - /* skip any initial delimiters found in read stream */ - - while (!done) { - ch = getc(fstream); - if (ch == EOF) { - value = -1; - done++; - } else { - /* trim high bits, check type and accumulate */ - ch &= 0xff; - if (isascii(ch) && isxdigit(ch)) { - value = (value << 4) + hexTable[ch]; - gotone++; - } else if ((hexTable[ch]) < 0 && gotone) - done++; - } - } - return value; -} - -int -XReadBitmapFileData ( - _Xconst char *filename, - unsigned int *width, /* RETURNED */ - unsigned int *height, /* RETURNED */ - unsigned char **data, /* RETURNED */ - int *x_hot, /* RETURNED */ - int *y_hot) /* RETURNED */ -{ - FILE *fstream; /* handle on file */ - unsigned char *bits = NULL; /* working variable */ - char line[MAX_SIZE]; /* input line from file */ - int size; /* number of bytes of data */ - char name_and_type[MAX_SIZE]; /* an input line */ - char *type; /* for parsing */ - int value; /* from an input line */ - int version10p; /* boolean, old format */ - int padding; /* to handle alignment */ - int bytes_per_line; /* per scanline of data */ - unsigned int ww = 0; /* width */ - unsigned int hh = 0; /* height */ - int hx = -1; /* x hotspot */ - int hy = -1; /* y hotspot */ - -#ifdef __UNIXOS2__ - filename = __XOS2RedirRoot(filename); -#endif - if (!(fstream = fopen(filename, "r"))) - return BitmapOpenFailed; - - /* error cleanup and return macro */ -#define RETURN(code) \ -{ if (bits) Xfree ((char *)bits); fclose (fstream); return code; } - - while (fgets(line, MAX_SIZE, fstream)) { - if (strlen(line) == MAX_SIZE-1) - RETURN (BitmapFileInvalid); - if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { - if (!(type = strrchr(name_and_type, '_'))) - type = name_and_type; - else - type++; - - if (!strcmp("width", type)) - ww = (unsigned int) value; - if (!strcmp("height", type)) - hh = (unsigned int) value; - if (!strcmp("hot", type)) { - if (type-- == name_and_type || type-- == name_and_type) - continue; - if (!strcmp("x_hot", type)) - hx = value; - if (!strcmp("y_hot", type)) - hy = value; - } - continue; - } - - if (sscanf(line, "static short %s = {", name_and_type) == 1) - version10p = 1; - else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) - version10p = 0; - else if (sscanf(line, "static char %s = {", name_and_type) == 1) - version10p = 0; - else - continue; - - if (!(type = strrchr(name_and_type, '_'))) - type = name_and_type; - else - type++; - - if (strcmp("bits[]", type)) - continue; - - if (!ww || !hh) - RETURN (BitmapFileInvalid); - - if ((ww % 16) && ((ww % 16) < 9) && version10p) - padding = 1; - else - padding = 0; - - bytes_per_line = (ww+7)/8 + padding; - - size = bytes_per_line * hh; - bits = (unsigned char *) Xmalloc ((unsigned int) size); - if (!bits) - RETURN (BitmapNoMemory); - - if (version10p) { - unsigned char *ptr; - int bytes; - - for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) { - if ((value = NextInt(fstream)) < 0) - RETURN (BitmapFileInvalid); - *(ptr++) = value; - if (!padding || ((bytes+2) % bytes_per_line)) - *(ptr++) = value >> 8; - } - } else { - unsigned char *ptr; - int bytes; - - for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) { - if ((value = NextInt(fstream)) < 0) - RETURN (BitmapFileInvalid); - *ptr=value; - } - } - - /* If we got to this point, we read a full bitmap file. Break so we don't - * start reading another one from the same file and leak the memory - * allocated for the previous one. */ - break; - } /* end while */ - - fclose(fstream); - if (!bits) - return (BitmapFileInvalid); - - *data = bits; - *width = ww; - *height = hh; - if (x_hot) *x_hot = hx; - if (y_hot) *y_hot = hy; - - return (BitmapSuccess); -} - -int -XReadBitmapFile ( - Display *display, - Drawable d, - _Xconst char *filename, - unsigned int *width, /* RETURNED */ - unsigned int *height, /* RETURNED */ - Pixmap *pixmap, /* RETURNED */ - int *x_hot, /* RETURNED */ - int *y_hot) /* RETURNED */ -{ - unsigned char *data; - int res; - - res = XReadBitmapFileData(filename, width, height, &data, x_hot, y_hot); - if (res != BitmapSuccess) - return res; - *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height); - Xfree((char *)data); - if (*pixmap == None) - return (BitmapNoMemory); - return (BitmapSuccess); -} +/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+/*
+ * Code to read bitmaps from disk files. Interprets
+ * data from X10 and X11 bitmap files and creates
+ * Pixmap representations of files. Returns Pixmap
+ * ID and specifics about image.
+ *
+ * Modified for speedup by Jim Becker, changed image
+ * data parsing logic (removed some fscanf()s).
+ * Aug 5, 1988
+ *
+ * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them
+ * that way (but don't use common source code so that people can have one
+ * without the other).
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include <X11/Xos.h>
+#include "Xutil.h"
+#include <stdio.h>
+#include <ctype.h>
+
+
+#define MAX_SIZE 255
+
+/* shared data for the image read/parse logic */
+static const signed char hexTable[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ ,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
+ , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0
+ , 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * read next hex value in the input stream, return -1 if EOF
+ */
+static int
+NextInt (
+ FILE *fstream)
+{
+ int ch;
+ int value = 0;
+ int gotone = 0;
+ int done = 0;
+
+ /* loop, accumulate hex value until find delimiter */
+ /* skip any initial delimiters found in read stream */
+
+ while (!done) {
+ ch = getc(fstream);
+ if (ch == EOF) {
+ value = -1;
+ done++;
+ } else {
+ /* trim high bits, check type and accumulate */
+ ch &= 0xff;
+ if (isascii(ch) && isxdigit(ch)) {
+ value = (value << 4) + hexTable[ch];
+ gotone++;
+ } else if ((hexTable[ch]) < 0 && gotone)
+ done++;
+ }
+ }
+ return value;
+}
+
+int
+XReadBitmapFileData (
+ _Xconst char *filename,
+ unsigned int *width, /* RETURNED */
+ unsigned int *height, /* RETURNED */
+ unsigned char **data, /* RETURNED */
+ int *x_hot, /* RETURNED */
+ int *y_hot) /* RETURNED */
+{
+ FILE *fstream; /* handle on file */
+ unsigned char *bits = NULL; /* working variable */
+ char line[MAX_SIZE]; /* input line from file */
+ int size; /* number of bytes of data */
+ char name_and_type[MAX_SIZE]; /* an input line */
+ char *type; /* for parsing */
+ int value; /* from an input line */
+ int version10p; /* boolean, old format */
+ int padding; /* to handle alignment */
+ int bytes_per_line; /* per scanline of data */
+ unsigned int ww = 0; /* width */
+ unsigned int hh = 0; /* height */
+ int hx = -1; /* x hotspot */
+ int hy = -1; /* y hotspot */
+
+#ifdef __UNIXOS2__
+ filename = __XOS2RedirRoot(filename);
+#endif
+ if (!(fstream = fopen(filename, "r")))
+ return BitmapOpenFailed;
+
+ /* error cleanup and return macro */
+#define RETURN(code) \
+{ if (bits) Xfree ((char *)bits); fclose (fstream); return code; }
+
+ while (fgets(line, MAX_SIZE, fstream)) {
+ if (strlen(line) == MAX_SIZE-1)
+ RETURN (BitmapFileInvalid);
+ if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
+ if (!(type = strrchr(name_and_type, '_')))
+ type = name_and_type;
+ else
+ type++;
+
+ if (!strcmp("width", type))
+ ww = (unsigned int) value;
+ if (!strcmp("height", type))
+ hh = (unsigned int) value;
+ if (!strcmp("hot", type)) {
+ if (type-- == name_and_type || type-- == name_and_type)
+ continue;
+ if (!strcmp("x_hot", type))
+ hx = value;
+ if (!strcmp("y_hot", type))
+ hy = value;
+ }
+ continue;
+ }
+
+ if (sscanf(line, "static short %s = {", name_and_type) == 1)
+ version10p = 1;
+ else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
+ version10p = 0;
+ else if (sscanf(line, "static char %s = {", name_and_type) == 1)
+ version10p = 0;
+ else
+ continue;
+
+ if (!(type = strrchr(name_and_type, '_')))
+ type = name_and_type;
+ else
+ type++;
+
+ if (strcmp("bits[]", type))
+ continue;
+
+ if (!ww || !hh)
+ RETURN (BitmapFileInvalid);
+
+ if ((ww % 16) && ((ww % 16) < 9) && version10p)
+ padding = 1;
+ else
+ padding = 0;
+
+ bytes_per_line = (ww+7)/8 + padding;
+
+ size = bytes_per_line * hh;
+ bits = (unsigned char *) Xmalloc ((unsigned int) size);
+ if (!bits)
+ RETURN (BitmapNoMemory);
+
+ if (version10p) {
+ unsigned char *ptr;
+ int bytes;
+
+ for (bytes=0, ptr=bits; bytes<size; (bytes += 2)) {
+ if ((value = NextInt(fstream)) < 0)
+ RETURN (BitmapFileInvalid);
+ *(ptr++) = value;
+ if (!padding || ((bytes+2) % bytes_per_line))
+ *(ptr++) = value >> 8;
+ }
+ } else {
+ unsigned char *ptr;
+ int bytes;
+
+ for (bytes=0, ptr=bits; bytes<size; bytes++, ptr++) {
+ if ((value = NextInt(fstream)) < 0)
+ RETURN (BitmapFileInvalid);
+ *ptr=value;
+ }
+ }
+
+ /* If we got to this point, we read a full bitmap file. Break so we don't
+ * start reading another one from the same file and leak the memory
+ * allocated for the previous one. */
+ break;
+ } /* end while */
+
+ fclose(fstream);
+ if (!bits)
+ return (BitmapFileInvalid);
+
+ *data = bits;
+ *width = ww;
+ *height = hh;
+ if (x_hot) *x_hot = hx;
+ if (y_hot) *y_hot = hy;
+
+ return (BitmapSuccess);
+}
+
+int
+XReadBitmapFile (
+ Display *display,
+ Drawable d,
+ _Xconst char *filename,
+ unsigned int *width, /* RETURNED */
+ unsigned int *height, /* RETURNED */
+ Pixmap *pixmap, /* RETURNED */
+ int *x_hot, /* RETURNED */
+ int *y_hot) /* RETURNED */
+{
+ unsigned char *data;
+ int res;
+
+ res = XReadBitmapFileData(filename, width, height, &data, x_hot, y_hot);
+ if (res != BitmapSuccess)
+ return res;
+ *pixmap = XCreateBitmapFromData(display, d, (char *)data, *width, *height);
+ Xfree((char *)data);
+ if (*pixmap == None)
+ return (BitmapNoMemory);
+ return (BitmapSuccess);
+}
diff --git a/libX11/src/SetLocale.c b/libX11/src/SetLocale.c index c49cb2e4e..81c946cdf 100644 --- a/libX11/src/SetLocale.c +++ b/libX11/src/SetLocale.c @@ -1,253 +1,254 @@ - -/* - * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, - * and Nippon Telegraph and Telephone Corporation - * - * 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 names of OMRON, NTT Software, and NTT - * not be used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. OMRON, NTT Software, - * and NTT make no representations about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, 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. - * - * Authors: Li Yuhong OMRON Corporation - * Tetsuya Kato NTT Software Corporation - * Hiroshi Kuribayashi OMRON Corporation - * - */ -/* - -Copyright 1987,1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include <X11/Xlocale.h> -#include <X11/Xos.h> -#include "XlcPubI.h" - -#define MAXLOCALE 64 /* buffer size of locale name */ - -#ifdef X_LOCALE - -/* alternative setlocale() for when the OS does not provide one */ - -char * -_Xsetlocale( - int category, - _Xconst char *name -) -{ - static char *xsl_name; - char *old_name; - XrmMethods methods; - XPointer state; - - if (category != LC_CTYPE && category != LC_ALL) - return NULL; - if (!name) { - if (xsl_name) - return xsl_name; - return "C"; - } - if (!*name) - name = getenv("LC_CTYPE"); - if (!name || !*name) - name = getenv("LANG"); - if (name && strlen(name) >= MAXLOCALE) - name = NULL; - if (!name || !*name || !_XOpenLC((char *) name)) - name = "C"; - old_name = xsl_name; - xsl_name = (char *)name; - methods = _XrmInitParseInfo(&state); - xsl_name = old_name; - if (!methods) - return NULL; - name = (*methods->lcname)(state); - xsl_name = strdup(name); - if (!xsl_name) { - xsl_name = old_name; - (*methods->destroy)(state); - return NULL; - } - if (old_name) - Xfree(old_name); - (*methods->destroy)(state); - return xsl_name; -} - -#else /* X_LOCALE */ - -#if defined(__APPLE__) || defined(__CYGWIN__) -char * -_Xsetlocale( - int category, - _Xconst char *name -) -{ - return setlocale(category, name); -} -#endif /* __APPLE__ || __CYGWIN__ */ - -/* - * _XlcMapOSLocaleName is an implementation dependent routine that derives - * the LC_CTYPE locale name as used in the sample implementation from that - * returned by setlocale. - * - * Should match the code in Xt ExtractLocaleName. - * - * This function name is a bit of a misnomer. Even the siname parameter - * name is a misnomer. On most modern operating systems this function is - * a no-op, simply returning the osname; but on older operating systems - * like Ultrix, or HPUX 9.x and earlier, when you set LANG=german.88591 - * then the string returned by setlocale(LC_ALL, "") will look something - * like: "german.88591 german.88591 ... german.88591". Then this function - * will pick out the LC_CTYPE component and return a pointer to that. - */ - -char * -_XlcMapOSLocaleName( - char *osname, - char *siname) -{ -#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined(linux) -# ifdef hpux -# ifndef _LastCategory - /* HPUX 9 and earlier */ -# define SKIPCOUNT 2 -# define STARTCHAR ':' -# define ENDCHAR ';' -# else - /* HPUX 10 */ -# define ENDCHAR ' ' -# endif -# else -# ifdef ultrix -# define SKIPCOUNT 2 -# define STARTCHAR '\001' -# define ENDCHAR '\001' -# else -# if defined(WIN32) || defined(__UNIXOS2__) -# define SKIPCOUNT 1 -# define STARTCHAR '=' -# define ENDCHAR ';' -# define WHITEFILL -# else -# if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4)) -# define STARTCHAR ' ' -# define ENDCHAR ' ' -# else -# if defined(linux) -# define STARTSTR "LC_CTYPE=" -# define ENDCHAR ';' -# else -# if !defined(sun) || defined(SVR4) -# define STARTCHAR '/' -# define ENDCHAR '/' -# endif -# endif -# endif -# endif -# endif -# endif - - char *start; - char *end; - int len; -# ifdef SKIPCOUNT - int n; -# endif - - start = osname; -# ifdef SKIPCOUNT - for (n = SKIPCOUNT; - --n >= 0 && start && (start = strchr (start, STARTCHAR)); - start++) - ; - if (!start) - start = osname; -# endif -# ifdef STARTCHAR - if (start && (start = strchr (start, STARTCHAR))) -# elif defined (STARTSTR) - if (start && (start = strstr (start,STARTSTR))) -# endif - { -# ifdef STARTCHAR - start++; -# elif defined (STARTSTR) - start += strlen(STARTSTR); -# endif - if ((end = strchr (start, ENDCHAR))) { - len = end - start; - if (len >= MAXLOCALE) - len = MAXLOCALE - 1; - strncpy(siname, start, len); - *(siname + len) = '\0'; -# ifdef WHITEFILL - for (start = siname; start = strchr(start, ' '); ) - *start++ = '-'; -# endif - return siname; - } else /* if no ENDCHAR is found we are at the end of the line */ - return start; - } -# ifdef WHITEFILL - if (strchr(osname, ' ')) { - len = strlen(osname); - if (len >= MAXLOCALE - 1) - len = MAXLOCALE - 1; - strncpy(siname, osname, len); - *(siname + len) = '\0'; - for (start = siname; start = strchr(start, ' '); ) - *start++ = '-'; - return siname; - } -# endif -# undef STARTCHAR -# undef ENDCHAR -# undef WHITEFILL -#endif - return osname; -} - -#endif /* X_LOCALE */ +
+/*
+ * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
+ * and Nippon Telegraph and Telephone Corporation
+ *
+ * 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 names of OMRON, NTT Software, and NTT
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. OMRON, NTT Software,
+ * and NTT make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, 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.
+ *
+ * Authors: Li Yuhong OMRON Corporation
+ * Tetsuya Kato NTT Software Corporation
+ * Hiroshi Kuribayashi OMRON Corporation
+ *
+ */
+/*
+
+Copyright 1987,1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include <X11/Xlocale.h>
+#include <X11/Xos.h>
+#include "XlcPubI.h"
+#include <unistd.h>
+
+#define MAXLOCALE 64 /* buffer size of locale name */
+
+#ifdef X_LOCALE
+
+/* alternative setlocale() for when the OS does not provide one */
+
+char *
+_Xsetlocale(
+ int category,
+ _Xconst char *name
+)
+{
+ static char *xsl_name;
+ char *old_name;
+ XrmMethods methods;
+ XPointer state;
+
+ if (category != LC_CTYPE && category != LC_ALL)
+ return NULL;
+ if (!name) {
+ if (xsl_name)
+ return xsl_name;
+ return "C";
+ }
+ if (!*name)
+ name = getenv("LC_CTYPE");
+ if (!name || !*name)
+ name = getenv("LANG");
+ if (name && strlen(name) >= MAXLOCALE)
+ name = NULL;
+ if (!name || !*name || !_XOpenLC((char *) name))
+ name = "C";
+ old_name = xsl_name;
+ xsl_name = (char *)name;
+ methods = _XrmInitParseInfo(&state);
+ xsl_name = old_name;
+ if (!methods)
+ return NULL;
+ name = (*methods->lcname)(state);
+ xsl_name = strdup(name);
+ if (!xsl_name) {
+ xsl_name = old_name;
+ (*methods->destroy)(state);
+ return NULL;
+ }
+ if (old_name)
+ Xfree(old_name);
+ (*methods->destroy)(state);
+ return xsl_name;
+}
+
+#else /* X_LOCALE */
+
+#if defined(__APPLE__) || defined(__CYGWIN__)
+char *
+_Xsetlocale(
+ int category,
+ _Xconst char *name
+)
+{
+ return setlocale(category, name);
+}
+#endif /* __APPLE__ || __CYGWIN__ */
+
+/*
+ * _XlcMapOSLocaleName is an implementation dependent routine that derives
+ * the LC_CTYPE locale name as used in the sample implementation from that
+ * returned by setlocale.
+ *
+ * Should match the code in Xt ExtractLocaleName.
+ *
+ * This function name is a bit of a misnomer. Even the siname parameter
+ * name is a misnomer. On most modern operating systems this function is
+ * a no-op, simply returning the osname; but on older operating systems
+ * like Ultrix, or HPUX 9.x and earlier, when you set LANG=german.88591
+ * then the string returned by setlocale(LC_ALL, "") will look something
+ * like: "german.88591 german.88591 ... german.88591". Then this function
+ * will pick out the LC_CTYPE component and return a pointer to that.
+ */
+
+char *
+_XlcMapOSLocaleName(
+ char *osname,
+ char *siname)
+{
+#if defined(hpux) || defined(CSRG_BASED) || defined(sun) || defined(SVR4) || defined(sgi) || defined(__osf__) || defined(AIXV3) || defined(ultrix) || defined(WIN32) || defined(__UNIXOS2__) || defined(linux)
+# ifdef hpux
+# ifndef _LastCategory
+ /* HPUX 9 and earlier */
+# define SKIPCOUNT 2
+# define STARTCHAR ':'
+# define ENDCHAR ';'
+# else
+ /* HPUX 10 */
+# define ENDCHAR ' '
+# endif
+# else
+# ifdef ultrix
+# define SKIPCOUNT 2
+# define STARTCHAR '\001'
+# define ENDCHAR '\001'
+# else
+# if defined(WIN32) || defined(__UNIXOS2__)
+# define SKIPCOUNT 1
+# define STARTCHAR '='
+# define ENDCHAR ';'
+# define WHITEFILL
+# else
+# if defined(__osf__) || (defined(AIXV3) && !defined(AIXV4))
+# define STARTCHAR ' '
+# define ENDCHAR ' '
+# else
+# if defined(linux)
+# define STARTSTR "LC_CTYPE="
+# define ENDCHAR ';'
+# else
+# if !defined(sun) || defined(SVR4)
+# define STARTCHAR '/'
+# define ENDCHAR '/'
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+
+ char *start;
+ char *end;
+ int len;
+# ifdef SKIPCOUNT
+ int n;
+# endif
+
+ start = osname;
+# ifdef SKIPCOUNT
+ for (n = SKIPCOUNT;
+ --n >= 0 && start && (start = strchr (start, STARTCHAR));
+ start++)
+ ;
+ if (!start)
+ start = osname;
+# endif
+# ifdef STARTCHAR
+ if (start && (start = strchr (start, STARTCHAR)))
+# elif defined (STARTSTR)
+ if (start && (start = strstr (start,STARTSTR)))
+# endif
+ {
+# ifdef STARTCHAR
+ start++;
+# elif defined (STARTSTR)
+ start += strlen(STARTSTR);
+# endif
+ if ((end = strchr (start, ENDCHAR))) {
+ len = end - start;
+ if (len >= MAXLOCALE)
+ len = MAXLOCALE - 1;
+ strncpy(siname, start, len);
+ *(siname + len) = '\0';
+# ifdef WHITEFILL
+ for (start = siname; start = strchr(start, ' '); )
+ *start++ = '-';
+# endif
+ return siname;
+ } else /* if no ENDCHAR is found we are at the end of the line */
+ return start;
+ }
+# ifdef WHITEFILL
+ if (strchr(osname, ' ')) {
+ len = strlen(osname);
+ if (len >= MAXLOCALE - 1)
+ len = MAXLOCALE - 1;
+ strncpy(siname, osname, len);
+ *(siname + len) = '\0';
+ for (start = siname; start = strchr(start, ' '); )
+ *start++ = '-';
+ return siname;
+ }
+# endif
+# undef STARTCHAR
+# undef ENDCHAR
+# undef WHITEFILL
+#endif
+ return osname;
+}
+
+#endif /* X_LOCALE */
diff --git a/libX11/src/StrKeysym.c b/libX11/src/StrKeysym.c index 6e9c427f8..907db507b 100644 --- a/libX11/src/StrKeysym.c +++ b/libX11/src/StrKeysym.c @@ -39,12 +39,14 @@ in this Software without prior written authorization from The Open Group. #ifndef KEYSYMDB
#ifndef XKEYSYMDB
-#define KEYSYMDB "/usr/lib/X11/XKeysymDB"
+#define KEYSYMDB "XKeysymDB"
#else
#define KEYSYMDB XKEYSYMDB
#endif
#endif
+#include <unistd.h>
+
static Bool initialized;
static XrmDatabase keysymdb;
static XrmQuark Qkeysym[2];
diff --git a/libX11/src/XlibInt.c b/libX11/src/XlibInt.c index 3db151e29..305670214 100644 --- a/libX11/src/XlibInt.c +++ b/libX11/src/XlibInt.c @@ -1,2158 +1,2177 @@ -/* - -Copyright 1985, 1986, 1987, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -/* - * XlibInt.c - Internal support routines for the C subroutine - * interface library (Xlib) to the X Window System Protocol V11.0. - */ - -#ifdef WIN32 -#define _XLIBINT_ -#endif -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xprivate.h" -#include <X11/Xpoll.h> -#include <assert.h> -#include <stdio.h> -#ifdef WIN32 -#include <direct.h> -#endif - -#ifdef XTHREADS -#include "locking.h" - -/* these pointers get initialized by XInitThreads */ -LockInfoPtr _Xglobal_lock = NULL; -void (*_XCreateMutex_fn)(LockInfoPtr) = NULL; -/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */ -void (*_XFreeMutex_fn)(LockInfoPtr) = NULL; -void (*_XLockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif - ) = NULL; -void (*_XUnlockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif - ) = NULL; -xthread_t (*_Xthread_self_fn)(void) = NULL; - -#define XThread_Self() ((*_Xthread_self_fn)()) - -#endif /* XTHREADS */ - -/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX - * systems are broken and return EWOULDBLOCK when they should return EAGAIN - */ -#ifdef WIN32 -#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) -#else -#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */ -#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) -#else -#if defined(EAGAIN) && defined(EWOULDBLOCK) -#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) -#else -#ifdef EAGAIN -#define ETEST() (errno == EAGAIN) -#else -#define ETEST() (errno == EWOULDBLOCK) -#endif /* EAGAIN */ -#endif /* EAGAIN && EWOULDBLOCK */ -#endif /* __CYGWIN__ */ -#endif /* WIN32 */ - -#ifdef WIN32 -#define ECHECK(err) (WSAGetLastError() == err) -#define ESET(val) WSASetLastError(val) -#else -#ifdef __UNIXOS2__ -#define ECHECK(err) (errno == err) -#define ESET(val) -#else -#define ECHECK(err) (errno == err) -#define ESET(val) errno = val -#endif -#endif - -#if defined(LOCALCONN) || defined(LACHMAN) -#ifdef EMSGSIZE -#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE)) -#else -#define ESZTEST() ECHECK(ERANGE) -#endif -#else -#ifdef EMSGSIZE -#define ESZTEST() ECHECK(EMSGSIZE) -#endif -#endif - -#ifdef __UNIXOS2__ -#include <limits.h> -#define MAX_PATH _POSIX_PATH_MAX -#endif - -/* - * The following routines are internal routines used by Xlib for protocol - * packet transmission and reception. - * - * _XIOError(Display *) will be called if any sort of system call error occurs. - * This is assumed to be a fatal condition, i.e., XIOError should not return. - * - * _XError(Display *, xError *) will be called whenever an X_Error event is - * received. This is not assumed to be a fatal condition, i.e., it is - * acceptable for this procedure to return. However, XError should NOT - * perform any operations (directly or indirectly) on the DISPLAY. - * - * Routines declared with a return type of 'Status' return 0 on failure, - * and non 0 on success. Routines with no declared return type don't - * return anything. Whenever possible routines that create objects return - * the object they have created. - */ - -#define POLLFD_CACHE_SIZE 5 - -/* initialize the struct array passed to poll() below */ -Bool _XPollfdCacheInit( - Display *dpy) -{ -#ifdef USE_POLL - struct pollfd *pfp; - - pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd)); - if (!pfp) - return False; - pfp[0].fd = dpy->fd; - pfp[0].events = POLLIN; - - dpy->filedes = (XPointer)pfp; -#endif - return True; -} - -void _XPollfdCacheAdd( - Display *dpy, - int fd) -{ -#ifdef USE_POLL - struct pollfd *pfp = (struct pollfd *)dpy->filedes; - - if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { - pfp[dpy->im_fd_length].fd = fd; - pfp[dpy->im_fd_length].events = POLLIN; - } -#endif -} - -/* ARGSUSED */ -void _XPollfdCacheDel( - Display *dpy, - int fd) /* not used */ -{ -#ifdef USE_POLL - struct pollfd *pfp = (struct pollfd *)dpy->filedes; - struct _XConnectionInfo *conni; - - /* just recalculate whole list */ - if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) { - int loc = 1; - for (conni = dpy->im_fd_info; conni; conni=conni->next) { - pfp[loc].fd = conni->fd; - pfp[loc].events = POLLIN; - loc++; - } - } -#endif -} - -static int sync_hazard(Display *dpy) -{ - unsigned long span = dpy->request - dpy->last_request_read; - unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10); - return span >= 65535 - hazard - 10; -} - -static -void sync_while_locked(Display *dpy) -{ -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_lock_display)(dpy); -#endif - UnlockDisplay(dpy); - SyncHandle(); - InternalLockDisplay(dpy, /* don't skip user locks */ 0); -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_unlock_display)(dpy); -#endif -} - -void _XSeqSyncFunction( - register Display *dpy) -{ - xGetInputFocusReply rep; - register xReq *req; - - if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { - GetEmptyReq(GetInputFocus, req); - (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); - sync_while_locked(dpy); - } else if (sync_hazard(dpy)) - _XSetPrivSyncFunction(dpy); -} - -/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ -static int -_XPrivSyncFunction (Display *dpy) -{ -#if XTHREADS - assert(!dpy->lock_fns); -#endif - assert(dpy->synchandler == _XPrivSyncFunction); - assert((dpy->flags & XlibDisplayPrivSync) != 0); - dpy->synchandler = dpy->savedsynchandler; - dpy->savedsynchandler = NULL; - dpy->flags &= ~XlibDisplayPrivSync; - if(dpy->synchandler) - dpy->synchandler(dpy); - _XIDHandler(dpy); - _XSeqSyncFunction(dpy); - return 0; -} - -void _XSetPrivSyncFunction(Display *dpy) -{ -#ifdef XTHREADS - if (dpy->lock_fns) - return; -#endif - if (!(dpy->flags & XlibDisplayPrivSync)) { - dpy->savedsynchandler = dpy->synchandler; - dpy->synchandler = _XPrivSyncFunction; - dpy->flags |= XlibDisplayPrivSync; - } -} - -void _XSetSeqSyncFunction(Display *dpy) -{ - if (sync_hazard(dpy)) - _XSetPrivSyncFunction (dpy); -} - -#ifdef LONG64 -void _XRead32( - Display *dpy, - register long *data, - long len) -{ - register int *buf; - register long i; - - if (len) { - (void) _XRead(dpy, (char *)data, len); - i = len >> 2; - buf = (int *)data + i; - data += i; - while (--i >= 0) - *--data = *--buf; - } -} -#endif /* LONG64 */ - -#ifdef WORD64 - -/* - * XXX This is a *really* stupid way of doing this.... - * PACKBUFFERSIZE must be a multiple of 4. - */ - -#define PACKBUFFERSIZE 4096 - - -/* - * _XRead32 - Read bytes from the socket unpacking each 32 bits - * into a long (64 bits on a CRAY computer). - * - */ -static void _doXRead32( - register Display *dpy, - register long *data - register long size, - register char *packbuffer) -{ - long *lpack,*lp; - long mask32 = 0x00000000ffffffff; - long maskw, nwords, i, bits; - - _XReadPad (dpy, packbuffer, size); - - lp = data; - lpack = (long *) packbuffer; - nwords = size >> 2; - bits = 32; - - for(i=0;i<nwords;i++){ - maskw = mask32 << bits; - *lp++ = ( *lpack & maskw ) >> bits; - bits = bits ^32; - if(bits){ - lpack++; - } - } -} - -void _XRead32( - Display *dpy, - long *data, - long len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 2; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) _doXRead32 (dpy, data, len, packbuffer); -} - - - -/* - * _XRead16 - Read bytes from the socket unpacking each 16 bits - * into a long (64 bits on a CRAY computer). - * - */ -static _doXRead16( - register Display *dpy, - register short *data, - register long size, - char *packbuffer) -{ - long *lpack,*lp; - long mask16 = 0x000000000000ffff; - long maskw, nwords, i, bits; - - (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */ - - lp = (long *) data; - lpack = (long *) packbuffer; - nwords = size >> 1; /* number of 16 bit words to be unpacked */ - bits = 48; - for(i=0;i<nwords;i++){ - maskw = mask16 << bits; - *lp++ = ( *lpack & maskw ) >> bits; - bits -= 16; - if(bits < 0){ - lpack++; - bits = 48; - } - } -} - -void _XRead16( - Display *dpy, - short *data, - long len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 1; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) _doXRead16 (dpy, data, len, packbuffer); -} - -void _XRead16Pad( - Display *dpy, - short *data, - long size) -{ - int slop = (size & 3); - short slopbuf[3]; - - _XRead16 (dpy, data, size); - if (slop > 0) { - _XRead16 (dpy, slopbuf, 4 - slop); - } -} -#endif /* WORD64 */ - -/* - * The hard part about this is that we only get 16 bits from a reply. - * We have three values that will march along, with the following invariant: - * dpy->last_request_read <= rep->sequenceNumber <= dpy->request - * We have to keep - * dpy->request - dpy->last_request_read < 2^16 - * or else we won't know for sure what value to use in events. We do this - * by forcing syncs when we get close. - */ - -unsigned long -_XSetLastRequestRead( - register Display *dpy, - register xGenericReply *rep) -{ - register unsigned long newseq, lastseq; - - lastseq = dpy->last_request_read; - /* - * KeymapNotify has no sequence number, but is always guaranteed - * to immediately follow another event, except when generated via - * SendEvent (hmmm). - */ - if ((rep->type & 0x7f) == KeymapNotify) - return(lastseq); - - newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber; - - if (newseq < lastseq) { - newseq += 0x10000; - if (newseq > dpy->request) { - (void) fprintf (stderr, - "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", - newseq, dpy->request, - (unsigned int) rep->type); - newseq -= 0x10000; - } - } - - dpy->last_request_read = newseq; - return(newseq); -} - -/* - * Support for internal connections, such as an IM might use. - * By Stephen Gildea, X Consortium, September 1993 - */ - -/* _XRegisterInternalConnection - * Each IM (or Xlib extension) that opens a file descriptor that Xlib should - * include in its select/poll mask must call this function to register the - * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch - * will also be called. - * - * Whenever Xlib detects input available on fd, it will call callback - * with call_data to process it. If non-Xlib code calls select/poll - * and detects input available, it must call XProcessInternalConnection, - * which will call the associated callback. - * - * Non-Xlib code can learn about these additional fds by calling - * XInternalConnectionNumbers or, more typically, by registering - * a XConnectionWatchProc with XAddConnectionWatch - * to be called when fds are registered or unregistered. - * - * Returns True if registration succeeded, False if not, typically - * because could not allocate memory. - * Assumes Display locked when called. - */ -Status -_XRegisterInternalConnection( - Display* dpy, - int fd, - _XInternalConnectionProc callback, - XPointer call_data -) -{ - struct _XConnectionInfo *new_conni, **iptr; - struct _XConnWatchInfo *watchers; - XPointer *wd; - - new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo)); - if (!new_conni) - return 0; - new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer)); - if (!new_conni->watch_data) { - Xfree(new_conni); - return 0; - } - new_conni->fd = fd; - new_conni->read_callback = callback; - new_conni->call_data = call_data; - new_conni->next = NULL; - /* link new structure onto end of list */ - for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next) - ; - *iptr = new_conni; - dpy->im_fd_length++; - _XPollfdCacheAdd(dpy, fd); - - for (watchers=dpy->conn_watchers, wd=new_conni->watch_data; - watchers; - watchers=watchers->next, wd++) { - *wd = NULL; /* for cleanliness */ - (*watchers->fn) (dpy, watchers->client_data, fd, True, wd); - } - - return 1; -} - -/* _XUnregisterInternalConnection - * Each IM (or Xlib extension) that closes a file descriptor previously - * registered with _XRegisterInternalConnection must call this function. - * Any XConnectionWatchProc registered by XAddConnectionWatch - * will also be called. - * - * Assumes Display locked when called. - */ -void -_XUnregisterInternalConnection( - Display* dpy, - int fd -) -{ - struct _XConnectionInfo *info_list, **prev; - struct _XConnWatchInfo *watch; - XPointer *wd; - - for (prev = &dpy->im_fd_info; (info_list = *prev); - prev = &info_list->next) { - if (info_list->fd == fd) { - *prev = info_list->next; - dpy->im_fd_length--; - for (watch=dpy->conn_watchers, wd=info_list->watch_data; - watch; - watch=watch->next, wd++) { - (*watch->fn) (dpy, watch->client_data, fd, False, wd); - } - if (info_list->watch_data) - Xfree (info_list->watch_data); - Xfree (info_list); - break; - } - } - _XPollfdCacheDel(dpy, fd); -} - -/* XInternalConnectionNumbers - * Returns an array of fds and an array of corresponding call data. - * Typically a XConnectionWatchProc registered with XAddConnectionWatch - * will be used instead of this function to discover - * additional fds to include in the select/poll mask. - * - * The list is allocated with Xmalloc and should be freed by the caller - * with Xfree; - */ -Status -XInternalConnectionNumbers( - Display *dpy, - int **fd_return, - int *count_return -) -{ - int count; - struct _XConnectionInfo *info_list; - int *fd_list; - - LockDisplay(dpy); - count = 0; - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) - count++; - fd_list = (int*) Xmalloc (count * sizeof(int)); - if (!fd_list) { - UnlockDisplay(dpy); - return 0; - } - count = 0; - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { - fd_list[count] = info_list->fd; - count++; - } - UnlockDisplay(dpy); - - *fd_return = fd_list; - *count_return = count; - return 1; -} - -void _XProcessInternalConnection( - Display *dpy, - struct _XConnectionInfo *conn_info) -{ - dpy->flags |= XlibDisplayProcConni; - UnlockDisplay(dpy); - (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data); - LockDisplay(dpy); - dpy->flags &= ~XlibDisplayProcConni; -} - -/* XProcessInternalConnection - * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection - * for this fd. - * The Display is NOT locked during the call. - */ -void -XProcessInternalConnection( - Display* dpy, - int fd -) -{ - struct _XConnectionInfo *info_list; - - LockDisplay(dpy); - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { - if (info_list->fd == fd) { - _XProcessInternalConnection(dpy, info_list); - break; - } - } - UnlockDisplay(dpy); -} - -/* XAddConnectionWatch - * Register a callback to be called whenever _XRegisterInternalConnection - * or _XUnregisterInternalConnection is called. - * Callbacks are called with the Display locked. - * If any connections are already registered, the callback is immediately - * called for each of them. - */ -Status -XAddConnectionWatch( - Display* dpy, - XConnectionWatchProc callback, - XPointer client_data -) -{ - struct _XConnWatchInfo *new_watcher, **wptr; - struct _XConnectionInfo *info_list; - XPointer *wd_array; - - LockDisplay(dpy); - - /* allocate new watch data */ - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { - wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data, - (dpy->watcher_count + 1) * - sizeof(XPointer)); - if (!wd_array) { - UnlockDisplay(dpy); - return 0; - } - info_list->watch_data = wd_array; - wd_array[dpy->watcher_count] = NULL; /* for cleanliness */ - } - - new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo)); - if (!new_watcher) { - UnlockDisplay(dpy); - return 0; - } - new_watcher->fn = callback; - new_watcher->client_data = client_data; - new_watcher->next = NULL; - - /* link new structure onto end of list */ - for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next) - ; - *wptr = new_watcher; - dpy->watcher_count++; - - /* call new watcher on all currently registered fds */ - for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) { - (*callback) (dpy, client_data, info_list->fd, True, - info_list->watch_data + dpy->watcher_count - 1); - } - - UnlockDisplay(dpy); - return 1; -} - -/* XRemoveConnectionWatch - * Unregister a callback registered by XAddConnectionWatch. - * Both callback and client_data must match what was passed to - * XAddConnectionWatch. - */ -void -XRemoveConnectionWatch( - Display* dpy, - XConnectionWatchProc callback, - XPointer client_data -) -{ - struct _XConnWatchInfo *watch; - struct _XConnWatchInfo *previous = NULL; - struct _XConnectionInfo *conni; - int counter = 0; - - LockDisplay(dpy); - for (watch=dpy->conn_watchers; watch; watch=watch->next) { - if (watch->fn == callback && watch->client_data == client_data) { - if (previous) - previous->next = watch->next; - else - dpy->conn_watchers = watch->next; - Xfree (watch); - dpy->watcher_count--; - /* remove our watch_data for each connection */ - for (conni=dpy->im_fd_info; conni; conni=conni->next) { - /* don't bother realloc'ing; these arrays are small anyway */ - /* overlapping */ - memmove(conni->watch_data+counter, - conni->watch_data+counter+1, - dpy->watcher_count - counter); - } - break; - } - previous = watch; - counter++; - } - UnlockDisplay(dpy); -} - -/* end of internal connections support */ - -/* Cookie jar implementation - dpy->cookiejar is a linked list. _XEnq receives the events but leaves - them in the normal EQ. _XStoreEvent returns the cookie event (minus - data pointer) and adds it to the cookiejar. _XDeq just removes - the entry like any other event but resets the data pointer for - cookie events (to avoid double-free, the memory is re-used by Xlib). - - _XFetchEventCookie (called from XGetEventData) removes a cookie from the - jar. _XFreeEventCookies removes all unclaimed cookies from the jar - (called by XNextEvent). - - _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the - normal EQ. - */ - -#include "utlist.h" -struct stored_event { - XGenericEventCookie ev; - struct stored_event *prev; - struct stored_event *next; -}; - -Bool -_XIsEventCookie(Display *dpy, XEvent *ev) -{ - return (ev->xcookie.type == GenericEvent && - dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL); -} - -/** - * Free all events in the event list. - */ -void -_XFreeEventCookies(Display *dpy) -{ - struct stored_event **head, *e, *tmp; - - if (!dpy->cookiejar) - return; - - head = (struct stored_event**)&dpy->cookiejar; - - DL_FOREACH_SAFE(*head, e, tmp) { - if (dpy->cookiejar == e) - dpy->cookiejar = NULL; - XFree(e->ev.data); - XFree(e); - } -} - -/** - * Add an event to the display's event list. This event must be freed on the - * next call to XNextEvent(). - */ -void -_XStoreEventCookie(Display *dpy, XEvent *event) -{ - XGenericEventCookie* cookie = &event->xcookie; - struct stored_event **head, *add; - - if (!_XIsEventCookie(dpy, event)) - return; - - head = (struct stored_event**)(&dpy->cookiejar); - - add = Xmalloc(sizeof(struct stored_event)); - if (!add) { - ESET(ENOMEM); - _XIOError(dpy); - } - add->ev = *cookie; - DL_APPEND(*head, add); - cookie->data = NULL; /* don't return data yet, must be claimed */ -} - -/** - * Return the event with the given cookie and remove it from the list. - */ -Bool -_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev) -{ - Bool ret = False; - struct stored_event **head, *event; - head = (struct stored_event**)&dpy->cookiejar; - - if (!_XIsEventCookie(dpy, (XEvent*)ev)) - return ret; - - DL_FOREACH(*head, event) { - if (event->ev.cookie == ev->cookie && - event->ev.extension == ev->extension && - event->ev.evtype == ev->evtype) { - *ev = event->ev; - DL_DELETE(*head, event); - Xfree(event); - ret = True; - break; - } - } - - return ret; -} - -Bool -_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) -{ - Bool ret = False; - int extension; - - if (!_XIsEventCookie(dpy, (XEvent*)in) || !out) - return ret; - - extension = in->extension & 0x7F; - - if (!dpy->generic_event_copy_vec[extension]) - return ret; - - ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out)); - out->cookie = ret ? ++dpy->next_cookie : 0; - return ret; -} - - -/* - * _XEnq - Place event packets on the display's queue. - * note that no squishing of move events in V11, since there - * is pointer motion hints.... - */ -void _XEnq( - register Display *dpy, - register xEvent *event) -{ - register _XQEvent *qelt; - int type, extension; - - if ((qelt = dpy->qfree)) { - /* If dpy->qfree is non-NULL do this, else malloc a new one. */ - dpy->qfree = qelt->next; - } - else if ((qelt = - (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { - /* Malloc call failed! */ - ESET(ENOMEM); - _XIOError(dpy); - } - qelt->next = NULL; - - type = event->u.u.type & 0177; - extension = ((xGenericEvent*)event)->extension; - - qelt->event.type = type; - /* If an extension has registerd a generic_event_vec handler, then - * it can handle event cookies. Otherwise, proceed with the normal - * event handlers. - * - * If the generic_event_vec is called, qelt->event is a event cookie - * with the data pointer and the "free" pointer set. Data pointer is - * some memory allocated by the extension. - */ - if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) { - XGenericEventCookie *cookie = &qelt->event.xcookie; - (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event); - cookie->cookie = ++dpy->next_cookie; - - qelt->qserial_num = dpy->next_event_serial_num++; - if (dpy->tail) dpy->tail->next = qelt; - else dpy->head = qelt; - - dpy->tail = qelt; - dpy->qlen++; - } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) { - qelt->qserial_num = dpy->next_event_serial_num++; - if (dpy->tail) dpy->tail->next = qelt; - else dpy->head = qelt; - - dpy->tail = qelt; - dpy->qlen++; - } else { - /* ignored, or stashed away for many-to-one compression */ - qelt->next = dpy->qfree; - dpy->qfree = qelt; - } -} - -/* - * _XDeq - Remove event packet from the display's queue. - */ -void _XDeq( - register Display *dpy, - register _XQEvent *prev, /* element before qelt */ - register _XQEvent *qelt) /* element to be unlinked */ -{ - if (prev) { - if ((prev->next = qelt->next) == NULL) - dpy->tail = prev; - } else { - /* no prev, so removing first elt */ - if ((dpy->head = qelt->next) == NULL) - dpy->tail = NULL; - } - qelt->qserial_num = 0; - qelt->next = dpy->qfree; - dpy->qfree = qelt; - dpy->qlen--; - - if (_XIsEventCookie(dpy, &qelt->event)) { - XGenericEventCookie* cookie = &qelt->event.xcookie; - /* dpy->qfree is re-used, reset memory to avoid double free on - * _XFreeDisplayStructure */ - cookie->data = NULL; - } -} - -/* - * EventToWire in separate file in that often not needed. - */ - -/*ARGSUSED*/ -Bool -_XUnknownWireEvent( - register Display *dpy, /* pointer to display structure */ - register XEvent *re, /* pointer to where event should be reformatted */ - register xEvent *event) /* wire protocol event */ -{ -#ifdef notdef - (void) fprintf(stderr, - "Xlib: unhandled wire event! event number = %d, display = %x\n.", - event->u.u.type, dpy); -#endif - return(False); -} - -Bool -_XUnknownWireEventCookie( - Display *dpy, /* pointer to display structure */ - XGenericEventCookie *re, /* pointer to where event should be reformatted */ - xEvent *event) /* wire protocol event */ -{ -#ifdef notdef - fprintf(stderr, - "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.", - ((xGenericEvent*)event)->extension, dpy); -#endif - return(False); -} - -Bool -_XUnknownCopyEventCookie( - Display *dpy, /* pointer to display structure */ - XGenericEventCookie *in, /* source */ - XGenericEventCookie *out) /* destination */ -{ -#ifdef notdef - fprintf(stderr, - "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.", - in->extension, dpy); -#endif - return(False); -} - -/*ARGSUSED*/ -Status -_XUnknownNativeEvent( - register Display *dpy, /* pointer to display structure */ - register XEvent *re, /* pointer to where event should be reformatted */ - register xEvent *event) /* wire protocol event */ -{ -#ifdef notdef - (void) fprintf(stderr, - "Xlib: unhandled native event! event number = %d, display = %x\n.", - re->type, dpy); -#endif - return(0); -} -/* - * reformat a wire event into an XEvent structure of the right type. - */ -Bool -_XWireToEvent( - register Display *dpy, /* pointer to display structure */ - register XEvent *re, /* pointer to where event should be reformatted */ - register xEvent *event) /* wire protocol event */ -{ - - re->type = event->u.u.type & 0x7f; - ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy, - (xGenericReply *)event); - ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); - ((XAnyEvent *)re)->display = dpy; - - /* Ignore the leading bit of the event type since it is set when a - client sends an event rather than the server. */ - - switch (event-> u.u.type & 0177) { - case KeyPress: - case KeyRelease: - { - register XKeyEvent *ev = (XKeyEvent*) re; - ev->root = event->u.keyButtonPointer.root; - ev->window = event->u.keyButtonPointer.event; - ev->subwindow = event->u.keyButtonPointer.child; - ev->time = event->u.keyButtonPointer.time; - ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); - ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); - ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); - ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); - ev->state = event->u.keyButtonPointer.state; - ev->same_screen = event->u.keyButtonPointer.sameScreen; - ev->keycode = event->u.u.detail; - } - break; - case ButtonPress: - case ButtonRelease: - { - register XButtonEvent *ev = (XButtonEvent *) re; - ev->root = event->u.keyButtonPointer.root; - ev->window = event->u.keyButtonPointer.event; - ev->subwindow = event->u.keyButtonPointer.child; - ev->time = event->u.keyButtonPointer.time; - ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); - ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); - ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); - ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); - ev->state = event->u.keyButtonPointer.state; - ev->same_screen = event->u.keyButtonPointer.sameScreen; - ev->button = event->u.u.detail; - } - break; - case MotionNotify: - { - register XMotionEvent *ev = (XMotionEvent *)re; - ev->root = event->u.keyButtonPointer.root; - ev->window = event->u.keyButtonPointer.event; - ev->subwindow = event->u.keyButtonPointer.child; - ev->time = event->u.keyButtonPointer.time; - ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX); - ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); - ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); - ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY); - ev->state = event->u.keyButtonPointer.state; - ev->same_screen = event->u.keyButtonPointer.sameScreen; - ev->is_hint = event->u.u.detail; - } - break; - case EnterNotify: - case LeaveNotify: - { - register XCrossingEvent *ev = (XCrossingEvent *) re; - ev->root = event->u.enterLeave.root; - ev->window = event->u.enterLeave.event; - ev->subwindow = event->u.enterLeave.child; - ev->time = event->u.enterLeave.time; - ev->x = cvtINT16toInt(event->u.enterLeave.eventX); - ev->y = cvtINT16toInt(event->u.enterLeave.eventY); - ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); - ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY); - ev->state = event->u.enterLeave.state; - ev->mode = event->u.enterLeave.mode; - ev->same_screen = (event->u.enterLeave.flags & - ELFlagSameScreen) && True; - ev->focus = (event->u.enterLeave.flags & - ELFlagFocus) && True; - ev->detail = event->u.u.detail; - } - break; - case FocusIn: - case FocusOut: - { - register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; - ev->window = event->u.focus.window; - ev->mode = event->u.focus.mode; - ev->detail = event->u.u.detail; - } - break; - case KeymapNotify: - { - register XKeymapEvent *ev = (XKeymapEvent *) re; - ev->window = None; - memcpy(&ev->key_vector[1], - (char *)((xKeymapEvent *) event)->map, - sizeof (((xKeymapEvent *) event)->map)); - } - break; - case Expose: - { - register XExposeEvent *ev = (XExposeEvent *) re; - ev->window = event->u.expose.window; - ev->x = event->u.expose.x; - ev->y = event->u.expose.y; - ev->width = event->u.expose.width; - ev->height = event->u.expose.height; - ev->count = event->u.expose.count; - } - break; - case GraphicsExpose: - { - register XGraphicsExposeEvent *ev = - (XGraphicsExposeEvent *) re; - ev->drawable = event->u.graphicsExposure.drawable; - ev->x = event->u.graphicsExposure.x; - ev->y = event->u.graphicsExposure.y; - ev->width = event->u.graphicsExposure.width; - ev->height = event->u.graphicsExposure.height; - ev->count = event->u.graphicsExposure.count; - ev->major_code = event->u.graphicsExposure.majorEvent; - ev->minor_code = event->u.graphicsExposure.minorEvent; - } - break; - case NoExpose: - { - register XNoExposeEvent *ev = (XNoExposeEvent *) re; - ev->drawable = event->u.noExposure.drawable; - ev->major_code = event->u.noExposure.majorEvent; - ev->minor_code = event->u.noExposure.minorEvent; - } - break; - case VisibilityNotify: - { - register XVisibilityEvent *ev = (XVisibilityEvent *) re; - ev->window = event->u.visibility.window; - ev->state = event->u.visibility.state; - } - break; - case CreateNotify: - { - register XCreateWindowEvent *ev = - (XCreateWindowEvent *) re; - ev->window = event->u.createNotify.window; - ev->parent = event->u.createNotify.parent; - ev->x = cvtINT16toInt(event->u.createNotify.x); - ev->y = cvtINT16toInt(event->u.createNotify.y); - ev->width = event->u.createNotify.width; - ev->height = event->u.createNotify.height; - ev->border_width = event->u.createNotify.borderWidth; - ev->override_redirect = event->u.createNotify.override; - } - break; - case DestroyNotify: - { - register XDestroyWindowEvent *ev = - (XDestroyWindowEvent *) re; - ev->window = event->u.destroyNotify.window; - ev->event = event->u.destroyNotify.event; - } - break; - case UnmapNotify: - { - register XUnmapEvent *ev = (XUnmapEvent *) re; - ev->window = event->u.unmapNotify.window; - ev->event = event->u.unmapNotify.event; - ev->from_configure = event->u.unmapNotify.fromConfigure; - } - break; - case MapNotify: - { - register XMapEvent *ev = (XMapEvent *) re; - ev->window = event->u.mapNotify.window; - ev->event = event->u.mapNotify.event; - ev->override_redirect = event->u.mapNotify.override; - } - break; - case MapRequest: - { - register XMapRequestEvent *ev = (XMapRequestEvent *) re; - ev->window = event->u.mapRequest.window; - ev->parent = event->u.mapRequest.parent; - } - break; - case ReparentNotify: - { - register XReparentEvent *ev = (XReparentEvent *) re; - ev->event = event->u.reparent.event; - ev->window = event->u.reparent.window; - ev->parent = event->u.reparent.parent; - ev->x = cvtINT16toInt(event->u.reparent.x); - ev->y = cvtINT16toInt(event->u.reparent.y); - ev->override_redirect = event->u.reparent.override; - } - break; - case ConfigureNotify: - { - register XConfigureEvent *ev = (XConfigureEvent *) re; - ev->event = event->u.configureNotify.event; - ev->window = event->u.configureNotify.window; - ev->above = event->u.configureNotify.aboveSibling; - ev->x = cvtINT16toInt(event->u.configureNotify.x); - ev->y = cvtINT16toInt(event->u.configureNotify.y); - ev->width = event->u.configureNotify.width; - ev->height = event->u.configureNotify.height; - ev->border_width = event->u.configureNotify.borderWidth; - ev->override_redirect = event->u.configureNotify.override; - } - break; - case ConfigureRequest: - { - register XConfigureRequestEvent *ev = - (XConfigureRequestEvent *) re; - ev->window = event->u.configureRequest.window; - ev->parent = event->u.configureRequest.parent; - ev->above = event->u.configureRequest.sibling; - ev->x = cvtINT16toInt(event->u.configureRequest.x); - ev->y = cvtINT16toInt(event->u.configureRequest.y); - ev->width = event->u.configureRequest.width; - ev->height = event->u.configureRequest.height; - ev->border_width = event->u.configureRequest.borderWidth; - ev->value_mask = event->u.configureRequest.valueMask; - ev->detail = event->u.u.detail; - } - break; - case GravityNotify: - { - register XGravityEvent *ev = (XGravityEvent *) re; - ev->window = event->u.gravity.window; - ev->event = event->u.gravity.event; - ev->x = cvtINT16toInt(event->u.gravity.x); - ev->y = cvtINT16toInt(event->u.gravity.y); - } - break; - case ResizeRequest: - { - register XResizeRequestEvent *ev = - (XResizeRequestEvent *) re; - ev->window = event->u.resizeRequest.window; - ev->width = event->u.resizeRequest.width; - ev->height = event->u.resizeRequest.height; - } - break; - case CirculateNotify: - { - register XCirculateEvent *ev = (XCirculateEvent *) re; - ev->window = event->u.circulate.window; - ev->event = event->u.circulate.event; - ev->place = event->u.circulate.place; - } - break; - case CirculateRequest: - { - register XCirculateRequestEvent *ev = - (XCirculateRequestEvent *) re; - ev->window = event->u.circulate.window; - ev->parent = event->u.circulate.event; - ev->place = event->u.circulate.place; - } - break; - case PropertyNotify: - { - register XPropertyEvent *ev = (XPropertyEvent *) re; - ev->window = event->u.property.window; - ev->atom = event->u.property.atom; - ev->time = event->u.property.time; - ev->state = event->u.property.state; - } - break; - case SelectionClear: - { - register XSelectionClearEvent *ev = - (XSelectionClearEvent *) re; - ev->window = event->u.selectionClear.window; - ev->selection = event->u.selectionClear.atom; - ev->time = event->u.selectionClear.time; - } - break; - case SelectionRequest: - { - register XSelectionRequestEvent *ev = - (XSelectionRequestEvent *) re; - ev->owner = event->u.selectionRequest.owner; - ev->requestor = event->u.selectionRequest.requestor; - ev->selection = event->u.selectionRequest.selection; - ev->target = event->u.selectionRequest.target; - ev->property = event->u.selectionRequest.property; - ev->time = event->u.selectionRequest.time; - } - break; - case SelectionNotify: - { - register XSelectionEvent *ev = (XSelectionEvent *) re; - ev->requestor = event->u.selectionNotify.requestor; - ev->selection = event->u.selectionNotify.selection; - ev->target = event->u.selectionNotify.target; - ev->property = event->u.selectionNotify.property; - ev->time = event->u.selectionNotify.time; - } - break; - case ColormapNotify: - { - register XColormapEvent *ev = (XColormapEvent *) re; - ev->window = event->u.colormap.window; - ev->colormap = event->u.colormap.colormap; - ev->new = event->u.colormap.new; - ev->state = event->u.colormap.state; - } - break; - case ClientMessage: - { - register int i; - register XClientMessageEvent *ev - = (XClientMessageEvent *) re; - ev->window = event->u.clientMessage.window; - ev->format = event->u.u.detail; - switch (ev->format) { - case 8: - ev->message_type = event->u.clientMessage.u.b.type; - for (i = 0; i < 20; i++) - ev->data.b[i] = event->u.clientMessage.u.b.bytes[i]; - break; - case 16: - ev->message_type = event->u.clientMessage.u.s.type; - ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0); - ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1); - ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2); - ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3); - ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4); - ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5); - ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6); - ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7); - ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8); - ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9); - break; - case 32: - ev->message_type = event->u.clientMessage.u.l.type; - ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0); - ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1); - ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2); - ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3); - ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4); - break; - default: /* XXX should never occur */ - break; - } - } - break; - case MappingNotify: - { - register XMappingEvent *ev = (XMappingEvent *)re; - ev->window = 0; - ev->first_keycode = event->u.mappingNotify.firstKeyCode; - ev->request = event->u.mappingNotify.request; - ev->count = event->u.mappingNotify.count; - } - break; - default: - return(_XUnknownWireEvent(dpy, re, event)); - } - return(True); -} - - -/* - * _XDefaultIOError - Default fatal system error reporting routine. Called - * when an X internal system error is encountered. - */ -int _XDefaultIOError( - Display *dpy) -{ - if (ECHECK(EPIPE)) { - (void) fprintf (stderr, - "X connection to %s broken (explicit kill or server shutdown).\r\n", - DisplayString (dpy)); - } else { - (void) fprintf (stderr, - "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n", -#ifdef WIN32 - WSAGetLastError(), strerror(WSAGetLastError()), -#else - errno, strerror (errno), -#endif - DisplayString (dpy)); - (void) fprintf (stderr, - " after %lu requests (%lu known processed) with %d events remaining.\r\n", - NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), - QLength(dpy)); - - } - exit(1); - return(0); /* dummy - function should never return */ -} - - -static int _XPrintDefaultError( - Display *dpy, - XErrorEvent *event, - FILE *fp) -{ - char buffer[BUFSIZ]; - char mesg[BUFSIZ]; - char number[32]; - const char *mtype = "XlibMessage"; - register _XExtension *ext = (_XExtension *)NULL; - _XExtension *bext = (_XExtension *)NULL; - XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); - XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ); - (void) fprintf(fp, "%s: %s\n ", mesg, buffer); - XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", - mesg, BUFSIZ); - (void) fprintf(fp, mesg, event->request_code); - if (event->request_code < 128) { - sprintf(number, "%d", event->request_code); - XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ); - } else { - for (ext = dpy->ext_procs; - ext && (ext->codes.major_opcode != event->request_code); - ext = ext->next) - ; - if (ext) { - strncpy(buffer, ext->name, BUFSIZ); - buffer[BUFSIZ - 1] = '\0'; - } else - buffer[0] = '\0'; - } - (void) fprintf(fp, " (%s)\n", buffer); - if (event->request_code >= 128) { - XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->minor_code); - if (ext) { - sprintf(mesg, "%s.%d", ext->name, event->minor_code); - XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ); - (void) fprintf(fp, " (%s)", buffer); - } - fputs("\n", fp); - } - if (event->error_code >= 128) { - /* kludge, try to find the extension that caused it */ - buffer[0] = '\0'; - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_string) - (*ext->error_string)(dpy, event->error_code, &ext->codes, - buffer, BUFSIZ); - if (buffer[0]) { - bext = ext; - break; - } - if (ext->codes.first_error && - ext->codes.first_error < (int)event->error_code && - (!bext || ext->codes.first_error > bext->codes.first_error)) - bext = ext; - } - if (bext) - sprintf(buffer, "%s.%d", bext->name, - event->error_code - bext->codes.first_error); - else - strcpy(buffer, "Value"); - XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ); - if (mesg[0]) { - fputs(" ", fp); - (void) fprintf(fp, mesg, event->resourceid); - fputs("\n", fp); - } - /* let extensions try to print the values */ - for (ext = dpy->ext_procs; ext; ext = ext->next) { - if (ext->error_values) - (*ext->error_values)(dpy, event, fp); - } - } else if ((event->error_code == BadWindow) || - (event->error_code == BadPixmap) || - (event->error_code == BadCursor) || - (event->error_code == BadFont) || - (event->error_code == BadDrawable) || - (event->error_code == BadColor) || - (event->error_code == BadGC) || - (event->error_code == BadIDChoice) || - (event->error_code == BadValue) || - (event->error_code == BadAtom)) { - if (event->error_code == BadValue) - XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x", - mesg, BUFSIZ); - else if (event->error_code == BadAtom) - XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x", - mesg, BUFSIZ); - else - XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->resourceid); - fputs("\n", fp); - } - XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", - mesg, BUFSIZ); - fputs(" ", fp); - (void) fprintf(fp, mesg, event->serial); - XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d", - mesg, BUFSIZ); - fputs("\n ", fp); - (void) fprintf(fp, mesg, dpy->request); - fputs("\n", fp); - if (event->error_code == BadImplementation) return 0; - return 1; -} - -int _XDefaultError( - Display *dpy, - XErrorEvent *event) -{ - if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0; - exit(1); - /*NOTREACHED*/ -} - -/*ARGSUSED*/ -Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) -{ - return True; -} - -/* - * _XError - upcall internal or user protocol error handler - */ -int _XError ( - Display *dpy, - register xError *rep) -{ - /* - * X_Error packet encountered! We need to unpack the error before - * giving it to the user. - */ - XEvent event; /* make it a large event */ - register _XAsyncHandler *async, *next; - - event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep); - - for (async = dpy->async_handlers; async; async = next) { - next = async->next; - if ((*async->handler)(dpy, (xReply *)rep, - (char *)rep, SIZEOF(xError), async->data)) - return 0; - } - - event.xerror.display = dpy; - event.xerror.type = X_Error; - event.xerror.resourceid = rep->resourceID; - event.xerror.error_code = rep->errorCode; - event.xerror.request_code = rep->majorCode; - event.xerror.minor_code = rep->minorCode; - if (dpy->error_vec && - !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep)) - return 0; - if (_XErrorFunction != NULL) { - int rtn_val; -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_lock_display)(dpy); - UnlockDisplay(dpy); -#endif - rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ -#ifdef XTHREADS - LockDisplay(dpy); - if (dpy->lock) - (*dpy->lock->user_unlock_display)(dpy); -#endif - return rtn_val; - } else { - return _XDefaultError(dpy, (XErrorEvent *)&event); - } -} - -/* - * _XIOError - call user connection error handler and exit - */ -int -_XIOError ( - Display *dpy) -{ - dpy->flags |= XlibDisplayIOError; -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - - /* This assumes that the thread calling exit will call any atexit handlers. - * If this does not hold, then an alternate solution would involve - * registering an atexit handler to take over the lock, which would only - * assume that the same thread calls all the atexit handlers. */ -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_lock_display)(dpy); -#endif - UnlockDisplay(dpy); - - if (_XIOErrorFunction != NULL) - (*_XIOErrorFunction)(dpy); - else - _XDefaultIOError(dpy); - exit (1); - return 0; -} - - -/* - * This routine can be used to (cheaply) get some memory within a single - * Xlib routine for scratch space. A single buffer is reused each time - * if possible. To be MT safe, you can only call this between a call to - * GetReq* and a call to Data* or _XSend*, or in a context when the thread - * is guaranteed to not unlock the display. - */ -char *_XAllocScratch( - register Display *dpy, - unsigned long nbytes) -{ - if (nbytes > dpy->scratch_length) { - if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer); - if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes))) - dpy->scratch_length = nbytes; - else dpy->scratch_length = 0; - } - return (dpy->scratch_buffer); -} - -/* - * Scratch space allocator you can call any time, multiple times, and be - * MT safe, but you must hand the buffer back with _XFreeTemp. - */ -char *_XAllocTemp( - register Display *dpy, - unsigned long nbytes) -{ - char *buf; - - buf = _XAllocScratch(dpy, nbytes); - dpy->scratch_buffer = NULL; - dpy->scratch_length = 0; - return buf; -} - -void _XFreeTemp( - register Display *dpy, - char *buf, - unsigned long nbytes) -{ - if (dpy->scratch_buffer) - Xfree(dpy->scratch_buffer); - dpy->scratch_buffer = buf; - dpy->scratch_length = nbytes; -} - -/* - * Given a visual id, find the visual structure for this id on this display. - */ -Visual *_XVIDtoVisual( - Display *dpy, - VisualID id) -{ - register int i, j, k; - register Screen *sp; - register Depth *dp; - register Visual *vp; - for (i = 0; i < dpy->nscreens; i++) { - sp = &dpy->screens[i]; - for (j = 0; j < sp->ndepths; j++) { - dp = &sp->depths[j]; - /* if nvisuals == 0 then visuals will be NULL */ - for (k = 0; k < dp->nvisuals; k++) { - vp = &dp->visuals[k]; - if (vp->visualid == id) return (vp); - } - } - } - return (NULL); -} - -int -XFree (void *data) -{ - Xfree (data); - return 1; -} - -#ifdef _XNEEDBCOPYFUNC -void _Xbcopy(b1, b2, length) - register char *b1, *b2; - register length; -{ - if (b1 < b2) { - b2 += length; - b1 += length; - while (length--) - *--b2 = *--b1; - } else { - while (length--) - *b2++ = *b1++; - } -} -#endif - -#ifdef DataRoutineIsProcedure -void Data( - Display *dpy, - char *data, - long len) -{ - if (dpy->bufptr + (len) <= dpy->bufmax) { - memcpy(dpy->bufptr, data, (int)len); - dpy->bufptr += ((len) + 3) & ~3; - } else { - _XSend(dpy, data, len); - } -} -#endif /* DataRoutineIsProcedure */ - - -#ifdef LONG64 -int -_XData32( - Display *dpy, - register long *data, - unsigned len) -{ - register int *buf; - register long i; - - while (len) { - buf = (int *)dpy->bufptr; - i = dpy->bufmax - (char *)buf; - if (!i) { - _XFlush(dpy); - continue; - } - if (len < i) - i = len; - dpy->bufptr = (char *)buf + i; - len -= i; - i >>= 2; - while (--i >= 0) - *buf++ = *data++; - } - return 0; -} -#endif /* LONG64 */ - -#ifdef WORD64 - -/* - * XXX This is a *really* stupid way of doing this. It should just use - * dpy->bufptr directly, taking into account where in the word it is. - */ - -/* - * Data16 - Place 16 bit data in the buffer. - * - * "dpy" is a pointer to a Display. - * "data" is a pointer to the data. - * "len" is the length in bytes of the data. - */ - -static doData16( - register Display *dpy, - short *data, - unsigned len, - char *packbuffer) -{ - long *lp,*lpack; - long i, nwords,bits; - long mask16 = 0x000000000000ffff; - - lp = (long *)data; - lpack = (long *)packbuffer; - -/* nwords is the number of 16 bit values to be packed, - * the low order 16 bits of each word will be packed - * into 64 bit words - */ - nwords = len >> 1; - bits = 48; - - for(i=0;i<nwords;i++){ - if (bits == 48) *lpack = 0; - *lpack ^= (*lp & mask16) << bits; - bits -= 16 ; - lp++; - if(bits < 0){ - lpack++; - bits = 48; - } - } - Data(dpy, packbuffer, len); -} - -_XData16 ( - Display *dpy, - short *data, - unsigned len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 1; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - doData16 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) doData16 (dpy, data, len, packbuffer); -} - -/* - * Data32 - Place 32 bit data in the buffer. - * - * "dpy" is a pointer to a Display. - * "data" is a pointer to the data. - * "len" is the length in bytes of the data. - */ - -static doData32( - register Display *dpy - long *data, - unsigned len, - char *packbuffer) -{ - long *lp,*lpack; - long i,bits,nwords; - long mask32 = 0x00000000ffffffff; - - lpack = (long *) packbuffer; - lp = data; - -/* nwords is the number of 32 bit values to be packed - * the low order 32 bits of each word will be packed - * into 64 bit words - */ - nwords = len >> 2; - bits = 32; - - for(i=0;i<nwords;i++){ - if (bits == 32) *lpack = 0; - *lpack ^= (*lp & mask32) << bits; - bits = bits ^32; - lp++; - if(bits) - lpack++; - } - Data(dpy, packbuffer, len); -} - -void _XData32( - Display *dpy, - long *data, - unsigned len) -{ - char packbuffer[PACKBUFFERSIZE]; - unsigned nunits = PACKBUFFERSIZE >> 2; - - for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) { - doData32 (dpy, data, PACKBUFFERSIZE, packbuffer); - } - if (len) doData32 (dpy, data, len, packbuffer); -} - -#endif /* WORD64 */ - - -/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm. - * Otherwise, Xau will not be able to find your cookies in the Xauthority file. - * - * Note: POSIX says that the ``nodename'' member of utsname does _not_ have - * to have sufficient information for interfacing to the network, - * and so, you may be better off using gethostname (if it exists). - */ - -#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4) -#define NEED_UTSNAME -#include <sys/utsname.h> -#else -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#endif - -/* - * _XGetHostname - similar to gethostname but allows special processing. - */ -int _XGetHostname ( - char *buf, - int maxlen) -{ - int len; - -#ifdef NEED_UTSNAME - struct utsname name; - - if (maxlen <= 0 || buf == NULL) - return 0; - - uname (&name); - len = strlen (name.nodename); - if (len >= maxlen) len = maxlen - 1; - strncpy (buf, name.nodename, len); - buf[len] = '\0'; -#else - if (maxlen <= 0 || buf == NULL) - return 0; - - buf[0] = '\0'; - (void) gethostname (buf, maxlen); - buf [maxlen - 1] = '\0'; - len = strlen(buf); -#endif /* NEED_UTSNAME */ - return len; -} - - -/* - * _XScreenOfWindow - get the Screen of a given window - */ - -Screen *_XScreenOfWindow(Display *dpy, Window w) -{ - register int i; - Window root; - int x, y; /* dummy variables */ - unsigned int width, height, bw, depth; /* dummy variables */ - - if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height, - &bw, &depth) == False) { - return NULL; - } - for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */ - if (root == RootWindow (dpy, i)) { - return ScreenOfDisplay (dpy, i); - } - } - return NULL; -} - - -#if defined(WIN32) - -/* - * These functions are intended to be used internally to Xlib only. - * These functions will always prefix the path with a DOS drive in the - * form "<drive-letter>:". As such, these functions are only suitable - * for use by Xlib function that supply a root-based path to some - * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will - * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir". - */ - -static int access_file (path, pathbuf, len_pathbuf, pathret) - char* path; - char* pathbuf; - int len_pathbuf; - char** pathret; -{ - if (access (path, F_OK) == 0) { - if (strlen (path) < len_pathbuf) - *pathret = pathbuf; - else - *pathret = Xmalloc (strlen (path) + 1); - if (*pathret) { - strcpy (*pathret, path); - return 1; - } - } - return 0; -} - -static int AccessFile (path, pathbuf, len_pathbuf, pathret) - char* path; - char* pathbuf; - int len_pathbuf; - char** pathret; -{ - unsigned long drives; - int i, len; - char* drive; - char buf[MAX_PATH]; - char* bufp; - - /* just try the "raw" name first and see if it works */ - if (access_file (path, pathbuf, len_pathbuf, pathret)) - return 1; - - /* try the places set in the environment */ - drive = getenv ("_XBASEDRIVE"); -#ifdef __UNIXOS2__ - if (!drive) - drive = getenv ("X11ROOT"); -#endif - if (!drive) - drive = "C:"; - len = strlen (drive) + strlen (path); - if (len < MAX_PATH) bufp = buf; - else bufp = Xmalloc (len + 1); - strcpy (bufp, drive); - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - if (bufp != buf) Xfree (bufp); - return 1; - } - -#ifndef __UNIXOS2__ - /* one last place to look */ - drive = getenv ("HOMEDRIVE"); - if (drive) { - len = strlen (drive) + strlen (path); - if (len < MAX_PATH) bufp = buf; - else bufp = Xmalloc (len + 1); - strcpy (bufp, drive); - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - if (bufp != buf) Xfree (bufp); - return 1; - } - } - - /* tried everywhere else, go fishing */ -#define C_DRIVE ('C' - 'A') -#define Z_DRIVE ('Z' - 'A') - /* does OS/2 (with or with gcc-emx) have getdrives? */ - drives = _getdrives (); - for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */ - if ((1 << i) & drives) { - len = 2 + strlen (path); - if (len < MAX_PATH) bufp = buf; - else bufp = Xmalloc (len + 1); - *bufp = 'A' + i; - *(bufp + 1) = ':'; - *(bufp + 2) = '\0'; - strcat (bufp, path); - if (access_file (bufp, pathbuf, len_pathbuf, pathret)) { - if (bufp != buf) Xfree (bufp); - return 1; - } - } - } -#endif - return 0; -} - -int _XOpenFile(path, flags) - _Xconst char* path; - int flags; -{ - char buf[MAX_PATH]; - char* bufp = NULL; - int ret = -1; - UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); - - if (AccessFile (path, buf, MAX_PATH, &bufp)) - ret = open (bufp, flags); - - (void) SetErrorMode (olderror); - - if (bufp != buf) Xfree (bufp); - - return ret; -} - -int _XOpenFileMode(path, flags, mode) - _Xconst char* path; - int flags; - mode_t mode; -{ - char buf[MAX_PATH]; - char* bufp = NULL; - int ret = -1; - UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); - - if (AccessFile (path, buf, MAX_PATH, &bufp)) - ret = open (bufp, flags, mode); - - (void) SetErrorMode (olderror); - - if (bufp != buf) Xfree (bufp); - - return ret; -} - -void* _XFopenFile(path, mode) - _Xconst char* path; - _Xconst char* mode; -{ - char buf[MAX_PATH]; - char* bufp = NULL; - void* ret = NULL; - UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); - - if (AccessFile (path, buf, MAX_PATH, &bufp)) - ret = fopen (bufp, mode); - - (void) SetErrorMode (olderror); - - if (bufp != buf) Xfree (bufp); - - return ret; -} - -int _XAccessFile(path) - _Xconst char* path; -{ - char buf[MAX_PATH]; - char* bufp; - int ret = -1; - UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS); - - ret = AccessFile (path, buf, MAX_PATH, &bufp); - - (void) SetErrorMode (olderror); - - if (bufp != buf) Xfree (bufp); - - return ret; -} - -#endif - -#ifdef WIN32 -#undef _Xdebug -int _Xdebug = 0; -int *_Xdebug_p = &_Xdebug; -void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn; -void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn; -void (**_XLockMutex_fn_p)(LockInfoPtr -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif - ) = &_XLockMutex_fn; -void (**_XUnlockMutex_fn_p)(LockInfoPtr -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif - ) = &_XUnlockMutex_fn; -LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock; -#endif +/*
+
+Copyright 1985, 1986, 1987, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+/*
+ * XlibInt.c - Internal support routines for the C subroutine
+ * interface library (Xlib) to the X Window System Protocol V11.0.
+ */
+
+#ifdef WIN32
+#define _XLIBINT_
+#include <X11\Xw32defs.h>
+#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xprivate.h"
+#include <X11/Xpoll.h>
+#include <assert.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <direct.h>
+#endif
+
+#ifdef XTHREADS
+#include "locking.h"
+
+/* these pointers get initialized by XInitThreads */
+LockInfoPtr _Xglobal_lock = NULL;
+void (*_XCreateMutex_fn)(LockInfoPtr) = NULL;
+/* struct _XCVList *(*_XCreateCVL_fn)() = NULL; */
+void (*_XFreeMutex_fn)(LockInfoPtr) = NULL;
+void (*_XLockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = NULL;
+void (*_XUnlockMutex_fn)(
+ LockInfoPtr /* lock */
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = NULL;
+xthread_t (*_Xthread_self_fn)(void) = NULL;
+
+#define XThread_Self() ((*_Xthread_self_fn)())
+
+#endif /* XTHREADS */
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifdef WIN32
+#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
+#else
+#ifdef __CYGWIN__ /* Cygwin uses ENOBUFS to signal socket is full */
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
+#else
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST() (errno == EAGAIN)
+#else
+#define ETEST() (errno == EWOULDBLOCK)
+#endif /* EAGAIN */
+#endif /* EAGAIN && EWOULDBLOCK */
+#endif /* __CYGWIN__ */
+#endif /* WIN32 */
+
+#ifdef WIN32
+#define ECHECK(err) (WSAGetLastError() == err)
+#define ESET(val) WSASetLastError(val)
+#else
+#ifdef __UNIXOS2__
+#define ECHECK(err) (errno == err)
+#define ESET(val)
+#else
+#define ECHECK(err) (errno == err)
+#define ESET(val) errno = val
+#endif
+#endif
+
+#if defined(LOCALCONN) || defined(LACHMAN)
+#ifdef EMSGSIZE
+#define ESZTEST() (ECHECK(EMSGSIZE) || ECHECK(ERANGE))
+#else
+#define ESZTEST() ECHECK(ERANGE)
+#endif
+#else
+#ifdef EMSGSIZE
+#define ESZTEST() ECHECK(EMSGSIZE)
+#endif
+#endif
+
+#ifdef __UNIXOS2__
+#include <limits.h>
+#define MAX_PATH _POSIX_PATH_MAX
+#endif
+
+/*
+ * The following routines are internal routines used by Xlib for protocol
+ * packet transmission and reception.
+ *
+ * _XIOError(Display *) will be called if any sort of system call error occurs.
+ * This is assumed to be a fatal condition, i.e., XIOError should not return.
+ *
+ * _XError(Display *, xError *) will be called whenever an X_Error event is
+ * received. This is not assumed to be a fatal condition, i.e., it is
+ * acceptable for this procedure to return. However, XError should NOT
+ * perform any operations (directly or indirectly) on the DISPLAY.
+ *
+ * Routines declared with a return type of 'Status' return 0 on failure,
+ * and non 0 on success. Routines with no declared return type don't
+ * return anything. Whenever possible routines that create objects return
+ * the object they have created.
+ */
+
+#define POLLFD_CACHE_SIZE 5
+
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
+struct pollfd {
+
+ SOCKET fd;
+ SHORT events;
+ SHORT revents;
+
+};
+#define POLLRDNORM 0x0100
+#define POLLRDBAND 0x0200
+#define POLLIN (POLLRDNORM | POLLRDBAND)
+#endif
+
+/* initialize the struct array passed to poll() below */
+Bool _XPollfdCacheInit(
+ Display *dpy)
+{
+#ifdef USE_POLL
+ struct pollfd *pfp;
+
+ pfp = (struct pollfd *)Xmalloc(POLLFD_CACHE_SIZE * sizeof(struct pollfd));
+ if (!pfp)
+ return False;
+ pfp[0].fd = dpy->fd;
+ pfp[0].events = POLLIN;
+
+ dpy->filedes = (XPointer)pfp;
+#endif
+ return True;
+}
+
+void _XPollfdCacheAdd(
+ Display *dpy,
+ int fd)
+{
+#ifdef USE_POLL
+ struct pollfd *pfp = (struct pollfd *)dpy->filedes;
+
+ if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
+ pfp[dpy->im_fd_length].fd = fd;
+ pfp[dpy->im_fd_length].events = POLLIN;
+ }
+#endif
+}
+
+/* ARGSUSED */
+void _XPollfdCacheDel(
+ Display *dpy,
+ int fd) /* not used */
+{
+#ifdef USE_POLL
+ struct pollfd *pfp = (struct pollfd *)dpy->filedes;
+ struct _XConnectionInfo *conni;
+
+ /* just recalculate whole list */
+ if (dpy->im_fd_length <= POLLFD_CACHE_SIZE) {
+ int loc = 1;
+ for (conni = dpy->im_fd_info; conni; conni=conni->next) {
+ pfp[loc].fd = conni->fd;
+ pfp[loc].events = POLLIN;
+ loc++;
+ }
+ }
+#endif
+}
+
+#ifdef _MSC_VER
+#undef min
+#define min __min
+#endif
+
+static int sync_hazard(Display *dpy)
+{
+ unsigned long span = dpy->request - dpy->last_request_read;
+ unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
+ return span >= 65535 - hazard - 10;
+}
+
+static
+void sync_while_locked(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+ SyncHandle();
+ InternalLockDisplay(dpy, /* don't skip user locks */ 0);
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_unlock_display)(dpy);
+#endif
+}
+
+void _XSeqSyncFunction(
+ register Display *dpy)
+{
+ xGetInputFocusReply rep;
+ register xReq *req;
+
+ if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
+ GetEmptyReq(GetInputFocus, req);
+ (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
+ sync_while_locked(dpy);
+ } else if (sync_hazard(dpy))
+ _XSetPrivSyncFunction(dpy);
+}
+
+/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */
+static int
+_XPrivSyncFunction (Display *dpy)
+{
+#ifdef XTHREADS
+ assert(!dpy->lock_fns);
+#endif
+ assert(dpy->synchandler == _XPrivSyncFunction);
+ assert((dpy->flags & XlibDisplayPrivSync) != 0);
+ dpy->synchandler = dpy->savedsynchandler;
+ dpy->savedsynchandler = NULL;
+ dpy->flags &= ~XlibDisplayPrivSync;
+ if(dpy->synchandler)
+ dpy->synchandler(dpy);
+ _XIDHandler(dpy);
+ _XSeqSyncFunction(dpy);
+ return 0;
+}
+
+void _XSetPrivSyncFunction(Display *dpy)
+{
+#ifdef XTHREADS
+ if (dpy->lock_fns)
+ return;
+#endif
+ if (!(dpy->flags & XlibDisplayPrivSync)) {
+ dpy->savedsynchandler = dpy->synchandler;
+ dpy->synchandler = _XPrivSyncFunction;
+ dpy->flags |= XlibDisplayPrivSync;
+ }
+}
+
+void _XSetSeqSyncFunction(Display *dpy)
+{
+ if (sync_hazard(dpy))
+ _XSetPrivSyncFunction (dpy);
+}
+
+#ifdef LONG64
+void _XRead32(
+ Display *dpy,
+ register long *data,
+ long len)
+{
+ register int *buf;
+ register long i;
+
+ if (len) {
+ (void) _XRead(dpy, (char *)data, len);
+ i = len >> 2;
+ buf = (int *)data + i;
+ data += i;
+ while (--i >= 0)
+ *--data = *--buf;
+ }
+}
+#endif /* LONG64 */
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this....
+ * PACKBUFFERSIZE must be a multiple of 4.
+ */
+
+#define PACKBUFFERSIZE 4096
+
+
+/*
+ * _XRead32 - Read bytes from the socket unpacking each 32 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static void _doXRead32(
+ register Display *dpy,
+ register long *data
+ register long size,
+ register char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask32 = 0x00000000ffffffff;
+ long maskw, nwords, i, bits;
+
+ _XReadPad (dpy, packbuffer, size);
+
+ lp = data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ maskw = mask32 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits = bits ^32;
+ if(bits){
+ lpack++;
+ }
+ }
+}
+
+void _XRead32(
+ Display *dpy,
+ long *data,
+ long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead32 (dpy, data, len, packbuffer);
+}
+
+
+
+/*
+ * _XRead16 - Read bytes from the socket unpacking each 16 bits
+ * into a long (64 bits on a CRAY computer).
+ *
+ */
+static _doXRead16(
+ register Display *dpy,
+ register short *data,
+ register long size,
+ char *packbuffer)
+{
+ long *lpack,*lp;
+ long mask16 = 0x000000000000ffff;
+ long maskw, nwords, i, bits;
+
+ (void) _XRead(dpy,packbuffer,size); /* don't do a padded read... */
+
+ lp = (long *) data;
+ lpack = (long *) packbuffer;
+ nwords = size >> 1; /* number of 16 bit words to be unpacked */
+ bits = 48;
+ for(i=0;i<nwords;i++){
+ maskw = mask16 << bits;
+ *lp++ = ( *lpack & maskw ) >> bits;
+ bits -= 16;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+}
+
+void _XRead16(
+ Display *dpy,
+ short *data,
+ long len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ _doXRead16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) _doXRead16 (dpy, data, len, packbuffer);
+}
+
+void _XRead16Pad(
+ Display *dpy,
+ short *data,
+ long size)
+{
+ int slop = (size & 3);
+ short slopbuf[3];
+
+ _XRead16 (dpy, data, size);
+ if (slop > 0) {
+ _XRead16 (dpy, slopbuf, 4 - slop);
+ }
+}
+#endif /* WORD64 */
+
+/*
+ * The hard part about this is that we only get 16 bits from a reply.
+ * We have three values that will march along, with the following invariant:
+ * dpy->last_request_read <= rep->sequenceNumber <= dpy->request
+ * We have to keep
+ * dpy->request - dpy->last_request_read < 2^16
+ * or else we won't know for sure what value to use in events. We do this
+ * by forcing syncs when we get close.
+ */
+
+unsigned long
+_XSetLastRequestRead(
+ register Display *dpy,
+ register xGenericReply *rep)
+{
+ register unsigned long newseq, lastseq;
+
+ lastseq = dpy->last_request_read;
+ /*
+ * KeymapNotify has no sequence number, but is always guaranteed
+ * to immediately follow another event, except when generated via
+ * SendEvent (hmmm).
+ */
+ if ((rep->type & 0x7f) == KeymapNotify)
+ return(lastseq);
+
+ newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
+
+ if (newseq < lastseq) {
+ newseq += 0x10000;
+ if (newseq > dpy->request) {
+ (void) fprintf (stderr,
+ "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
+ newseq, dpy->request,
+ (unsigned int) rep->type);
+ newseq -= 0x10000;
+ }
+ }
+
+ dpy->last_request_read = newseq;
+ return(newseq);
+}
+
+/*
+ * Support for internal connections, such as an IM might use.
+ * By Stephen Gildea, X Consortium, September 1993
+ */
+
+/* _XRegisterInternalConnection
+ * Each IM (or Xlib extension) that opens a file descriptor that Xlib should
+ * include in its select/poll mask must call this function to register the
+ * fd with Xlib. Any XConnectionWatchProc registered by XAddConnectionWatch
+ * will also be called.
+ *
+ * Whenever Xlib detects input available on fd, it will call callback
+ * with call_data to process it. If non-Xlib code calls select/poll
+ * and detects input available, it must call XProcessInternalConnection,
+ * which will call the associated callback.
+ *
+ * Non-Xlib code can learn about these additional fds by calling
+ * XInternalConnectionNumbers or, more typically, by registering
+ * a XConnectionWatchProc with XAddConnectionWatch
+ * to be called when fds are registered or unregistered.
+ *
+ * Returns True if registration succeeded, False if not, typically
+ * because could not allocate memory.
+ * Assumes Display locked when called.
+ */
+Status
+_XRegisterInternalConnection(
+ Display* dpy,
+ int fd,
+ _XInternalConnectionProc callback,
+ XPointer call_data
+)
+{
+ struct _XConnectionInfo *new_conni, **iptr;
+ struct _XConnWatchInfo *watchers;
+ XPointer *wd;
+
+ new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
+ if (!new_conni)
+ return 0;
+ new_conni->watch_data = (XPointer *)Xmalloc(dpy->watcher_count * sizeof(XPointer));
+ if (!new_conni->watch_data) {
+ Xfree(new_conni);
+ return 0;
+ }
+ new_conni->fd = fd;
+ new_conni->read_callback = callback;
+ new_conni->call_data = call_data;
+ new_conni->next = NULL;
+ /* link new structure onto end of list */
+ for (iptr = &dpy->im_fd_info; *iptr; iptr = &(*iptr)->next)
+ ;
+ *iptr = new_conni;
+ dpy->im_fd_length++;
+ _XPollfdCacheAdd(dpy, fd);
+
+ for (watchers=dpy->conn_watchers, wd=new_conni->watch_data;
+ watchers;
+ watchers=watchers->next, wd++) {
+ *wd = NULL; /* for cleanliness */
+ (*watchers->fn) (dpy, watchers->client_data, fd, True, wd);
+ }
+
+ return 1;
+}
+
+/* _XUnregisterInternalConnection
+ * Each IM (or Xlib extension) that closes a file descriptor previously
+ * registered with _XRegisterInternalConnection must call this function.
+ * Any XConnectionWatchProc registered by XAddConnectionWatch
+ * will also be called.
+ *
+ * Assumes Display locked when called.
+ */
+void
+_XUnregisterInternalConnection(
+ Display* dpy,
+ int fd
+)
+{
+ struct _XConnectionInfo *info_list, **prev;
+ struct _XConnWatchInfo *watch;
+ XPointer *wd;
+
+ for (prev = &dpy->im_fd_info; (info_list = *prev);
+ prev = &info_list->next) {
+ if (info_list->fd == fd) {
+ *prev = info_list->next;
+ dpy->im_fd_length--;
+ for (watch=dpy->conn_watchers, wd=info_list->watch_data;
+ watch;
+ watch=watch->next, wd++) {
+ (*watch->fn) (dpy, watch->client_data, fd, False, wd);
+ }
+ if (info_list->watch_data)
+ Xfree (info_list->watch_data);
+ Xfree (info_list);
+ break;
+ }
+ }
+ _XPollfdCacheDel(dpy, fd);
+}
+
+/* XInternalConnectionNumbers
+ * Returns an array of fds and an array of corresponding call data.
+ * Typically a XConnectionWatchProc registered with XAddConnectionWatch
+ * will be used instead of this function to discover
+ * additional fds to include in the select/poll mask.
+ *
+ * The list is allocated with Xmalloc and should be freed by the caller
+ * with Xfree;
+ */
+Status
+XInternalConnectionNumbers(
+ Display *dpy,
+ int **fd_return,
+ int *count_return
+)
+{
+ int count;
+ struct _XConnectionInfo *info_list;
+ int *fd_list;
+
+ LockDisplay(dpy);
+ count = 0;
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
+ count++;
+ fd_list = (int*) Xmalloc (count * sizeof(int));
+ if (!fd_list) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ count = 0;
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ fd_list[count] = info_list->fd;
+ count++;
+ }
+ UnlockDisplay(dpy);
+
+ *fd_return = fd_list;
+ *count_return = count;
+ return 1;
+}
+
+void _XProcessInternalConnection(
+ Display *dpy,
+ struct _XConnectionInfo *conn_info)
+{
+ dpy->flags |= XlibDisplayProcConni;
+ UnlockDisplay(dpy);
+ (*conn_info->read_callback) (dpy, conn_info->fd, conn_info->call_data);
+ LockDisplay(dpy);
+ dpy->flags &= ~XlibDisplayProcConni;
+}
+
+/* XProcessInternalConnection
+ * Call the _XInternalConnectionProc registered by _XRegisterInternalConnection
+ * for this fd.
+ * The Display is NOT locked during the call.
+ */
+void
+XProcessInternalConnection(
+ Display* dpy,
+ int fd
+)
+{
+ struct _XConnectionInfo *info_list;
+
+ LockDisplay(dpy);
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ if (info_list->fd == fd) {
+ _XProcessInternalConnection(dpy, info_list);
+ break;
+ }
+ }
+ UnlockDisplay(dpy);
+}
+
+/* XAddConnectionWatch
+ * Register a callback to be called whenever _XRegisterInternalConnection
+ * or _XUnregisterInternalConnection is called.
+ * Callbacks are called with the Display locked.
+ * If any connections are already registered, the callback is immediately
+ * called for each of them.
+ */
+Status
+XAddConnectionWatch(
+ Display* dpy,
+ XConnectionWatchProc callback,
+ XPointer client_data
+)
+{
+ struct _XConnWatchInfo *new_watcher, **wptr;
+ struct _XConnectionInfo *info_list;
+ XPointer *wd_array;
+
+ LockDisplay(dpy);
+
+ /* allocate new watch data */
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ wd_array = (XPointer *)Xrealloc((char *)info_list->watch_data,
+ (dpy->watcher_count + 1) *
+ sizeof(XPointer));
+ if (!wd_array) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ info_list->watch_data = wd_array;
+ wd_array[dpy->watcher_count] = NULL; /* for cleanliness */
+ }
+
+ new_watcher = (struct _XConnWatchInfo*)Xmalloc(sizeof(struct _XConnWatchInfo));
+ if (!new_watcher) {
+ UnlockDisplay(dpy);
+ return 0;
+ }
+ new_watcher->fn = callback;
+ new_watcher->client_data = client_data;
+ new_watcher->next = NULL;
+
+ /* link new structure onto end of list */
+ for (wptr = &dpy->conn_watchers; *wptr; wptr = &(*wptr)->next)
+ ;
+ *wptr = new_watcher;
+ dpy->watcher_count++;
+
+ /* call new watcher on all currently registered fds */
+ for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ (*callback) (dpy, client_data, info_list->fd, True,
+ info_list->watch_data + dpy->watcher_count - 1);
+ }
+
+ UnlockDisplay(dpy);
+ return 1;
+}
+
+/* XRemoveConnectionWatch
+ * Unregister a callback registered by XAddConnectionWatch.
+ * Both callback and client_data must match what was passed to
+ * XAddConnectionWatch.
+ */
+void
+XRemoveConnectionWatch(
+ Display* dpy,
+ XConnectionWatchProc callback,
+ XPointer client_data
+)
+{
+ struct _XConnWatchInfo *watch;
+ struct _XConnWatchInfo *previous = NULL;
+ struct _XConnectionInfo *conni;
+ int counter = 0;
+
+ LockDisplay(dpy);
+ for (watch=dpy->conn_watchers; watch; watch=watch->next) {
+ if (watch->fn == callback && watch->client_data == client_data) {
+ if (previous)
+ previous->next = watch->next;
+ else
+ dpy->conn_watchers = watch->next;
+ Xfree (watch);
+ dpy->watcher_count--;
+ /* remove our watch_data for each connection */
+ for (conni=dpy->im_fd_info; conni; conni=conni->next) {
+ /* don't bother realloc'ing; these arrays are small anyway */
+ /* overlapping */
+ memmove(conni->watch_data+counter,
+ conni->watch_data+counter+1,
+ dpy->watcher_count - counter);
+ }
+ break;
+ }
+ previous = watch;
+ counter++;
+ }
+ UnlockDisplay(dpy);
+}
+
+/* end of internal connections support */
+
+/* Cookie jar implementation
+ dpy->cookiejar is a linked list. _XEnq receives the events but leaves
+ them in the normal EQ. _XStoreEvent returns the cookie event (minus
+ data pointer) and adds it to the cookiejar. _XDeq just removes
+ the entry like any other event but resets the data pointer for
+ cookie events (to avoid double-free, the memory is re-used by Xlib).
+
+ _XFetchEventCookie (called from XGetEventData) removes a cookie from the
+ jar. _XFreeEventCookies removes all unclaimed cookies from the jar
+ (called by XNextEvent).
+
+ _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the
+ normal EQ.
+ */
+
+#include "utlist.h"
+struct stored_event {
+ XGenericEventCookie ev;
+ struct stored_event *prev;
+ struct stored_event *next;
+};
+
+Bool
+_XIsEventCookie(Display *dpy, XEvent *ev)
+{
+ return (ev->xcookie.type == GenericEvent &&
+ dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL);
+}
+
+/**
+ * Free all events in the event list.
+ */
+void
+_XFreeEventCookies(Display *dpy)
+{
+ struct stored_event **head, *e, *tmp;
+
+ if (!dpy->cookiejar)
+ return;
+
+ head = (struct stored_event**)&dpy->cookiejar;
+
+ DL_FOREACH_SAFE(*head, e, tmp) {
+ if (dpy->cookiejar == e)
+ dpy->cookiejar = NULL;
+ XFree(e->ev.data);
+ XFree(e);
+ }
+}
+
+/**
+ * Add an event to the display's event list. This event must be freed on the
+ * next call to XNextEvent().
+ */
+void
+_XStoreEventCookie(Display *dpy, XEvent *event)
+{
+ XGenericEventCookie* cookie = &event->xcookie;
+ struct stored_event **head, *add;
+
+ if (!_XIsEventCookie(dpy, event))
+ return;
+
+ head = (struct stored_event**)(&dpy->cookiejar);
+
+ add = Xmalloc(sizeof(struct stored_event));
+ if (!add) {
+ ESET(ENOMEM);
+ _XIOError(dpy);
+ }
+ add->ev = *cookie;
+ DL_APPEND(*head, add);
+ cookie->data = NULL; /* don't return data yet, must be claimed */
+}
+
+/**
+ * Return the event with the given cookie and remove it from the list.
+ */
+Bool
+_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev)
+{
+ Bool ret = False;
+ struct stored_event **head, *event;
+ head = (struct stored_event**)&dpy->cookiejar;
+
+ if (!_XIsEventCookie(dpy, (XEvent*)ev))
+ return ret;
+
+ DL_FOREACH(*head, event) {
+ if (event->ev.cookie == ev->cookie &&
+ event->ev.extension == ev->extension &&
+ event->ev.evtype == ev->evtype) {
+ *ev = event->ev;
+ DL_DELETE(*head, event);
+ Xfree(event);
+ ret = True;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+Bool
+_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
+{
+ Bool ret = False;
+ int extension;
+
+ if (!_XIsEventCookie(dpy, (XEvent*)in) || !out)
+ return ret;
+
+ extension = in->extension & 0x7F;
+
+ if (!dpy->generic_event_copy_vec[extension])
+ return ret;
+
+ ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out));
+ out->cookie = ret ? ++dpy->next_cookie : 0;
+ return ret;
+}
+
+
+/*
+ * _XEnq - Place event packets on the display's queue.
+ * note that no squishing of move events in V11, since there
+ * is pointer motion hints....
+ */
+void _XEnq(
+ register Display *dpy,
+ register xEvent *event)
+{
+ register _XQEvent *qelt;
+ int type, extension;
+
+ if ((qelt = dpy->qfree)) {
+ /* If dpy->qfree is non-NULL do this, else malloc a new one. */
+ dpy->qfree = qelt->next;
+ }
+ else if ((qelt =
+ (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
+ /* Malloc call failed! */
+ ESET(ENOMEM);
+ _XIOError(dpy);
+ }
+ qelt->next = NULL;
+
+ type = event->u.u.type & 0177;
+ extension = ((xGenericEvent*)event)->extension;
+
+ qelt->event.type = type;
+ /* If an extension has registerd a generic_event_vec handler, then
+ * it can handle event cookies. Otherwise, proceed with the normal
+ * event handlers.
+ *
+ * If the generic_event_vec is called, qelt->event is a event cookie
+ * with the data pointer and the "free" pointer set. Data pointer is
+ * some memory allocated by the extension.
+ */
+ if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
+ XGenericEventCookie *cookie = &qelt->event.xcookie;
+ (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
+ cookie->cookie = ++dpy->next_cookie;
+
+ qelt->qserial_num = dpy->next_event_serial_num++;
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
+ qelt->qserial_num = dpy->next_event_serial_num++;
+ if (dpy->tail) dpy->tail->next = qelt;
+ else dpy->head = qelt;
+
+ dpy->tail = qelt;
+ dpy->qlen++;
+ } else {
+ /* ignored, or stashed away for many-to-one compression */
+ qelt->next = dpy->qfree;
+ dpy->qfree = qelt;
+ }
+}
+
+/*
+ * _XDeq - Remove event packet from the display's queue.
+ */
+void _XDeq(
+ register Display *dpy,
+ register _XQEvent *prev, /* element before qelt */
+ register _XQEvent *qelt) /* element to be unlinked */
+{
+ if (prev) {
+ if ((prev->next = qelt->next) == NULL)
+ dpy->tail = prev;
+ } else {
+ /* no prev, so removing first elt */
+ if ((dpy->head = qelt->next) == NULL)
+ dpy->tail = NULL;
+ }
+ qelt->qserial_num = 0;
+ qelt->next = dpy->qfree;
+ dpy->qfree = qelt;
+ dpy->qlen--;
+
+ if (_XIsEventCookie(dpy, &qelt->event)) {
+ XGenericEventCookie* cookie = &qelt->event.xcookie;
+ /* dpy->qfree is re-used, reset memory to avoid double free on
+ * _XFreeDisplayStructure */
+ cookie->data = NULL;
+ }
+}
+
+/*
+ * EventToWire in separate file in that often not needed.
+ */
+
+/*ARGSUSED*/
+Bool
+_XUnknownWireEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ (void) fprintf(stderr,
+ "Xlib: unhandled wire event! event number = %d, display = %x\n.",
+ event->u.u.type, dpy);
+#endif
+ return(False);
+}
+
+Bool
+_XUnknownWireEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *re, /* pointer to where event should be reformatted */
+ xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
+ ((xGenericEvent*)event)->extension, dpy);
+#endif
+ return(False);
+}
+
+Bool
+_XUnknownCopyEventCookie(
+ Display *dpy, /* pointer to display structure */
+ XGenericEventCookie *in, /* source */
+ XGenericEventCookie *out) /* destination */
+{
+#ifdef notdef
+ fprintf(stderr,
+ "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
+ in->extension, dpy);
+#endif
+ return(False);
+}
+
+/*ARGSUSED*/
+Status
+_XUnknownNativeEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+#ifdef notdef
+ (void) fprintf(stderr,
+ "Xlib: unhandled native event! event number = %d, display = %x\n.",
+ re->type, dpy);
+#endif
+ return(0);
+}
+/*
+ * reformat a wire event into an XEvent structure of the right type.
+ */
+Bool
+_XWireToEvent(
+ register Display *dpy, /* pointer to display structure */
+ register XEvent *re, /* pointer to where event should be reformatted */
+ register xEvent *event) /* wire protocol event */
+{
+
+ re->type = event->u.u.type & 0x7f;
+ ((XAnyEvent *)re)->serial = _XSetLastRequestRead(dpy,
+ (xGenericReply *)event);
+ ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
+ ((XAnyEvent *)re)->display = dpy;
+
+ /* Ignore the leading bit of the event type since it is set when a
+ client sends an event rather than the server. */
+
+ switch (event-> u.u.type & 0177) {
+ case KeyPress:
+ case KeyRelease:
+ {
+ register XKeyEvent *ev = (XKeyEvent*) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->keycode = event->u.u.detail;
+ }
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ register XButtonEvent *ev = (XButtonEvent *) re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->button = event->u.u.detail;
+ }
+ break;
+ case MotionNotify:
+ {
+ register XMotionEvent *ev = (XMotionEvent *)re;
+ ev->root = event->u.keyButtonPointer.root;
+ ev->window = event->u.keyButtonPointer.event;
+ ev->subwindow = event->u.keyButtonPointer.child;
+ ev->time = event->u.keyButtonPointer.time;
+ ev->x = cvtINT16toInt(event->u.keyButtonPointer.eventX);
+ ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY);
+ ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX);
+ ev->y_root = cvtINT16toInt(event->u.keyButtonPointer.rootY);
+ ev->state = event->u.keyButtonPointer.state;
+ ev->same_screen = event->u.keyButtonPointer.sameScreen;
+ ev->is_hint = event->u.u.detail;
+ }
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ {
+ register XCrossingEvent *ev = (XCrossingEvent *) re;
+ ev->root = event->u.enterLeave.root;
+ ev->window = event->u.enterLeave.event;
+ ev->subwindow = event->u.enterLeave.child;
+ ev->time = event->u.enterLeave.time;
+ ev->x = cvtINT16toInt(event->u.enterLeave.eventX);
+ ev->y = cvtINT16toInt(event->u.enterLeave.eventY);
+ ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX);
+ ev->y_root = cvtINT16toInt(event->u.enterLeave.rootY);
+ ev->state = event->u.enterLeave.state;
+ ev->mode = event->u.enterLeave.mode;
+ ev->same_screen = (event->u.enterLeave.flags &
+ ELFlagSameScreen) && True;
+ ev->focus = (event->u.enterLeave.flags &
+ ELFlagFocus) && True;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case FocusIn:
+ case FocusOut:
+ {
+ register XFocusChangeEvent *ev = (XFocusChangeEvent *) re;
+ ev->window = event->u.focus.window;
+ ev->mode = event->u.focus.mode;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case KeymapNotify:
+ {
+ register XKeymapEvent *ev = (XKeymapEvent *) re;
+ ev->window = None;
+ memcpy(&ev->key_vector[1],
+ (char *)((xKeymapEvent *) event)->map,
+ sizeof (((xKeymapEvent *) event)->map));
+ }
+ break;
+ case Expose:
+ {
+ register XExposeEvent *ev = (XExposeEvent *) re;
+ ev->window = event->u.expose.window;
+ ev->x = event->u.expose.x;
+ ev->y = event->u.expose.y;
+ ev->width = event->u.expose.width;
+ ev->height = event->u.expose.height;
+ ev->count = event->u.expose.count;
+ }
+ break;
+ case GraphicsExpose:
+ {
+ register XGraphicsExposeEvent *ev =
+ (XGraphicsExposeEvent *) re;
+ ev->drawable = event->u.graphicsExposure.drawable;
+ ev->x = event->u.graphicsExposure.x;
+ ev->y = event->u.graphicsExposure.y;
+ ev->width = event->u.graphicsExposure.width;
+ ev->height = event->u.graphicsExposure.height;
+ ev->count = event->u.graphicsExposure.count;
+ ev->major_code = event->u.graphicsExposure.majorEvent;
+ ev->minor_code = event->u.graphicsExposure.minorEvent;
+ }
+ break;
+ case NoExpose:
+ {
+ register XNoExposeEvent *ev = (XNoExposeEvent *) re;
+ ev->drawable = event->u.noExposure.drawable;
+ ev->major_code = event->u.noExposure.majorEvent;
+ ev->minor_code = event->u.noExposure.minorEvent;
+ }
+ break;
+ case VisibilityNotify:
+ {
+ register XVisibilityEvent *ev = (XVisibilityEvent *) re;
+ ev->window = event->u.visibility.window;
+ ev->state = event->u.visibility.state;
+ }
+ break;
+ case CreateNotify:
+ {
+ register XCreateWindowEvent *ev =
+ (XCreateWindowEvent *) re;
+ ev->window = event->u.createNotify.window;
+ ev->parent = event->u.createNotify.parent;
+ ev->x = cvtINT16toInt(event->u.createNotify.x);
+ ev->y = cvtINT16toInt(event->u.createNotify.y);
+ ev->width = event->u.createNotify.width;
+ ev->height = event->u.createNotify.height;
+ ev->border_width = event->u.createNotify.borderWidth;
+ ev->override_redirect = event->u.createNotify.override;
+ }
+ break;
+ case DestroyNotify:
+ {
+ register XDestroyWindowEvent *ev =
+ (XDestroyWindowEvent *) re;
+ ev->window = event->u.destroyNotify.window;
+ ev->event = event->u.destroyNotify.event;
+ }
+ break;
+ case UnmapNotify:
+ {
+ register XUnmapEvent *ev = (XUnmapEvent *) re;
+ ev->window = event->u.unmapNotify.window;
+ ev->event = event->u.unmapNotify.event;
+ ev->from_configure = event->u.unmapNotify.fromConfigure;
+ }
+ break;
+ case MapNotify:
+ {
+ register XMapEvent *ev = (XMapEvent *) re;
+ ev->window = event->u.mapNotify.window;
+ ev->event = event->u.mapNotify.event;
+ ev->override_redirect = event->u.mapNotify.override;
+ }
+ break;
+ case MapRequest:
+ {
+ register XMapRequestEvent *ev = (XMapRequestEvent *) re;
+ ev->window = event->u.mapRequest.window;
+ ev->parent = event->u.mapRequest.parent;
+ }
+ break;
+ case ReparentNotify:
+ {
+ register XReparentEvent *ev = (XReparentEvent *) re;
+ ev->event = event->u.reparent.event;
+ ev->window = event->u.reparent.window;
+ ev->parent = event->u.reparent.parent;
+ ev->x = cvtINT16toInt(event->u.reparent.x);
+ ev->y = cvtINT16toInt(event->u.reparent.y);
+ ev->override_redirect = event->u.reparent.override;
+ }
+ break;
+ case ConfigureNotify:
+ {
+ register XConfigureEvent *ev = (XConfigureEvent *) re;
+ ev->event = event->u.configureNotify.event;
+ ev->window = event->u.configureNotify.window;
+ ev->above = event->u.configureNotify.aboveSibling;
+ ev->x = cvtINT16toInt(event->u.configureNotify.x);
+ ev->y = cvtINT16toInt(event->u.configureNotify.y);
+ ev->width = event->u.configureNotify.width;
+ ev->height = event->u.configureNotify.height;
+ ev->border_width = event->u.configureNotify.borderWidth;
+ ev->override_redirect = event->u.configureNotify.override;
+ }
+ break;
+ case ConfigureRequest:
+ {
+ register XConfigureRequestEvent *ev =
+ (XConfigureRequestEvent *) re;
+ ev->window = event->u.configureRequest.window;
+ ev->parent = event->u.configureRequest.parent;
+ ev->above = event->u.configureRequest.sibling;
+ ev->x = cvtINT16toInt(event->u.configureRequest.x);
+ ev->y = cvtINT16toInt(event->u.configureRequest.y);
+ ev->width = event->u.configureRequest.width;
+ ev->height = event->u.configureRequest.height;
+ ev->border_width = event->u.configureRequest.borderWidth;
+ ev->value_mask = event->u.configureRequest.valueMask;
+ ev->detail = event->u.u.detail;
+ }
+ break;
+ case GravityNotify:
+ {
+ register XGravityEvent *ev = (XGravityEvent *) re;
+ ev->window = event->u.gravity.window;
+ ev->event = event->u.gravity.event;
+ ev->x = cvtINT16toInt(event->u.gravity.x);
+ ev->y = cvtINT16toInt(event->u.gravity.y);
+ }
+ break;
+ case ResizeRequest:
+ {
+ register XResizeRequestEvent *ev =
+ (XResizeRequestEvent *) re;
+ ev->window = event->u.resizeRequest.window;
+ ev->width = event->u.resizeRequest.width;
+ ev->height = event->u.resizeRequest.height;
+ }
+ break;
+ case CirculateNotify:
+ {
+ register XCirculateEvent *ev = (XCirculateEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->event = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case CirculateRequest:
+ {
+ register XCirculateRequestEvent *ev =
+ (XCirculateRequestEvent *) re;
+ ev->window = event->u.circulate.window;
+ ev->parent = event->u.circulate.event;
+ ev->place = event->u.circulate.place;
+ }
+ break;
+ case PropertyNotify:
+ {
+ register XPropertyEvent *ev = (XPropertyEvent *) re;
+ ev->window = event->u.property.window;
+ ev->atom = event->u.property.atom;
+ ev->time = event->u.property.time;
+ ev->state = event->u.property.state;
+ }
+ break;
+ case SelectionClear:
+ {
+ register XSelectionClearEvent *ev =
+ (XSelectionClearEvent *) re;
+ ev->window = event->u.selectionClear.window;
+ ev->selection = event->u.selectionClear.atom;
+ ev->time = event->u.selectionClear.time;
+ }
+ break;
+ case SelectionRequest:
+ {
+ register XSelectionRequestEvent *ev =
+ (XSelectionRequestEvent *) re;
+ ev->owner = event->u.selectionRequest.owner;
+ ev->requestor = event->u.selectionRequest.requestor;
+ ev->selection = event->u.selectionRequest.selection;
+ ev->target = event->u.selectionRequest.target;
+ ev->property = event->u.selectionRequest.property;
+ ev->time = event->u.selectionRequest.time;
+ }
+ break;
+ case SelectionNotify:
+ {
+ register XSelectionEvent *ev = (XSelectionEvent *) re;
+ ev->requestor = event->u.selectionNotify.requestor;
+ ev->selection = event->u.selectionNotify.selection;
+ ev->target = event->u.selectionNotify.target;
+ ev->property = event->u.selectionNotify.property;
+ ev->time = event->u.selectionNotify.time;
+ }
+ break;
+ case ColormapNotify:
+ {
+ register XColormapEvent *ev = (XColormapEvent *) re;
+ ev->window = event->u.colormap.window;
+ ev->colormap = event->u.colormap.colormap;
+ ev->new = event->u.colormap.new;
+ ev->state = event->u.colormap.state;
+ }
+ break;
+ case ClientMessage:
+ {
+ register int i;
+ register XClientMessageEvent *ev
+ = (XClientMessageEvent *) re;
+ ev->window = event->u.clientMessage.window;
+ ev->format = event->u.u.detail;
+ switch (ev->format) {
+ case 8:
+ ev->message_type = event->u.clientMessage.u.b.type;
+ for (i = 0; i < 20; i++)
+ ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
+ break;
+ case 16:
+ ev->message_type = event->u.clientMessage.u.s.type;
+ ev->data.s[0] = cvtINT16toShort(event->u.clientMessage.u.s.shorts0);
+ ev->data.s[1] = cvtINT16toShort(event->u.clientMessage.u.s.shorts1);
+ ev->data.s[2] = cvtINT16toShort(event->u.clientMessage.u.s.shorts2);
+ ev->data.s[3] = cvtINT16toShort(event->u.clientMessage.u.s.shorts3);
+ ev->data.s[4] = cvtINT16toShort(event->u.clientMessage.u.s.shorts4);
+ ev->data.s[5] = cvtINT16toShort(event->u.clientMessage.u.s.shorts5);
+ ev->data.s[6] = cvtINT16toShort(event->u.clientMessage.u.s.shorts6);
+ ev->data.s[7] = cvtINT16toShort(event->u.clientMessage.u.s.shorts7);
+ ev->data.s[8] = cvtINT16toShort(event->u.clientMessage.u.s.shorts8);
+ ev->data.s[9] = cvtINT16toShort(event->u.clientMessage.u.s.shorts9);
+ break;
+ case 32:
+ ev->message_type = event->u.clientMessage.u.l.type;
+ ev->data.l[0] = cvtINT32toLong(event->u.clientMessage.u.l.longs0);
+ ev->data.l[1] = cvtINT32toLong(event->u.clientMessage.u.l.longs1);
+ ev->data.l[2] = cvtINT32toLong(event->u.clientMessage.u.l.longs2);
+ ev->data.l[3] = cvtINT32toLong(event->u.clientMessage.u.l.longs3);
+ ev->data.l[4] = cvtINT32toLong(event->u.clientMessage.u.l.longs4);
+ break;
+ default: /* XXX should never occur */
+ break;
+ }
+ }
+ break;
+ case MappingNotify:
+ {
+ register XMappingEvent *ev = (XMappingEvent *)re;
+ ev->window = 0;
+ ev->first_keycode = event->u.mappingNotify.firstKeyCode;
+ ev->request = event->u.mappingNotify.request;
+ ev->count = event->u.mappingNotify.count;
+ }
+ break;
+ default:
+ return(_XUnknownWireEvent(dpy, re, event));
+ }
+ return(True);
+}
+
+
+/*
+ * _XDefaultIOError - Default fatal system error reporting routine. Called
+ * when an X internal system error is encountered.
+ */
+int _XDefaultIOError(
+ Display *dpy)
+{
+ if (ECHECK(EPIPE)) {
+ (void) fprintf (stderr,
+ "X connection to %s broken (explicit kill or server shutdown).\r\n",
+ DisplayString (dpy));
+ } else {
+ (void) fprintf (stderr,
+ "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n",
+#ifdef WIN32
+ WSAGetLastError(), strerror(WSAGetLastError()),
+#else
+ errno, strerror (errno),
+#endif
+ DisplayString (dpy));
+ (void) fprintf (stderr,
+ " after %lu requests (%lu known processed) with %d events remaining.\r\n",
+ NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
+ QLength(dpy));
+
+ }
+ exit(1);
+ return(0); /* dummy - function should never return */
+}
+
+
+static int _XPrintDefaultError(
+ Display *dpy,
+ XErrorEvent *event,
+ FILE *fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ const char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(fp, mesg, event->request_code);
+ if (event->request_code < 128) {
+ sprintf(number, "%d", event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != event->request_code);
+ ext = ext->next)
+ ;
+ if (ext) {
+ strncpy(buffer, ext->name, BUFSIZ);
+ buffer[BUFSIZ - 1] = '\0';
+ } else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(fp, " (%s)\n", buffer);
+ if (event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(fp, " (%s)", buffer);
+ }
+ fputs("\n", fp);
+ }
+ if (event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, event, fp);
+ }
+ } else if ((event->error_code == BadWindow) ||
+ (event->error_code == BadPixmap) ||
+ (event->error_code == BadCursor) ||
+ (event->error_code == BadFont) ||
+ (event->error_code == BadDrawable) ||
+ (event->error_code == BadColor) ||
+ (event->error_code == BadGC) ||
+ (event->error_code == BadIDChoice) ||
+ (event->error_code == BadValue) ||
+ (event->error_code == BadAtom)) {
+ if (event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", fp);
+ (void) fprintf(fp, mesg, dpy->request);
+ fputs("\n", fp);
+ if (event->error_code == BadImplementation) return 0;
+ return 1;
+}
+
+int _XDefaultError(
+ Display *dpy,
+ XErrorEvent *event)
+{
+ if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0;
+ exit(1);
+ /*NOTREACHED*/
+}
+
+/*ARGSUSED*/
+Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
+{
+ return True;
+}
+
+/*
+ * _XError - upcall internal or user protocol error handler
+ */
+int _XError (
+ Display *dpy,
+ register xError *rep)
+{
+ /*
+ * X_Error packet encountered! We need to unpack the error before
+ * giving it to the user.
+ */
+ XEvent event; /* make it a large event */
+ register _XAsyncHandler *async, *next;
+
+ event.xerror.serial = _XSetLastRequestRead(dpy, (xGenericReply *)rep);
+
+ for (async = dpy->async_handlers; async; async = next) {
+ next = async->next;
+ if ((*async->handler)(dpy, (xReply *)rep,
+ (char *)rep, SIZEOF(xError), async->data))
+ return 0;
+ }
+
+ event.xerror.display = dpy;
+ event.xerror.type = X_Error;
+ event.xerror.resourceid = rep->resourceID;
+ event.xerror.error_code = rep->errorCode;
+ event.xerror.request_code = rep->majorCode;
+ event.xerror.minor_code = rep->minorCode;
+ if (dpy->error_vec &&
+ !(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep))
+ return 0;
+ if (_XErrorFunction != NULL) {
+ int rtn_val;
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+ UnlockDisplay(dpy);
+#endif
+ rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
+#ifdef XTHREADS
+ LockDisplay(dpy);
+ if (dpy->lock)
+ (*dpy->lock->user_unlock_display)(dpy);
+#endif
+ return rtn_val;
+ } else {
+ return _XDefaultError(dpy, (XErrorEvent *)&event);
+ }
+}
+
+/*
+ * _XIOError - call user connection error handler and exit
+ */
+int
+_XIOError (
+ Display *dpy)
+{
+ dpy->flags |= XlibDisplayIOError;
+#ifdef WIN32
+ errno = WSAGetLastError();
+#endif
+
+ /* This assumes that the thread calling exit will call any atexit handlers.
+ * If this does not hold, then an alternate solution would involve
+ * registering an atexit handler to take over the lock, which would only
+ * assume that the same thread calls all the atexit handlers. */
+#ifdef XTHREADS
+ if (dpy->lock)
+ (*dpy->lock->user_lock_display)(dpy);
+#endif
+ UnlockDisplay(dpy);
+
+ if (_XIOErrorFunction != NULL)
+ (*_XIOErrorFunction)(dpy);
+ else
+ _XDefaultIOError(dpy);
+ exit (1);
+ return 0;
+}
+
+
+/*
+ * This routine can be used to (cheaply) get some memory within a single
+ * Xlib routine for scratch space. A single buffer is reused each time
+ * if possible. To be MT safe, you can only call this between a call to
+ * GetReq* and a call to Data* or _XSend*, or in a context when the thread
+ * is guaranteed to not unlock the display.
+ */
+char *_XAllocScratch(
+ register Display *dpy,
+ unsigned long nbytes)
+{
+ if (nbytes > dpy->scratch_length) {
+ if (dpy->scratch_buffer) Xfree (dpy->scratch_buffer);
+ if ((dpy->scratch_buffer = Xmalloc((unsigned) nbytes)))
+ dpy->scratch_length = nbytes;
+ else dpy->scratch_length = 0;
+ }
+ return (dpy->scratch_buffer);
+}
+
+/*
+ * Scratch space allocator you can call any time, multiple times, and be
+ * MT safe, but you must hand the buffer back with _XFreeTemp.
+ */
+char *_XAllocTemp(
+ register Display *dpy,
+ unsigned long nbytes)
+{
+ char *buf;
+
+ buf = _XAllocScratch(dpy, nbytes);
+ dpy->scratch_buffer = NULL;
+ dpy->scratch_length = 0;
+ return buf;
+}
+
+void _XFreeTemp(
+ register Display *dpy,
+ char *buf,
+ unsigned long nbytes)
+{
+ if (dpy->scratch_buffer)
+ Xfree(dpy->scratch_buffer);
+ dpy->scratch_buffer = buf;
+ dpy->scratch_length = nbytes;
+}
+
+/*
+ * Given a visual id, find the visual structure for this id on this display.
+ */
+Visual *_XVIDtoVisual(
+ Display *dpy,
+ VisualID id)
+{
+ register int i, j, k;
+ register Screen *sp;
+ register Depth *dp;
+ register Visual *vp;
+ for (i = 0; i < dpy->nscreens; i++) {
+ sp = &dpy->screens[i];
+ for (j = 0; j < sp->ndepths; j++) {
+ dp = &sp->depths[j];
+ /* if nvisuals == 0 then visuals will be NULL */
+ for (k = 0; k < dp->nvisuals; k++) {
+ vp = &dp->visuals[k];
+ if (vp->visualid == id) return (vp);
+ }
+ }
+ }
+ return (NULL);
+}
+
+int
+XFree (void *data)
+{
+ Xfree (data);
+ return 1;
+}
+
+#ifdef _XNEEDBCOPYFUNC
+void _Xbcopy(b1, b2, length)
+ register char *b1, *b2;
+ register length;
+{
+ if (b1 < b2) {
+ b2 += length;
+ b1 += length;
+ while (length--)
+ *--b2 = *--b1;
+ } else {
+ while (length--)
+ *b2++ = *b1++;
+ }
+}
+#endif
+
+#ifdef DataRoutineIsProcedure
+void Data(
+ Display *dpy,
+ char *data,
+ long len)
+{
+ if (dpy->bufptr + (len) <= dpy->bufmax) {
+ memcpy(dpy->bufptr, data, (int)len);
+ dpy->bufptr += ((len) + 3) & ~3;
+ } else {
+ _XSend(dpy, data, len);
+ }
+}
+#endif /* DataRoutineIsProcedure */
+
+
+#ifdef LONG64
+int
+_XData32(
+ Display *dpy,
+ register long *data,
+ unsigned len)
+{
+ register int *buf;
+ register long i;
+
+ while (len) {
+ buf = (int *)dpy->bufptr;
+ i = dpy->bufmax - (char *)buf;
+ if (!i) {
+ _XFlush(dpy);
+ continue;
+ }
+ if (len < i)
+ i = len;
+ dpy->bufptr = (char *)buf + i;
+ len -= i;
+ i >>= 2;
+ while (--i >= 0)
+ *buf++ = *data++;
+ }
+ return 0;
+}
+#endif /* LONG64 */
+
+#ifdef WORD64
+
+/*
+ * XXX This is a *really* stupid way of doing this. It should just use
+ * dpy->bufptr directly, taking into account where in the word it is.
+ */
+
+/*
+ * Data16 - Place 16 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static doData16(
+ register Display *dpy,
+ short *data,
+ unsigned len,
+ char *packbuffer)
+{
+ long *lp,*lpack;
+ long i, nwords,bits;
+ long mask16 = 0x000000000000ffff;
+
+ lp = (long *)data;
+ lpack = (long *)packbuffer;
+
+/* nwords is the number of 16 bit values to be packed,
+ * the low order 16 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 1;
+ bits = 48;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 48) *lpack = 0;
+ *lpack ^= (*lp & mask16) << bits;
+ bits -= 16 ;
+ lp++;
+ if(bits < 0){
+ lpack++;
+ bits = 48;
+ }
+ }
+ Data(dpy, packbuffer, len);
+}
+
+_XData16 (
+ Display *dpy,
+ short *data,
+ unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 1;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData16 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData16 (dpy, data, len, packbuffer);
+}
+
+/*
+ * Data32 - Place 32 bit data in the buffer.
+ *
+ * "dpy" is a pointer to a Display.
+ * "data" is a pointer to the data.
+ * "len" is the length in bytes of the data.
+ */
+
+static doData32(
+ register Display *dpy
+ long *data,
+ unsigned len,
+ char *packbuffer)
+{
+ long *lp,*lpack;
+ long i,bits,nwords;
+ long mask32 = 0x00000000ffffffff;
+
+ lpack = (long *) packbuffer;
+ lp = data;
+
+/* nwords is the number of 32 bit values to be packed
+ * the low order 32 bits of each word will be packed
+ * into 64 bit words
+ */
+ nwords = len >> 2;
+ bits = 32;
+
+ for(i=0;i<nwords;i++){
+ if (bits == 32) *lpack = 0;
+ *lpack ^= (*lp & mask32) << bits;
+ bits = bits ^32;
+ lp++;
+ if(bits)
+ lpack++;
+ }
+ Data(dpy, packbuffer, len);
+}
+
+void _XData32(
+ Display *dpy,
+ long *data,
+ unsigned len)
+{
+ char packbuffer[PACKBUFFERSIZE];
+ unsigned nunits = PACKBUFFERSIZE >> 2;
+
+ for (; len > PACKBUFFERSIZE; len -= PACKBUFFERSIZE, data += nunits) {
+ doData32 (dpy, data, PACKBUFFERSIZE, packbuffer);
+ }
+ if (len) doData32 (dpy, data, len, packbuffer);
+}
+
+#endif /* WORD64 */
+
+
+/* Make sure this produces the same string as DefineLocal/DefineSelf in xdm.
+ * Otherwise, Xau will not be able to find your cookies in the Xauthority file.
+ *
+ * Note: POSIX says that the ``nodename'' member of utsname does _not_ have
+ * to have sufficient information for interfacing to the network,
+ * and so, you may be better off using gethostname (if it exists).
+ */
+
+#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(SVR4)
+#define NEED_UTSNAME
+#include <sys/utsname.h>
+#else
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#endif
+
+/*
+ * _XGetHostname - similar to gethostname but allows special processing.
+ */
+int _XGetHostname (
+ char *buf,
+ int maxlen)
+{
+ int len;
+
+#ifdef NEED_UTSNAME
+ struct utsname name;
+
+ if (maxlen <= 0 || buf == NULL)
+ return 0;
+
+ uname (&name);
+ len = strlen (name.nodename);
+ if (len >= maxlen) len = maxlen - 1;
+ strncpy (buf, name.nodename, len);
+ buf[len] = '\0';
+#else
+ if (maxlen <= 0 || buf == NULL)
+ return 0;
+
+ buf[0] = '\0';
+ (void) gethostname (buf, maxlen);
+ buf [maxlen - 1] = '\0';
+ len = strlen(buf);
+#endif /* NEED_UTSNAME */
+ return len;
+}
+
+
+/*
+ * _XScreenOfWindow - get the Screen of a given window
+ */
+
+Screen *_XScreenOfWindow(Display *dpy, Window w)
+{
+ register int i;
+ Window root;
+ int x, y; /* dummy variables */
+ unsigned int width, height, bw, depth; /* dummy variables */
+
+ if (XGetGeometry (dpy, w, &root, &x, &y, &width, &height,
+ &bw, &depth) == False) {
+ return NULL;
+ }
+ for (i = 0; i < ScreenCount (dpy); i++) { /* find root from list */
+ if (root == RootWindow (dpy, i)) {
+ return ScreenOfDisplay (dpy, i);
+ }
+ }
+ return NULL;
+}
+
+
+#if defined(WIN32)
+
+/*
+ * These functions are intended to be used internally to Xlib only.
+ * These functions will always prefix the path with a DOS drive in the
+ * form "<drive-letter>:". As such, these functions are only suitable
+ * for use by Xlib function that supply a root-based path to some
+ * particular file, e.g. <ProjectRoot>/lib/X11/locale/locale.dir will
+ * be converted to "C:/usr/X11R6.3/lib/X11/locale/locale.dir".
+ */
+
+static int access_file (path, pathbuf, len_pathbuf, pathret)
+ char* path;
+ char* pathbuf;
+ int len_pathbuf;
+ char** pathret;
+{
+ if (access (path, F_OK) == 0) {
+ if (strlen (path) < len_pathbuf)
+ *pathret = pathbuf;
+ else
+ *pathret = Xmalloc (strlen (path) + 1);
+ if (*pathret) {
+ strcpy (*pathret, path);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int AccessFile (path, pathbuf, len_pathbuf, pathret)
+ char* path;
+ char* pathbuf;
+ int len_pathbuf;
+ char** pathret;
+{
+ unsigned long drives;
+ int i, len;
+ char* drive;
+ char buf[MAX_PATH];
+ char* bufp;
+
+ /* just try the "raw" name first and see if it works */
+ if (access_file (path, pathbuf, len_pathbuf, pathret))
+ return 1;
+
+ /* try the places set in the environment */
+ drive = getenv ("_XBASEDRIVE");
+#ifdef __UNIXOS2__
+ if (!drive)
+ drive = getenv ("X11ROOT");
+#endif
+ if (!drive)
+ drive = "C:";
+ len = strlen (drive) + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+
+#ifndef __UNIXOS2__
+ /* one last place to look */
+ drive = getenv ("HOMEDRIVE");
+ if (drive) {
+ len = strlen (drive) + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ strcpy (bufp, drive);
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+ }
+
+ /* tried everywhere else, go fishing */
+#define C_DRIVE ('C' - 'A')
+#define Z_DRIVE ('Z' - 'A')
+ /* does OS/2 (with or with gcc-emx) have getdrives? */
+ drives = _getdrives ();
+ for (i = C_DRIVE; i <= Z_DRIVE; i++) { /* don't check on A: or B: */
+ if ((1 << i) & drives) {
+ len = 2 + strlen (path);
+ if (len < MAX_PATH) bufp = buf;
+ else bufp = Xmalloc (len + 1);
+ *bufp = 'A' + i;
+ *(bufp + 1) = ':';
+ *(bufp + 2) = '\0';
+ strcat (bufp, path);
+ if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
+ if (bufp != buf) Xfree (bufp);
+ return 1;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+int _XOpenFile(path, flags)
+ _Xconst char* path;
+ int flags;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = open (bufp, flags);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+int _XOpenFileMode(path, flags, mode)
+ _Xconst char* path;
+ int flags;
+ mode_t mode;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = open (bufp, flags, mode);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+void* _XFopenFile(path, mode)
+ _Xconst char* path;
+ _Xconst char* mode;
+{
+ char buf[MAX_PATH];
+ char* bufp = NULL;
+ void* ret = NULL;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ if (AccessFile (path, buf, MAX_PATH, &bufp))
+ ret = fopen (bufp, mode);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+int _XAccessFile(path)
+ _Xconst char* path;
+{
+ char buf[MAX_PATH];
+ char* bufp;
+ int ret = -1;
+ UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
+
+ ret = AccessFile (path, buf, MAX_PATH, &bufp);
+
+ (void) SetErrorMode (olderror);
+
+ if (bufp != buf) Xfree (bufp);
+
+ return ret;
+}
+
+#endif
+
+#ifdef WIN32
+#undef _Xdebug
+int _Xdebug = 0;
+int *_Xdebug_p = &_Xdebug;
+void (**_XCreateMutex_fn_p)(LockInfoPtr) = &_XCreateMutex_fn;
+void (**_XFreeMutex_fn_p)(LockInfoPtr) = &_XFreeMutex_fn;
+void (**_XLockMutex_fn_p)(LockInfoPtr
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = &_XLockMutex_fn;
+void (**_XUnlockMutex_fn_p)(LockInfoPtr
+#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+ , char * /* file */
+ , int /* line */
+#endif
+ ) = &_XUnlockMutex_fn;
+LockInfoPtr *_Xglobal_lock_p = &_Xglobal_lock;
+#endif
diff --git a/libX11/src/Xrm.c b/libX11/src/Xrm.c index 53467aedc..7dff61e68 100644 --- a/libX11/src/Xrm.c +++ b/libX11/src/Xrm.c @@ -1,2660 +1,2660 @@ - -/*********************************************************** -Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL 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. - -******************************************************************/ -/* - -Copyright 1987, 1988, 1990, 1998 The Open Group - -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. - -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 OPEN GROUP 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 name of The Open Group 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 Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <ctype.h> -#include "Xlibint.h" -#include <X11/Xresource.h> -#include "Xlcint.h" -#ifdef XTHREADS -#include "locking.h" -#endif -#include <X11/Xos.h> -#include <sys/stat.h> -#include "Xresinternal.h" -#include "Xresource.h" - -/* - -These Xrm routines allow very fast lookup of resources in the resource -database. Several usage patterns are exploited: - -(1) Widgets get a lot of resources at one time. Rather than look up each from -scratch, we can precompute the prioritized list of database levels once, then -search for each resource starting at the beginning of the list. - -(2) Many database levels don't contain any leaf resource nodes. There is no -point in looking for resources on a level that doesn't contain any. This -information is kept on a per-level basis. - -(3) Sometimes the widget instance tree is structured such that you get the same -class name repeated on the fully qualified widget name. This can result in the -same database level occuring multiple times on the search list. The code below -only checks to see if you get two identical search lists in a row, rather than -look back through all database levels, but in practice this removes all -duplicates I've ever observed. - -Joel McCormack - -*/ - -/* - -The Xrm representation has been completely redesigned to substantially reduce -memory and hopefully improve performance. - -The database is structured into two kinds of tables: LTables that contain -only values, and NTables that contain only other tables. - -Some invariants: - -The next pointer of the top-level node table points to the top-level leaf -table, if any. - -Within an LTable, for a given name, the tight value always precedes the -loose value, and if both are present the loose value is always right after -the tight value. - -Within an NTable, all of the entries for a given name are contiguous, -in the order tight NTable, loose NTable, tight LTable, loose LTable. - -Bob Scheifler - -*/ - -static XrmQuark XrmQString, XrmQANY; - -typedef Bool (*DBEnumProc)( - XrmDatabase* /* db */, - XrmBindingList /* bindings */, - XrmQuarkList /* quarks */, - XrmRepresentation* /* type */, - XrmValue* /* value */, - XPointer /* closure */ -); - -typedef struct _VEntry { - struct _VEntry *next; /* next in chain */ - XrmQuark name; /* name of this entry */ - unsigned int tight:1; /* 1 if it is a tight binding */ - unsigned int string:1; /* 1 if type is String */ - unsigned int size:30; /* size of value */ -} VEntryRec, *VEntry; - - -typedef struct _DEntry { - VEntryRec entry; /* entry */ - XrmRepresentation type; /* representation type */ -} DEntryRec, *DEntry; - -/* the value is right after the structure */ -#define StringValue(ve) (XPointer)((ve) + 1) -#define RepType(ve) ((DEntry)(ve))->type -/* the value is right after the structure */ -#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1) -#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve)) - -typedef struct _NTable { - struct _NTable *next; /* next in chain */ - XrmQuark name; /* name of this entry */ - unsigned int tight:1; /* 1 if it is a tight binding */ - unsigned int leaf:1; /* 1 if children are values */ - unsigned int hasloose:1; /* 1 if has loose children */ - unsigned int hasany:1; /* 1 if has ANY entry */ - unsigned int pad:4; /* unused */ - unsigned int mask:8; /* hash size - 1 */ - unsigned int entries:16; /* number of children */ -} NTableRec, *NTable; - -/* the buckets are right after the structure */ -#define NodeBuckets(ne) ((NTable *)((ne) + 1)) -#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask] - -/* leaf tables have an extra level of indirection for the buckets, - * so that resizing can be done without invalidating a search list. - * This is completely ugly, and wastes some memory, but the Xlib - * spec doesn't really specify whether invalidation is OK, and the - * old implementation did not invalidate. - */ -typedef struct _LTable { - NTableRec table; - VEntry *buckets; -} LTableRec, *LTable; - -#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask] - -/* An XrmDatabase just holds a pointer to the first top-level table. - * The type name is no longer descriptive, but better to not change - * the Xresource.h header file. This type also gets used to define - * XrmSearchList, which is a complete crock, but we'll just leave it - * and caste types as required. - */ -typedef struct _XrmHashBucketRec { - NTable table; - XPointer mbstate; - XrmMethods methods; -#ifdef XTHREADS - LockInfoRec linfo; -#endif -} XrmHashBucketRec; - -/* closure used in get/put resource */ -typedef struct _VClosure { - XrmRepresentation *type; /* type of value */ - XrmValuePtr value; /* value itself */ -} VClosureRec, *VClosure; - -/* closure used in get search list */ -typedef struct _SClosure { - LTable *list; /* search list */ - int idx; /* index of last filled element */ - int limit; /* maximum index */ -} SClosureRec, *SClosure; - -/* placed in XrmSearchList to indicate next table is loose only */ -#define LOOSESEARCH ((LTable)1) - -/* closure used in enumerate database */ -typedef struct _EClosure { - XrmDatabase db; /* the database */ - DBEnumProc proc; /* the user proc */ - XPointer closure; /* the user closure */ - XrmBindingList bindings; /* binding list */ - XrmQuarkList quarks; /* quark list */ - int mode; /* XrmEnum<kind> */ -} EClosureRec, *EClosure; - -/* types for typecasting ETable based functions to NTable based functions */ -typedef Bool (*getNTableSProcp)( - NTable table, - XrmNameList names, - XrmClassList classes, - SClosure closure); -typedef Bool (*getNTableVProcp)( - NTable table, - XrmNameList names, - XrmClassList classes, - VClosure closure); -typedef Bool (*getNTableEProcp)( - NTable table, - XrmNameList names, - XrmClassList classes, - register int level, - EClosure closure); - -/* predicate to determine when to resize a hash table */ -#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2)) - -#define GROW(prev) \ - if (GrowthPred((*prev)->entries, (*prev)->mask)) \ - GrowTable(prev) - -/* pick a reasonable value for maximum depth of resource database */ -#define MAXDBDEPTH 100 - -/* macro used in get/search functions */ - -/* find an entry named ename, with leafness given by leaf */ -#define NFIND(ename) \ - q = ename; \ - entry = NodeHash(table, q); \ - while (entry && entry->name != q) \ - entry = entry->next; \ - if (leaf && entry && !entry->leaf) { \ - entry = entry->next; \ - if (entry && !entry->leaf) \ - entry = entry->next; \ - if (entry && entry->name != q) \ - entry = (NTable)NULL; \ - } - -/* resourceQuarks keeps track of what quarks have been associated with values - * in all LTables. If a quark has never been used in an LTable, we don't need - * to bother looking for it. - */ - -static unsigned char *resourceQuarks = (unsigned char *)NULL; -static XrmQuark maxResourceQuark = -1; - -/* determines if a quark has been used for a value in any database */ -#define IsResourceQuark(q) ((q) > 0 && (q) <= maxResourceQuark && \ - resourceQuarks[(q) >> 3] & (1 << ((q) & 7))) - -typedef unsigned char XrmBits; - -#define BSLASH ((XrmBits) (1 << 5)) -#define NORMAL ((XrmBits) (1 << 4)) -#define EOQ ((XrmBits) (1 << 3)) -#define SEP ((XrmBits) (1 << 2)) -#define ENDOF ((XrmBits) (1 << 1)) -#define SPACE (NORMAL|EOQ|SEP|(XrmBits)0) -#define RSEP (NORMAL|EOQ|SEP|(XrmBits)1) -#define EOS (EOQ|SEP|ENDOF|(XrmBits)0) -#define EOL (EOQ|SEP|ENDOF|(XrmBits)1) -#define BINDING (NORMAL|EOQ) -#define ODIGIT (NORMAL|(XrmBits)1) - -#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))] -#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)] - -#define is_space(bits) ((bits) == SPACE) -#define is_EOQ(bits) ((bits) & EOQ) -#define is_EOF(bits) ((bits) == EOS) -#define is_EOL(bits) ((bits) & ENDOF) -#define is_binding(bits) ((bits) == BINDING) -#define is_odigit(bits) ((bits) == ODIGIT) -#define is_separator(bits) ((bits) & SEP) -#define is_nonpcs(bits) (!(bits)) -#define is_normal(bits) ((bits) & NORMAL) -#define is_simple(bits) ((bits) & (NORMAL|BSLASH)) -#define is_special(bits) ((bits) & (ENDOF|BSLASH)) - -/* parsing types */ -static XrmBits const xrmtypes[256] = { - EOS,0,0,0,0,0,0,0, - 0,SPACE,EOL,0,0, -#if defined(WIN32) || defined(__UNIXOS2__) - EOL, /* treat CR the same as LF, just in case */ -#else - 0, -#endif - 0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL, - ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT, - NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL, - NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0 - /* The rest will be automatically initialized to zero. */ -}; - -void XrmInitialize(void) -{ - XrmQString = XrmPermStringToQuark("String"); - XrmQANY = XrmPermStringToQuark("?"); -} - -XrmDatabase XrmGetDatabase( - Display *display) -{ - XrmDatabase retval; - LockDisplay(display); - retval = display->db; - UnlockDisplay(display); - return retval; -} - -void XrmSetDatabase( - Display *display, - XrmDatabase database) -{ - LockDisplay(display); - /* destroy database if set up imlicitely by XGetDefault() */ - if (display->db && (display->flags & XlibDisplayDfltRMDB)) { - XrmDestroyDatabase(display->db); - display->flags &= ~XlibDisplayDfltRMDB; - } - display->db = database; - UnlockDisplay(display); -} - -void -XrmStringToQuarkList( - register _Xconst char *name, - register XrmQuarkList quarks) /* RETURN */ -{ - register XrmBits bits; - register Signature sig = 0; - register char ch, *tname; - register int i = 0; - - if ((tname = (char *)name)) { - tname--; - while (!is_EOF(bits = next_char(ch, tname))) { - if (is_binding (bits)) { - if (i) { - /* Found a complete name */ - *quarks++ = _XrmInternalStringToQuark(name,tname - name, - sig, False); - i = 0; - sig = 0; - } - name = tname+1; - } - else { - sig = (sig << 1) + ch; /* Compute the signature. */ - i++; - } - } - *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False); - } - *quarks = NULLQUARK; -} - -void -XrmStringToBindingQuarkList( - register _Xconst char *name, - register XrmBindingList bindings, /* RETURN */ - register XrmQuarkList quarks) /* RETURN */ -{ - register XrmBits bits; - register Signature sig = 0; - register char ch, *tname; - register XrmBinding binding; - register int i = 0; - - if ((tname = (char *)name)) { - tname--; - binding = XrmBindTightly; - while (!is_EOF(bits = next_char(ch, tname))) { - if (is_binding (bits)) { - if (i) { - /* Found a complete name */ - *bindings++ = binding; - *quarks++ = _XrmInternalStringToQuark(name, tname - name, - sig, False); - - i = 0; - sig = 0; - binding = XrmBindTightly; - } - name = tname+1; - - if (ch == '*') - binding = XrmBindLoosely; - } - else { - sig = (sig << 1) + ch; /* Compute the signature. */ - i++; - } - } - *bindings = binding; - *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False); - } - *quarks = NULLQUARK; -} - -#ifdef DEBUG - -static void PrintQuarkList( - XrmQuarkList quarks, - FILE *stream) -{ - Bool firstNameSeen; - - for (firstNameSeen = False; *quarks; quarks++) { - if (firstNameSeen) { - (void) fprintf(stream, "."); - } - firstNameSeen = True; - (void) fputs(XrmQuarkToString(*quarks), stream); - } -} /* PrintQuarkList */ - -#endif /* DEBUG */ - - -/* - * Fallback methods for Xrm parsing. - * Simulate a C locale. No state needed here. - */ - -static void -c_mbnoop( - XPointer state) -{ -} - -static char -c_mbchar( - XPointer state, - const char *str, - int *lenp) -{ - *lenp = 1; - return *str; -} - -static const char * -c_lcname( - XPointer state) -{ - return "C"; -} - -static const XrmMethodsRec mb_methods = { - c_mbnoop, /* mbinit */ - c_mbchar, /* mbchar */ - c_mbnoop, /* mbfinish */ - c_lcname, /* lcname */ - c_mbnoop /* destroy */ -}; - - -static XrmDatabase NewDatabase(void) -{ - register XrmDatabase db; - - db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec)); - if (db) { - _XCreateMutex(&db->linfo); - db->table = (NTable)NULL; - db->mbstate = (XPointer)NULL; - db->methods = _XrmInitParseInfo(&db->mbstate); - if (!db->methods) - db->methods = &mb_methods; - } - return db; -} - -/* move all values from ftable to ttable, and free ftable's buckets. - * ttable is quaranteed empty to start with. - */ -static void MoveValues( - LTable ftable, - register LTable ttable) -{ - register VEntry fentry, nfentry; - register VEntry *prev; - register VEntry *bucket; - register VEntry tentry; - register int i; - - for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) { - for (fentry = *bucket++; fentry; fentry = nfentry) { - prev = &LeafHash(ttable, fentry->name); - tentry = *prev; - *prev = fentry; - /* chain on all with same name, to preserve invariant order */ - while ((nfentry = fentry->next) && nfentry->name == fentry->name) - fentry = nfentry; - fentry->next = tentry; - } - } - Xfree((char *)ftable->buckets); -} - -/* move all tables from ftable to ttable, and free ftable. - * ttable is quaranteed empty to start with. - */ -static void MoveTables( - NTable ftable, - register NTable ttable) -{ - register NTable fentry, nfentry; - register NTable *prev; - register NTable *bucket; - register NTable tentry; - register int i; - - for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) { - for (fentry = *bucket++; fentry; fentry = nfentry) { - prev = &NodeHash(ttable, fentry->name); - tentry = *prev; - *prev = fentry; - /* chain on all with same name, to preserve invariant order */ - while ((nfentry = fentry->next) && nfentry->name == fentry->name) - fentry = nfentry; - fentry->next = tentry; - } - } - Xfree((char *)ftable); -} - -/* grow the table, based on current number of entries */ -static void GrowTable( - NTable *prev) -{ - register NTable table; - register int i; - - table = *prev; - i = table->mask; - if (i == 255) /* biggest it gets */ - return; - while (i < 255 && GrowthPred(table->entries, i)) - i = (i << 1) + 1; - i++; /* i is now the new size */ - if (table->leaf) { - register LTable ltable; - LTableRec otable; - - ltable = (LTable)table; - /* cons up a copy to make MoveValues look symmetric */ - otable = *ltable; - ltable->buckets = Xcalloc(i, sizeof(VEntry)); - if (!ltable->buckets) { - ltable->buckets = otable.buckets; - return; - } - ltable->table.mask = i - 1; - MoveValues(&otable, ltable); - } else { - register NTable ntable; - - ntable = Xcalloc(1, sizeof(NTableRec) + (i * sizeof(NTable))); - if (!ntable) - return; - *ntable = *table; - ntable->mask = i - 1; - *prev = ntable; - MoveTables(table, ntable); - } -} - -/* merge values from ftable into *pprev, destroy ftable in the process */ -static void MergeValues( - LTable ftable, - NTable *pprev, - Bool override) -{ - register VEntry fentry, tentry; - register VEntry *prev; - register LTable ttable; - VEntry *bucket; - int i; - register XrmQuark q; - - ttable = (LTable)*pprev; - if (ftable->table.hasloose) - ttable->table.hasloose = 1; - for (i = ftable->table.mask, bucket = ftable->buckets; - i >= 0; - i--, bucket++) { - for (fentry = *bucket; fentry; ) { - q = fentry->name; - prev = &LeafHash(ttable, q); - tentry = *prev; - while (tentry && tentry->name != q) - tentry = *(prev = &tentry->next); - /* note: test intentionally uses fentry->name instead of q */ - /* permits serendipitous inserts */ - while (tentry && tentry->name == fentry->name) { - /* if tentry is earlier, skip it */ - if (!fentry->tight && tentry->tight) { - tentry = *(prev = &tentry->next); - continue; - } - if (fentry->tight != tentry->tight) { - /* no match, chain in fentry */ - *prev = fentry; - prev = &fentry->next; - fentry = *prev; - *prev = tentry; - ttable->table.entries++; - } else if (override) { - /* match, chain in fentry, splice out and free tentry */ - *prev = fentry; - prev = &fentry->next; - fentry = *prev; - *prev = tentry->next; - /* free the overridden entry */ - Xfree((char *)tentry); - /* get next tentry */ - tentry = *prev; - } else { - /* match, discard fentry */ - prev = &tentry->next; - tentry = fentry; /* use as a temp var */ - fentry = fentry->next; - /* free the overpowered entry */ - Xfree((char *)tentry); - /* get next tentry */ - tentry = *prev; - } - if (!fentry) - break; - } - /* at this point, tentry cannot match any fentry named q */ - /* chain in all bindings together, preserve invariant order */ - while (fentry && fentry->name == q) { - *prev = fentry; - prev = &fentry->next; - fentry = *prev; - *prev = tentry; - ttable->table.entries++; - } - } - } - Xfree((char *)ftable->buckets); - Xfree((char *)ftable); - /* resize if necessary, now that we're all done */ - GROW(pprev); -} - -/* merge tables from ftable into *pprev, destroy ftable in the process */ -static void MergeTables( - NTable ftable, - NTable *pprev, - Bool override) -{ - register NTable fentry, tentry; - NTable nfentry; - register NTable *prev; - register NTable ttable; - NTable *bucket; - int i; - register XrmQuark q; - - ttable = *pprev; - if (ftable->hasloose) - ttable->hasloose = 1; - if (ftable->hasany) - ttable->hasany = 1; - for (i = ftable->mask, bucket = NodeBuckets(ftable); - i >= 0; - i--, bucket++) { - for (fentry = *bucket; fentry; ) { - q = fentry->name; - prev = &NodeHash(ttable, q); - tentry = *prev; - while (tentry && tentry->name != q) - tentry = *(prev = &tentry->next); - /* note: test intentionally uses fentry->name instead of q */ - /* permits serendipitous inserts */ - while (tentry && tentry->name == fentry->name) { - /* if tentry is earlier, skip it */ - if ((fentry->leaf && !tentry->leaf) || - (!fentry->tight && tentry->tight && - (fentry->leaf || !tentry->leaf))) { - tentry = *(prev = &tentry->next); - continue; - } - nfentry = fentry->next; - if (fentry->leaf != tentry->leaf || - fentry->tight != tentry->tight) { - /* no match, just chain in */ - *prev = fentry; - *(prev = &fentry->next) = tentry; - ttable->entries++; - } else { - if (fentry->leaf) - MergeValues((LTable)fentry, prev, override); - else - MergeTables(fentry, prev, override); - /* bump to next tentry */ - tentry = *(prev = &(*prev)->next); - } - /* bump to next fentry */ - fentry = nfentry; - if (!fentry) - break; - } - /* at this point, tentry cannot match any fentry named q */ - /* chain in all bindings together, preserve invariant order */ - while (fentry && fentry->name == q) { - *prev = fentry; - prev = &fentry->next; - fentry = *prev; - *prev = tentry; - ttable->entries++; - } - } - } - Xfree((char *)ftable); - /* resize if necessary, now that we're all done */ - GROW(pprev); -} - -void XrmCombineDatabase( - XrmDatabase from, XrmDatabase *into, - Bool override) -{ - register NTable *prev; - register NTable ftable, ttable, nftable; - - if (!*into) { - *into = from; - } else if (from) { - _XLockMutex(&from->linfo); - _XLockMutex(&(*into)->linfo); - if ((ftable = from->table)) { - prev = &(*into)->table; - ttable = *prev; - if (!ftable->leaf) { - nftable = ftable->next; - if (ttable && !ttable->leaf) { - /* both have node tables, merge them */ - MergeTables(ftable, prev, override); - /* bump to into's leaf table, if any */ - ttable = *(prev = &(*prev)->next); - } else { - /* into has no node table, link from's in */ - *prev = ftable; - *(prev = &ftable->next) = ttable; - } - /* bump to from's leaf table, if any */ - ftable = nftable; - } else { - /* bump to into's leaf table, if any */ - if (ttable && !ttable->leaf) - ttable = *(prev = &ttable->next); - } - if (ftable) { - /* if into has a leaf, merge, else insert */ - if (ttable) - MergeValues((LTable)ftable, prev, override); - else - *prev = ftable; - } - } - (from->methods->destroy)(from->mbstate); - _XUnlockMutex(&from->linfo); - _XFreeMutex(&from->linfo); - Xfree((char *)from); - _XUnlockMutex(&(*into)->linfo); - } -} - -void XrmMergeDatabases( - XrmDatabase from, XrmDatabase *into) -{ - XrmCombineDatabase(from, into, True); -} - -/* store a value in the database, overriding any existing entry */ -static void PutEntry( - XrmDatabase db, - XrmBindingList bindings, - XrmQuarkList quarks, - XrmRepresentation type, - XrmValuePtr value) -{ - register NTable *pprev, *prev; - register NTable table; - register XrmQuark q; - register VEntry *vprev; - register VEntry entry; - NTable *nprev, *firstpprev; - -#define NEWTABLE(q,i) \ - table = (NTable)Xmalloc(sizeof(LTableRec)); \ - if (!table) \ - return; \ - table->name = q; \ - table->hasloose = 0; \ - table->hasany = 0; \ - table->mask = 0; \ - table->entries = 0; \ - if (quarks[i]) { \ - table->leaf = 0; \ - nprev = NodeBuckets(table); \ - } else { \ - table->leaf = 1; \ - if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) {\ - Xfree(table); \ - return; \ - } \ - ((LTable)table)->buckets = (VEntry *)nprev; \ - } \ - *nprev = (NTable)NULL; \ - table->next = *prev; \ - *prev = table - - if (!db || !*quarks) - return; - table = *(prev = &db->table); - /* if already at leaf, bump to the leaf table */ - if (!quarks[1] && table && !table->leaf) - table = *(prev = &table->next); - pprev = prev; - if (!table || (quarks[1] && table->leaf)) { - /* no top-level node table, create one and chain it in */ - NEWTABLE(NULLQUARK,1); - table->tight = 1; /* arbitrary */ - prev = nprev; - } else { - /* search along until we need a value */ - while (quarks[1]) { - q = *quarks; - table = *(prev = &NodeHash(table, q)); - while (table && table->name != q) - table = *(prev = &table->next); - if (!table) - break; /* not found */ - if (quarks[2]) { - if (table->leaf) - break; /* not found */ - } else { - if (!table->leaf) { - /* bump to leaf table, if any */ - table = *(prev = &table->next); - if (!table || table->name != q) - break; /* not found */ - if (!table->leaf) { - /* bump to leaf table, if any */ - table = *(prev = &table->next); - if (!table || table->name != q) - break; /* not found */ - } - } - } - if (*bindings == XrmBindTightly) { - if (!table->tight) - break; /* not found */ - } else { - if (table->tight) { - /* bump to loose table, if any */ - table = *(prev = &table->next); - if (!table || table->name != q || - !quarks[2] != table->leaf) - break; /* not found */ - } - } - /* found that one, bump to next quark */ - pprev = prev; - quarks++; - bindings++; - } - if (!quarks[1]) { - /* found all the way to a leaf */ - q = *quarks; - entry = *(vprev = &LeafHash((LTable)table, q)); - while (entry && entry->name != q) - entry = *(vprev = &entry->next); - /* if want loose and have tight, bump to next entry */ - if (entry && *bindings == XrmBindLoosely && entry->tight) - entry = *(vprev = &entry->next); - if (entry && entry->name == q && - (*bindings == XrmBindTightly) == entry->tight) { - /* match, need to override */ - if ((type == XrmQString) == entry->string && - entry->size == value->size) { - /* update type if not String, can be different */ - if (!entry->string) - RepType(entry) = type; - /* identical size, just overwrite value */ - memcpy(RawValue(entry), (char *)value->addr, value->size); - return; - } - /* splice out and free old entry */ - *vprev = entry->next; - Xfree((char *)entry); - (*pprev)->entries--; - } - /* this is where to insert */ - prev = (NTable *)vprev; - } - } - /* keep the top table, because we may have to grow it */ - firstpprev = pprev; - /* iterate until we get to the leaf */ - while (quarks[1]) { - /* build a new table and chain it in */ - NEWTABLE(*quarks,2); - if (*quarks++ == XrmQANY) - (*pprev)->hasany = 1; - if (*bindings++ == XrmBindTightly) { - table->tight = 1; - } else { - table->tight = 0; - (*pprev)->hasloose = 1; - } - (*pprev)->entries++; - pprev = prev; - prev = nprev; - } - /* now allocate the value entry */ - entry = (VEntry)Xmalloc(((type == XrmQString) ? - sizeof(VEntryRec) : sizeof(DEntryRec)) + - value->size); - if (!entry) - return; - entry->name = q = *quarks; - if (*bindings == XrmBindTightly) { - entry->tight = 1; - } else { - entry->tight = 0; - (*pprev)->hasloose = 1; - } - /* chain it in, with a bit of type cast ugliness */ - entry->next = *((VEntry *)prev); - *((VEntry *)prev) = entry; - entry->size = value->size; - if (type == XrmQString) { - entry->string = 1; - } else { - entry->string = 0; - RepType(entry) = type; - } - /* save a copy of the value */ - memcpy(RawValue(entry), (char *)value->addr, value->size); - (*pprev)->entries++; - /* this is a new leaf, need to remember it for search lists */ - if (q > maxResourceQuark) { - unsigned oldsize = (maxResourceQuark + 1) >> 3; - unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */ - if (resourceQuarks) { - unsigned char *prevQuarks = resourceQuarks; - - resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks, - size); - if (!resourceQuarks) { - Xfree(prevQuarks); - } - } else - resourceQuarks = (unsigned char *)Xmalloc(size); - if (resourceQuarks) { - bzero((char *)&resourceQuarks[oldsize], size - oldsize); - maxResourceQuark = (size << 3) - 1; - } else { - maxResourceQuark = -1; - } - } - if (q > 0 && resourceQuarks) - resourceQuarks[q >> 3] |= 1 << (q & 0x7); - GROW(firstpprev); - -#undef NEWTABLE -} - -void XrmQPutResource( - XrmDatabase *pdb, - XrmBindingList bindings, - XrmQuarkList quarks, - XrmRepresentation type, - XrmValuePtr value) -{ - if (!*pdb) *pdb = NewDatabase(); - _XLockMutex(&(*pdb)->linfo); - PutEntry(*pdb, bindings, quarks, type, value); - _XUnlockMutex(&(*pdb)->linfo); -} - -void -XrmPutResource( - XrmDatabase *pdb, - _Xconst char *specifier, - _Xconst char *type, - XrmValuePtr value) -{ - XrmBinding bindings[MAXDBDEPTH+1]; - XrmQuark quarks[MAXDBDEPTH+1]; - - if (!*pdb) *pdb = NewDatabase(); - _XLockMutex(&(*pdb)->linfo); - XrmStringToBindingQuarkList(specifier, bindings, quarks); - PutEntry(*pdb, bindings, quarks, XrmStringToQuark(type), value); - _XUnlockMutex(&(*pdb)->linfo); -} - -void -XrmQPutStringResource( - XrmDatabase *pdb, - XrmBindingList bindings, - XrmQuarkList quarks, - _Xconst char *str) -{ - XrmValue value; - - if (!*pdb) *pdb = NewDatabase(); - value.addr = (XPointer) str; - value.size = strlen(str)+1; - _XLockMutex(&(*pdb)->linfo); - PutEntry(*pdb, bindings, quarks, XrmQString, &value); - _XUnlockMutex(&(*pdb)->linfo); -} - -/* Function Name: GetDatabase - * Description: Parses a string and stores it as a database. - * Arguments: db - the database. - * str - a pointer to the string containing the database. - * filename - source filename, if any. - * doall - whether to do all lines or just one - */ - -/* - * This function is highly optimized to inline as much as possible. - * Be very careful with modifications, or simplifications, as they - * may adversely affect the performance. - * - * Chris Peterson, MIT X Consortium 5/17/90. - */ - -/* - * Xlib spec says max 100 quarks in a lookup, will stop and return if - * return if any single production's lhs has more than 100 components. - */ -#define QLIST_SIZE 100 - -/* - * This should be big enough to handle things like the XKeysymDB or biggish - * ~/.Xdefaults or app-defaults files. Anything bigger will be allocated on - * the heap. - */ -#define DEF_BUFF_SIZE 8192 - -static void GetIncludeFile( - XrmDatabase db, - _Xconst char *base, - _Xconst char *fname, - int fnamelen); - -static void GetDatabase( - XrmDatabase db, - _Xconst register char *str, - _Xconst char *filename, - Bool doall) -{ - char *rhs; - char *lhs, lhs_s[DEF_BUFF_SIZE]; - XrmQuark quarks[QLIST_SIZE + 1]; /* allow for a terminal NullQuark */ - XrmBinding bindings[QLIST_SIZE + 1]; - - register char *ptr; - register XrmBits bits = 0; - register char c; - register Signature sig; - register char *ptr_max; - register int num_quarks; - register XrmBindingList t_bindings; - - int len, alloc_chars; - unsigned long str_len; - XrmValue value; - Bool only_pcs; - Bool dolines; - - if (!db) - return; - - /* - * if strlen (str) < DEF_BUFF_SIZE allocate buffers on the stack for - * speed otherwise malloc the buffer. From a buffer overflow standpoint - * we can be sure that neither: a) a component on the lhs, or b) a - * value on the rhs, will be longer than the overall length of str, - * i.e. strlen(str). - * - * This should give good performance when parsing "*foo: bar" type - * databases as might be passed with -xrm command line options; but - * with larger databases, e.g. .Xdefaults, app-defaults, or KeysymDB - * files, the size of the buffers will be overly large. One way - * around this would be to double-parse each production with a resulting - * performance hit. In any event we can be assured that a lhs component - * name or a rhs value won't be longer than str itself. - */ - - str_len = strlen (str); - if (DEF_BUFF_SIZE > str_len) lhs = lhs_s; - else if ((lhs = (char*) Xmalloc (str_len)) == NULL) - return; - - alloc_chars = DEF_BUFF_SIZE < str_len ? str_len : DEF_BUFF_SIZE; - if ((rhs = (char*) Xmalloc (alloc_chars)) == NULL) { - if (lhs != lhs_s) Xfree (lhs); - return; - } - - (*db->methods->mbinit)(db->mbstate); - str--; - dolines = True; - while (!is_EOF(bits) && dolines) { - dolines = doall; - - /* - * First: Remove extra whitespace. - */ - - do { - bits = next_char(c, str); - } while is_space(bits); - - /* - * Ignore empty lines. - */ - - if (is_EOL(bits)) - continue; /* start a new line. */ - - /* - * Second: check the first character in a line to see if it is - * "!" signifying a comment, or "#" signifying a directive. - */ - - if (c == '!') { /* Comment, spin to next newline */ - while (is_simple(bits = next_char(c, str))) {} - if (is_EOL(bits)) - continue; - while (!is_EOL(bits = next_mbchar(c, len, str))) {} - str--; - continue; /* start a new line. */ - } - - if (c == '#') { /* Directive */ - /* remove extra whitespace */ - only_pcs = True; - while (is_space(bits = next_char(c, str))) {}; - /* only "include" directive is currently defined */ - if (!strncmp(str, "include", 7)) { - str += (7-1); - /* remove extra whitespace */ - while (is_space(bits = next_char(c, str))) {}; - /* must have a starting " */ - if (c == '"') { - _Xconst char *fname = str+1; - len = 0; - do { - if (only_pcs) { - bits = next_char(c, str); - if (is_nonpcs(bits)) - only_pcs = False; - } - if (!only_pcs) - bits = next_mbchar(c, len, str); - } while (c != '"' && !is_EOL(bits)); - /* must have an ending " */ - if (c == '"') - GetIncludeFile(db, filename, fname, str - len - fname); - } - } - /* spin to next newline */ - if (only_pcs) { - while (is_simple(bits)) - bits = next_char(c, str); - if (is_EOL(bits)) - continue; - } - while (!is_EOL(bits)) - bits = next_mbchar(c, len, str); - str--; - continue; /* start a new line. */ - } - - /* - * Third: loop through the LHS of the resource specification - * storing characters and converting this to a Quark. - */ - - num_quarks = 0; - t_bindings = bindings; - - sig = 0; - ptr = lhs; - *t_bindings = XrmBindTightly; - for(;;) { - if (!is_binding(bits)) { - while (!is_EOQ(bits)) { - *ptr++ = c; - sig = (sig << 1) + c; /* Compute the signature. */ - bits = next_char(c, str); - } - - quarks[num_quarks++] = - _XrmInternalStringToQuark(lhs, ptr - lhs, sig, False); - - if (num_quarks > QLIST_SIZE) { - Xfree(rhs); - if (lhs != lhs_s) Xfree (lhs); - (*db->methods->mbfinish)(db->mbstate); - return; - } - - if (is_separator(bits)) { - if (!is_space(bits)) - break; - - /* Remove white space */ - do { - *ptr++ = c; - sig = (sig << 1) + c; /* Compute the signature. */ - } while (is_space(bits = next_char(c, str))); - - /* - * The spec doesn't permit it, but support spaces - * internal to resource name/class - */ - - if (is_separator(bits)) - break; - num_quarks--; - continue; - } - - if (c == '.') - *(++t_bindings) = XrmBindTightly; - else - *(++t_bindings) = XrmBindLoosely; - - sig = 0; - ptr = lhs; - } - else { - /* - * Magic unspecified feature #254. - * - * If two separators appear with no Text between them then - * ignore them. - * - * If anyone of those separators is a '*' then the binding - * will be loose, otherwise it will be tight. - */ - - if (c == '*') - *t_bindings = XrmBindLoosely; - } - - bits = next_char(c, str); - } - - quarks[num_quarks] = NULLQUARK; - - /* - * Make sure that there is a ':' in this line. - */ - - if (c != ':') { - char oldc; - - /* - * A parsing error has occured, toss everything on the line - * a new_line can still be escaped with a '\'. - */ - - while (is_normal(bits)) - bits = next_char(c, str); - if (is_EOL(bits)) - continue; - bits = next_mbchar(c, len, str); - do { - oldc = c; - bits = next_mbchar(c, len, str); - } while (c && (c != '\n' || oldc == '\\')); - str--; - continue; - } - - /* - * I now have a quark and binding list for the entire left hand - * side. "c" currently points to the ":" separating the left hand - * side for the right hand side. It is time to begin processing - * the right hand side. - */ - - /* - * Fourth: Remove more whitespace - */ - - for(;;) { - if (is_space(bits = next_char(c, str))) - continue; - if (c != '\\') - break; - bits = next_char(c, str); - if (c == '\n') - continue; - str--; - bits = BSLASH; - c = '\\'; - break; - } - - /* - * Fifth: Process the right hand side. - */ - - ptr = rhs; - ptr_max = ptr + alloc_chars - 4; - only_pcs = True; - len = 1; - - for(;;) { - - /* - * Tight loop for the normal case: Non backslash, non-end of value - * character that will fit into the allocated buffer. - */ - - if (only_pcs) { - while (is_normal(bits) && ptr < ptr_max) { - *ptr++ = c; - bits = next_char(c, str); - } - if (is_EOL(bits)) - break; - if (is_nonpcs(bits)) { - only_pcs = False; - bits = next_mbchar(c, len, str); - } - } - while (!is_special(bits) && ptr + len <= ptr_max) { - len = -len; - while (len) - *ptr++ = str[len++]; - if (*str == '\0') { - bits = EOS; - break; - } - bits = next_mbchar(c, len, str); - } - - if (is_EOL(bits)) { - str--; - break; - } - - if (c == '\\') { - /* - * We need to do some magic after a backslash. - */ - Bool read_next = True; - - if (only_pcs) { - bits = next_char(c, str); - if (is_nonpcs(bits)) - only_pcs = False; - } - if (!only_pcs) - bits = next_mbchar(c, len, str); - - if (is_EOL(bits)) { - if (is_EOF(bits)) - continue; - } else if (c == 'n') { - /* - * "\n" means insert a newline. - */ - *ptr++ = '\n'; - } else if (c == '\\') { - /* - * "\\" completes to just one backslash. - */ - *ptr++ = '\\'; - } else { - /* - * pick up to three octal digits after the '\'. - */ - char temp[3]; - int count = 0; - while (is_odigit(bits) && count < 3) { - temp[count++] = c; - if (only_pcs) { - bits = next_char(c, str); - if (is_nonpcs(bits)) - only_pcs = False; - } - if (!only_pcs) - bits = next_mbchar(c, len, str); - } - - /* - * If we found three digits then insert that octal code - * into the value string as a character. - */ - - if (count == 3) { - *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 + - (temp[1] - '0') * 010 + - (temp[2] - '0')); - } - else { - int tcount; - - /* - * Otherwise just insert those characters into the - * string, since no special processing is needed on - * numerics we can skip the special processing. - */ - - for (tcount = 0; tcount < count; tcount++) { - *ptr++ = temp[tcount]; /* print them in - the correct order */ - } - } - read_next = False; - } - if (read_next) { - if (only_pcs) { - bits = next_char(c, str); - if (is_nonpcs(bits)) - only_pcs = False; - } - if (!only_pcs) - bits = next_mbchar(c, len, str); - } - } - - /* - * It is important to make sure that there is room for at least - * four more characters in the buffer, since I can add that - * many characters into the buffer after a backslash has occured. - */ - - if (ptr + len > ptr_max) { - char * temp_str; - - alloc_chars += BUFSIZ/10; - temp_str = Xrealloc(rhs, sizeof(char) * alloc_chars); - - if (!temp_str) { - Xfree(rhs); - if (lhs != lhs_s) Xfree (lhs); - (*db->methods->mbfinish)(db->mbstate); - return; - } - - ptr = temp_str + (ptr - rhs); /* reset pointer. */ - rhs = temp_str; - ptr_max = rhs + alloc_chars - 4; - } - } - - /* - * Lastly: Terminate the value string, and store this entry - * into the database. - */ - - *ptr++ = '\0'; - - /* Store it in database */ - value.size = ptr - rhs; - value.addr = (XPointer) rhs; - - PutEntry(db, bindings, quarks, XrmQString, &value); - } - - if (lhs != lhs_s) Xfree (lhs); - Xfree (rhs); - - (*db->methods->mbfinish)(db->mbstate); -} - -void -XrmPutStringResource( - XrmDatabase *pdb, - _Xconst char*specifier, - _Xconst char*str) -{ - XrmValue value; - XrmBinding bindings[MAXDBDEPTH+1]; - XrmQuark quarks[MAXDBDEPTH+1]; - - if (!*pdb) *pdb = NewDatabase(); - XrmStringToBindingQuarkList(specifier, bindings, quarks); - value.addr = (XPointer) str; - value.size = strlen(str)+1; - _XLockMutex(&(*pdb)->linfo); - PutEntry(*pdb, bindings, quarks, XrmQString, &value); - _XUnlockMutex(&(*pdb)->linfo); -} - - -void -XrmPutLineResource( - XrmDatabase *pdb, - _Xconst char*line) -{ - if (!*pdb) *pdb = NewDatabase(); - _XLockMutex(&(*pdb)->linfo); - GetDatabase(*pdb, line, (char *)NULL, False); - _XUnlockMutex(&(*pdb)->linfo); -} - -XrmDatabase -XrmGetStringDatabase( - _Xconst char *data) -{ - XrmDatabase db; - - db = NewDatabase(); - _XLockMutex(&db->linfo); - GetDatabase(db, data, (char *)NULL, True); - _XUnlockMutex(&db->linfo); - return db; -} - -/* Function Name: ReadInFile - * Description: Reads the file into a buffer. - * Arguments: filename - the name of the file. - * Returns: An allocated string containing the contents of the file. - */ - -static char * -ReadInFile(_Xconst char *filename) -{ - register int fd, size; - char * filebuf; - -#ifdef __UNIXOS2__ - filename = __XOS2RedirRoot(filename); -#endif - - /* - * MS-Windows and OS/2 note: Default open mode includes O_TEXT - */ - if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 ) - return (char *)NULL; - - /* - * MS-Windows and OS/2 note: depending on how the sources are - * untarred, the newlines in resource files may or may not have - * been expanded to CRLF. Either way the size returned by fstat - * is sufficient to read the file into because in text-mode any - * CRLFs in a file will be converted to newlines (LF) with the - * result that the number of bytes actually read with be <= - * to the size returned by fstat. - */ - { - struct stat status_buffer; - if ( (fstat(fd, &status_buffer)) == -1 ) { - close (fd); - return (char *)NULL; - } else - size = status_buffer.st_size; - } - - if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */ - close(fd); - return (char *)NULL; - } - size = read (fd, filebuf, size); - -#ifdef __UNIXOS2__ - { /* kill CRLF */ - int i,k; - for (i=k=0; i<size; i++) - if (filebuf[i] != 0x0d) { - filebuf[k++] = filebuf[i]; - } - filebuf[k] = 0; - } -#endif - - if (size < 0) { - close (fd); - Xfree(filebuf); - return (char *)NULL; - } - close (fd); - - filebuf[size] = '\0'; /* NULL terminate it. */ - return filebuf; -} - -static void -GetIncludeFile( - XrmDatabase db, - _Xconst char *base, - _Xconst char *fname, - int fnamelen) -{ - int len; - char *str; - char realfname[BUFSIZ]; - - if (fnamelen <= 0 || fnamelen >= BUFSIZ) - return; - if (*fname != '/' && base && (str = strrchr(base, '/'))) { - len = str - base + 1; - if (len + fnamelen >= BUFSIZ) - return; - strncpy(realfname, base, len); - strncpy(realfname + len, fname, fnamelen); - realfname[len + fnamelen] = '\0'; - } else { - strncpy(realfname, fname, fnamelen); - realfname[fnamelen] = '\0'; - } - if (!(str = ReadInFile(realfname))) - return; - GetDatabase(db, str, realfname, True); - Xfree(str); -} - -XrmDatabase -XrmGetFileDatabase( - _Xconst char *filename) -{ - XrmDatabase db; - char *str; - - if (!(str = ReadInFile(filename))) - return (XrmDatabase)NULL; - - db = NewDatabase(); - _XLockMutex(&db->linfo); - GetDatabase(db, str, filename, True); - _XUnlockMutex(&db->linfo); - Xfree(str); - return db; -} - -Status -XrmCombineFileDatabase( - _Xconst char *filename, - XrmDatabase *target, - Bool override) -{ - XrmDatabase db; - char *str; - - if (!(str = ReadInFile(filename))) - return 0; - if (override) { - db = *target; - if (!db) - *target = db = NewDatabase(); - } else - db = NewDatabase(); - _XLockMutex(&db->linfo); - GetDatabase(db, str, filename, True); - _XUnlockMutex(&db->linfo); - Xfree(str); - if (!override) - XrmCombineDatabase(db, target, False); - return 1; -} - -/* call the user proc for every value in the table, arbitrary order. - * stop if user proc returns True. level is current depth in database. - */ -/*ARGSUSED*/ -static Bool EnumLTable( - LTable table, - XrmNameList names, - XrmClassList classes, - register int level, - register EClosure closure) -{ - register VEntry *bucket; - register int i; - register VEntry entry; - XrmValue value; - XrmRepresentation type; - Bool tightOk; - - closure->bindings[level] = (table->table.tight ? - XrmBindTightly : XrmBindLoosely); - closure->quarks[level] = table->table.name; - level++; - tightOk = !*names; - closure->quarks[level + 1] = NULLQUARK; - for (i = table->table.mask, bucket = table->buckets; - i >= 0; - i--, bucket++) { - for (entry = *bucket; entry; entry = entry->next) { - if (entry->tight && !tightOk) - continue; - closure->bindings[level] = (entry->tight ? - XrmBindTightly : XrmBindLoosely); - closure->quarks[level] = entry->name; - value.size = entry->size; - if (entry->string) { - type = XrmQString; - value.addr = StringValue(entry); - } else { - type = RepType(entry); - value.addr = DataValue(entry); - } - if ((*closure->proc)(&closure->db, closure->bindings+1, - closure->quarks+1, &type, &value, - closure->closure)) - return True; - } - } - return False; -} - -static Bool EnumAllNTable( - NTable table, - register int level, - register EClosure closure) -{ - register NTable *bucket; - register int i; - register NTable entry; - XrmQuark empty = NULLQUARK; - - if (level >= MAXDBDEPTH) - return False; - for (i = table->mask, bucket = NodeBuckets(table); - i >= 0; - i--, bucket++) { - for (entry = *bucket; entry; entry = entry->next) { - if (entry->leaf) { - if (EnumLTable((LTable)entry, &empty, &empty, level, closure)) - return True; - } else { - closure->bindings[level] = (entry->tight ? - XrmBindTightly : XrmBindLoosely); - closure->quarks[level] = entry->name; - if (EnumAllNTable(entry, level+1, closure)) - return True; - } - } - } - return False; -} - -/* recurse on every table in the table, arbitrary order. - * stop if user proc returns True. level is current depth in database. - */ -static Bool EnumNTable( - NTable table, - XrmNameList names, - XrmClassList classes, - register int level, - register EClosure closure) -{ - register NTable entry; - register XrmQuark q; - register unsigned int leaf; - Bool (*get)( - NTable table, - XrmNameList names, - XrmClassList classes, - register int level, - EClosure closure); - Bool bilevel; - -/* find entries named ename, leafness leaf, tight or loose, and call get */ -#define ITIGHTLOOSE(ename) \ - NFIND(ename); \ - if (entry) { \ - if (leaf == entry->leaf) { \ - if (!leaf && !entry->tight && entry->next && \ - entry->next->name == q && entry->next->tight && \ - (bilevel || entry->next->hasloose) && \ - EnumLTable((LTable)entry->next, names+1, classes+1, \ - level, closure)) \ - return True; \ - if ((*get)(entry, names+1, classes+1, level, closure)) \ - return True; \ - if (entry->tight && (entry = entry->next) && \ - entry->name == q && leaf == entry->leaf && \ - (*get)(entry, names+1, classes+1, level, closure)) \ - return True; \ - } else if (entry->leaf) { \ - if ((bilevel || entry->hasloose) && \ - EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ - return True; \ - if (entry->tight && (entry = entry->next) && \ - entry->name == q && (bilevel || entry->hasloose) && \ - EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ - return True; \ - } \ - } - -/* find entries named ename, leafness leaf, loose only, and call get */ -#define ILOOSE(ename) \ - NFIND(ename); \ - if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ - entry = (NTable)NULL; \ - if (entry) { \ - if (leaf == entry->leaf) { \ - if ((*get)(entry, names+1, classes+1, level, closure)) \ - return True; \ - } else if (entry->leaf && (bilevel || entry->hasloose)) { \ - if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\ - return True; \ - } \ - } - - if (level >= MAXDBDEPTH) - return False; - closure->bindings[level] = (table->tight ? - XrmBindTightly : XrmBindLoosely); - closure->quarks[level] = table->name; - level++; - if (!*names) { - if (EnumAllNTable(table, level, closure)) - return True; - } else { - if (names[1] || closure->mode == XrmEnumAllLevels) { - get = EnumNTable; /* recurse */ - leaf = 0; - bilevel = !names[1]; - } else { - get = (getNTableEProcp)EnumLTable; /* bottom of recursion */ - leaf = 1; - bilevel = False; - } - if (table->hasloose && closure->mode == XrmEnumAllLevels) { - NTable *bucket; - int i; - XrmQuark empty = NULLQUARK; - - for (i = table->mask, bucket = NodeBuckets(table); - i >= 0; - i--, bucket++) { - q = NULLQUARK; - for (entry = *bucket; entry; entry = entry->next) { - if (!entry->tight && entry->name != q && - entry->name != *names && entry->name != *classes) { - q = entry->name; - if (entry->leaf) { - if (EnumLTable((LTable)entry, &empty, &empty, - level, closure)) - return True; - } else { - if (EnumNTable(entry, &empty, &empty, - level, closure)) - return True; - } - } - } - } - } - - ITIGHTLOOSE(*names); /* do name, tight and loose */ - ITIGHTLOOSE(*classes); /* do class, tight and loose */ - if (table->hasany) { - ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */ - } - if (table->hasloose) { - while (1) { - names++; - classes++; - if (!*names) - break; - if (!names[1] && closure->mode != XrmEnumAllLevels) { - get = (getNTableEProcp)EnumLTable; /* bottom of recursion */ - leaf = 1; - } - ILOOSE(*names); /* loose names */ - ILOOSE(*classes); /* loose classes */ - if (table->hasany) { - ILOOSE(XrmQANY); /* loose ANY */ - } - } - names--; - classes--; - } - } - /* now look for matching leaf nodes */ - entry = table->next; - if (!entry) - return False; - if (entry->leaf) { - if (entry->tight && !table->tight) - entry = entry->next; - } else { - entry = entry->next; - if (!entry || !entry->tight) - return False; - } - if (!entry || entry->name != table->name) - return False; - /* found one */ - level--; - if ((!*names || entry->hasloose) && - EnumLTable((LTable)entry, names, classes, level, closure)) - return True; - if (entry->tight && entry == table->next && (entry = entry->next) && - entry->name == table->name && (!*names || entry->hasloose)) - return EnumLTable((LTable)entry, names, classes, level, closure); - return False; - -#undef ITIGHTLOOSE -#undef ILOOSE -} - -/* call the proc for every value in the database, arbitrary order. - * stop if the proc returns True. - */ -Bool XrmEnumerateDatabase( - XrmDatabase db, - XrmNameList names, - XrmClassList classes, - int mode, - DBEnumProc proc, - XPointer closure) -{ - XrmBinding bindings[MAXDBDEPTH+2]; - XrmQuark quarks[MAXDBDEPTH+2]; - register NTable table; - EClosureRec eclosure; - Bool retval = False; - - if (!db) - return False; - _XLockMutex(&db->linfo); - eclosure.db = db; - eclosure.proc = proc; - eclosure.closure = closure; - eclosure.bindings = bindings; - eclosure.quarks = quarks; - eclosure.mode = mode; - table = db->table; - if (table && !table->leaf && !*names && mode == XrmEnumOneLevel) - table = table->next; - if (table) { - if (!table->leaf) - retval = EnumNTable(table, names, classes, 0, &eclosure); - else - retval = EnumLTable((LTable)table, names, classes, 0, &eclosure); - } - _XUnlockMutex(&db->linfo); - return retval; -} - -static void PrintBindingQuarkList( - XrmBindingList bindings, - XrmQuarkList quarks, - FILE *stream) -{ - Bool firstNameSeen; - - for (firstNameSeen = False; *quarks; bindings++, quarks++) { - if (*bindings == XrmBindLoosely) { - (void) fprintf(stream, "*"); - } else if (firstNameSeen) { - (void) fprintf(stream, "."); - } - firstNameSeen = True; - (void) fputs(XrmQuarkToString(*quarks), stream); - } -} - -/* output out the entry in correct file syntax */ -/*ARGSUSED*/ -static Bool DumpEntry( - XrmDatabase *db, - XrmBindingList bindings, - XrmQuarkList quarks, - XrmRepresentation *type, - XrmValuePtr value, - XPointer data) -{ - FILE *stream = (FILE *)data; - register unsigned int i; - register char *s; - register char c; - - if (*type != XrmQString) - (void) putc('!', stream); - PrintBindingQuarkList(bindings, quarks, stream); - s = value->addr; - i = value->size; - if (*type == XrmQString) { - (void) fputs(":\t", stream); - if (i) - i--; - } - else - (void) fprintf(stream, "=%s:\t", XrmRepresentationToString(*type)); - if (i && (*s == ' ' || *s == '\t')) - (void) putc('\\', stream); /* preserve leading whitespace */ - while (i--) { - c = *s++; - if (c == '\n') { - if (i) - (void) fputs("\\n\\\n", stream); - else - (void) fputs("\\n", stream); - } else if (c == '\\') - (void) fputs("\\\\", stream); - else if ((c < ' ' && c != '\t') || - ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0)) - (void) fprintf(stream, "\\%03o", (unsigned char)c); - else - (void) putc(c, stream); - } - (void) putc('\n', stream); - return ferror(stream) != 0; -} - -#ifdef DEBUG - -void PrintTable( - NTable table, - FILE *file) -{ - XrmBinding bindings[MAXDBDEPTH+1]; - XrmQuark quarks[MAXDBDEPTH+1]; - EClosureRec closure; - XrmQuark empty = NULLQUARK; - - closure.db = (XrmDatabase)NULL; - closure.proc = DumpEntry; - closure.closure = (XPointer)file; - closure.bindings = bindings; - closure.quarks = quarks; - closure.mode = XrmEnumAllLevels; - if (table->leaf) - EnumLTable((LTable)table, &empty, &empty, 0, &closure); - else - EnumNTable(table, &empty, &empty, 0, &closure); -} - -#endif /* DEBUG */ - -void -XrmPutFileDatabase( - XrmDatabase db, - _Xconst char *fileName) -{ - FILE *file; - XrmQuark empty = NULLQUARK; - - if (!db) return; - if (!(file = fopen(fileName, "w"))) return; - if (XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels, - DumpEntry, (XPointer) file)) - unlink((char *)fileName); - fclose(file); -} - -/* macros used in get/search functions */ - -/* find entries named ename, leafness leaf, tight or loose, and call get */ -#define GTIGHTLOOSE(ename,looseleaf) \ - NFIND(ename); \ - if (entry) { \ - if (leaf == entry->leaf) { \ - if (!leaf && !entry->tight && entry->next && \ - entry->next->name == q && entry->next->tight && \ - entry->next->hasloose && \ - looseleaf((LTable)entry->next, names+1, classes+1, closure)) \ - return True; \ - if ((*get)(entry, names+1, classes+1, closure)) \ - return True; \ - if (entry->tight && (entry = entry->next) && \ - entry->name == q && leaf == entry->leaf && \ - (*get)(entry, names+1, classes+1, closure)) \ - return True; \ - } else if (entry->leaf) { \ - if (entry->hasloose && \ - looseleaf((LTable)entry, names+1, classes+1, closure)) \ - return True; \ - if (entry->tight && (entry = entry->next) && \ - entry->name == q && entry->hasloose && \ - looseleaf((LTable)entry, names+1, classes+1, closure)) \ - return True; \ - } \ - } - -/* find entries named ename, leafness leaf, loose only, and call get */ -#define GLOOSE(ename,looseleaf) \ - NFIND(ename); \ - if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ - entry = (NTable)NULL; \ - if (entry) { \ - if (leaf == entry->leaf) { \ - if ((*get)(entry, names+1, classes+1, closure)) \ - return True; \ - } else if (entry->leaf && entry->hasloose) { \ - if (looseleaf((LTable)entry, names+1, classes+1, closure)) \ - return True; \ - } \ - } - -/* add tight/loose entry to the search list, return True if list is full */ -/*ARGSUSED*/ -static Bool AppendLEntry( - LTable table, - XrmNameList names, - XrmClassList classes, - register SClosure closure) -{ - /* check for duplicate */ - if (closure->idx >= 0 && closure->list[closure->idx] == table) - return False; - if (closure->idx == closure->limit) - return True; - /* append it */ - closure->idx++; - closure->list[closure->idx] = table; - return False; -} - -/* add loose entry to the search list, return True if list is full */ -/*ARGSUSED*/ -static Bool AppendLooseLEntry( - LTable table, - XrmNameList names, - XrmClassList classes, - register SClosure closure) -{ - /* check for duplicate */ - if (closure->idx >= 0 && closure->list[closure->idx] == table) - return False; - if (closure->idx >= closure->limit - 1) - return True; - /* append it */ - closure->idx++; - closure->list[closure->idx] = LOOSESEARCH; - closure->idx++; - closure->list[closure->idx] = table; - return False; -} - -/* search for a leaf table */ -static Bool SearchNEntry( - NTable table, - XrmNameList names, - XrmClassList classes, - SClosure closure) -{ - register NTable entry; - register XrmQuark q; - register unsigned int leaf; - Bool (*get)( - NTable table, - XrmNameList names, - XrmClassList classes, - SClosure closure); - - if (names[1]) { - get = SearchNEntry; /* recurse */ - leaf = 0; - } else { - get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */ - leaf = 1; - } - GTIGHTLOOSE(*names, AppendLooseLEntry); /* do name, tight and loose */ - GTIGHTLOOSE(*classes, AppendLooseLEntry); /* do class, tight and loose */ - if (table->hasany) { - GTIGHTLOOSE(XrmQANY, AppendLooseLEntry); /* do ANY, tight and loose */ - } - if (table->hasloose) { - while (1) { - names++; - classes++; - if (!*names) - break; - if (!names[1]) { - get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */ - leaf = 1; - } - GLOOSE(*names, AppendLooseLEntry); /* loose names */ - GLOOSE(*classes, AppendLooseLEntry); /* loose classes */ - if (table->hasany) { - GLOOSE(XrmQANY, AppendLooseLEntry); /* loose ANY */ - } - } - } - /* now look for matching leaf nodes */ - entry = table->next; - if (!entry) - return False; - if (entry->leaf) { - if (entry->tight && !table->tight) - entry = entry->next; - } else { - entry = entry->next; - if (!entry || !entry->tight) - return False; - } - if (!entry || entry->name != table->name) - return False; - /* found one */ - if (entry->hasloose && - AppendLooseLEntry((LTable)entry, names, classes, closure)) - return True; - if (entry->tight && entry == table->next && (entry = entry->next) && - entry->name == table->name && entry->hasloose) - return AppendLooseLEntry((LTable)entry, names, classes, closure); - return False; -} - -Bool XrmQGetSearchList( - XrmDatabase db, - XrmNameList names, - XrmClassList classes, - XrmSearchList searchList, /* RETURN */ - int listLength) -{ - register NTable table; - SClosureRec closure; - - if (listLength <= 0) - return False; - closure.list = (LTable *)searchList; - closure.idx = -1; - closure.limit = listLength - 2; - if (db) { - _XLockMutex(&db->linfo); - table = db->table; - if (*names) { - if (table && !table->leaf) { - if (SearchNEntry(table, names, classes, &closure)) { - _XUnlockMutex(&db->linfo); - return False; - } - } else if (table && table->hasloose && - AppendLooseLEntry((LTable)table, names, classes, - &closure)) { - _XUnlockMutex(&db->linfo); - return False; - } - } else { - if (table && !table->leaf) - table = table->next; - if (table && - AppendLEntry((LTable)table, names, classes, &closure)) { - _XUnlockMutex(&db->linfo); - return False; - } - } - _XUnlockMutex(&db->linfo); - } - closure.list[closure.idx + 1] = (LTable)NULL; - return True; -} - -Bool XrmQGetSearchResource( - XrmSearchList searchList, - register XrmName name, - register XrmClass class, - XrmRepresentation *pType, /* RETURN */ - XrmValue *pValue) /* RETURN */ -{ - register LTable *list; - register LTable table; - register VEntry entry = NULL; - int flags; - -/* find tight or loose entry */ -#define VTIGHTLOOSE(q) \ - entry = LeafHash(table, q); \ - while (entry && entry->name != q) \ - entry = entry->next; \ - if (entry) \ - break - -/* find loose entry */ -#define VLOOSE(q) \ - entry = LeafHash(table, q); \ - while (entry && entry->name != q) \ - entry = entry->next; \ - if (entry) { \ - if (!entry->tight) \ - break; \ - if ((entry = entry->next) && entry->name == q) \ - break; \ - } - - list = (LTable *)searchList; - /* figure out which combination of name and class we need to search for */ - flags = 0; - if (IsResourceQuark(name)) - flags = 2; - if (IsResourceQuark(class)) - flags |= 1; - if (!flags) { - /* neither name nor class has ever been used to name a resource */ - table = (LTable)NULL; - } else if (flags == 3) { - /* both name and class */ - while ((table = *list++)) { - if (table != LOOSESEARCH) { - VTIGHTLOOSE(name); /* do name, tight and loose */ - VTIGHTLOOSE(class); /* do class, tight and loose */ - } else { - table = *list++; - VLOOSE(name); /* do name, loose only */ - VLOOSE(class); /* do class, loose only */ - } - } - } else { - /* just one of name or class */ - if (flags == 1) - name = class; - while ((table = *list++)) { - if (table != LOOSESEARCH) { - VTIGHTLOOSE(name); /* tight and loose */ - } else { - table = *list++; - VLOOSE(name); /* loose only */ - } - } - } - if (table) { - /* found a match */ - if (entry->string) { - *pType = XrmQString; - pValue->addr = StringValue(entry); - } else { - *pType = RepType(entry); - pValue->addr = DataValue(entry); - } - pValue->size = entry->size; - return True; - } - *pType = NULLQUARK; - pValue->addr = (XPointer)NULL; - pValue->size = 0; - return False; - -#undef VTIGHTLOOSE -#undef VLOOSE -} - -/* look for a tight/loose value */ -static Bool GetVEntry( - LTable table, - XrmNameList names, - XrmClassList classes, - VClosure closure) -{ - register VEntry entry; - register XrmQuark q; - - /* try name first */ - q = *names; - entry = LeafHash(table, q); - while (entry && entry->name != q) - entry = entry->next; - if (!entry) { - /* not found, try class */ - q = *classes; - entry = LeafHash(table, q); - while (entry && entry->name != q) - entry = entry->next; - if (!entry) - return False; - } - if (entry->string) { - *closure->type = XrmQString; - closure->value->addr = StringValue(entry); - } else { - *closure->type = RepType(entry); - closure->value->addr = DataValue(entry); - } - closure->value->size = entry->size; - return True; -} - -/* look for a loose value */ -static Bool GetLooseVEntry( - LTable table, - XrmNameList names, - XrmClassList classes, - VClosure closure) -{ - register VEntry entry; - register XrmQuark q; - -#define VLOOSE(ename) \ - q = ename; \ - entry = LeafHash(table, q); \ - while (entry && entry->name != q) \ - entry = entry->next; \ - if (entry && entry->tight && (entry = entry->next) && entry->name != q) \ - entry = (VEntry)NULL; - - /* bump to last component */ - while (names[1]) { - names++; - classes++; - } - VLOOSE(*names); /* do name, loose only */ - if (!entry) { - VLOOSE(*classes); /* do class, loose only */ - if (!entry) - return False; - } - if (entry->string) { - *closure->type = XrmQString; - closure->value->addr = StringValue(entry); - } else { - *closure->type = RepType(entry); - closure->value->addr = DataValue(entry); - } - closure->value->size = entry->size; - return True; - -#undef VLOOSE -} - -/* recursive search for a value */ -static Bool GetNEntry( - NTable table, - XrmNameList names, - XrmClassList classes, - VClosure closure) -{ - register NTable entry; - register XrmQuark q; - register unsigned int leaf; - Bool (*get)( - NTable table, - XrmNameList names, - XrmClassList classes, - VClosure closure); - NTable otable; - - if (names[2]) { - get = GetNEntry; /* recurse */ - leaf = 0; - } else { - get = (getNTableVProcp)GetVEntry; /* bottom of recursion */ - leaf = 1; - } - GTIGHTLOOSE(*names, GetLooseVEntry); /* do name, tight and loose */ - GTIGHTLOOSE(*classes, GetLooseVEntry); /* do class, tight and loose */ - if (table->hasany) { - GTIGHTLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, tight and loose */ - } - if (table->hasloose) { - while (1) { - names++; - classes++; - if (!names[1]) - break; - if (!names[2]) { - get = (getNTableVProcp)GetVEntry; /* bottom of recursion */ - leaf = 1; - } - GLOOSE(*names, GetLooseVEntry); /* do name, loose only */ - GLOOSE(*classes, GetLooseVEntry); /* do class, loose only */ - if (table->hasany) { - GLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, loose only */ - } - } - } - /* look for matching leaf tables */ - otable = table; - table = table->next; - if (!table) - return False; - if (table->leaf) { - if (table->tight && !otable->tight) - table = table->next; - } else { - table = table->next; - if (!table || !table->tight) - return False; - } - if (!table || table->name != otable->name) - return False; - /* found one */ - if (table->hasloose && - GetLooseVEntry((LTable)table, names, classes, closure)) - return True; - if (table->tight && table == otable->next) { - table = table->next; - if (table && table->name == otable->name && table->hasloose) - return GetLooseVEntry((LTable)table, names, classes, closure); - } - return False; -} - -Bool XrmQGetResource( - XrmDatabase db, - XrmNameList names, - XrmClassList classes, - XrmRepresentation *pType, /* RETURN */ - XrmValuePtr pValue) /* RETURN */ -{ - register NTable table; - VClosureRec closure; - - if (db && *names) { - _XLockMutex(&db->linfo); - closure.type = pType; - closure.value = pValue; - table = db->table; - if (names[1]) { - if (table && !table->leaf) { - if (GetNEntry(table, names, classes, &closure)) { - _XUnlockMutex(&db->linfo); - return True; - } - } else if (table && table->hasloose && - GetLooseVEntry((LTable)table, names, classes, &closure)) { - _XUnlockMutex (&db->linfo); - return True; - } - } else { - if (table && !table->leaf) - table = table->next; - if (table && GetVEntry((LTable)table, names, classes, &closure)) { - _XUnlockMutex(&db->linfo); - return True; - } - } - _XUnlockMutex(&db->linfo); - } - *pType = NULLQUARK; - pValue->addr = (XPointer)NULL; - pValue->size = 0; - return False; -} - -Bool -XrmGetResource(XrmDatabase db, _Xconst char *name_str, _Xconst char *class_str, - XrmString *pType_str, XrmValuePtr pValue) -{ - XrmName names[MAXDBDEPTH+1]; - XrmClass classes[MAXDBDEPTH+1]; - XrmRepresentation fromType; - Bool result; - - XrmStringToNameList(name_str, names); - XrmStringToClassList(class_str, classes); - result = XrmQGetResource(db, names, classes, &fromType, pValue); - (*pType_str) = XrmQuarkToString(fromType); - return result; -} - -/* destroy all values, plus table itself */ -static void DestroyLTable( - LTable table) -{ - register int i; - register VEntry *buckets; - register VEntry entry, next; - - buckets = table->buckets; - for (i = table->table.mask; i >= 0; i--, buckets++) { - for (next = *buckets; (entry = next); ) { - next = entry->next; - Xfree((char *)entry); - } - } - Xfree((char *)table->buckets); - Xfree((char *)table); -} - -/* destroy all contained tables, plus table itself */ -static void DestroyNTable( - NTable table) -{ - register int i; - register NTable *buckets; - register NTable entry, next; - - buckets = NodeBuckets(table); - for (i = table->mask; i >= 0; i--, buckets++) { - for (next = *buckets; (entry = next); ) { - next = entry->next; - if (entry->leaf) - DestroyLTable((LTable)entry); - else - DestroyNTable(entry); - } - } - Xfree((char *)table); -} - -const char * -XrmLocaleOfDatabase( - XrmDatabase db) -{ - const char* retval; - _XLockMutex(&db->linfo); - retval = (*db->methods->lcname)(db->mbstate); - _XUnlockMutex(&db->linfo); - return retval; -} - -void XrmDestroyDatabase( - XrmDatabase db) -{ - register NTable table, next; - - if (db) { - _XLockMutex(&db->linfo); - for (next = db->table; (table = next); ) { - next = table->next; - if (table->leaf) - DestroyLTable((LTable)table); - else - DestroyNTable(table); - } - _XUnlockMutex(&db->linfo); - _XFreeMutex(&db->linfo); - (*db->methods->destroy)(db->mbstate); - Xfree((char *)db); - } -} +
+/***********************************************************
+Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/*
+
+Copyright 1987, 1988, 1990, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 name of The Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include "Xlibint.h"
+#include <X11/Xresource.h>
+#include "Xlcint.h"
+#ifdef XTHREADS
+#include "locking.h"
+#endif
+#include <X11/Xos.h>
+#include <sys/stat.h>
+#include "Xresinternal.h"
+#include "Xresource.h"
+
+/*
+
+These Xrm routines allow very fast lookup of resources in the resource
+database. Several usage patterns are exploited:
+
+(1) Widgets get a lot of resources at one time. Rather than look up each from
+scratch, we can precompute the prioritized list of database levels once, then
+search for each resource starting at the beginning of the list.
+
+(2) Many database levels don't contain any leaf resource nodes. There is no
+point in looking for resources on a level that doesn't contain any. This
+information is kept on a per-level basis.
+
+(3) Sometimes the widget instance tree is structured such that you get the same
+class name repeated on the fully qualified widget name. This can result in the
+same database level occuring multiple times on the search list. The code below
+only checks to see if you get two identical search lists in a row, rather than
+look back through all database levels, but in practice this removes all
+duplicates I've ever observed.
+
+Joel McCormack
+
+*/
+
+/*
+
+The Xrm representation has been completely redesigned to substantially reduce
+memory and hopefully improve performance.
+
+The database is structured into two kinds of tables: LTables that contain
+only values, and NTables that contain only other tables.
+
+Some invariants:
+
+The next pointer of the top-level node table points to the top-level leaf
+table, if any.
+
+Within an LTable, for a given name, the tight value always precedes the
+loose value, and if both are present the loose value is always right after
+the tight value.
+
+Within an NTable, all of the entries for a given name are contiguous,
+in the order tight NTable, loose NTable, tight LTable, loose LTable.
+
+Bob Scheifler
+
+*/
+
+static XrmQuark XrmQString, XrmQANY;
+
+typedef Bool (*DBEnumProc)(
+ XrmDatabase* /* db */,
+ XrmBindingList /* bindings */,
+ XrmQuarkList /* quarks */,
+ XrmRepresentation* /* type */,
+ XrmValue* /* value */,
+ XPointer /* closure */
+);
+
+typedef struct _VEntry {
+ struct _VEntry *next; /* next in chain */
+ XrmQuark name; /* name of this entry */
+ unsigned int tight:1; /* 1 if it is a tight binding */
+ unsigned int string:1; /* 1 if type is String */
+ unsigned int size:30; /* size of value */
+} VEntryRec, *VEntry;
+
+
+typedef struct _DEntry {
+ VEntryRec entry; /* entry */
+ XrmRepresentation type; /* representation type */
+} DEntryRec, *DEntry;
+
+/* the value is right after the structure */
+#define StringValue(ve) (XPointer)((ve) + 1)
+#define RepType(ve) ((DEntry)(ve))->type
+/* the value is right after the structure */
+#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1)
+#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve))
+
+typedef struct _NTable {
+ struct _NTable *next; /* next in chain */
+ XrmQuark name; /* name of this entry */
+ unsigned int tight:1; /* 1 if it is a tight binding */
+ unsigned int leaf:1; /* 1 if children are values */
+ unsigned int hasloose:1; /* 1 if has loose children */
+ unsigned int hasany:1; /* 1 if has ANY entry */
+ unsigned int pad:4; /* unused */
+ unsigned int mask:8; /* hash size - 1 */
+ unsigned int entries:16; /* number of children */
+} NTableRec, *NTable;
+
+/* the buckets are right after the structure */
+#define NodeBuckets(ne) ((NTable *)((ne) + 1))
+#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask]
+
+/* leaf tables have an extra level of indirection for the buckets,
+ * so that resizing can be done without invalidating a search list.
+ * This is completely ugly, and wastes some memory, but the Xlib
+ * spec doesn't really specify whether invalidation is OK, and the
+ * old implementation did not invalidate.
+ */
+typedef struct _LTable {
+ NTableRec table;
+ VEntry *buckets;
+} LTableRec, *LTable;
+
+#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask]
+
+/* An XrmDatabase just holds a pointer to the first top-level table.
+ * The type name is no longer descriptive, but better to not change
+ * the Xresource.h header file. This type also gets used to define
+ * XrmSearchList, which is a complete crock, but we'll just leave it
+ * and caste types as required.
+ */
+typedef struct _XrmHashBucketRec {
+ NTable table;
+ XPointer mbstate;
+ XrmMethods methods;
+#ifdef XTHREADS
+ LockInfoRec linfo;
+#endif
+} XrmHashBucketRec;
+
+/* closure used in get/put resource */
+typedef struct _VClosure {
+ XrmRepresentation *type; /* type of value */
+ XrmValuePtr value; /* value itself */
+} VClosureRec, *VClosure;
+
+/* closure used in get search list */
+typedef struct _SClosure {
+ LTable *list; /* search list */
+ int idx; /* index of last filled element */
+ int limit; /* maximum index */
+} SClosureRec, *SClosure;
+
+/* placed in XrmSearchList to indicate next table is loose only */
+#define LOOSESEARCH ((LTable)1)
+
+/* closure used in enumerate database */
+typedef struct _EClosure {
+ XrmDatabase db; /* the database */
+ DBEnumProc proc; /* the user proc */
+ XPointer closure; /* the user closure */
+ XrmBindingList bindings; /* binding list */
+ XrmQuarkList quarks; /* quark list */
+ int mode; /* XrmEnum<kind> */
+} EClosureRec, *EClosure;
+
+/* types for typecasting ETable based functions to NTable based functions */
+typedef Bool (*getNTableSProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure);
+typedef Bool (*getNTableVProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure);
+typedef Bool (*getNTableEProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ EClosure closure);
+
+/* predicate to determine when to resize a hash table */
+#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2))
+
+#define GROW(prev) \
+ if (GrowthPred((*prev)->entries, (*prev)->mask)) \
+ GrowTable(prev)
+
+/* pick a reasonable value for maximum depth of resource database */
+#define MAXDBDEPTH 100
+
+/* macro used in get/search functions */
+
+/* find an entry named ename, with leafness given by leaf */
+#define NFIND(ename) \
+ q = ename; \
+ entry = NodeHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (leaf && entry && !entry->leaf) { \
+ entry = entry->next; \
+ if (entry && !entry->leaf) \
+ entry = entry->next; \
+ if (entry && entry->name != q) \
+ entry = (NTable)NULL; \
+ }
+
+/* resourceQuarks keeps track of what quarks have been associated with values
+ * in all LTables. If a quark has never been used in an LTable, we don't need
+ * to bother looking for it.
+ */
+
+static unsigned char *resourceQuarks = (unsigned char *)NULL;
+static XrmQuark maxResourceQuark = -1;
+
+/* determines if a quark has been used for a value in any database */
+#define IsResourceQuark(q) ((q) > 0 && (q) <= maxResourceQuark && \
+ resourceQuarks[(q) >> 3] & (1 << ((q) & 7)))
+
+typedef unsigned char XrmBits;
+
+#define BSLASH ((XrmBits) (1 << 5))
+#define NORMAL ((XrmBits) (1 << 4))
+#define EOQ ((XrmBits) (1 << 3))
+#define SEP ((XrmBits) (1 << 2))
+#define ENDOF ((XrmBits) (1 << 1))
+#define SPACE (NORMAL|EOQ|SEP|(XrmBits)0)
+#define RSEP (NORMAL|EOQ|SEP|(XrmBits)1)
+#define EOS (EOQ|SEP|ENDOF|(XrmBits)0)
+#define EOL (EOQ|SEP|ENDOF|(XrmBits)1)
+#define BINDING (NORMAL|EOQ)
+#define ODIGIT (NORMAL|(XrmBits)1)
+
+#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))]
+#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)]
+
+#define is_space(bits) ((bits) == SPACE)
+#define is_EOQ(bits) ((bits) & EOQ)
+#define is_EOF(bits) ((bits) == EOS)
+#define is_EOL(bits) ((bits) & ENDOF)
+#define is_binding(bits) ((bits) == BINDING)
+#define is_odigit(bits) ((bits) == ODIGIT)
+#define is_separator(bits) ((bits) & SEP)
+#define is_nonpcs(bits) (!(bits))
+#define is_normal(bits) ((bits) & NORMAL)
+#define is_simple(bits) ((bits) & (NORMAL|BSLASH))
+#define is_special(bits) ((bits) & (ENDOF|BSLASH))
+
+/* parsing types */
+static XrmBits const xrmtypes[256] = {
+ EOS,0,0,0,0,0,0,0,
+ 0,SPACE,EOL,0,0,
+#if defined(WIN32) || defined(__UNIXOS2__)
+ EOL, /* treat CR the same as LF, just in case */
+#else
+ 0,
+#endif
+ 0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL,
+ ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,
+ NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0
+ /* The rest will be automatically initialized to zero. */
+};
+
+void XrmInitialize(void)
+{
+ XrmQString = XrmPermStringToQuark("String");
+ XrmQANY = XrmPermStringToQuark("?");
+}
+
+XrmDatabase XrmGetDatabase(
+ Display *display)
+{
+ XrmDatabase retval;
+ LockDisplay(display);
+ retval = display->db;
+ UnlockDisplay(display);
+ return retval;
+}
+
+void XrmSetDatabase(
+ Display *display,
+ XrmDatabase database)
+{
+ LockDisplay(display);
+ /* destroy database if set up imlicitely by XGetDefault() */
+ if (display->db && (display->flags & XlibDisplayDfltRMDB)) {
+ XrmDestroyDatabase(display->db);
+ display->flags &= ~XlibDisplayDfltRMDB;
+ }
+ display->db = database;
+ UnlockDisplay(display);
+}
+
+void
+XrmStringToQuarkList(
+ register _Xconst char *name,
+ register XrmQuarkList quarks) /* RETURN */
+{
+ register XrmBits bits;
+ register Signature sig = 0;
+ register char ch, *tname;
+ register int i = 0;
+
+ if ((tname = (char *)name)) {
+ tname--;
+ while (!is_EOF(bits = next_char(ch, tname))) {
+ if (is_binding (bits)) {
+ if (i) {
+ /* Found a complete name */
+ *quarks++ = _XrmInternalStringToQuark(name,tname - name,
+ sig, False);
+ i = 0;
+ sig = 0;
+ }
+ name = tname+1;
+ }
+ else {
+ sig = (sig << 1) + ch; /* Compute the signature. */
+ i++;
+ }
+ }
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
+ }
+ *quarks = NULLQUARK;
+}
+
+void
+XrmStringToBindingQuarkList(
+ register _Xconst char *name,
+ register XrmBindingList bindings, /* RETURN */
+ register XrmQuarkList quarks) /* RETURN */
+{
+ register XrmBits bits;
+ register Signature sig = 0;
+ register char ch, *tname;
+ register XrmBinding binding;
+ register int i = 0;
+
+ if ((tname = (char *)name)) {
+ tname--;
+ binding = XrmBindTightly;
+ while (!is_EOF(bits = next_char(ch, tname))) {
+ if (is_binding (bits)) {
+ if (i) {
+ /* Found a complete name */
+ *bindings++ = binding;
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name,
+ sig, False);
+
+ i = 0;
+ sig = 0;
+ binding = XrmBindTightly;
+ }
+ name = tname+1;
+
+ if (ch == '*')
+ binding = XrmBindLoosely;
+ }
+ else {
+ sig = (sig << 1) + ch; /* Compute the signature. */
+ i++;
+ }
+ }
+ *bindings = binding;
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
+ }
+ *quarks = NULLQUARK;
+}
+
+#ifdef DEBUG
+
+static void PrintQuarkList(
+ XrmQuarkList quarks,
+ FILE *stream)
+{
+ Bool firstNameSeen;
+
+ for (firstNameSeen = False; *quarks; quarks++) {
+ if (firstNameSeen) {
+ (void) fprintf(stream, ".");
+ }
+ firstNameSeen = True;
+ (void) fputs(XrmQuarkToString(*quarks), stream);
+ }
+} /* PrintQuarkList */
+
+#endif /* DEBUG */
+
+
+/*
+ * Fallback methods for Xrm parsing.
+ * Simulate a C locale. No state needed here.
+ */
+
+static void
+c_mbnoop(
+ XPointer state)
+{
+}
+
+static char
+c_mbchar(
+ XPointer state,
+ const char *str,
+ int *lenp)
+{
+ *lenp = 1;
+ return *str;
+}
+
+static const char *
+c_lcname(
+ XPointer state)
+{
+ return "C";
+}
+
+static const XrmMethodsRec mb_methods = {
+ c_mbnoop, /* mbinit */
+ c_mbchar, /* mbchar */
+ c_mbnoop, /* mbfinish */
+ c_lcname, /* lcname */
+ c_mbnoop /* destroy */
+};
+
+
+static XrmDatabase NewDatabase(void)
+{
+ register XrmDatabase db;
+
+ db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec));
+ if (db) {
+ _XCreateMutex(&db->linfo);
+ db->table = (NTable)NULL;
+ db->mbstate = (XPointer)NULL;
+ db->methods = _XrmInitParseInfo(&db->mbstate);
+ if (!db->methods)
+ db->methods = &mb_methods;
+ }
+ return db;
+}
+
+/* move all values from ftable to ttable, and free ftable's buckets.
+ * ttable is quaranteed empty to start with.
+ */
+static void MoveValues(
+ LTable ftable,
+ register LTable ttable)
+{
+ register VEntry fentry, nfentry;
+ register VEntry *prev;
+ register VEntry *bucket;
+ register VEntry tentry;
+ register int i;
+
+ for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) {
+ for (fentry = *bucket++; fentry; fentry = nfentry) {
+ prev = &LeafHash(ttable, fentry->name);
+ tentry = *prev;
+ *prev = fentry;
+ /* chain on all with same name, to preserve invariant order */
+ while ((nfentry = fentry->next) && nfentry->name == fentry->name)
+ fentry = nfentry;
+ fentry->next = tentry;
+ }
+ }
+ Xfree((char *)ftable->buckets);
+}
+
+/* move all tables from ftable to ttable, and free ftable.
+ * ttable is quaranteed empty to start with.
+ */
+static void MoveTables(
+ NTable ftable,
+ register NTable ttable)
+{
+ register NTable fentry, nfentry;
+ register NTable *prev;
+ register NTable *bucket;
+ register NTable tentry;
+ register int i;
+
+ for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) {
+ for (fentry = *bucket++; fentry; fentry = nfentry) {
+ prev = &NodeHash(ttable, fentry->name);
+ tentry = *prev;
+ *prev = fentry;
+ /* chain on all with same name, to preserve invariant order */
+ while ((nfentry = fentry->next) && nfentry->name == fentry->name)
+ fentry = nfentry;
+ fentry->next = tentry;
+ }
+ }
+ Xfree((char *)ftable);
+}
+
+/* grow the table, based on current number of entries */
+static void GrowTable(
+ NTable *prev)
+{
+ register NTable table;
+ register int i;
+
+ table = *prev;
+ i = table->mask;
+ if (i == 255) /* biggest it gets */
+ return;
+ while (i < 255 && GrowthPred(table->entries, i))
+ i = (i << 1) + 1;
+ i++; /* i is now the new size */
+ if (table->leaf) {
+ register LTable ltable;
+ LTableRec otable;
+
+ ltable = (LTable)table;
+ /* cons up a copy to make MoveValues look symmetric */
+ otable = *ltable;
+ ltable->buckets = Xcalloc(i, sizeof(VEntry));
+ if (!ltable->buckets) {
+ ltable->buckets = otable.buckets;
+ return;
+ }
+ ltable->table.mask = i - 1;
+ MoveValues(&otable, ltable);
+ } else {
+ register NTable ntable;
+
+ ntable = Xcalloc(1, sizeof(NTableRec) + (i * sizeof(NTable)));
+ if (!ntable)
+ return;
+ *ntable = *table;
+ ntable->mask = i - 1;
+ *prev = ntable;
+ MoveTables(table, ntable);
+ }
+}
+
+/* merge values from ftable into *pprev, destroy ftable in the process */
+static void MergeValues(
+ LTable ftable,
+ NTable *pprev,
+ Bool override)
+{
+ register VEntry fentry, tentry;
+ register VEntry *prev;
+ register LTable ttable;
+ VEntry *bucket;
+ int i;
+ register XrmQuark q;
+
+ ttable = (LTable)*pprev;
+ if (ftable->table.hasloose)
+ ttable->table.hasloose = 1;
+ for (i = ftable->table.mask, bucket = ftable->buckets;
+ i >= 0;
+ i--, bucket++) {
+ for (fentry = *bucket; fentry; ) {
+ q = fentry->name;
+ prev = &LeafHash(ttable, q);
+ tentry = *prev;
+ while (tentry && tentry->name != q)
+ tentry = *(prev = &tentry->next);
+ /* note: test intentionally uses fentry->name instead of q */
+ /* permits serendipitous inserts */
+ while (tentry && tentry->name == fentry->name) {
+ /* if tentry is earlier, skip it */
+ if (!fentry->tight && tentry->tight) {
+ tentry = *(prev = &tentry->next);
+ continue;
+ }
+ if (fentry->tight != tentry->tight) {
+ /* no match, chain in fentry */
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->table.entries++;
+ } else if (override) {
+ /* match, chain in fentry, splice out and free tentry */
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry->next;
+ /* free the overridden entry */
+ Xfree((char *)tentry);
+ /* get next tentry */
+ tentry = *prev;
+ } else {
+ /* match, discard fentry */
+ prev = &tentry->next;
+ tentry = fentry; /* use as a temp var */
+ fentry = fentry->next;
+ /* free the overpowered entry */
+ Xfree((char *)tentry);
+ /* get next tentry */
+ tentry = *prev;
+ }
+ if (!fentry)
+ break;
+ }
+ /* at this point, tentry cannot match any fentry named q */
+ /* chain in all bindings together, preserve invariant order */
+ while (fentry && fentry->name == q) {
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->table.entries++;
+ }
+ }
+ }
+ Xfree((char *)ftable->buckets);
+ Xfree((char *)ftable);
+ /* resize if necessary, now that we're all done */
+ GROW(pprev);
+}
+
+/* merge tables from ftable into *pprev, destroy ftable in the process */
+static void MergeTables(
+ NTable ftable,
+ NTable *pprev,
+ Bool override)
+{
+ register NTable fentry, tentry;
+ NTable nfentry;
+ register NTable *prev;
+ register NTable ttable;
+ NTable *bucket;
+ int i;
+ register XrmQuark q;
+
+ ttable = *pprev;
+ if (ftable->hasloose)
+ ttable->hasloose = 1;
+ if (ftable->hasany)
+ ttable->hasany = 1;
+ for (i = ftable->mask, bucket = NodeBuckets(ftable);
+ i >= 0;
+ i--, bucket++) {
+ for (fentry = *bucket; fentry; ) {
+ q = fentry->name;
+ prev = &NodeHash(ttable, q);
+ tentry = *prev;
+ while (tentry && tentry->name != q)
+ tentry = *(prev = &tentry->next);
+ /* note: test intentionally uses fentry->name instead of q */
+ /* permits serendipitous inserts */
+ while (tentry && tentry->name == fentry->name) {
+ /* if tentry is earlier, skip it */
+ if ((fentry->leaf && !tentry->leaf) ||
+ (!fentry->tight && tentry->tight &&
+ (fentry->leaf || !tentry->leaf))) {
+ tentry = *(prev = &tentry->next);
+ continue;
+ }
+ nfentry = fentry->next;
+ if (fentry->leaf != tentry->leaf ||
+ fentry->tight != tentry->tight) {
+ /* no match, just chain in */
+ *prev = fentry;
+ *(prev = &fentry->next) = tentry;
+ ttable->entries++;
+ } else {
+ if (fentry->leaf)
+ MergeValues((LTable)fentry, prev, override);
+ else
+ MergeTables(fentry, prev, override);
+ /* bump to next tentry */
+ tentry = *(prev = &(*prev)->next);
+ }
+ /* bump to next fentry */
+ fentry = nfentry;
+ if (!fentry)
+ break;
+ }
+ /* at this point, tentry cannot match any fentry named q */
+ /* chain in all bindings together, preserve invariant order */
+ while (fentry && fentry->name == q) {
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->entries++;
+ }
+ }
+ }
+ Xfree((char *)ftable);
+ /* resize if necessary, now that we're all done */
+ GROW(pprev);
+}
+
+void XrmCombineDatabase(
+ XrmDatabase from, XrmDatabase *into,
+ Bool override)
+{
+ register NTable *prev;
+ register NTable ftable, ttable, nftable;
+
+ if (!*into) {
+ *into = from;
+ } else if (from) {
+ _XLockMutex(&from->linfo);
+ _XLockMutex(&(*into)->linfo);
+ if ((ftable = from->table)) {
+ prev = &(*into)->table;
+ ttable = *prev;
+ if (!ftable->leaf) {
+ nftable = ftable->next;
+ if (ttable && !ttable->leaf) {
+ /* both have node tables, merge them */
+ MergeTables(ftable, prev, override);
+ /* bump to into's leaf table, if any */
+ ttable = *(prev = &(*prev)->next);
+ } else {
+ /* into has no node table, link from's in */
+ *prev = ftable;
+ *(prev = &ftable->next) = ttable;
+ }
+ /* bump to from's leaf table, if any */
+ ftable = nftable;
+ } else {
+ /* bump to into's leaf table, if any */
+ if (ttable && !ttable->leaf)
+ ttable = *(prev = &ttable->next);
+ }
+ if (ftable) {
+ /* if into has a leaf, merge, else insert */
+ if (ttable)
+ MergeValues((LTable)ftable, prev, override);
+ else
+ *prev = ftable;
+ }
+ }
+ (from->methods->destroy)(from->mbstate);
+ _XUnlockMutex(&from->linfo);
+ _XFreeMutex(&from->linfo);
+ Xfree((char *)from);
+ _XUnlockMutex(&(*into)->linfo);
+ }
+}
+
+void XrmMergeDatabases(
+ XrmDatabase from, XrmDatabase *into)
+{
+ XrmCombineDatabase(from, into, True);
+}
+
+/* store a value in the database, overriding any existing entry */
+static void PutEntry(
+ XrmDatabase db,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation type,
+ XrmValuePtr value)
+{
+ register NTable *pprev, *prev;
+ register NTable table;
+ register XrmQuark q;
+ register VEntry *vprev;
+ register VEntry entry;
+ NTable *nprev, *firstpprev;
+
+#define NEWTABLE(q,i) \
+ table = (NTable)Xmalloc(sizeof(LTableRec)); \
+ if (!table) \
+ return; \
+ table->name = q; \
+ table->hasloose = 0; \
+ table->hasany = 0; \
+ table->mask = 0; \
+ table->entries = 0; \
+ if (quarks[i]) { \
+ table->leaf = 0; \
+ nprev = NodeBuckets(table); \
+ } else { \
+ table->leaf = 1; \
+ if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) {\
+ Xfree(table); \
+ return; \
+ } \
+ ((LTable)table)->buckets = (VEntry *)nprev; \
+ } \
+ *nprev = (NTable)NULL; \
+ table->next = *prev; \
+ *prev = table
+
+ if (!db || !*quarks)
+ return;
+ table = *(prev = &db->table);
+ /* if already at leaf, bump to the leaf table */
+ if (!quarks[1] && table && !table->leaf)
+ table = *(prev = &table->next);
+ pprev = prev;
+ if (!table || (quarks[1] && table->leaf)) {
+ /* no top-level node table, create one and chain it in */
+ NEWTABLE(NULLQUARK,1);
+ table->tight = 1; /* arbitrary */
+ prev = nprev;
+ } else {
+ /* search along until we need a value */
+ while (quarks[1]) {
+ q = *quarks;
+ table = *(prev = &NodeHash(table, q));
+ while (table && table->name != q)
+ table = *(prev = &table->next);
+ if (!table)
+ break; /* not found */
+ if (quarks[2]) {
+ if (table->leaf)
+ break; /* not found */
+ } else {
+ if (!table->leaf) {
+ /* bump to leaf table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q)
+ break; /* not found */
+ if (!table->leaf) {
+ /* bump to leaf table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q)
+ break; /* not found */
+ }
+ }
+ }
+ if (*bindings == XrmBindTightly) {
+ if (!table->tight)
+ break; /* not found */
+ } else {
+ if (table->tight) {
+ /* bump to loose table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q ||
+ !quarks[2] != table->leaf)
+ break; /* not found */
+ }
+ }
+ /* found that one, bump to next quark */
+ pprev = prev;
+ quarks++;
+ bindings++;
+ }
+ if (!quarks[1]) {
+ /* found all the way to a leaf */
+ q = *quarks;
+ entry = *(vprev = &LeafHash((LTable)table, q));
+ while (entry && entry->name != q)
+ entry = *(vprev = &entry->next);
+ /* if want loose and have tight, bump to next entry */
+ if (entry && *bindings == XrmBindLoosely && entry->tight)
+ entry = *(vprev = &entry->next);
+ if (entry && entry->name == q &&
+ (*bindings == XrmBindTightly) == entry->tight) {
+ /* match, need to override */
+ if ((type == XrmQString) == entry->string &&
+ entry->size == value->size) {
+ /* update type if not String, can be different */
+ if (!entry->string)
+ RepType(entry) = type;
+ /* identical size, just overwrite value */
+ memcpy(RawValue(entry), (char *)value->addr, value->size);
+ return;
+ }
+ /* splice out and free old entry */
+ *vprev = entry->next;
+ Xfree((char *)entry);
+ (*pprev)->entries--;
+ }
+ /* this is where to insert */
+ prev = (NTable *)vprev;
+ }
+ }
+ /* keep the top table, because we may have to grow it */
+ firstpprev = pprev;
+ /* iterate until we get to the leaf */
+ while (quarks[1]) {
+ /* build a new table and chain it in */
+ NEWTABLE(*quarks,2);
+ if (*quarks++ == XrmQANY)
+ (*pprev)->hasany = 1;
+ if (*bindings++ == XrmBindTightly) {
+ table->tight = 1;
+ } else {
+ table->tight = 0;
+ (*pprev)->hasloose = 1;
+ }
+ (*pprev)->entries++;
+ pprev = prev;
+ prev = nprev;
+ }
+ /* now allocate the value entry */
+ entry = (VEntry)Xmalloc(((type == XrmQString) ?
+ sizeof(VEntryRec) : sizeof(DEntryRec)) +
+ value->size);
+ if (!entry)
+ return;
+ entry->name = q = *quarks;
+ if (*bindings == XrmBindTightly) {
+ entry->tight = 1;
+ } else {
+ entry->tight = 0;
+ (*pprev)->hasloose = 1;
+ }
+ /* chain it in, with a bit of type cast ugliness */
+ entry->next = *((VEntry *)prev);
+ *((VEntry *)prev) = entry;
+ entry->size = value->size;
+ if (type == XrmQString) {
+ entry->string = 1;
+ } else {
+ entry->string = 0;
+ RepType(entry) = type;
+ }
+ /* save a copy of the value */
+ memcpy(RawValue(entry), (char *)value->addr, value->size);
+ (*pprev)->entries++;
+ /* this is a new leaf, need to remember it for search lists */
+ if (q > maxResourceQuark) {
+ unsigned oldsize = (maxResourceQuark + 1) >> 3;
+ unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */
+ if (resourceQuarks) {
+ unsigned char *prevQuarks = resourceQuarks;
+
+ resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks,
+ size);
+ if (!resourceQuarks) {
+ Xfree(prevQuarks);
+ }
+ } else
+ resourceQuarks = (unsigned char *)Xmalloc(size);
+ if (resourceQuarks) {
+ bzero((char *)&resourceQuarks[oldsize], size - oldsize);
+ maxResourceQuark = (size << 3) - 1;
+ } else {
+ maxResourceQuark = -1;
+ }
+ }
+ if (q > 0 && resourceQuarks)
+ resourceQuarks[q >> 3] |= 1 << (q & 0x7);
+ GROW(firstpprev);
+
+#undef NEWTABLE
+}
+
+void XrmQPutResource(
+ XrmDatabase *pdb,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation type,
+ XrmValuePtr value)
+{
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, type, value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+void
+XrmPutResource(
+ XrmDatabase *pdb,
+ _Xconst char *specifier,
+ _Xconst char *type,
+ XrmValuePtr value)
+{
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ XrmStringToBindingQuarkList(specifier, bindings, quarks);
+ PutEntry(*pdb, bindings, quarks, XrmStringToQuark(type), value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+void
+XrmQPutStringResource(
+ XrmDatabase *pdb,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ _Xconst char *str)
+{
+ XrmValue value;
+
+ if (!*pdb) *pdb = NewDatabase();
+ value.addr = (XPointer) str;
+ value.size = strlen(str)+1;
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, XrmQString, &value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+/* Function Name: GetDatabase
+ * Description: Parses a string and stores it as a database.
+ * Arguments: db - the database.
+ * str - a pointer to the string containing the database.
+ * filename - source filename, if any.
+ * doall - whether to do all lines or just one
+ */
+
+/*
+ * This function is highly optimized to inline as much as possible.
+ * Be very careful with modifications, or simplifications, as they
+ * may adversely affect the performance.
+ *
+ * Chris Peterson, MIT X Consortium 5/17/90.
+ */
+
+/*
+ * Xlib spec says max 100 quarks in a lookup, will stop and return if
+ * return if any single production's lhs has more than 100 components.
+ */
+#define QLIST_SIZE 100
+
+/*
+ * This should be big enough to handle things like the XKeysymDB or biggish
+ * ~/.Xdefaults or app-defaults files. Anything bigger will be allocated on
+ * the heap.
+ */
+#define DEF_BUFF_SIZE 8192
+
+static void GetIncludeFile(
+ XrmDatabase db,
+ _Xconst char *base,
+ _Xconst char *fname,
+ int fnamelen);
+
+static void GetDatabase(
+ XrmDatabase db,
+ _Xconst register char *str,
+ _Xconst char *filename,
+ Bool doall)
+{
+ char *rhs;
+ char *lhs, lhs_s[DEF_BUFF_SIZE];
+ XrmQuark quarks[QLIST_SIZE + 1]; /* allow for a terminal NullQuark */
+ XrmBinding bindings[QLIST_SIZE + 1];
+
+ register char *ptr;
+ register XrmBits bits = 0;
+ register char c;
+ register Signature sig;
+ register char *ptr_max;
+ register int num_quarks;
+ register XrmBindingList t_bindings;
+
+ int len, alloc_chars;
+ unsigned long str_len;
+ XrmValue value;
+ Bool only_pcs;
+ Bool dolines;
+
+ if (!db)
+ return;
+
+ /*
+ * if strlen (str) < DEF_BUFF_SIZE allocate buffers on the stack for
+ * speed otherwise malloc the buffer. From a buffer overflow standpoint
+ * we can be sure that neither: a) a component on the lhs, or b) a
+ * value on the rhs, will be longer than the overall length of str,
+ * i.e. strlen(str).
+ *
+ * This should give good performance when parsing "*foo: bar" type
+ * databases as might be passed with -xrm command line options; but
+ * with larger databases, e.g. .Xdefaults, app-defaults, or KeysymDB
+ * files, the size of the buffers will be overly large. One way
+ * around this would be to double-parse each production with a resulting
+ * performance hit. In any event we can be assured that a lhs component
+ * name or a rhs value won't be longer than str itself.
+ */
+
+ str_len = strlen (str);
+ if (DEF_BUFF_SIZE > str_len) lhs = lhs_s;
+ else if ((lhs = (char*) Xmalloc (str_len)) == NULL)
+ return;
+
+ alloc_chars = DEF_BUFF_SIZE < str_len ? str_len : DEF_BUFF_SIZE;
+ if ((rhs = (char*) Xmalloc (alloc_chars)) == NULL) {
+ if (lhs != lhs_s) Xfree (lhs);
+ return;
+ }
+
+ (*db->methods->mbinit)(db->mbstate);
+ str--;
+ dolines = True;
+ while (!is_EOF(bits) && dolines) {
+ dolines = doall;
+
+ /*
+ * First: Remove extra whitespace.
+ */
+
+ do {
+ bits = next_char(c, str);
+ } while is_space(bits);
+
+ /*
+ * Ignore empty lines.
+ */
+
+ if (is_EOL(bits))
+ continue; /* start a new line. */
+
+ /*
+ * Second: check the first character in a line to see if it is
+ * "!" signifying a comment, or "#" signifying a directive.
+ */
+
+ if (c == '!') { /* Comment, spin to next newline */
+ while (is_simple(bits = next_char(c, str))) {}
+ if (is_EOL(bits))
+ continue;
+ while (!is_EOL(bits = next_mbchar(c, len, str))) {}
+ str--;
+ continue; /* start a new line. */
+ }
+
+ if (c == '#') { /* Directive */
+ /* remove extra whitespace */
+ only_pcs = True;
+ while (is_space(bits = next_char(c, str))) {};
+ /* only "include" directive is currently defined */
+ if (!strncmp(str, "include", 7)) {
+ str += (7-1);
+ /* remove extra whitespace */
+ while (is_space(bits = next_char(c, str))) {};
+ /* must have a starting " */
+ if (c == '"') {
+ _Xconst char *fname = str+1;
+ len = 0;
+ do {
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ } while (c != '"' && !is_EOL(bits));
+ /* must have an ending " */
+ if (c == '"')
+ GetIncludeFile(db, filename, fname, str - len - fname);
+ }
+ }
+ /* spin to next newline */
+ if (only_pcs) {
+ while (is_simple(bits))
+ bits = next_char(c, str);
+ if (is_EOL(bits))
+ continue;
+ }
+ while (!is_EOL(bits))
+ bits = next_mbchar(c, len, str);
+ str--;
+ continue; /* start a new line. */
+ }
+
+ /*
+ * Third: loop through the LHS of the resource specification
+ * storing characters and converting this to a Quark.
+ */
+
+ num_quarks = 0;
+ t_bindings = bindings;
+
+ sig = 0;
+ ptr = lhs;
+ *t_bindings = XrmBindTightly;
+ for(;;) {
+ if (!is_binding(bits)) {
+ while (!is_EOQ(bits)) {
+ *ptr++ = c;
+ sig = (sig << 1) + c; /* Compute the signature. */
+ bits = next_char(c, str);
+ }
+
+ quarks[num_quarks++] =
+ _XrmInternalStringToQuark(lhs, ptr - lhs, sig, False);
+
+ if (num_quarks > QLIST_SIZE) {
+ Xfree(rhs);
+ if (lhs != lhs_s) Xfree (lhs);
+ (*db->methods->mbfinish)(db->mbstate);
+ return;
+ }
+
+ if (is_separator(bits)) {
+ if (!is_space(bits))
+ break;
+
+ /* Remove white space */
+ do {
+ *ptr++ = c;
+ sig = (sig << 1) + c; /* Compute the signature. */
+ } while (is_space(bits = next_char(c, str)));
+
+ /*
+ * The spec doesn't permit it, but support spaces
+ * internal to resource name/class
+ */
+
+ if (is_separator(bits))
+ break;
+ num_quarks--;
+ continue;
+ }
+
+ if (c == '.')
+ *(++t_bindings) = XrmBindTightly;
+ else
+ *(++t_bindings) = XrmBindLoosely;
+
+ sig = 0;
+ ptr = lhs;
+ }
+ else {
+ /*
+ * Magic unspecified feature #254.
+ *
+ * If two separators appear with no Text between them then
+ * ignore them.
+ *
+ * If anyone of those separators is a '*' then the binding
+ * will be loose, otherwise it will be tight.
+ */
+
+ if (c == '*')
+ *t_bindings = XrmBindLoosely;
+ }
+
+ bits = next_char(c, str);
+ }
+
+ quarks[num_quarks] = NULLQUARK;
+
+ /*
+ * Make sure that there is a ':' in this line.
+ */
+
+ if (c != ':') {
+ char oldc;
+
+ /*
+ * A parsing error has occured, toss everything on the line
+ * a new_line can still be escaped with a '\'.
+ */
+
+ while (is_normal(bits))
+ bits = next_char(c, str);
+ if (is_EOL(bits))
+ continue;
+ bits = next_mbchar(c, len, str);
+ do {
+ oldc = c;
+ bits = next_mbchar(c, len, str);
+ } while (c && (c != '\n' || oldc == '\\'));
+ str--;
+ continue;
+ }
+
+ /*
+ * I now have a quark and binding list for the entire left hand
+ * side. "c" currently points to the ":" separating the left hand
+ * side for the right hand side. It is time to begin processing
+ * the right hand side.
+ */
+
+ /*
+ * Fourth: Remove more whitespace
+ */
+
+ for(;;) {
+ if (is_space(bits = next_char(c, str)))
+ continue;
+ if (c != '\\')
+ break;
+ bits = next_char(c, str);
+ if (c == '\n')
+ continue;
+ str--;
+ bits = BSLASH;
+ c = '\\';
+ break;
+ }
+
+ /*
+ * Fifth: Process the right hand side.
+ */
+
+ ptr = rhs;
+ ptr_max = ptr + alloc_chars - 4;
+ only_pcs = True;
+ len = 1;
+
+ for(;;) {
+
+ /*
+ * Tight loop for the normal case: Non backslash, non-end of value
+ * character that will fit into the allocated buffer.
+ */
+
+ if (only_pcs) {
+ while (is_normal(bits) && ptr < ptr_max) {
+ *ptr++ = c;
+ bits = next_char(c, str);
+ }
+ if (is_EOL(bits))
+ break;
+ if (is_nonpcs(bits)) {
+ only_pcs = False;
+ bits = next_mbchar(c, len, str);
+ }
+ }
+ while (!is_special(bits) && ptr + len <= ptr_max) {
+ len = -len;
+ while (len)
+ *ptr++ = str[len++];
+ if (*str == '\0') {
+ bits = EOS;
+ break;
+ }
+ bits = next_mbchar(c, len, str);
+ }
+
+ if (is_EOL(bits)) {
+ str--;
+ break;
+ }
+
+ if (c == '\\') {
+ /*
+ * We need to do some magic after a backslash.
+ */
+ Bool read_next = True;
+
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+
+ if (is_EOL(bits)) {
+ if (is_EOF(bits))
+ continue;
+ } else if (c == 'n') {
+ /*
+ * "\n" means insert a newline.
+ */
+ *ptr++ = '\n';
+ } else if (c == '\\') {
+ /*
+ * "\\" completes to just one backslash.
+ */
+ *ptr++ = '\\';
+ } else {
+ /*
+ * pick up to three octal digits after the '\'.
+ */
+ char temp[3];
+ int count = 0;
+ while (is_odigit(bits) && count < 3) {
+ temp[count++] = c;
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ }
+
+ /*
+ * If we found three digits then insert that octal code
+ * into the value string as a character.
+ */
+
+ if (count == 3) {
+ *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 +
+ (temp[1] - '0') * 010 +
+ (temp[2] - '0'));
+ }
+ else {
+ int tcount;
+
+ /*
+ * Otherwise just insert those characters into the
+ * string, since no special processing is needed on
+ * numerics we can skip the special processing.
+ */
+
+ for (tcount = 0; tcount < count; tcount++) {
+ *ptr++ = temp[tcount]; /* print them in
+ the correct order */
+ }
+ }
+ read_next = False;
+ }
+ if (read_next) {
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ }
+ }
+
+ /*
+ * It is important to make sure that there is room for at least
+ * four more characters in the buffer, since I can add that
+ * many characters into the buffer after a backslash has occured.
+ */
+
+ if (ptr + len > ptr_max) {
+ char * temp_str;
+
+ alloc_chars += BUFSIZ/10;
+ temp_str = Xrealloc(rhs, sizeof(char) * alloc_chars);
+
+ if (!temp_str) {
+ Xfree(rhs);
+ if (lhs != lhs_s) Xfree (lhs);
+ (*db->methods->mbfinish)(db->mbstate);
+ return;
+ }
+
+ ptr = temp_str + (ptr - rhs); /* reset pointer. */
+ rhs = temp_str;
+ ptr_max = rhs + alloc_chars - 4;
+ }
+ }
+
+ /*
+ * Lastly: Terminate the value string, and store this entry
+ * into the database.
+ */
+
+ *ptr++ = '\0';
+
+ /* Store it in database */
+ value.size = ptr - rhs;
+ value.addr = (XPointer) rhs;
+
+ PutEntry(db, bindings, quarks, XrmQString, &value);
+ }
+
+ if (lhs != lhs_s) Xfree (lhs);
+ Xfree (rhs);
+
+ (*db->methods->mbfinish)(db->mbstate);
+}
+
+void
+XrmPutStringResource(
+ XrmDatabase *pdb,
+ _Xconst char*specifier,
+ _Xconst char*str)
+{
+ XrmValue value;
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+
+ if (!*pdb) *pdb = NewDatabase();
+ XrmStringToBindingQuarkList(specifier, bindings, quarks);
+ value.addr = (XPointer) str;
+ value.size = strlen(str)+1;
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, XrmQString, &value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+
+void
+XrmPutLineResource(
+ XrmDatabase *pdb,
+ _Xconst char*line)
+{
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ GetDatabase(*pdb, line, (char *)NULL, False);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+XrmDatabase
+XrmGetStringDatabase(
+ _Xconst char *data)
+{
+ XrmDatabase db;
+
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, data, (char *)NULL, True);
+ _XUnlockMutex(&db->linfo);
+ return db;
+}
+
+/* Function Name: ReadInFile
+ * Description: Reads the file into a buffer.
+ * Arguments: filename - the name of the file.
+ * Returns: An allocated string containing the contents of the file.
+ */
+
+static char *
+ReadInFile(_Xconst char *filename)
+{
+ register int fd, size;
+ char * filebuf;
+
+#ifdef __UNIXOS2__
+ filename = __XOS2RedirRoot(filename);
+#endif
+
+ /*
+ * MS-Windows and OS/2 note: Default open mode includes O_TEXT
+ */
+ if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 )
+ return (char *)NULL;
+
+ /*
+ * MS-Windows and OS/2 note: depending on how the sources are
+ * untarred, the newlines in resource files may or may not have
+ * been expanded to CRLF. Either way the size returned by fstat
+ * is sufficient to read the file into because in text-mode any
+ * CRLFs in a file will be converted to newlines (LF) with the
+ * result that the number of bytes actually read with be <=
+ * to the size returned by fstat.
+ */
+ {
+ struct stat status_buffer;
+ if ( (fstat(fd, &status_buffer)) == -1 ) {
+ close (fd);
+ return (char *)NULL;
+ } else
+ size = status_buffer.st_size;
+ }
+
+ if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */
+ close(fd);
+ return (char *)NULL;
+ }
+ size = read (fd, filebuf, size);
+
+#ifdef __UNIXOS2__
+ { /* kill CRLF */
+ int i,k;
+ for (i=k=0; i<size; i++)
+ if (filebuf[i] != 0x0d) {
+ filebuf[k++] = filebuf[i];
+ }
+ filebuf[k] = 0;
+ }
+#endif
+
+ if (size < 0) {
+ close (fd);
+ Xfree(filebuf);
+ return (char *)NULL;
+ }
+ close (fd);
+
+ filebuf[size] = '\0'; /* NULL terminate it. */
+ return filebuf;
+}
+
+static void
+GetIncludeFile(
+ XrmDatabase db,
+ _Xconst char *base,
+ _Xconst char *fname,
+ int fnamelen)
+{
+ int len;
+ char *str;
+ char realfname[BUFSIZ];
+
+ if (fnamelen <= 0 || fnamelen >= BUFSIZ)
+ return;
+ if (*fname != '/' && base && (str = strrchr(base, '/'))) {
+ len = str - base + 1;
+ if (len + fnamelen >= BUFSIZ)
+ return;
+ strncpy(realfname, base, len);
+ strncpy(realfname + len, fname, fnamelen);
+ realfname[len + fnamelen] = '\0';
+ } else {
+ strncpy(realfname, fname, fnamelen);
+ realfname[fnamelen] = '\0';
+ }
+ if (!(str = ReadInFile(realfname)))
+ return;
+ GetDatabase(db, str, realfname, True);
+ Xfree(str);
+}
+
+XrmDatabase
+XrmGetFileDatabase(
+ _Xconst char *filename)
+{
+ XrmDatabase db;
+ char *str;
+
+ if (!(str = ReadInFile(filename)))
+ return (XrmDatabase)NULL;
+
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, str, filename, True);
+ _XUnlockMutex(&db->linfo);
+ Xfree(str);
+ return db;
+}
+
+Status
+XrmCombineFileDatabase(
+ _Xconst char *filename,
+ XrmDatabase *target,
+ Bool override)
+{
+ XrmDatabase db;
+ char *str;
+
+ if (!(str = ReadInFile(filename)))
+ return 0;
+ if (override) {
+ db = *target;
+ if (!db)
+ *target = db = NewDatabase();
+ } else
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, str, filename, True);
+ _XUnlockMutex(&db->linfo);
+ Xfree(str);
+ if (!override)
+ XrmCombineDatabase(db, target, False);
+ return 1;
+}
+
+/* call the user proc for every value in the table, arbitrary order.
+ * stop if user proc returns True. level is current depth in database.
+ */
+/*ARGSUSED*/
+static Bool EnumLTable(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ register EClosure closure)
+{
+ register VEntry *bucket;
+ register int i;
+ register VEntry entry;
+ XrmValue value;
+ XrmRepresentation type;
+ Bool tightOk;
+
+ closure->bindings[level] = (table->table.tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = table->table.name;
+ level++;
+ tightOk = !*names;
+ closure->quarks[level + 1] = NULLQUARK;
+ for (i = table->table.mask, bucket = table->buckets;
+ i >= 0;
+ i--, bucket++) {
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (entry->tight && !tightOk)
+ continue;
+ closure->bindings[level] = (entry->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = entry->name;
+ value.size = entry->size;
+ if (entry->string) {
+ type = XrmQString;
+ value.addr = StringValue(entry);
+ } else {
+ type = RepType(entry);
+ value.addr = DataValue(entry);
+ }
+ if ((*closure->proc)(&closure->db, closure->bindings+1,
+ closure->quarks+1, &type, &value,
+ closure->closure))
+ return True;
+ }
+ }
+ return False;
+}
+
+static Bool EnumAllNTable(
+ NTable table,
+ register int level,
+ register EClosure closure)
+{
+ register NTable *bucket;
+ register int i;
+ register NTable entry;
+ XrmQuark empty = NULLQUARK;
+
+ if (level >= MAXDBDEPTH)
+ return False;
+ for (i = table->mask, bucket = NodeBuckets(table);
+ i >= 0;
+ i--, bucket++) {
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (entry->leaf) {
+ if (EnumLTable((LTable)entry, &empty, &empty, level, closure))
+ return True;
+ } else {
+ closure->bindings[level] = (entry->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = entry->name;
+ if (EnumAllNTable(entry, level+1, closure))
+ return True;
+ }
+ }
+ }
+ return False;
+}
+
+/* recurse on every table in the table, arbitrary order.
+ * stop if user proc returns True. level is current depth in database.
+ */
+static Bool EnumNTable(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ register EClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ EClosure closure);
+ Bool bilevel;
+
+/* find entries named ename, leafness leaf, tight or loose, and call get */
+#define ITIGHTLOOSE(ename) \
+ NFIND(ename); \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if (!leaf && !entry->tight && entry->next && \
+ entry->next->name == q && entry->next->tight && \
+ (bilevel || entry->next->hasloose) && \
+ EnumLTable((LTable)entry->next, names+1, classes+1, \
+ level, closure)) \
+ return True; \
+ if ((*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && leaf == entry->leaf && \
+ (*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ } else if (entry->leaf) { \
+ if ((bilevel || entry->hasloose) && \
+ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && (bilevel || entry->hasloose) && \
+ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ } \
+ }
+
+/* find entries named ename, leafness leaf, loose only, and call get */
+#define ILOOSE(ename) \
+ NFIND(ename); \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (NTable)NULL; \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if ((*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ } else if (entry->leaf && (bilevel || entry->hasloose)) { \
+ if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ } \
+ }
+
+ if (level >= MAXDBDEPTH)
+ return False;
+ closure->bindings[level] = (table->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = table->name;
+ level++;
+ if (!*names) {
+ if (EnumAllNTable(table, level, closure))
+ return True;
+ } else {
+ if (names[1] || closure->mode == XrmEnumAllLevels) {
+ get = EnumNTable; /* recurse */
+ leaf = 0;
+ bilevel = !names[1];
+ } else {
+ get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
+ leaf = 1;
+ bilevel = False;
+ }
+ if (table->hasloose && closure->mode == XrmEnumAllLevels) {
+ NTable *bucket;
+ int i;
+ XrmQuark empty = NULLQUARK;
+
+ for (i = table->mask, bucket = NodeBuckets(table);
+ i >= 0;
+ i--, bucket++) {
+ q = NULLQUARK;
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (!entry->tight && entry->name != q &&
+ entry->name != *names && entry->name != *classes) {
+ q = entry->name;
+ if (entry->leaf) {
+ if (EnumLTable((LTable)entry, &empty, &empty,
+ level, closure))
+ return True;
+ } else {
+ if (EnumNTable(entry, &empty, &empty,
+ level, closure))
+ return True;
+ }
+ }
+ }
+ }
+ }
+
+ ITIGHTLOOSE(*names); /* do name, tight and loose */
+ ITIGHTLOOSE(*classes); /* do class, tight and loose */
+ if (table->hasany) {
+ ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!*names)
+ break;
+ if (!names[1] && closure->mode != XrmEnumAllLevels) {
+ get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
+ leaf = 1;
+ }
+ ILOOSE(*names); /* loose names */
+ ILOOSE(*classes); /* loose classes */
+ if (table->hasany) {
+ ILOOSE(XrmQANY); /* loose ANY */
+ }
+ }
+ names--;
+ classes--;
+ }
+ }
+ /* now look for matching leaf nodes */
+ entry = table->next;
+ if (!entry)
+ return False;
+ if (entry->leaf) {
+ if (entry->tight && !table->tight)
+ entry = entry->next;
+ } else {
+ entry = entry->next;
+ if (!entry || !entry->tight)
+ return False;
+ }
+ if (!entry || entry->name != table->name)
+ return False;
+ /* found one */
+ level--;
+ if ((!*names || entry->hasloose) &&
+ EnumLTable((LTable)entry, names, classes, level, closure))
+ return True;
+ if (entry->tight && entry == table->next && (entry = entry->next) &&
+ entry->name == table->name && (!*names || entry->hasloose))
+ return EnumLTable((LTable)entry, names, classes, level, closure);
+ return False;
+
+#undef ITIGHTLOOSE
+#undef ILOOSE
+}
+
+/* call the proc for every value in the database, arbitrary order.
+ * stop if the proc returns True.
+ */
+Bool XrmEnumerateDatabase(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ int mode,
+ DBEnumProc proc,
+ XPointer closure)
+{
+ XrmBinding bindings[MAXDBDEPTH+2];
+ XrmQuark quarks[MAXDBDEPTH+2];
+ register NTable table;
+ EClosureRec eclosure;
+ Bool retval = False;
+
+ if (!db)
+ return False;
+ _XLockMutex(&db->linfo);
+ eclosure.db = db;
+ eclosure.proc = proc;
+ eclosure.closure = closure;
+ eclosure.bindings = bindings;
+ eclosure.quarks = quarks;
+ eclosure.mode = mode;
+ table = db->table;
+ if (table && !table->leaf && !*names && mode == XrmEnumOneLevel)
+ table = table->next;
+ if (table) {
+ if (!table->leaf)
+ retval = EnumNTable(table, names, classes, 0, &eclosure);
+ else
+ retval = EnumLTable((LTable)table, names, classes, 0, &eclosure);
+ }
+ _XUnlockMutex(&db->linfo);
+ return retval;
+}
+
+static void PrintBindingQuarkList(
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ FILE *stream)
+{
+ Bool firstNameSeen;
+
+ for (firstNameSeen = False; *quarks; bindings++, quarks++) {
+ if (*bindings == XrmBindLoosely) {
+ (void) fprintf(stream, "*");
+ } else if (firstNameSeen) {
+ (void) fprintf(stream, ".");
+ }
+ firstNameSeen = True;
+ (void) fputs(XrmQuarkToString(*quarks), stream);
+ }
+}
+
+/* output out the entry in correct file syntax */
+/*ARGSUSED*/
+static Bool DumpEntry(
+ XrmDatabase *db,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation *type,
+ XrmValuePtr value,
+ XPointer data)
+{
+ FILE *stream = (FILE *)data;
+ register unsigned int i;
+ register char *s;
+ register char c;
+
+ if (*type != XrmQString)
+ (void) putc('!', stream);
+ PrintBindingQuarkList(bindings, quarks, stream);
+ s = value->addr;
+ i = value->size;
+ if (*type == XrmQString) {
+ (void) fputs(":\t", stream);
+ if (i)
+ i--;
+ }
+ else
+ (void) fprintf(stream, "=%s:\t", XrmRepresentationToString(*type));
+ if (i && (*s == ' ' || *s == '\t'))
+ (void) putc('\\', stream); /* preserve leading whitespace */
+ while (i--) {
+ c = *s++;
+ if (c == '\n') {
+ if (i)
+ (void) fputs("\\n\\\n", stream);
+ else
+ (void) fputs("\\n", stream);
+ } else if (c == '\\')
+ (void) fputs("\\\\", stream);
+ else if ((c < ' ' && c != '\t') ||
+ ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0))
+ (void) fprintf(stream, "\\%03o", (unsigned char)c);
+ else
+ (void) putc(c, stream);
+ }
+ (void) putc('\n', stream);
+ return ferror(stream) != 0;
+}
+
+#ifdef DEBUG
+
+void PrintTable(
+ NTable table,
+ FILE *file)
+{
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+ EClosureRec closure;
+ XrmQuark empty = NULLQUARK;
+
+ closure.db = (XrmDatabase)NULL;
+ closure.proc = DumpEntry;
+ closure.closure = (XPointer)file;
+ closure.bindings = bindings;
+ closure.quarks = quarks;
+ closure.mode = XrmEnumAllLevels;
+ if (table->leaf)
+ EnumLTable((LTable)table, &empty, &empty, 0, &closure);
+ else
+ EnumNTable(table, &empty, &empty, 0, &closure);
+}
+
+#endif /* DEBUG */
+
+void
+XrmPutFileDatabase(
+ XrmDatabase db,
+ _Xconst char *fileName)
+{
+ FILE *file;
+ XrmQuark empty = NULLQUARK;
+
+ if (!db) return;
+ if (!(file = fopen(fileName, "w"))) return;
+ if (XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
+ DumpEntry, (XPointer) file))
+ unlink((char *)fileName);
+ fclose(file);
+}
+
+/* macros used in get/search functions */
+
+/* find entries named ename, leafness leaf, tight or loose, and call get */
+#define GTIGHTLOOSE(ename,looseleaf) \
+ NFIND(ename); \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if (!leaf && !entry->tight && entry->next && \
+ entry->next->name == q && entry->next->tight && \
+ entry->next->hasloose && \
+ looseleaf((LTable)entry->next, names+1, classes+1, closure)) \
+ return True; \
+ if ((*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && leaf == entry->leaf && \
+ (*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ } else if (entry->leaf) { \
+ if (entry->hasloose && \
+ looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && entry->hasloose && \
+ looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ } \
+ }
+
+/* find entries named ename, leafness leaf, loose only, and call get */
+#define GLOOSE(ename,looseleaf) \
+ NFIND(ename); \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (NTable)NULL; \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if ((*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ } else if (entry->leaf && entry->hasloose) { \
+ if (looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ } \
+ }
+
+/* add tight/loose entry to the search list, return True if list is full */
+/*ARGSUSED*/
+static Bool AppendLEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register SClosure closure)
+{
+ /* check for duplicate */
+ if (closure->idx >= 0 && closure->list[closure->idx] == table)
+ return False;
+ if (closure->idx == closure->limit)
+ return True;
+ /* append it */
+ closure->idx++;
+ closure->list[closure->idx] = table;
+ return False;
+}
+
+/* add loose entry to the search list, return True if list is full */
+/*ARGSUSED*/
+static Bool AppendLooseLEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register SClosure closure)
+{
+ /* check for duplicate */
+ if (closure->idx >= 0 && closure->list[closure->idx] == table)
+ return False;
+ if (closure->idx >= closure->limit - 1)
+ return True;
+ /* append it */
+ closure->idx++;
+ closure->list[closure->idx] = LOOSESEARCH;
+ closure->idx++;
+ closure->list[closure->idx] = table;
+ return False;
+}
+
+/* search for a leaf table */
+static Bool SearchNEntry(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure);
+
+ if (names[1]) {
+ get = SearchNEntry; /* recurse */
+ leaf = 0;
+ } else {
+ get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GTIGHTLOOSE(*names, AppendLooseLEntry); /* do name, tight and loose */
+ GTIGHTLOOSE(*classes, AppendLooseLEntry); /* do class, tight and loose */
+ if (table->hasany) {
+ GTIGHTLOOSE(XrmQANY, AppendLooseLEntry); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!*names)
+ break;
+ if (!names[1]) {
+ get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GLOOSE(*names, AppendLooseLEntry); /* loose names */
+ GLOOSE(*classes, AppendLooseLEntry); /* loose classes */
+ if (table->hasany) {
+ GLOOSE(XrmQANY, AppendLooseLEntry); /* loose ANY */
+ }
+ }
+ }
+ /* now look for matching leaf nodes */
+ entry = table->next;
+ if (!entry)
+ return False;
+ if (entry->leaf) {
+ if (entry->tight && !table->tight)
+ entry = entry->next;
+ } else {
+ entry = entry->next;
+ if (!entry || !entry->tight)
+ return False;
+ }
+ if (!entry || entry->name != table->name)
+ return False;
+ /* found one */
+ if (entry->hasloose &&
+ AppendLooseLEntry((LTable)entry, names, classes, closure))
+ return True;
+ if (entry->tight && entry == table->next && (entry = entry->next) &&
+ entry->name == table->name && entry->hasloose)
+ return AppendLooseLEntry((LTable)entry, names, classes, closure);
+ return False;
+}
+
+Bool XrmQGetSearchList(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ XrmSearchList searchList, /* RETURN */
+ int listLength)
+{
+ register NTable table;
+ SClosureRec closure;
+
+ if (listLength <= 0)
+ return False;
+ closure.list = (LTable *)searchList;
+ closure.idx = -1;
+ closure.limit = listLength - 2;
+ if (db) {
+ _XLockMutex(&db->linfo);
+ table = db->table;
+ if (*names) {
+ if (table && !table->leaf) {
+ if (SearchNEntry(table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ } else if (table && table->hasloose &&
+ AppendLooseLEntry((LTable)table, names, classes,
+ &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ } else {
+ if (table && !table->leaf)
+ table = table->next;
+ if (table &&
+ AppendLEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ }
+ _XUnlockMutex(&db->linfo);
+ }
+ closure.list[closure.idx + 1] = (LTable)NULL;
+ return True;
+}
+
+Bool XrmQGetSearchResource(
+ XrmSearchList searchList,
+ register XrmName name,
+ register XrmClass class,
+ XrmRepresentation *pType, /* RETURN */
+ XrmValue *pValue) /* RETURN */
+{
+ register LTable *list;
+ register LTable table;
+ register VEntry entry = NULL;
+ int flags;
+
+/* find tight or loose entry */
+#define VTIGHTLOOSE(q) \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry) \
+ break
+
+/* find loose entry */
+#define VLOOSE(q) \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry) { \
+ if (!entry->tight) \
+ break; \
+ if ((entry = entry->next) && entry->name == q) \
+ break; \
+ }
+
+ list = (LTable *)searchList;
+ /* figure out which combination of name and class we need to search for */
+ flags = 0;
+ if (IsResourceQuark(name))
+ flags = 2;
+ if (IsResourceQuark(class))
+ flags |= 1;
+ if (!flags) {
+ /* neither name nor class has ever been used to name a resource */
+ table = (LTable)NULL;
+ } else if (flags == 3) {
+ /* both name and class */
+ while ((table = *list++)) {
+ if (table != LOOSESEARCH) {
+ VTIGHTLOOSE(name); /* do name, tight and loose */
+ VTIGHTLOOSE(class); /* do class, tight and loose */
+ } else {
+ table = *list++;
+ VLOOSE(name); /* do name, loose only */
+ VLOOSE(class); /* do class, loose only */
+ }
+ }
+ } else {
+ /* just one of name or class */
+ if (flags == 1)
+ name = class;
+ while ((table = *list++)) {
+ if (table != LOOSESEARCH) {
+ VTIGHTLOOSE(name); /* tight and loose */
+ } else {
+ table = *list++;
+ VLOOSE(name); /* loose only */
+ }
+ }
+ }
+ if (table) {
+ /* found a match */
+ if (entry->string) {
+ *pType = XrmQString;
+ pValue->addr = StringValue(entry);
+ } else {
+ *pType = RepType(entry);
+ pValue->addr = DataValue(entry);
+ }
+ pValue->size = entry->size;
+ return True;
+ }
+ *pType = NULLQUARK;
+ pValue->addr = (XPointer)NULL;
+ pValue->size = 0;
+ return False;
+
+#undef VTIGHTLOOSE
+#undef VLOOSE
+}
+
+/* look for a tight/loose value */
+static Bool GetVEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register VEntry entry;
+ register XrmQuark q;
+
+ /* try name first */
+ q = *names;
+ entry = LeafHash(table, q);
+ while (entry && entry->name != q)
+ entry = entry->next;
+ if (!entry) {
+ /* not found, try class */
+ q = *classes;
+ entry = LeafHash(table, q);
+ while (entry && entry->name != q)
+ entry = entry->next;
+ if (!entry)
+ return False;
+ }
+ if (entry->string) {
+ *closure->type = XrmQString;
+ closure->value->addr = StringValue(entry);
+ } else {
+ *closure->type = RepType(entry);
+ closure->value->addr = DataValue(entry);
+ }
+ closure->value->size = entry->size;
+ return True;
+}
+
+/* look for a loose value */
+static Bool GetLooseVEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register VEntry entry;
+ register XrmQuark q;
+
+#define VLOOSE(ename) \
+ q = ename; \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (VEntry)NULL;
+
+ /* bump to last component */
+ while (names[1]) {
+ names++;
+ classes++;
+ }
+ VLOOSE(*names); /* do name, loose only */
+ if (!entry) {
+ VLOOSE(*classes); /* do class, loose only */
+ if (!entry)
+ return False;
+ }
+ if (entry->string) {
+ *closure->type = XrmQString;
+ closure->value->addr = StringValue(entry);
+ } else {
+ *closure->type = RepType(entry);
+ closure->value->addr = DataValue(entry);
+ }
+ closure->value->size = entry->size;
+ return True;
+
+#undef VLOOSE
+}
+
+/* recursive search for a value */
+static Bool GetNEntry(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure);
+ NTable otable;
+
+ if (names[2]) {
+ get = GetNEntry; /* recurse */
+ leaf = 0;
+ } else {
+ get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GTIGHTLOOSE(*names, GetLooseVEntry); /* do name, tight and loose */
+ GTIGHTLOOSE(*classes, GetLooseVEntry); /* do class, tight and loose */
+ if (table->hasany) {
+ GTIGHTLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!names[1])
+ break;
+ if (!names[2]) {
+ get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GLOOSE(*names, GetLooseVEntry); /* do name, loose only */
+ GLOOSE(*classes, GetLooseVEntry); /* do class, loose only */
+ if (table->hasany) {
+ GLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, loose only */
+ }
+ }
+ }
+ /* look for matching leaf tables */
+ otable = table;
+ table = table->next;
+ if (!table)
+ return False;
+ if (table->leaf) {
+ if (table->tight && !otable->tight)
+ table = table->next;
+ } else {
+ table = table->next;
+ if (!table || !table->tight)
+ return False;
+ }
+ if (!table || table->name != otable->name)
+ return False;
+ /* found one */
+ if (table->hasloose &&
+ GetLooseVEntry((LTable)table, names, classes, closure))
+ return True;
+ if (table->tight && table == otable->next) {
+ table = table->next;
+ if (table && table->name == otable->name && table->hasloose)
+ return GetLooseVEntry((LTable)table, names, classes, closure);
+ }
+ return False;
+}
+
+Bool XrmQGetResource(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ XrmRepresentation *pType, /* RETURN */
+ XrmValuePtr pValue) /* RETURN */
+{
+ register NTable table;
+ VClosureRec closure;
+
+ if (db && *names) {
+ _XLockMutex(&db->linfo);
+ closure.type = pType;
+ closure.value = pValue;
+ table = db->table;
+ if (names[1]) {
+ if (table && !table->leaf) {
+ if (GetNEntry(table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return True;
+ }
+ } else if (table && table->hasloose &&
+ GetLooseVEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex (&db->linfo);
+ return True;
+ }
+ } else {
+ if (table && !table->leaf)
+ table = table->next;
+ if (table && GetVEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return True;
+ }
+ }
+ _XUnlockMutex(&db->linfo);
+ }
+ *pType = NULLQUARK;
+ pValue->addr = (XPointer)NULL;
+ pValue->size = 0;
+ return False;
+}
+
+Bool
+XrmGetResource(XrmDatabase db, _Xconst char *name_str, _Xconst char *class_str,
+ XrmString *pType_str, XrmValuePtr pValue)
+{
+ XrmName names[MAXDBDEPTH+1];
+ XrmClass classes[MAXDBDEPTH+1];
+ XrmRepresentation fromType;
+ Bool result;
+
+ XrmStringToNameList(name_str, names);
+ XrmStringToClassList(class_str, classes);
+ result = XrmQGetResource(db, names, classes, &fromType, pValue);
+ (*pType_str) = XrmQuarkToString(fromType);
+ return result;
+}
+
+/* destroy all values, plus table itself */
+static void DestroyLTable(
+ LTable table)
+{
+ register int i;
+ register VEntry *buckets;
+ register VEntry entry, next;
+
+ buckets = table->buckets;
+ for (i = table->table.mask; i >= 0; i--, buckets++) {
+ for (next = *buckets; (entry = next); ) {
+ next = entry->next;
+ Xfree((char *)entry);
+ }
+ }
+ Xfree((char *)table->buckets);
+ Xfree((char *)table);
+}
+
+/* destroy all contained tables, plus table itself */
+static void DestroyNTable(
+ NTable table)
+{
+ register int i;
+ register NTable *buckets;
+ register NTable entry, next;
+
+ buckets = NodeBuckets(table);
+ for (i = table->mask; i >= 0; i--, buckets++) {
+ for (next = *buckets; (entry = next); ) {
+ next = entry->next;
+ if (entry->leaf)
+ DestroyLTable((LTable)entry);
+ else
+ DestroyNTable(entry);
+ }
+ }
+ Xfree((char *)table);
+}
+
+const char *
+XrmLocaleOfDatabase(
+ XrmDatabase db)
+{
+ const char* retval;
+ _XLockMutex(&db->linfo);
+ retval = (*db->methods->lcname)(db->mbstate);
+ _XUnlockMutex(&db->linfo);
+ return retval;
+}
+
+void XrmDestroyDatabase(
+ XrmDatabase db)
+{
+ register NTable table, next;
+
+ if (db) {
+ _XLockMutex(&db->linfo);
+ for (next = db->table; (table = next); ) {
+ next = table->next;
+ if (table->leaf)
+ DestroyLTable((LTable)table);
+ else
+ DestroyNTable(table);
+ }
+ _XUnlockMutex(&db->linfo);
+ _XFreeMutex(&db->linfo);
+ (*db->methods->destroy)(db->mbstate);
+ Xfree((char *)db);
+ }
+}
diff --git a/libX11/src/config.h b/libX11/src/config.h new file mode 100644 index 000000000..abbac6e3b --- /dev/null +++ b/libX11/src/config.h @@ -0,0 +1,243 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if `struct sockaddr_in' has a `sin_len' member */ +/* #undef BSD44SOCKETS */ + +/* Include compose table cache support */ +#define COMPOSECACHE 1 + +/* Has getresuid() & getresgid() functions */ +/* #undef HASGETRESUID */ + +/* Has issetugid() function */ +/* #undef HASSETUGID */ + +/* Has shm*() functions */ +//MH#define HAS_SHM 1 + +/* Define to 1 if you have the `authdes_create' function. */ +/* #undef HAVE_AUTHDES_CREATE */ + +/* Define to 1 if you have the `authdes_seccreate' function. */ +/* #undef HAVE_AUTHDES_SECCREATE */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <endian.h> header file. */ +#define HAVE_ENDIAN_H 1 + +/* Use dlopen to load shared libraries */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the <dl.h> header file. */ +/* #undef HAVE_DL_H */ + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* launchd support available */ +/* #undef HAVE_LAUNCHD */ + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Use shl_load to load shared libraries */ +/* #undef HAVE_SHL_LOAD */ + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 0 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/poll.h> header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Support IPv6 for TCP connections */ +/* #undef IPv6 */ + +/* Support dynamically loaded font modules */ +#define LOADABLEFONTS 1 + +/* Support os-specific local connections */ +/* #undef LOCALCONN */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Disable XLOCALEDIR environment variable */ +#define NO_XLOCALEDIR 1 + +/* Name of package */ +#define PACKAGE "libX11" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://bugs.freedesktop.org/enter_bug.cgi?product=xorg" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libX11" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libX11 1.1.5" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libX11" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.1.5" + +/* Major version of this package */ +#define PACKAGE_VERSION_MAJOR 1 + +/* Minor version of this package */ +#define PACKAGE_VERSION_MINOR 1 + +/* Patch version of this package */ +#define PACKAGE_VERSION_PATCHLEVEL 5 + +/* Define as the return type of signal handlers (`int' or `void'). */ +/* #undef RETSIGTYPE */ + +/* Support Secure RPC ("SUN-DES-1") authentication for X11 clients */ +/* #undef SECURE_RPC */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Support TCP socket connections */ +#define TCPCONN 1 + +/* launchd support available */ +/* #undef TRANS_REOPEN */ + +/* Support UNIX socket connections */ +#define UNIXCONN 1 + +/* Split some i18n functions into loadable modules */ +/* #undef USE_DYNAMIC_LC */ + +/* Use the X cursor library to load cursors */ +#define USE_DYNAMIC_XCURSOR 1 + +/* poll() function is available */ +#define USE_POLL 1 + +/* Use XCB for low-level protocol implementation */ +#define USE_XCB 1 + +/* Version number of package */ +#define VERSION "1.1.5" + +/* Support bdf format bitmap font files */ +#define XFONT_BDFFORMAT 1 + +/* Location of libX11 data */ +#define X11_DATADIR "/usr/share/X11" + +/* Location of libX11 library data */ +#define X11_LIBDIR "/usr/lib/X11" + +/* Include support for XCMS */ +#define XCMS 1 + +/* Location of error message database */ +#define XERRORDB "XErrorDB" + +/* Enable XF86BIGFONT extension */ +/* #undef XF86BIGFONT */ + +/* Use XKB */ +#define XKB 1 + +/* Location of keysym database */ +#define XKEYSYMDB "XKeysymDB" + +/* support for X Locales */ +#define XLOCALE 1 + +/* Location of libX11 locale data */ +#define XLOCALEDATADIR "locale" + +/* Location of libX11 locale data */ +#define XLOCALEDIR "locale" + +/* Location of libX11 locale libraries */ +#define XLOCALELIBDIR "locale" + +/* Whether libX11 is compiled with thread support */ +#define XTHREADS /**/ + +/* Whether libX11 needs to use MT safe API's */ +#define XUSE_MTSAFE_API /**/ + +/* Enable GNU and other extensions to the C environment for glibc */ +/* #undef _GNU_SOURCE */ + +/* Support bitmap font files */ +#define XFONT_BITMAP 1 + +/* Support built-in fonts */ +#define XFONT_BUILTINS 1 + +/* Support the X Font Services Protocol */ +#define XFONT_FC 1 + +/* Support fonts in files */ +#define XFONT_FONTFILE 1 + +/* Support FreeType rasterizer for nearly all font file formats */ +#define XFONT_FREETYPE 1 + +/* Support pcf format bitmap font files */ +#define XFONT_PCFFORMAT 1 + +/* Support snf format bitmap font files */ +#define XFONT_SNFFORMAT 1 + +/* Support Speedo font files */ +#define XFONT_SPEEDO 1 + +/* Support IBM Type 1 rasterizer for Type1 font files */ +#define XFONT_TYPE1 1 + +/* Support bzip2 for bitmap fonts */ +/* #undef X_BZIP2_FONT_COMPRESSION */ + +/* Support gzip for bitmap fonts */ +#define X_GZIP_FONT_COMPRESSION 1 + +#define INCL_WINSOCK_API_TYPEDEFS 1 +#include <X11/Xwinsock.h> +#include <X11/Xwindows.h> diff --git a/libX11/src/genhextable.py b/libX11/src/genhextable.py new file mode 100644 index 000000000..2a45a9e83 --- /dev/null +++ b/libX11/src/genhextable.py @@ -0,0 +1,39 @@ +import sys
+
+HexTable={
+ '0' : 0, '1' : 1,
+ '2' : 2, '3' : 3,
+ '4' : 4, '5' : 5,
+ '6' : 6, '7' : 7,
+ '8' : 8, '9' : 9,
+ 'A' : 10, 'B' : 11,
+ 'C' : 12, 'D' : 13,
+ 'E' : 14, 'F' : 15,
+ 'a' : 10, 'b' : 11,
+ 'c' : 12, 'd' : 13,
+ 'e' : 14, 'f' : 15,
+
+ ' ' : -1, ',' : -1,
+ '}' : -1, '\n' : -1,
+ '\t' : -1
+}
+
+OutHexTable=[0]*256
+
+for Char,Val in HexTable.iteritems():
+ OutHexTable[ord(Char)]=Val
+
+print "static const short hexTable[256] = {"
+i=0
+for Item in OutHexTable:
+ if i==0:
+ PreFix=" "
+ elif i%16 == 0:
+ PreFix="\n ,"
+ else:
+ PreFix=", "
+ i+=1
+ Val="%d"%Item
+ if len(Val)==1: Val = " "+Val
+ sys.stdout.write("%s%s"%(PreFix,Val))
+print "\n};"
\ No newline at end of file diff --git a/libX11/src/makefile b/libX11/src/makefile new file mode 100644 index 000000000..e89f573c7 --- /dev/null +++ b/libX11/src/makefile @@ -0,0 +1,278 @@ +LIBRARY=libx11 + +DEFINES += X11_t TRANS_CLIENT + +CSRCS = \ + AllCells.c \ + AllowEv.c \ + AllPlanes.c \ + AutoRep.c \ + Backgnd.c \ + BdrWidth.c \ + Bell.c \ + Border.c \ + ChAccCon.c \ + ChActPGb.c \ + ChClMode.c \ + ChCmap.c \ + ChGC.c \ + ChKeyCon.c \ + ChkIfEv.c \ + ChkMaskEv.c \ + ChkTypEv.c \ + ChkTypWEv.c \ + ChkWinEv.c \ + ChPntCon.c \ + ChProp.c \ + ChSaveSet.c \ + ChWAttrs.c \ + ChWindow.c \ + CirWin.c \ + CirWinDn.c \ + CirWinUp.c \ + ClDisplay.c \ + ClearArea.c \ + Clear.c \ + ConfWind.c \ + Context.c \ + ConvSel.c \ + CopyArea.c \ + CopyCmap.c \ + CopyGC.c \ + CopyPlane.c \ + CrBFData.c \ + CrCmap.c \ + CrCursor.c \ + CrGC.c \ + CrGlCur.c \ + CrPFBData.c \ + CrPixmap.c \ + CrWindow.c \ + Cursor.c \ + DefCursor.c \ + DelProp.c \ + Depths.c \ + DestSubs.c \ + DestWind.c \ + DisName.c \ + DrArc.c \ + DrArcs.c \ + DrLine.c \ + DrLines.c \ + DrPoint.c \ + DrPoints.c \ + DrRect.c \ + DrRects.c \ + DrSegs.c \ + ErrDes.c \ + ErrHndlr.c \ + evtomask.c \ + EvToWire.c \ + FetchName.c \ + FillArc.c \ + FillArcs.c \ + FillPoly.c \ + FillRct.c \ + FillRcts.c \ + FilterEv.c \ + Flush.c \ + Font.c \ + FontInfo.c \ + FontNames.c \ + FreeCmap.c \ + FreeCols.c \ + FreeCurs.c \ + FreeEData.c \ + FreeEventData.c \ + FreeGC.c \ + FreePix.c \ + FSSaver.c \ + FSWrap.c \ + GCMisc.c \ + Geom.c \ + GetAtomNm.c \ + GetColor.c \ + GetDflt.c \ + GetEventData.c \ + GetFPath.c \ + GetFProp.c \ + GetGCVals.c \ + GetGeom.c \ + GetHColor.c \ + GetHints.c \ + GetIFocus.c \ + GetImage.c \ + GetKCnt.c \ + GetMoEv.c \ + GetNrmHint.c \ + GetPCnt.c \ + GetPntMap.c \ + GetProp.c \ + GetRGBCMap.c \ + GetSOwner.c \ + GetSSaver.c \ + GetStCmap.c \ + GetTxtProp.c \ + GetWAttrs.c \ + GetWMCMapW.c \ + GetWMProto.c \ + globals.c \ + GrButton.c \ + GrKeybd.c \ + GrKey.c \ + GrPointer.c \ + GrServer.c \ + Host.c \ + Iconify.c \ + IfEvent.c \ + imConv.c \ + ImText16.c \ + ImText.c \ + ImUtil.c \ + InitExt.c \ + InsCmap.c \ + IntAtom.c \ + KeyBind.c \ + KeysymStr.c \ + KillCl.c \ + LiHosts.c \ + LiICmaps.c \ + LiProps.c \ + ListExt.c \ + LoadFont.c \ + LockDis.c \ + locking.c \ + LookupCol.c \ + LowerWin.c \ + Macros.c \ + MapRaised.c \ + MapSubs.c \ + MapWindow.c \ + MaskEvent.c \ + Misc.c \ + ModMap.c \ + MoveWin.c \ + NextEvent.c \ + OCWrap.c \ + OMWrap.c \ + OpenDis.c \ + ParseCmd.c \ + ParseCol.c \ + ParseGeom.c \ + PeekEvent.c \ + PeekIfEv.c \ + Pending.c \ + PixFormats.c \ + PmapBgnd.c \ + PmapBord.c \ + PolyReg.c \ + PolyTxt16.c \ + PolyTxt.c \ + PropAlloc.c \ + PutBEvent.c \ + PutImage.c \ + Quarks.c \ + QuBest.c \ + QuColor.c \ + QuColors.c \ + QuCurShp.c \ + QuExt.c \ + QuKeybd.c \ + QuPntr.c \ + QuStipShp.c \ + QuTextE16.c \ + QuTextExt.c \ + QuTileShp.c \ + QuTree.c \ + RaiseWin.c \ + RdBitF.c \ + RecolorC.c \ + ReconfWin.c \ + ReconfWM.c \ + Region.c \ + RegstFlt.c \ + RepWindow.c \ + RestackWs.c \ + RotProp.c \ + ScrResStr.c \ + SelInput.c \ + SendEvent.c \ + SetBack.c \ + SetClMask.c \ + SetClOrig.c \ + SetCRects.c \ + SetDashes.c \ + SetFont.c \ + SetFore.c \ + SetFPath.c \ + SetFunc.c \ + SetHints.c \ + SetIFocus.c \ + SetLocale.c \ + SetLStyle.c \ + SetNrmHint.c \ + SetPMask.c \ + SetPntMap.c \ + SetRGBCMap.c \ + SetSOwner.c \ + SetSSaver.c \ + SetState.c \ + SetStCmap.c \ + SetStip.c \ + SetTile.c \ + SetTSOrig.c \ + SetTxtProp.c \ + SetWMCMapW.c \ + SetWMProto.c \ + StBytes.c \ + StColor.c \ + StColors.c \ + StName.c \ + StNColor.c \ + StrKeysym.c \ + StrToText.c \ + Sync.c \ + Synchro.c \ + Text16.c \ + Text.c \ + TextExt16.c \ + TextExt.c \ + TextToStr.c \ + TrCoords.c \ + UndefCurs.c \ + UngrabBut.c \ + UngrabKbd.c \ + UngrabKey.c \ + UngrabPtr.c \ + UngrabSvr.c \ + UninsCmap.c \ + UnldFont.c \ + UnmapSubs.c \ + UnmapWin.c \ + VisUtil.c \ + WarpPtr.c \ + Window.c \ + WinEvent.c \ + Withdraw.c \ + WMGeom.c \ + WMProps.c \ + WrBitF.c \ + xcb_disp.c \ + xcb_io.c \ + XlibAsync.c \ + XlibInt.c \ + Xrm.c \ + + +INCLUDES := . xcms xlibi18n xkb $(MHMAKECONF)\X11 $(OBJDIR) $(INCLUDES) + +KEYSYMDEF = $(MHMAKECONF)/X11/keysymdef.h + +$(OBJDIR)\$(LIBRARY).lib: $(OBJDIR)\ks_tables.h + +load_makefile util\makefile MAKESERVER=$(MAKESERVER) DEBUG=$(DEBUG) + +$(OBJDIR)\ks_tables.h: $(KEYSYMDEF) util\$(OBJDIR)\makekeys.exe + util\$(OBJDIR)\makekeys $(relpath $<) > $(relpath $@) + + diff --git a/libX11/src/util/makefile b/libX11/src/util/makefile new file mode 100644 index 000000000..27da68335 --- /dev/null +++ b/libX11/src/util/makefile @@ -0,0 +1,6 @@ +TTYAPP=makekeys + +DEFINES += X11_t TRANS_CLIENT + +CSRCS = makekeys.c + diff --git a/libX11/src/util/makekeys.c b/libX11/src/util/makekeys.c index 85ce75268..fb758b9cb 100644 --- a/libX11/src/util/makekeys.c +++ b/libX11/src/util/makekeys.c @@ -33,6 +33,7 @@ from The Open Group. #include <X11/keysymdef.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
typedef unsigned long Signature;
@@ -157,7 +158,7 @@ main(int argc, char *argv[]) num_found = 0;
for (z = ksnum; z < KTNUM; z++) {
max_rehash = 0;
- for (name = tab, i = z; --i >= 0;)
+ for (name = &tab[0], i = z; --i >= 0;)
*name++ = 0;
for (i = 0; i < ksnum; i++) {
name = info[i].name;
diff --git a/libX11/src/xcb_io.c b/libX11/src/xcb_io.c index bac9bdf0b..63be2c5a8 100644 --- a/libX11/src/xcb_io.c +++ b/libX11/src/xcb_io.c @@ -22,6 +22,9 @@ #ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#include <sys/time.h>
+
+#include <X11/Xtrans/Xtrans.h>
#define xcb_fail_assert(_message, _var) { \
unsigned int _var = 1; \
diff --git a/libX11/src/xcms/LRGB.c b/libX11/src/xcms/LRGB.c index 5ecb7d120..2dc5a20cf 100644 --- a/libX11/src/xcms/LRGB.c +++ b/libX11/src/xcms/LRGB.c @@ -1,1844 +1,1844 @@ - -/* - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System. Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation. TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose. It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. - * - * - * NAME - * XcmsLRGB.c - * - * DESCRIPTION - * This file contains the conversion routines: - * 1. CIE XYZ to RGB intensity - * 2. RGB intensity to device RGB - * 3. device RGB to RGB intensity - * 4. RGB intensity to CIE XYZ - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xcmsint.h" -#include "Cv.h" - -/* - * LOCAL DEFINES - * #define declarations local to this package. - */ -#define EPS 0.001 -#ifndef MIN -#define MIN(x,y) ((x) > (y) ? (y) : (x)) -#endif /* MIN */ -#ifndef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) -#endif /* MAX */ -#ifndef MIN3 -#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) -#endif /* MIN3 */ -#ifndef MAX3 -#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) -#endif /* MAX3 */ - -/* - * LOCAL TYPEDEFS - * typedefs local to this package (for use with local vars). - * - */ - -/* - * FORWARD DECLARATIONS - */ -static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp); -static int LINEAR_RGB_InitSCCData(Display *dpy, - int screenNumber, XcmsPerScrnInfo *pPerScrnInfo); -static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor); -static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor); -static Status -_XcmsGetTableType0( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount); -static Status -_XcmsGetTableType1( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount); - -/* - * LOCALS VARIABLES - * Variables local to this package. - * Usage example: - * static int ExampleLocalVar; - */ - -static unsigned short const MASK[17] = { - 0x0000, /* 0 bitsPerRGB */ - 0x8000, /* 1 bitsPerRGB */ - 0xc000, /* 2 bitsPerRGB */ - 0xe000, /* 3 bitsPerRGB */ - 0xf000, /* 4 bitsPerRGB */ - 0xf800, /* 5 bitsPerRGB */ - 0xfc00, /* 6 bitsPerRGB */ - 0xfe00, /* 7 bitsPerRGB */ - 0xff00, /* 8 bitsPerRGB */ - 0xff80, /* 9 bitsPerRGB */ - 0xffc0, /* 10 bitsPerRGB */ - 0xffe0, /* 11 bitsPerRGB */ - 0xfff0, /* 12 bitsPerRGB */ - 0xfff8, /* 13 bitsPerRGB */ - 0xfffc, /* 14 bitsPerRGB */ - 0xfffe, /* 15 bitsPerRGB */ - 0xffff /* 16 bitsPerRGB */ -}; - - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsRGBFormat - * to XcmsCIEXYZFormat. - */ -static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = { - (XcmsConversionProc)XcmsRGBToRGBi, - (XcmsConversionProc)XcmsRGBiToCIEXYZ, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsCIEXYZFormat - * to XcmsRGBFormat. - */ -static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = { - (XcmsConversionProc)XcmsCIEXYZToRGBi, - (XcmsConversionProc)XcmsRGBiToRGB, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsRGBiFormat - * to XcmsCIEXYZFormat. - */ -static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = { - (XcmsConversionProc)XcmsRGBiToCIEXYZ, - NULL -}; - - /* - * A NULL terminated array of function pointers that when applied - * in series will convert an XcmsColor structure from XcmsCIEXYZFormat - * to XcmsRGBiFormat. - */ -static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = { - (XcmsConversionProc)XcmsCIEXYZToRGBi, - NULL -}; - - /* - * RGBi Color Spaces - */ -XcmsColorSpace XcmsRGBiColorSpace = - { - _XcmsRGBi_prefix, /* prefix */ - XcmsRGBiFormat, /* id */ - XcmsLRGB_RGBi_ParseString, /* parseString */ - Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */ - Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */ - 1 - }; - - /* - * RGB Color Spaces - */ -XcmsColorSpace XcmsRGBColorSpace = - { - _XcmsRGB_prefix, /* prefix */ - XcmsRGBFormat, /* id */ - XcmsLRGB_RGB_ParseString, /* parseString */ - Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */ - Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */ - 1 - }; - - /* - * Device-Independent Color Spaces known to the - * LINEAR_RGB Screen Color Characteristics Function Set. - */ -static XcmsColorSpace *DDColorSpaces[] = { - &XcmsRGBColorSpace, - &XcmsRGBiColorSpace, - NULL -}; - - -/* - * GLOBALS - * Variables declared in this package that are allowed - * to be used globally. - */ - - /* - * LINEAR_RGB Screen Color Characteristics Function Set. - */ -XcmsFunctionSet XcmsLinearRGBFunctionSet = - { - &DDColorSpaces[0], /* pDDColorSpaces */ - LINEAR_RGB_InitSCCData, /* pInitScrnFunc */ - LINEAR_RGB_FreeSCCData /* pFreeSCCData */ - }; - -/* - * DESCRIPTION - * Contents of Default SCCData should be replaced if other - * data should be used as default. - * - * - */ - -/* - * NAME Tektronix 19" (Sony) CRT - * PART_NUMBER 119-2451-00 - * MODEL Tek4300, Tek4800 - */ - -static IntensityRec const Default_RGB_RedTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x0909, 0.000000 }, - { 0x0a0a, 0.000936 }, - { 0x0f0f, 0.001481 }, - { 0x1414, 0.002329 }, - { 0x1919, 0.003529 }, - { 0x1e1e, 0.005127 }, - { 0x2323, 0.007169 }, - { 0x2828, 0.009699 }, - { 0x2d2d, 0.012759 }, - { 0x3232, 0.016392 }, - { 0x3737, 0.020637 }, - { 0x3c3c, 0.025533 }, - { 0x4141, 0.031119 }, - { 0x4646, 0.037431 }, - { 0x4b4b, 0.044504 }, - { 0x5050, 0.052373 }, - { 0x5555, 0.061069 }, - { 0x5a5a, 0.070624 }, - { 0x5f5f, 0.081070 }, - { 0x6464, 0.092433 }, - { 0x6969, 0.104744 }, - { 0x6e6e, 0.118026 }, - { 0x7373, 0.132307 }, - { 0x7878, 0.147610 }, - { 0x7d7d, 0.163958 }, - { 0x8282, 0.181371 }, - { 0x8787, 0.199871 }, - { 0x8c8c, 0.219475 }, - { 0x9191, 0.240202 }, - { 0x9696, 0.262069 }, - { 0x9b9b, 0.285089 }, - { 0xa0a0, 0.309278 }, - { 0xa5a5, 0.334647 }, - { 0xaaaa, 0.361208 }, - { 0xafaf, 0.388971 }, - { 0xb4b4, 0.417945 }, - { 0xb9b9, 0.448138 }, - { 0xbebe, 0.479555 }, - { 0xc3c3, 0.512202 }, - { 0xc8c8, 0.546082 }, - { 0xcdcd, 0.581199 }, - { 0xd2d2, 0.617552 }, - { 0xd7d7, 0.655144 }, - { 0xdcdc, 0.693971 }, - { 0xe1e1, 0.734031 }, - { 0xe6e6, 0.775322 }, - { 0xebeb, 0.817837 }, - { 0xf0f0, 0.861571 }, - { 0xf5f5, 0.906515 }, - { 0xfafa, 0.952662 }, - { 0xffff, 1.000000 } -}; - -static IntensityRec const Default_RGB_GreenTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x1313, 0.000000 }, - { 0x1414, 0.000832 }, - { 0x1919, 0.001998 }, - { 0x1e1e, 0.003612 }, - { 0x2323, 0.005736 }, - { 0x2828, 0.008428 }, - { 0x2d2d, 0.011745 }, - { 0x3232, 0.015740 }, - { 0x3737, 0.020463 }, - { 0x3c3c, 0.025960 }, - { 0x4141, 0.032275 }, - { 0x4646, 0.039449 }, - { 0x4b4b, 0.047519 }, - { 0x5050, 0.056520 }, - { 0x5555, 0.066484 }, - { 0x5a5a, 0.077439 }, - { 0x5f5f, 0.089409 }, - { 0x6464, 0.102418 }, - { 0x6969, 0.116485 }, - { 0x6e6e, 0.131625 }, - { 0x7373, 0.147853 }, - { 0x7878, 0.165176 }, - { 0x7d7d, 0.183604 }, - { 0x8282, 0.203140 }, - { 0x8787, 0.223783 }, - { 0x8c8c, 0.245533 }, - { 0x9191, 0.268384 }, - { 0x9696, 0.292327 }, - { 0x9b9b, 0.317351 }, - { 0xa0a0, 0.343441 }, - { 0xa5a5, 0.370580 }, - { 0xaaaa, 0.398747 }, - { 0xafaf, 0.427919 }, - { 0xb4b4, 0.458068 }, - { 0xb9b9, 0.489165 }, - { 0xbebe, 0.521176 }, - { 0xc3c3, 0.554067 }, - { 0xc8c8, 0.587797 }, - { 0xcdcd, 0.622324 }, - { 0xd2d2, 0.657604 }, - { 0xd7d7, 0.693588 }, - { 0xdcdc, 0.730225 }, - { 0xe1e1, 0.767459 }, - { 0xe6e6, 0.805235 }, - { 0xebeb, 0.843491 }, - { 0xf0f0, 0.882164 }, - { 0xf5f5, 0.921187 }, - { 0xfafa, 0.960490 }, - { 0xffff, 1.000000 } -}; - -static IntensityRec const Default_RGB_BlueTuples[] = { - /* {unsigned short value, XcmsFloat intensity} */ - { 0x0000, 0.000000 }, - { 0x0e0e, 0.000000 }, - { 0x0f0f, 0.001341 }, - { 0x1414, 0.002080 }, - { 0x1919, 0.003188 }, - { 0x1e1e, 0.004729 }, - { 0x2323, 0.006766 }, - { 0x2828, 0.009357 }, - { 0x2d2d, 0.012559 }, - { 0x3232, 0.016424 }, - { 0x3737, 0.021004 }, - { 0x3c3c, 0.026344 }, - { 0x4141, 0.032489 }, - { 0x4646, 0.039481 }, - { 0x4b4b, 0.047357 }, - { 0x5050, 0.056154 }, - { 0x5555, 0.065903 }, - { 0x5a5a, 0.076634 }, - { 0x5f5f, 0.088373 }, - { 0x6464, 0.101145 }, - { 0x6969, 0.114968 }, - { 0x6e6e, 0.129862 }, - { 0x7373, 0.145841 }, - { 0x7878, 0.162915 }, - { 0x7d7d, 0.181095 }, - { 0x8282, 0.200386 }, - { 0x8787, 0.220791 }, - { 0x8c8c, 0.242309 }, - { 0x9191, 0.264937 }, - { 0x9696, 0.288670 }, - { 0x9b9b, 0.313499 }, - { 0xa0a0, 0.339410 }, - { 0xa5a5, 0.366390 }, - { 0xaaaa, 0.394421 }, - { 0xafaf, 0.423481 }, - { 0xb4b4, 0.453547 }, - { 0xb9b9, 0.484592 }, - { 0xbebe, 0.516587 }, - { 0xc3c3, 0.549498 }, - { 0xc8c8, 0.583291 }, - { 0xcdcd, 0.617925 }, - { 0xd2d2, 0.653361 }, - { 0xd7d7, 0.689553 }, - { 0xdcdc, 0.726454 }, - { 0xe1e1, 0.764013 }, - { 0xe6e6, 0.802178 }, - { 0xebeb, 0.840891 }, - { 0xf0f0, 0.880093 }, - { 0xf5f5, 0.919723 }, - { 0xfafa, 0.959715 }, - { 0xffff, 1.00000 } -}; - -static IntensityTbl Default_RGB_RedTbl = { - /* IntensityRec *pBase */ - (IntensityRec *) Default_RGB_RedTuples, - /* unsigned int nEntries */ - 52 -}; - -static IntensityTbl Default_RGB_GreenTbl = { - /* IntensityRec *pBase */ - (IntensityRec *)Default_RGB_GreenTuples, - /* unsigned int nEntries */ - 50 -}; - -static IntensityTbl Default_RGB_BlueTbl = { - /* IntensityRec *pBase */ - (IntensityRec *)Default_RGB_BlueTuples, - /* unsigned int nEntries */ - 51 -}; - -static LINEAR_RGB_SCCData Default_RGB_SCCData = { - /* XcmsFloat XYZtoRGBmatrix[3][3] */ - { - { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 }, - {-1.07152751306193600, 1.96593795204372400, 0.03673691339553462 }, - { 0.06351179790497788, -0.20020501000496480, 0.81070942031648220 } - }, - - /* XcmsFloat RGBtoXYZmatrix[3][3] */ - { - { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 }, - { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 }, - { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 } - }, - - /* IntensityTbl *pRedTbl */ - &Default_RGB_RedTbl, - - /* IntensityTbl *pGreenTbl */ - &Default_RGB_GreenTbl, - - /* IntensityTbl *pBlueTbl */ - &Default_RGB_BlueTbl -}; - -/************************************************************************ - * * - * PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * LINEAR_RGB_InitSCCData() - * - * SYNOPSIS - */ -static Status -LINEAR_RGB_InitSCCData( - Display *dpy, - int screenNumber, - XcmsPerScrnInfo *pPerScrnInfo) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); - Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); - int format_return, count, cType, nTables; - unsigned long nitems, nbytes_return; - char *property_return, *pChar; - XcmsFloat *pValue; -#ifdef ALLDEBUG - IntensityRec *pIRec; -#endif /* ALLDEBUG */ - VisualID visualID; - - LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData; - XcmsIntensityMap *pNewMap; - - /* - * Allocate memory for pScreenData - */ - if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *) - Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { - return(XcmsFailure); - } - - /* - * 1. Get the XYZ->RGB and RGB->XYZ matrices - */ - - if (MatrixAtom == None || - !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom, - &format_return, &nitems, &nbytes_return, &property_return) || - nitems != 18 || format_return != 32) { - /* - * As per the XDCCC, there must be 18 data items and each must be - * in 32 bits ! - */ - goto FreeSCCData; - - } else { - - /* - * RGBtoXYZ and XYZtoRGB matrices - */ - pValue = (XcmsFloat *) pScreenData; - pChar = property_return; - for (count = 0; count < 18; count++) { - *pValue++ = (long)_XcmsGetElement(format_return, &pChar, - &nitems) / (XcmsFloat)XDCCC_NUMBER; - } - Xfree ((char *)property_return); - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = - pScreenData->RGBtoXYZmatrix[0][0] + - pScreenData->RGBtoXYZmatrix[0][1] + - pScreenData->RGBtoXYZmatrix[0][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = - pScreenData->RGBtoXYZmatrix[1][0] + - pScreenData->RGBtoXYZmatrix[1][1] + - pScreenData->RGBtoXYZmatrix[1][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = - pScreenData->RGBtoXYZmatrix[2][0] + - pScreenData->RGBtoXYZmatrix[2][1] + - pScreenData->RGBtoXYZmatrix[2][2]; - - /* - * Compute the Screen White Point - */ - if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) - || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { - goto FreeSCCData; - } else { - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; - } - pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; - pPerScrnInfo->screenWhitePt.pixel = 0; - -#ifdef PDEBUG - printf ("RGB to XYZ Matrix values:\n"); - printf (" %f %f %f\n %f %f %f\n %f %f %f\n", - pScreenData->RGBtoXYZmatrix[0][0], - pScreenData->RGBtoXYZmatrix[0][1], - pScreenData->RGBtoXYZmatrix[0][2], - pScreenData->RGBtoXYZmatrix[1][0], - pScreenData->RGBtoXYZmatrix[1][1], - pScreenData->RGBtoXYZmatrix[1][2], - pScreenData->RGBtoXYZmatrix[2][0], - pScreenData->RGBtoXYZmatrix[2][1], - pScreenData->RGBtoXYZmatrix[2][2]); - printf ("XYZ to RGB Matrix values:\n"); - printf (" %f %f %f\n %f %f %f\n %f %f %f\n", - pScreenData->XYZtoRGBmatrix[0][0], - pScreenData->XYZtoRGBmatrix[0][1], - pScreenData->XYZtoRGBmatrix[0][2], - pScreenData->XYZtoRGBmatrix[1][0], - pScreenData->XYZtoRGBmatrix[1][1], - pScreenData->XYZtoRGBmatrix[1][2], - pScreenData->XYZtoRGBmatrix[2][0], - pScreenData->XYZtoRGBmatrix[2][1], - pScreenData->XYZtoRGBmatrix[2][2]); - printf ("Screen White Pt value: %f %f %f\n", - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X, - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y, - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z); -#endif /* PDEBUG */ - } - - /* - * 2. Get the Intensity Profile - */ - if (CorrectAtom == None || - !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom, - &format_return, &nitems, &nbytes_return, &property_return)) { - goto FreeSCCData; - } - - pChar = property_return; - - while (nitems) { - switch (format_return) { - case 8: - /* - * Must have at least: - * VisualID0 - * VisualID1 - * VisualID2 - * VisualID3 - * type - * count - * length - * intensity1 - * intensity2 - */ - if (nitems < 9) { - goto Free_property_return; - } - count = 3; - break; - case 16: - /* - * Must have at least: - * VisualID0 - * VisualID3 - * type - * count - * length - * intensity1 - * intensity2 - */ - if (nitems < 7) { - goto Free_property_return; - } - count = 1; - break; - case 32: - /* - * Must have at least: - * VisualID0 - * type - * count - * length - * intensity1 - * intensity2 - */ - if (nitems < 6) { - goto Free_property_return; - } - count = 0; - break; - default: - goto Free_property_return; - } - - /* - * Get VisualID - */ - visualID = _XcmsGetElement(format_return, &pChar, &nitems); - while (count--) { - visualID = visualID << format_return; - visualID |= _XcmsGetElement(format_return, &pChar, &nitems); - } - - if (visualID == 0) { - /* - * This is a shared intensity table - */ - pScreenData = pScreenDefaultData; - } else { - /* - * This is a per-Visual intensity table - */ - if (!(pScreenData = (LINEAR_RGB_SCCData *) - Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) { - goto Free_property_return; - } - /* copy matrices */ - memcpy((char *)pScreenData, (char *)pScreenDefaultData, - 18 * sizeof(XcmsFloat)); - - /* Create, initialize, and add map */ - if (!(pNewMap = (XcmsIntensityMap *) - Xcalloc (1, sizeof(XcmsIntensityMap)))) { - Xfree((char *)pScreenData); - goto Free_property_return; - } - pNewMap->visualID = visualID; - pNewMap->screenData = (XPointer)pScreenData; - pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData; - pNewMap->pNext = - (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps; - dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap; - dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps; - } - - cType = _XcmsGetElement(format_return, &pChar, &nitems); - nTables = _XcmsGetElement(format_return, &pChar, &nitems); - - if (cType == 0) { - - /* Red Intensity Table */ - if (!(pScreenData->pRedTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto Free_property_return; - } - if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeRedTbl; - } - - if (nTables == 1) { - /* Green Intensity Table */ - pScreenData->pGreenTbl = pScreenData->pRedTbl; - /* Blue Intensity Table */ - pScreenData->pBlueTbl = pScreenData->pRedTbl; - } else { - /* Green Intensity Table */ - if (!(pScreenData->pGreenTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto FreeRedTblElements; - } - if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeGreenTbl; - } - - /* Blue Intensity Table */ - if (!(pScreenData->pBlueTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto FreeGreenTblElements; - } - if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeBlueTbl; - } - } - } else if (cType == 1) { - /* Red Intensity Table */ - if (!(pScreenData->pRedTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto Free_property_return; - } - if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeRedTbl; - } - - if (nTables == 1) { - - /* Green Intensity Table */ - pScreenData->pGreenTbl = pScreenData->pRedTbl; - /* Blue Intensity Table */ - pScreenData->pBlueTbl = pScreenData->pRedTbl; - - } else { - - /* Green Intensity Table */ - if (!(pScreenData->pGreenTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto FreeRedTblElements; - } - if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeGreenTbl; - } - - /* Blue Intensity Table */ - if (!(pScreenData->pBlueTbl = (IntensityTbl *) - Xcalloc (1, sizeof(IntensityTbl)))) { - goto FreeGreenTblElements; - } - if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar, - &nitems) == XcmsFailure) { - goto FreeBlueTbl; - } - } - } else { - goto Free_property_return; - } - -#ifdef ALLDEBUG - printf ("Intensity Table RED %d\n", pScreenData->pRedTbl->nEntries); - pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase; - for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) { - printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); - } - if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) { - printf ("Intensity Table GREEN %d\n", pScreenData->pGreenTbl->nEntries); - pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase; - for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) { - printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); - } - } - if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) { - printf ("Intensity Table BLUE %d\n", pScreenData->pBlueTbl->nEntries); - pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase; - for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) { - printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity); - } - } -#endif /* ALLDEBUG */ - } - - Xfree ((char *)property_return); - - /* Free the old memory and use the new structure created. */ - LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData); - - pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet; - - pPerScrnInfo->screenData = (XPointer) pScreenData; - - pPerScrnInfo->state = XcmsInitSuccess; - - return(XcmsSuccess); - -FreeBlueTblElements: - Xfree((char *)pScreenData->pBlueTbl->pBase); - -FreeBlueTbl: - Xfree((char *)pScreenData->pBlueTbl); - -FreeGreenTblElements: - Xfree((char *)pScreenData->pGreenTbl->pBase); - -FreeGreenTbl: - Xfree((char *)pScreenData->pGreenTbl); - -FreeRedTblElements: - Xfree((char *)pScreenData->pRedTbl->pBase); - -FreeRedTbl: - Xfree((char *)pScreenData->pRedTbl); - -Free_property_return: - Xfree ((char *)property_return); - -FreeSCCData: - Xfree((char *)pScreenDefaultData); - pPerScrnInfo->state = XcmsInitNone; - return(XcmsFailure); -} - - -/* - * NAME - * LINEAR_RGB_FreeSCCData() - * - * SYNOPSIS - */ -static void -LINEAR_RGB_FreeSCCData( - XPointer pScreenDataTemp) -/* - * DESCRIPTION - * - * RETURNS - * 0 if failed. - * 1 if succeeded with no modifications. - * - */ -{ - LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp; - - if (pScreenData && pScreenData != &Default_RGB_SCCData) { - if (pScreenData->pRedTbl) { - if (pScreenData->pGreenTbl) { - if (pScreenData->pRedTbl->pBase != - pScreenData->pGreenTbl->pBase) { - if (pScreenData->pGreenTbl->pBase) { - Xfree ((char *)pScreenData->pGreenTbl->pBase); - } - } - if (pScreenData->pGreenTbl != pScreenData->pRedTbl) { - Xfree ((char *)pScreenData->pGreenTbl); - } - } - if (pScreenData->pBlueTbl) { - if (pScreenData->pRedTbl->pBase != - pScreenData->pBlueTbl->pBase) { - if (pScreenData->pBlueTbl->pBase) { - Xfree ((char *)pScreenData->pBlueTbl->pBase); - } - } - if (pScreenData->pBlueTbl != pScreenData->pRedTbl) { - Xfree ((char *)pScreenData->pBlueTbl); - } - } - if (pScreenData->pRedTbl->pBase) { - Xfree ((char *)pScreenData->pRedTbl->pBase); - } - Xfree ((char *)pScreenData->pRedTbl); - } - Xfree ((char *)pScreenData); - } -} - - - -/************************************************************************ - * * - * API PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * _XcmsGetTableType0 - * - * SYNOPSIS - */ -static Status -_XcmsGetTableType0( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - unsigned int nElements; - IntensityRec *pIRec; - - nElements = pTbl->nEntries = - _XcmsGetElement(format, pChar, pCount) + 1; - if (!(pIRec = pTbl->pBase = (IntensityRec *) - Xcalloc (nElements, sizeof(IntensityRec)))) { - return(XcmsFailure); - } - - switch (format) { - case 8: - for (; nElements--; pIRec++) { - /* 0xFFFF/0xFF = 0x101 */ - pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; - pIRec->intensity = - _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; - } - break; - case 16: - for (; nElements--; pIRec++) { - pIRec->value = _XcmsGetElement (format, pChar, pCount); - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)65535.0; - } - break; - case 32: - for (; nElements--; pIRec++) { - pIRec->value = _XcmsGetElement (format, pChar, pCount); - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)4294967295.0; - } - break; - default: - return(XcmsFailure); - } - return(XcmsSuccess); -} - - -/* - * NAME - * _XcmsGetTableType1 - * - * SYNOPSIS - */ -static Status -_XcmsGetTableType1( - IntensityTbl *pTbl, - int format, - char **pChar, - unsigned long *pCount) -/* - * DESCRIPTION - * - * RETURNS - * XcmsFailure if failed. - * XcmsSuccess if succeeded. - * - */ -{ - int count; - unsigned int max_index; - IntensityRec *pIRec; - - max_index = _XcmsGetElement(format, pChar, pCount); - pTbl->nEntries = max_index + 1; - if (!(pIRec = pTbl->pBase = (IntensityRec *) - Xcalloc (max_index+1, sizeof(IntensityRec)))) { - return(XcmsFailure); - } - - switch (format) { - case 8: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)255.0; - } - break; - case 16: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)65535.0; - } - break; - case 32: - for (count = 0; count < max_index+1; count++, pIRec++) { - pIRec->value = (count * 65535) / max_index; - pIRec->intensity = _XcmsGetElement (format, pChar, pCount) - / (XcmsFloat)4294967295.0; - } - break; - default: - return(XcmsFailure); - } - - return(XcmsSuccess); -} - - -/* - * NAME - * ValueCmp - * - * SYNOPSIS - */ -static int -_XcmsValueCmp( - IntensityRec *p1, IntensityRec *p2) -/* - * DESCRIPTION - * Compares the value component of two IntensityRec - * structures. - * - * RETURNS - * 0 if p1->value is equal to p2->value - * < 0 if p1->value is less than p2->value - * > 0 if p1->value is greater than p2->value - * - */ -{ - return (p1->value - p2->value); -} - - -/* - * NAME - * IntensityCmp - * - * SYNOPSIS - */ -static int -_XcmsIntensityCmp( - IntensityRec *p1, IntensityRec *p2) -/* - * DESCRIPTION - * Compares the intensity component of two IntensityRec - * structures. - * - * RETURNS - * 0 if equal; - * < 0 if first precedes second - * > 0 if first succeeds second - * - */ -{ - if (p1->intensity < p2->intensity) { - return (-1); - } - if (p1->intensity > p2->intensity) { - return (XcmsSuccess); - } - return (XcmsFailure); -} - -/* - * NAME - * ValueInterpolation - * - * SYNOPSIS - */ -/* ARGSUSED */ -static int -_XcmsValueInterpolation( - IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, - int bitsPerRGB) -/* - * DESCRIPTION - * Based on a given value, performs a linear interpolation - * on the intensities between two IntensityRec structures. - * Note that the bitsPerRGB parameter is ignored. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - */ -{ - XcmsFloat ratio; - - ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / - ((XcmsFloat)hi->value - (XcmsFloat)lo->value); - answer->value = key->value; - answer->intensity = (hi->intensity - lo->intensity) * ratio; - answer->intensity += lo->intensity; - return (XcmsSuccess); -} - -/* - * NAME - * IntensityInterpolation - * - * SYNOPSIS - */ -static int -_XcmsIntensityInterpolation( - IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer, - int bitsPerRGB) -/* - * DESCRIPTION - * Based on a given intensity, performs a linear interpolation - * on the values between two IntensityRec structures. - * The bitsPerRGB parameter is necessary to perform rounding - * to the correct number of significant bits. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - */ -{ - XcmsFloat ratio; - long target, up, down; - int shift = 16 - bitsPerRGB; - int max_color = (1 << bitsPerRGB) - 1; - - ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); - answer->intensity = key->intensity; - target = hi->value - lo->value; - target *= ratio; - target += lo->value; - - /* - * Ok now, lets find the closest in respects to bits per RGB - */ - up = ((target >> shift) * 0xFFFF) / max_color; - if (up < target) { - down = up; - up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; - } else { - down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; - } - answer->value = ((up - target) < (target - down) ? up : down); - answer->value &= MASK[bitsPerRGB]; - return (XcmsSuccess); -} - - - -typedef int (*comparProcp)( - char *p1, - char *p2); -typedef int (*interpolProcp)( - char *key, - char *lo, - char *hi, - char *answer, - int bitsPerRGB); - -/* - * NAME - * _XcmsTableSearch - * - * SYNOPSIS - */ -static int -_XcmsTableSearch( - char *key, - int bitsPerRGB, - char *base, - unsigned nel, - unsigned nKeyPtrSize, - int (*compar)( - char *p1, - char *p2), - int (*interpol)( - char *key, - char *lo, - char *hi, - char *answer, - int bitsPerRGB), - char *answer) - -/* - * DESCRIPTION - * A binary search through the specificied table. - * - * RETURNS - * Returns 0 if failed; otherwise non-zero. - * - */ -{ - char *hi, *lo, *mid, *last; - int result; - - last = hi = base + ((nel - 1) * nKeyPtrSize); - mid = lo = base; - - /* use only the significants bits, then scale into 16 bits */ - ((IntensityRec *)key)->value = ((unsigned long) - (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) - / ((1 << bitsPerRGB) - 1); - - /* Special case so that zero intensity always maps to zero value */ - if ((*compar) (key,lo) <= 0) { - memcpy (answer, lo, nKeyPtrSize); - ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; - return XcmsSuccess; - } - while (mid != last) { - last = mid; - mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; - result = (*compar) (key, mid); - if (result == 0) { - - memcpy(answer, mid, nKeyPtrSize); - ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; - return (XcmsSuccess); - } else if (result < 0) { - hi = mid; - } else { - lo = mid; - } - } - - /* - * If we got to here, we didn't find a solution, so we - * need to apply interpolation. - */ - return ((*interpol)(key, lo, hi, answer, bitsPerRGB)); -} - - -/* - * NAME - * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector - * - * SYNOPSIS - */ -static void _XcmsMatVec( - XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut) -/* - * DESCRIPTION - * Multiply the passed vector by the passed matrix to return a - * vector. Matrix is 3x3, vectors are of length 3. - * - * RETURNS - * void - */ -{ - int i, j; - - for (i = 0; i < 3; i++) { - pOut[i] = 0.0; - for (j = 0; j < 3; j++) - pOut[i] += *(pMat+(i*3)+j) * pIn[j]; - } -} - - -/************************************************************************ - * * - * PUBLIC ROUTINES * - * * - ************************************************************************/ - - -/* - * NAME - * XcmsLRGB_RGB_ParseString - * - * SYNOPSIS - */ -static int -XcmsLRGB_RGB_ParseString( - register char *spec, - XcmsColor *pColor) -/* - * DESCRIPTION - * This routines takes a string and attempts to convert - * it into a XcmsColor structure with XcmsRGBFormat. - * - * RETURNS - * 0 if failed, non-zero otherwise. - */ -{ - register int n, i; - unsigned short r, g, b; - char c; - char *pchar; - unsigned short *pShort; - - /* - * Check for old # format - */ - if (*spec == '#') { - /* - * Attempt to parse the value portion. - */ - spec++; - n = strlen(spec); - if (n != 3 && n != 6 && n != 9 && n != 12) { - return(XcmsFailure); - } - - n /= 3; - g = b = 0; - do { - r = g; - g = b; - b = 0; - for (i = n; --i >= 0; ) { - c = *spec++; - b <<= 4; - if (c >= '0' && c <= '9') - b |= c - '0'; - /* assume string in lowercase - else if (c >= 'A' && c <= 'F') - b |= c - ('A' - 10); - */ - else if (c >= 'a' && c <= 'f') - b |= c - ('a' - 10); - else return (XcmsFailure); - } - } while (*spec != '\0'); - - /* - * Succeeded ! - */ - n <<= 2; - n = 16 - n; - /* shift instead of scale, to match old broken semantics */ - pColor->spec.RGB.red = r << n; - pColor->spec.RGB.green = g << n; - pColor->spec.RGB.blue = b << n; - } else { - if ((pchar = strchr(spec, ':')) == NULL) { - return(XcmsFailure); - } - n = (int)(pchar - spec); - - /* - * Check for proper prefix. - */ - if (strncmp(spec, _XcmsRGB_prefix, n) != 0) { - return(XcmsFailure); - } - - /* - * Attempt to parse the value portion. - */ - spec += (n + 1); - pShort = &pColor->spec.RGB.red; - for (i = 0; i < 3; i++, pShort++, spec++) { - n = 0; - *pShort = 0; - while (*spec != '/' && *spec != '\0') { - if (++n > 4) { - return(XcmsFailure); - } - c = *spec++; - *pShort <<= 4; - if (c >= '0' && c <= '9') - *pShort |= c - '0'; - /* assume string in lowercase - else if (c >= 'A' && c <= 'F') - *pShort |= c - ('A' - 10); - */ - else if (c >= 'a' && c <= 'f') - *pShort |= c - ('a' - 10); - else return (XcmsFailure); - } - if (n == 0) - return (XcmsFailure); - if (n < 4) { - *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); - } - } - } - pColor->format = XcmsRGBFormat; - pColor->pixel = 0; - return (XcmsSuccess); -} - - -/* - * NAME - * XcmsLRGB_RGBi_ParseString - * - * SYNOPSIS - */ -static int -XcmsLRGB_RGBi_ParseString( - register char *spec, - XcmsColor *pColor) -/* - * DESCRIPTION - * This routines takes a string and attempts to convert - * it into a XcmsColor structure with XcmsRGBiFormat. - * The assumed RGBi string syntax is: - * RGBi:<r>/<g>/<b> - * Where r, g, and b are in string input format for floats - * consisting of: - * a. an optional sign - * b. a string of numbers possibly containing a decimal point, - * c. an optional exponent field containing an 'E' or 'e' - * followed by a possibly signed integer string. - * - * RETURNS - * 0 if failed, non-zero otherwise. - */ -{ - int n; - char *pchar; - - if ((pchar = strchr(spec, ':')) == NULL) { - return(XcmsFailure); - } - n = (int)(pchar - spec); - - /* - * Check for proper prefix. - */ - if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) { - return(XcmsFailure); - } - - /* - * Attempt to parse the value portion. - */ - if (sscanf(spec + n + 1, "%lf/%lf/%lf", - &pColor->spec.RGBi.red, - &pColor->spec.RGBi.green, - &pColor->spec.RGBi.blue) != 3) { - char *s; /* Maybe failed due to locale */ - int f; - if ((s = strdup(spec))) { - for (f = 0; s[f]; ++f) - if (s[f] == '.') - s[f] = ','; - else if (s[f] == ',') - s[f] = '.'; - if (sscanf(s + n + 1, "%lf/%lf/%lf", - &pColor->spec.RGBi.red, - &pColor->spec.RGBi.green, - &pColor->spec.RGBi.blue) != 3) { - free(s); - return(XcmsFailure); - } - free(s); - } else - return(XcmsFailure); - } - - /* - * Succeeded ! - */ - pColor->format = XcmsRGBiFormat; - pColor->pixel = 0; - return (XcmsSuccess); -} - - -/* - * NAME - * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsCIEXYZToRGBi( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to an array of Bool */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGB format to RGBi format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded without gamut compression. - * XcmsSuccessWithCompression if succeeded with gamut - * compression. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsFloat tmp[3]; - int hasCompressed = 0; - unsigned int i; - XcmsColor *pColor = pXcmsColors_in_out; - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - /* - * XcmsColors should be White Point Adjusted, if necessary, by now! - */ - - /* - * NEW!!! for extended gamut compression - * - * 1. Need to zero out pCompressed - * - * 2. Need to save initial address of pColor - * - * 3. Need to save initial address of pCompressed - */ - - for (i = 0; i < nColors; i++) { - - /* Make sure format is XcmsCIEXYZFormat */ - if (pColor->format != XcmsCIEXYZFormat) { - return(XcmsFailure); - } - - /* Multiply [A]-1 * [XYZ] to get RGB intensity */ - _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, - (XcmsFloat *) &pColor->spec, tmp); - - if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || - (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { - - /* - * RGBi out of screen's gamut - */ - - if (ccc->gamutCompProc == NULL) { - /* - * Aha!! Here's that little trick that will allow - * gamut compression routines to get the out of bound - * RGBi. - */ - memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); - pColor->format = XcmsRGBiFormat; - return(XcmsFailure); - } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors, - i, pCompressed) == 0) { - return(XcmsFailure); - } - - /* - * The gamut compression function should return colors in CIEXYZ - * Also check again to if the new color is within gamut. - */ - if (pColor->format != XcmsCIEXYZFormat) { - return(XcmsFailure); - } - _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix, - (XcmsFloat *) &pColor->spec, tmp); - if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) || - (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) { - return(XcmsFailure); - } - hasCompressed++; - } - memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp)); - /* These if statements are done to ensure the fudge factor is */ - /* is taken into account. */ - if (pColor->spec.RGBi.red < 0.0) { - pColor->spec.RGBi.red = 0.0; - } else if (pColor->spec.RGBi.red > 1.0) { - pColor->spec.RGBi.red = 1.0; - } - if (pColor->spec.RGBi.green < 0.0) { - pColor->spec.RGBi.green = 0.0; - } else if (pColor->spec.RGBi.green > 1.0) { - pColor->spec.RGBi.green = 1.0; - } - if (pColor->spec.RGBi.blue < 0.0) { - pColor->spec.RGBi.blue = 0.0; - } else if (pColor->spec.RGBi.blue > 1.0) { - pColor->spec.RGBi.blue = 1.0; - } - (pColor++)->format = XcmsRGBiFormat; - } - return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess); -} - - -/* - * NAME - * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToCIEXYZ( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGBi format to CIEXYZ format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsFloat tmp[3]; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - /* - * XcmsColors should be White Point Adjusted, if necessary, by now! - */ - - while (nColors--) { - - /* Multiply [A]-1 * [XYZ] to get RGB intensity */ - _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix, - (XcmsFloat *) &pXcmsColors_in_out->spec, tmp); - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp)); - (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat; - } - return(XcmsSuccess); -} - - -/* - * NAME - * XcmsRGBiToRGB - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBiToRGB( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGBi format to RGB format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded without gamut compression. - * XcmsSuccessWithCompression if succeeded with gamut - * compression. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsRGB tmpRGB; - IntensityRec keyIRec, answerIRec; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - while (nColors--) { - - /* Make sure format is XcmsRGBiFormat */ - if (pXcmsColors_in_out->format != XcmsRGBiFormat) { - return(XcmsFailure); - } - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pRedTbl->pBase, - (unsigned)pScreenData->pRedTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.red = answerIRec.value; - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pGreenTbl->pBase, - (unsigned)pScreenData->pGreenTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.green = answerIRec.value; - - keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pBlueTbl->pBase, - (unsigned)pScreenData->pBlueTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGB.blue = answerIRec.value; - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB)); - (pXcmsColors_in_out++)->format = XcmsRGBFormat; - } - return(XcmsSuccess); -} - - -/* - * NAME - * XcmsRGBToRGBi - * - * SYNOPSIS - */ -/* ARGSUSED */ -Status -XcmsRGBToRGBi( - XcmsCCC ccc, - XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */ - unsigned int nColors, /* Number of colors */ - Bool *pCompressed) /* pointer to a bit array */ -/* - * DESCRIPTION - * Converts color specifications in an array of XcmsColor - * structures from RGB format to RGBi format. - * - * RETURNS - * XcmsFailure if failed, - * XcmsSuccess if succeeded. - */ -{ - LINEAR_RGB_SCCData *pScreenData; - XcmsRGBi tmpRGBi; - IntensityRec keyIRec, answerIRec; - - /* - * pCompressed ignored in this function. - */ - - if (ccc == NULL) { - return(XcmsFailure); - } - - pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData; - - while (nColors--) { - - /* Make sure format is XcmsRGBFormat */ - if (pXcmsColors_in_out->format != XcmsRGBFormat) { - return(XcmsFailure); - } - - keyIRec.value = pXcmsColors_in_out->spec.RGB.red; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pRedTbl->pBase, - (unsigned)pScreenData->pRedTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.red = answerIRec.intensity; - - keyIRec.value = pXcmsColors_in_out->spec.RGB.green; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pGreenTbl->pBase, - (unsigned)pScreenData->pGreenTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.green = answerIRec.intensity; - - keyIRec.value = pXcmsColors_in_out->spec.RGB.blue; - if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb, - (char *)pScreenData->pBlueTbl->pBase, - (unsigned)pScreenData->pBlueTbl->nEntries, - (unsigned)sizeof(IntensityRec), - (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) { - return(XcmsFailure); - } - tmpRGBi.blue = answerIRec.intensity; - - memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi)); - (pXcmsColors_in_out++)->format = XcmsRGBiFormat; - } - return(XcmsSuccess); -} - -/* - * NAME - * _XcmsInitScrnDefaultInfo - * - * SYNOPSIS - */ -/* ARGSUSED */ -int -_XcmsLRGB_InitScrnDefault( - Display *dpy, - int screenNumber, - XcmsPerScrnInfo *pPerScrnInfo) -/* - * DESCRIPTION - * Given a display and screen number, this routine attempts - * to initialize the Xcms per Screen Info structure - * (XcmsPerScrnInfo) with defaults. - * - * RETURNS - * Returns zero if initialization failed; non-zero otherwise. - */ -{ - pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X = - Default_RGB_SCCData.RGBtoXYZmatrix[0][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[0][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[0][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = - Default_RGB_SCCData.RGBtoXYZmatrix[1][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[1][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[1][2]; - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z = - Default_RGB_SCCData.RGBtoXYZmatrix[2][0] + - Default_RGB_SCCData.RGBtoXYZmatrix[2][1] + - Default_RGB_SCCData.RGBtoXYZmatrix[2][2]; - if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) ) - || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) { - pPerScrnInfo->screenData = (XPointer)NULL; - pPerScrnInfo->state = XcmsInitNone; - return(0); - } - pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0; - pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat; - pPerScrnInfo->screenWhitePt.pixel = 0; - pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet; - pPerScrnInfo->state = XcmsInitFailure; /* default initialization */ - return(1); -} +
+/*
+ * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
+ * All Rights Reserved
+ *
+ * This file is a component of an X Window System-specific implementation
+ * of Xcms based on the TekColor Color Management System. Permission is
+ * hereby granted to use, copy, modify, sell, and otherwise distribute this
+ * software and its documentation for any purpose and without fee, provided
+ * that this copyright, permission, and disclaimer notice is reproduced in
+ * all copies of this software and in supporting documentation. TekColor
+ * is a trademark of Tektronix, Inc.
+ *
+ * Tektronix makes no representation about the suitability of this software
+ * for any purpose. It is provided "as is" and with all faults.
+ *
+ * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
+ * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE.
+ *
+ *
+ * NAME
+ * XcmsLRGB.c
+ *
+ * DESCRIPTION
+ * This file contains the conversion routines:
+ * 1. CIE XYZ to RGB intensity
+ * 2. RGB intensity to device RGB
+ * 3. device RGB to RGB intensity
+ * 4. RGB intensity to CIE XYZ
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xcmsint.h"
+#include "Cv.h"
+
+/*
+ * LOCAL DEFINES
+ * #define declarations local to this package.
+ */
+#define EPS 0.001
+#ifndef MIN
+#define MIN(x,y) ((x) > (y) ? (y) : (x))
+#endif /* MIN */
+#ifndef MAX
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#endif /* MAX */
+#ifndef MIN3
+#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x))
+#endif /* MIN3 */
+#ifndef MAX3
+#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z))))
+#endif /* MAX3 */
+
+/*
+ * LOCAL TYPEDEFS
+ * typedefs local to this package (for use with local vars).
+ *
+ */
+
+/*
+ * FORWARD DECLARATIONS
+ */
+static void LINEAR_RGB_FreeSCCData(XPointer pScreenDataTemp);
+static int LINEAR_RGB_InitSCCData(Display *dpy,
+ int screenNumber, XcmsPerScrnInfo *pPerScrnInfo);
+static int XcmsLRGB_RGB_ParseString(register char *spec, XcmsColor *pColor);
+static int XcmsLRGB_RGBi_ParseString(register char *spec, XcmsColor *pColor);
+static Status
+_XcmsGetTableType0(
+ IntensityTbl *pTbl,
+ int format,
+ char **pChar,
+ unsigned long *pCount);
+static Status
+_XcmsGetTableType1(
+ IntensityTbl *pTbl,
+ int format,
+ char **pChar,
+ unsigned long *pCount);
+
+/*
+ * LOCALS VARIABLES
+ * Variables local to this package.
+ * Usage example:
+ * static int ExampleLocalVar;
+ */
+
+static unsigned short const MASK[17] = {
+ 0x0000, /* 0 bitsPerRGB */
+ 0x8000, /* 1 bitsPerRGB */
+ 0xc000, /* 2 bitsPerRGB */
+ 0xe000, /* 3 bitsPerRGB */
+ 0xf000, /* 4 bitsPerRGB */
+ 0xf800, /* 5 bitsPerRGB */
+ 0xfc00, /* 6 bitsPerRGB */
+ 0xfe00, /* 7 bitsPerRGB */
+ 0xff00, /* 8 bitsPerRGB */
+ 0xff80, /* 9 bitsPerRGB */
+ 0xffc0, /* 10 bitsPerRGB */
+ 0xffe0, /* 11 bitsPerRGB */
+ 0xfff0, /* 12 bitsPerRGB */
+ 0xfff8, /* 13 bitsPerRGB */
+ 0xfffc, /* 14 bitsPerRGB */
+ 0xfffe, /* 15 bitsPerRGB */
+ 0xffff /* 16 bitsPerRGB */
+};
+
+
+ /*
+ * A NULL terminated array of function pointers that when applied
+ * in series will convert an XcmsColor structure from XcmsRGBFormat
+ * to XcmsCIEXYZFormat.
+ */
+static XcmsConversionProc Fl_RGB_to_CIEXYZ[] = {
+ (XcmsConversionProc)XcmsRGBToRGBi,
+ (XcmsConversionProc)XcmsRGBiToCIEXYZ,
+ NULL
+};
+
+ /*
+ * A NULL terminated array of function pointers that when applied
+ * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
+ * to XcmsRGBFormat.
+ */
+static XcmsConversionProc Fl_CIEXYZ_to_RGB[] = {
+ (XcmsConversionProc)XcmsCIEXYZToRGBi,
+ (XcmsConversionProc)XcmsRGBiToRGB,
+ NULL
+};
+
+ /*
+ * A NULL terminated array of function pointers that when applied
+ * in series will convert an XcmsColor structure from XcmsRGBiFormat
+ * to XcmsCIEXYZFormat.
+ */
+static XcmsConversionProc Fl_RGBi_to_CIEXYZ[] = {
+ (XcmsConversionProc)XcmsRGBiToCIEXYZ,
+ NULL
+};
+
+ /*
+ * A NULL terminated array of function pointers that when applied
+ * in series will convert an XcmsColor structure from XcmsCIEXYZFormat
+ * to XcmsRGBiFormat.
+ */
+static XcmsConversionProc Fl_CIEXYZ_to_RGBi[] = {
+ (XcmsConversionProc)XcmsCIEXYZToRGBi,
+ NULL
+};
+
+ /*
+ * RGBi Color Spaces
+ */
+XcmsColorSpace XcmsRGBiColorSpace =
+ {
+ _XcmsRGBi_prefix, /* prefix */
+ XcmsRGBiFormat, /* id */
+ XcmsLRGB_RGBi_ParseString, /* parseString */
+ Fl_RGBi_to_CIEXYZ, /* to_CIEXYZ */
+ Fl_CIEXYZ_to_RGBi, /* from_CIEXYZ */
+ 1
+ };
+
+ /*
+ * RGB Color Spaces
+ */
+XcmsColorSpace XcmsRGBColorSpace =
+ {
+ _XcmsRGB_prefix, /* prefix */
+ XcmsRGBFormat, /* id */
+ XcmsLRGB_RGB_ParseString, /* parseString */
+ Fl_RGB_to_CIEXYZ, /* to_CIEXYZ */
+ Fl_CIEXYZ_to_RGB, /* from_CIEXYZ */
+ 1
+ };
+
+ /*
+ * Device-Independent Color Spaces known to the
+ * LINEAR_RGB Screen Color Characteristics Function Set.
+ */
+static XcmsColorSpace *DDColorSpaces[] = {
+ &XcmsRGBColorSpace,
+ &XcmsRGBiColorSpace,
+ NULL
+};
+
+
+/*
+ * GLOBALS
+ * Variables declared in this package that are allowed
+ * to be used globally.
+ */
+
+ /*
+ * LINEAR_RGB Screen Color Characteristics Function Set.
+ */
+XcmsFunctionSet XcmsLinearRGBFunctionSet =
+ {
+ &DDColorSpaces[0], /* pDDColorSpaces */
+ LINEAR_RGB_InitSCCData, /* pInitScrnFunc */
+ LINEAR_RGB_FreeSCCData /* pFreeSCCData */
+ };
+
+/*
+ * DESCRIPTION
+ * Contents of Default SCCData should be replaced if other
+ * data should be used as default.
+ *
+ *
+ */
+
+/*
+ * NAME Tektronix 19" (Sony) CRT
+ * PART_NUMBER 119-2451-00
+ * MODEL Tek4300, Tek4800
+ */
+
+static IntensityRec const Default_RGB_RedTuples[] = {
+ /* {unsigned short value, XcmsFloat intensity} */
+ { 0x0000, 0.000000 },
+ { 0x0909, 0.000000 },
+ { 0x0a0a, 0.000936 },
+ { 0x0f0f, 0.001481 },
+ { 0x1414, 0.002329 },
+ { 0x1919, 0.003529 },
+ { 0x1e1e, 0.005127 },
+ { 0x2323, 0.007169 },
+ { 0x2828, 0.009699 },
+ { 0x2d2d, 0.012759 },
+ { 0x3232, 0.016392 },
+ { 0x3737, 0.020637 },
+ { 0x3c3c, 0.025533 },
+ { 0x4141, 0.031119 },
+ { 0x4646, 0.037431 },
+ { 0x4b4b, 0.044504 },
+ { 0x5050, 0.052373 },
+ { 0x5555, 0.061069 },
+ { 0x5a5a, 0.070624 },
+ { 0x5f5f, 0.081070 },
+ { 0x6464, 0.092433 },
+ { 0x6969, 0.104744 },
+ { 0x6e6e, 0.118026 },
+ { 0x7373, 0.132307 },
+ { 0x7878, 0.147610 },
+ { 0x7d7d, 0.163958 },
+ { 0x8282, 0.181371 },
+ { 0x8787, 0.199871 },
+ { 0x8c8c, 0.219475 },
+ { 0x9191, 0.240202 },
+ { 0x9696, 0.262069 },
+ { 0x9b9b, 0.285089 },
+ { 0xa0a0, 0.309278 },
+ { 0xa5a5, 0.334647 },
+ { 0xaaaa, 0.361208 },
+ { 0xafaf, 0.388971 },
+ { 0xb4b4, 0.417945 },
+ { 0xb9b9, 0.448138 },
+ { 0xbebe, 0.479555 },
+ { 0xc3c3, 0.512202 },
+ { 0xc8c8, 0.546082 },
+ { 0xcdcd, 0.581199 },
+ { 0xd2d2, 0.617552 },
+ { 0xd7d7, 0.655144 },
+ { 0xdcdc, 0.693971 },
+ { 0xe1e1, 0.734031 },
+ { 0xe6e6, 0.775322 },
+ { 0xebeb, 0.817837 },
+ { 0xf0f0, 0.861571 },
+ { 0xf5f5, 0.906515 },
+ { 0xfafa, 0.952662 },
+ { 0xffff, 1.000000 }
+};
+
+static IntensityRec const Default_RGB_GreenTuples[] = {
+ /* {unsigned short value, XcmsFloat intensity} */
+ { 0x0000, 0.000000 },
+ { 0x1313, 0.000000 },
+ { 0x1414, 0.000832 },
+ { 0x1919, 0.001998 },
+ { 0x1e1e, 0.003612 },
+ { 0x2323, 0.005736 },
+ { 0x2828, 0.008428 },
+ { 0x2d2d, 0.011745 },
+ { 0x3232, 0.015740 },
+ { 0x3737, 0.020463 },
+ { 0x3c3c, 0.025960 },
+ { 0x4141, 0.032275 },
+ { 0x4646, 0.039449 },
+ { 0x4b4b, 0.047519 },
+ { 0x5050, 0.056520 },
+ { 0x5555, 0.066484 },
+ { 0x5a5a, 0.077439 },
+ { 0x5f5f, 0.089409 },
+ { 0x6464, 0.102418 },
+ { 0x6969, 0.116485 },
+ { 0x6e6e, 0.131625 },
+ { 0x7373, 0.147853 },
+ { 0x7878, 0.165176 },
+ { 0x7d7d, 0.183604 },
+ { 0x8282, 0.203140 },
+ { 0x8787, 0.223783 },
+ { 0x8c8c, 0.245533 },
+ { 0x9191, 0.268384 },
+ { 0x9696, 0.292327 },
+ { 0x9b9b, 0.317351 },
+ { 0xa0a0, 0.343441 },
+ { 0xa5a5, 0.370580 },
+ { 0xaaaa, 0.398747 },
+ { 0xafaf, 0.427919 },
+ { 0xb4b4, 0.458068 },
+ { 0xb9b9, 0.489165 },
+ { 0xbebe, 0.521176 },
+ { 0xc3c3, 0.554067 },
+ { 0xc8c8, 0.587797 },
+ { 0xcdcd, 0.622324 },
+ { 0xd2d2, 0.657604 },
+ { 0xd7d7, 0.693588 },
+ { 0xdcdc, 0.730225 },
+ { 0xe1e1, 0.767459 },
+ { 0xe6e6, 0.805235 },
+ { 0xebeb, 0.843491 },
+ { 0xf0f0, 0.882164 },
+ { 0xf5f5, 0.921187 },
+ { 0xfafa, 0.960490 },
+ { 0xffff, 1.000000 }
+};
+
+static IntensityRec const Default_RGB_BlueTuples[] = {
+ /* {unsigned short value, XcmsFloat intensity} */
+ { 0x0000, 0.000000 },
+ { 0x0e0e, 0.000000 },
+ { 0x0f0f, 0.001341 },
+ { 0x1414, 0.002080 },
+ { 0x1919, 0.003188 },
+ { 0x1e1e, 0.004729 },
+ { 0x2323, 0.006766 },
+ { 0x2828, 0.009357 },
+ { 0x2d2d, 0.012559 },
+ { 0x3232, 0.016424 },
+ { 0x3737, 0.021004 },
+ { 0x3c3c, 0.026344 },
+ { 0x4141, 0.032489 },
+ { 0x4646, 0.039481 },
+ { 0x4b4b, 0.047357 },
+ { 0x5050, 0.056154 },
+ { 0x5555, 0.065903 },
+ { 0x5a5a, 0.076634 },
+ { 0x5f5f, 0.088373 },
+ { 0x6464, 0.101145 },
+ { 0x6969, 0.114968 },
+ { 0x6e6e, 0.129862 },
+ { 0x7373, 0.145841 },
+ { 0x7878, 0.162915 },
+ { 0x7d7d, 0.181095 },
+ { 0x8282, 0.200386 },
+ { 0x8787, 0.220791 },
+ { 0x8c8c, 0.242309 },
+ { 0x9191, 0.264937 },
+ { 0x9696, 0.288670 },
+ { 0x9b9b, 0.313499 },
+ { 0xa0a0, 0.339410 },
+ { 0xa5a5, 0.366390 },
+ { 0xaaaa, 0.394421 },
+ { 0xafaf, 0.423481 },
+ { 0xb4b4, 0.453547 },
+ { 0xb9b9, 0.484592 },
+ { 0xbebe, 0.516587 },
+ { 0xc3c3, 0.549498 },
+ { 0xc8c8, 0.583291 },
+ { 0xcdcd, 0.617925 },
+ { 0xd2d2, 0.653361 },
+ { 0xd7d7, 0.689553 },
+ { 0xdcdc, 0.726454 },
+ { 0xe1e1, 0.764013 },
+ { 0xe6e6, 0.802178 },
+ { 0xebeb, 0.840891 },
+ { 0xf0f0, 0.880093 },
+ { 0xf5f5, 0.919723 },
+ { 0xfafa, 0.959715 },
+ { 0xffff, 1.00000 }
+};
+
+static IntensityTbl Default_RGB_RedTbl = {
+ /* IntensityRec *pBase */
+ (IntensityRec *) Default_RGB_RedTuples,
+ /* unsigned int nEntries */
+ 52
+};
+
+static IntensityTbl Default_RGB_GreenTbl = {
+ /* IntensityRec *pBase */
+ (IntensityRec *)Default_RGB_GreenTuples,
+ /* unsigned int nEntries */
+ 50
+};
+
+static IntensityTbl Default_RGB_BlueTbl = {
+ /* IntensityRec *pBase */
+ (IntensityRec *)Default_RGB_BlueTuples,
+ /* unsigned int nEntries */
+ 51
+};
+
+static LINEAR_RGB_SCCData Default_RGB_SCCData = {
+ /* XcmsFloat XYZtoRGBmatrix[3][3] */
+ {
+ { 3.48340481253539000, -1.52176374927285200, -0.55923133354049780 },
+ {-1.07152751306193600, 1.96593795204372400, 0.03673691339553462 },
+ { 0.06351179790497788, -0.20020501000496480, 0.81070942031648220 }
+ },
+
+ /* XcmsFloat RGBtoXYZmatrix[3][3] */
+ {
+ { 0.38106149108714790, 0.32025712365352110, 0.24834578525933100 },
+ { 0.20729745115140850, 0.68054638776373240, 0.11215616108485920 },
+ { 0.02133944350088028, 0.14297193020246480, 1.24172892629665500 }
+ },
+
+ /* IntensityTbl *pRedTbl */
+ &Default_RGB_RedTbl,
+
+ /* IntensityTbl *pGreenTbl */
+ &Default_RGB_GreenTbl,
+
+ /* IntensityTbl *pBlueTbl */
+ &Default_RGB_BlueTbl
+};
+
+/************************************************************************
+ * *
+ * PRIVATE ROUTINES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * LINEAR_RGB_InitSCCData()
+ *
+ * SYNOPSIS
+ */
+static Status
+LINEAR_RGB_InitSCCData(
+ Display *dpy,
+ int screenNumber,
+ XcmsPerScrnInfo *pPerScrnInfo)
+/*
+ * DESCRIPTION
+ *
+ * RETURNS
+ * XcmsFailure if failed.
+ * XcmsSuccess if succeeded.
+ *
+ */
+{
+ Atom CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True);
+ Atom MatrixAtom = XInternAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True);
+ int format_return, count, cType, nTables;
+ unsigned long nitems, nbytes_return;
+ char *property_return, *pChar;
+ XcmsFloat *pValue;
+#ifdef ALLDEBUG
+ IntensityRec *pIRec;
+#endif /* ALLDEBUG */
+ VisualID visualID;
+
+ LINEAR_RGB_SCCData *pScreenData, *pScreenDefaultData;
+ XcmsIntensityMap *pNewMap;
+
+ /*
+ * Allocate memory for pScreenData
+ */
+ if (!(pScreenData = pScreenDefaultData = (LINEAR_RGB_SCCData *)
+ Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
+ return(XcmsFailure);
+ }
+
+ /*
+ * 1. Get the XYZ->RGB and RGB->XYZ matrices
+ */
+
+ if (MatrixAtom == None ||
+ !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), MatrixAtom,
+ &format_return, &nitems, &nbytes_return, &property_return) ||
+ nitems != 18 || format_return != 32) {
+ /*
+ * As per the XDCCC, there must be 18 data items and each must be
+ * in 32 bits !
+ */
+ goto FreeSCCData;
+
+ } else {
+
+ /*
+ * RGBtoXYZ and XYZtoRGB matrices
+ */
+ pValue = (XcmsFloat *) pScreenData;
+ pChar = property_return;
+ for (count = 0; count < 18; count++) {
+ *pValue++ = (long)_XcmsGetElement(format_return, &pChar,
+ &nitems) / (XcmsFloat)XDCCC_NUMBER;
+ }
+ Xfree ((char *)property_return);
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
+ pScreenData->RGBtoXYZmatrix[0][0] +
+ pScreenData->RGBtoXYZmatrix[0][1] +
+ pScreenData->RGBtoXYZmatrix[0][2];
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
+ pScreenData->RGBtoXYZmatrix[1][0] +
+ pScreenData->RGBtoXYZmatrix[1][1] +
+ pScreenData->RGBtoXYZmatrix[1][2];
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
+ pScreenData->RGBtoXYZmatrix[2][0] +
+ pScreenData->RGBtoXYZmatrix[2][1] +
+ pScreenData->RGBtoXYZmatrix[2][2];
+
+ /*
+ * Compute the Screen White Point
+ */
+ if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
+ || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
+ goto FreeSCCData;
+ } else {
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
+ }
+ pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
+ pPerScrnInfo->screenWhitePt.pixel = 0;
+
+#ifdef PDEBUG
+ printf ("RGB to XYZ Matrix values:\n");
+ printf (" %f %f %f\n %f %f %f\n %f %f %f\n",
+ pScreenData->RGBtoXYZmatrix[0][0],
+ pScreenData->RGBtoXYZmatrix[0][1],
+ pScreenData->RGBtoXYZmatrix[0][2],
+ pScreenData->RGBtoXYZmatrix[1][0],
+ pScreenData->RGBtoXYZmatrix[1][1],
+ pScreenData->RGBtoXYZmatrix[1][2],
+ pScreenData->RGBtoXYZmatrix[2][0],
+ pScreenData->RGBtoXYZmatrix[2][1],
+ pScreenData->RGBtoXYZmatrix[2][2]);
+ printf ("XYZ to RGB Matrix values:\n");
+ printf (" %f %f %f\n %f %f %f\n %f %f %f\n",
+ pScreenData->XYZtoRGBmatrix[0][0],
+ pScreenData->XYZtoRGBmatrix[0][1],
+ pScreenData->XYZtoRGBmatrix[0][2],
+ pScreenData->XYZtoRGBmatrix[1][0],
+ pScreenData->XYZtoRGBmatrix[1][1],
+ pScreenData->XYZtoRGBmatrix[1][2],
+ pScreenData->XYZtoRGBmatrix[2][0],
+ pScreenData->XYZtoRGBmatrix[2][1],
+ pScreenData->XYZtoRGBmatrix[2][2]);
+ printf ("Screen White Pt value: %f %f %f\n",
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X,
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y,
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z);
+#endif /* PDEBUG */
+ }
+
+ /*
+ * 2. Get the Intensity Profile
+ */
+ if (CorrectAtom == None ||
+ !_XcmsGetProperty (dpy, RootWindow(dpy, screenNumber), CorrectAtom,
+ &format_return, &nitems, &nbytes_return, &property_return)) {
+ goto FreeSCCData;
+ }
+
+ pChar = property_return;
+
+ while (nitems) {
+ switch (format_return) {
+ case 8:
+ /*
+ * Must have at least:
+ * VisualID0
+ * VisualID1
+ * VisualID2
+ * VisualID3
+ * type
+ * count
+ * length
+ * intensity1
+ * intensity2
+ */
+ if (nitems < 9) {
+ goto Free_property_return;
+ }
+ count = 3;
+ break;
+ case 16:
+ /*
+ * Must have at least:
+ * VisualID0
+ * VisualID3
+ * type
+ * count
+ * length
+ * intensity1
+ * intensity2
+ */
+ if (nitems < 7) {
+ goto Free_property_return;
+ }
+ count = 1;
+ break;
+ case 32:
+ /*
+ * Must have at least:
+ * VisualID0
+ * type
+ * count
+ * length
+ * intensity1
+ * intensity2
+ */
+ if (nitems < 6) {
+ goto Free_property_return;
+ }
+ count = 0;
+ break;
+ default:
+ goto Free_property_return;
+ }
+
+ /*
+ * Get VisualID
+ */
+ visualID = _XcmsGetElement(format_return, &pChar, &nitems);
+ while (count--) {
+ visualID = visualID << format_return;
+ visualID |= _XcmsGetElement(format_return, &pChar, &nitems);
+ }
+
+ if (visualID == 0) {
+ /*
+ * This is a shared intensity table
+ */
+ pScreenData = pScreenDefaultData;
+ } else {
+ /*
+ * This is a per-Visual intensity table
+ */
+ if (!(pScreenData = (LINEAR_RGB_SCCData *)
+ Xcalloc (1, sizeof(LINEAR_RGB_SCCData)))) {
+ goto Free_property_return;
+ }
+ /* copy matrices */
+ memcpy((char *)pScreenData, (char *)pScreenDefaultData,
+ 18 * sizeof(XcmsFloat));
+
+ /* Create, initialize, and add map */
+ if (!(pNewMap = (XcmsIntensityMap *)
+ Xcalloc (1, sizeof(XcmsIntensityMap)))) {
+ Xfree((char *)pScreenData);
+ goto Free_property_return;
+ }
+ pNewMap->visualID = visualID;
+ pNewMap->screenData = (XPointer)pScreenData;
+ pNewMap->pFreeScreenData = LINEAR_RGB_FreeSCCData;
+ pNewMap->pNext =
+ (XcmsIntensityMap *)dpy->cms.perVisualIntensityMaps;
+ dpy->cms.perVisualIntensityMaps = (XPointer)pNewMap;
+ dpy->free_funcs->intensityMaps = _XcmsFreeIntensityMaps;
+ }
+
+ cType = _XcmsGetElement(format_return, &pChar, &nitems);
+ nTables = _XcmsGetElement(format_return, &pChar, &nitems);
+
+ if (cType == 0) {
+
+ /* Red Intensity Table */
+ if (!(pScreenData->pRedTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto Free_property_return;
+ }
+ if (_XcmsGetTableType0(pScreenData->pRedTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeRedTbl;
+ }
+
+ if (nTables == 1) {
+ /* Green Intensity Table */
+ pScreenData->pGreenTbl = pScreenData->pRedTbl;
+ /* Blue Intensity Table */
+ pScreenData->pBlueTbl = pScreenData->pRedTbl;
+ } else {
+ /* Green Intensity Table */
+ if (!(pScreenData->pGreenTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto FreeRedTblElements;
+ }
+ if (_XcmsGetTableType0(pScreenData->pGreenTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeGreenTbl;
+ }
+
+ /* Blue Intensity Table */
+ if (!(pScreenData->pBlueTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto FreeGreenTblElements;
+ }
+ if (_XcmsGetTableType0(pScreenData->pBlueTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeBlueTbl;
+ }
+ }
+ } else if (cType == 1) {
+ /* Red Intensity Table */
+ if (!(pScreenData->pRedTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto Free_property_return;
+ }
+ if (_XcmsGetTableType1(pScreenData->pRedTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeRedTbl;
+ }
+
+ if (nTables == 1) {
+
+ /* Green Intensity Table */
+ pScreenData->pGreenTbl = pScreenData->pRedTbl;
+ /* Blue Intensity Table */
+ pScreenData->pBlueTbl = pScreenData->pRedTbl;
+
+ } else {
+
+ /* Green Intensity Table */
+ if (!(pScreenData->pGreenTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto FreeRedTblElements;
+ }
+ if (_XcmsGetTableType1(pScreenData->pGreenTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeGreenTbl;
+ }
+
+ /* Blue Intensity Table */
+ if (!(pScreenData->pBlueTbl = (IntensityTbl *)
+ Xcalloc (1, sizeof(IntensityTbl)))) {
+ goto FreeGreenTblElements;
+ }
+ if (_XcmsGetTableType1(pScreenData->pBlueTbl, format_return, &pChar,
+ &nitems) == XcmsFailure) {
+ goto FreeBlueTbl;
+ }
+ }
+ } else {
+ goto Free_property_return;
+ }
+
+#ifdef ALLDEBUG
+ printf ("Intensity Table RED %d\n", pScreenData->pRedTbl->nEntries);
+ pIRec = (IntensityRec *) pScreenData->pRedTbl->pBase;
+ for (count = 0; count < pScreenData->pRedTbl->nEntries; count++, pIRec++) {
+ printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+ }
+ if (pScreenData->pGreenTbl->pBase != pScreenData->pRedTbl->pBase) {
+ printf ("Intensity Table GREEN %d\n", pScreenData->pGreenTbl->nEntries);
+ pIRec = (IntensityRec *)pScreenData->pGreenTbl->pBase;
+ for (count = 0; count < pScreenData->pGreenTbl->nEntries; count++, pIRec++) {
+ printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+ }
+ }
+ if (pScreenData->pBlueTbl->pBase != pScreenData->pRedTbl->pBase) {
+ printf ("Intensity Table BLUE %d\n", pScreenData->pBlueTbl->nEntries);
+ pIRec = (IntensityRec *) pScreenData->pBlueTbl->pBase;
+ for (count = 0; count < pScreenData->pBlueTbl->nEntries; count++, pIRec++) {
+ printf ("\t0x%4x\t%f\n", pIRec->value, pIRec->intensity);
+ }
+ }
+#endif /* ALLDEBUG */
+ }
+
+ Xfree ((char *)property_return);
+
+ /* Free the old memory and use the new structure created. */
+ LINEAR_RGB_FreeSCCData(pPerScrnInfo->screenData);
+
+ pPerScrnInfo->functionSet = (XPointer) &XcmsLinearRGBFunctionSet;
+
+ pPerScrnInfo->screenData = (XPointer) pScreenData;
+
+ pPerScrnInfo->state = XcmsInitSuccess;
+
+ return(XcmsSuccess);
+
+FreeBlueTblElements:
+ Xfree((char *)pScreenData->pBlueTbl->pBase);
+
+FreeBlueTbl:
+ Xfree((char *)pScreenData->pBlueTbl);
+
+FreeGreenTblElements:
+ Xfree((char *)pScreenData->pGreenTbl->pBase);
+
+FreeGreenTbl:
+ Xfree((char *)pScreenData->pGreenTbl);
+
+FreeRedTblElements:
+ Xfree((char *)pScreenData->pRedTbl->pBase);
+
+FreeRedTbl:
+ Xfree((char *)pScreenData->pRedTbl);
+
+Free_property_return:
+ Xfree ((char *)property_return);
+
+FreeSCCData:
+ Xfree((char *)pScreenDefaultData);
+ pPerScrnInfo->state = XcmsInitNone;
+ return(XcmsFailure);
+}
+
+
+/*
+ * NAME
+ * LINEAR_RGB_FreeSCCData()
+ *
+ * SYNOPSIS
+ */
+static void
+LINEAR_RGB_FreeSCCData(
+ XPointer pScreenDataTemp)
+/*
+ * DESCRIPTION
+ *
+ * RETURNS
+ * 0 if failed.
+ * 1 if succeeded with no modifications.
+ *
+ */
+{
+ LINEAR_RGB_SCCData *pScreenData = (LINEAR_RGB_SCCData *) pScreenDataTemp;
+
+ if (pScreenData && pScreenData != &Default_RGB_SCCData) {
+ if (pScreenData->pRedTbl) {
+ if (pScreenData->pGreenTbl) {
+ if (pScreenData->pRedTbl->pBase !=
+ pScreenData->pGreenTbl->pBase) {
+ if (pScreenData->pGreenTbl->pBase) {
+ Xfree ((char *)pScreenData->pGreenTbl->pBase);
+ }
+ }
+ if (pScreenData->pGreenTbl != pScreenData->pRedTbl) {
+ Xfree ((char *)pScreenData->pGreenTbl);
+ }
+ }
+ if (pScreenData->pBlueTbl) {
+ if (pScreenData->pRedTbl->pBase !=
+ pScreenData->pBlueTbl->pBase) {
+ if (pScreenData->pBlueTbl->pBase) {
+ Xfree ((char *)pScreenData->pBlueTbl->pBase);
+ }
+ }
+ if (pScreenData->pBlueTbl != pScreenData->pRedTbl) {
+ Xfree ((char *)pScreenData->pBlueTbl);
+ }
+ }
+ if (pScreenData->pRedTbl->pBase) {
+ Xfree ((char *)pScreenData->pRedTbl->pBase);
+ }
+ Xfree ((char *)pScreenData->pRedTbl);
+ }
+ Xfree ((char *)pScreenData);
+ }
+}
+
+
+
+/************************************************************************
+ * *
+ * API PRIVATE ROUTINES *
+ * *
+ ************************************************************************/
+
+/*
+ * NAME
+ * _XcmsGetTableType0
+ *
+ * SYNOPSIS
+ */
+static Status
+_XcmsGetTableType0(
+ IntensityTbl *pTbl,
+ int format,
+ char **pChar,
+ unsigned long *pCount)
+/*
+ * DESCRIPTION
+ *
+ * RETURNS
+ * XcmsFailure if failed.
+ * XcmsSuccess if succeeded.
+ *
+ */
+{
+ unsigned int nElements;
+ IntensityRec *pIRec;
+
+ nElements = pTbl->nEntries =
+ _XcmsGetElement(format, pChar, pCount) + 1;
+ if (!(pIRec = pTbl->pBase = (IntensityRec *)
+ Xcalloc (nElements, sizeof(IntensityRec)))) {
+ return(XcmsFailure);
+ }
+
+ switch (format) {
+ case 8:
+ for (; nElements--; pIRec++) {
+ /* 0xFFFF/0xFF = 0x101 */
+ pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101;
+ pIRec->intensity =
+ _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0;
+ }
+ break;
+ case 16:
+ for (; nElements--; pIRec++) {
+ pIRec->value = _XcmsGetElement (format, pChar, pCount);
+ pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+ / (XcmsFloat)65535.0;
+ }
+ break;
+ case 32:
+ for (; nElements--; pIRec++) {
+ pIRec->value = _XcmsGetElement (format, pChar, pCount);
+ pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+ / (XcmsFloat)4294967295.0;
+ }
+ break;
+ default:
+ return(XcmsFailure);
+ }
+ return(XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * _XcmsGetTableType1
+ *
+ * SYNOPSIS
+ */
+static Status
+_XcmsGetTableType1(
+ IntensityTbl *pTbl,
+ int format,
+ char **pChar,
+ unsigned long *pCount)
+/*
+ * DESCRIPTION
+ *
+ * RETURNS
+ * XcmsFailure if failed.
+ * XcmsSuccess if succeeded.
+ *
+ */
+{
+ int count;
+ unsigned int max_index;
+ IntensityRec *pIRec;
+
+ max_index = _XcmsGetElement(format, pChar, pCount);
+ pTbl->nEntries = max_index + 1;
+ if (!(pIRec = pTbl->pBase = (IntensityRec *)
+ Xcalloc (max_index+1, sizeof(IntensityRec)))) {
+ return(XcmsFailure);
+ }
+
+ switch (format) {
+ case 8:
+ for (count = 0; count < max_index+1; count++, pIRec++) {
+ pIRec->value = (count * 65535) / max_index;
+ pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+ / (XcmsFloat)255.0;
+ }
+ break;
+ case 16:
+ for (count = 0; count < max_index+1; count++, pIRec++) {
+ pIRec->value = (count * 65535) / max_index;
+ pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+ / (XcmsFloat)65535.0;
+ }
+ break;
+ case 32:
+ for (count = 0; count < max_index+1; count++, pIRec++) {
+ pIRec->value = (count * 65535) / max_index;
+ pIRec->intensity = _XcmsGetElement (format, pChar, pCount)
+ / (XcmsFloat)4294967295.0;
+ }
+ break;
+ default:
+ return(XcmsFailure);
+ }
+
+ return(XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * ValueCmp
+ *
+ * SYNOPSIS
+ */
+static int
+_XcmsValueCmp(
+ IntensityRec *p1, IntensityRec *p2)
+/*
+ * DESCRIPTION
+ * Compares the value component of two IntensityRec
+ * structures.
+ *
+ * RETURNS
+ * 0 if p1->value is equal to p2->value
+ * < 0 if p1->value is less than p2->value
+ * > 0 if p1->value is greater than p2->value
+ *
+ */
+{
+ return (p1->value - p2->value);
+}
+
+
+/*
+ * NAME
+ * IntensityCmp
+ *
+ * SYNOPSIS
+ */
+static int
+_XcmsIntensityCmp(
+ IntensityRec *p1, IntensityRec *p2)
+/*
+ * DESCRIPTION
+ * Compares the intensity component of two IntensityRec
+ * structures.
+ *
+ * RETURNS
+ * 0 if equal;
+ * < 0 if first precedes second
+ * > 0 if first succeeds second
+ *
+ */
+{
+ if (p1->intensity < p2->intensity) {
+ return (-1);
+ }
+ if (p1->intensity > p2->intensity) {
+ return (XcmsSuccess);
+ }
+ return (XcmsFailure);
+}
+
+/*
+ * NAME
+ * ValueInterpolation
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+static int
+_XcmsValueInterpolation(
+ IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
+ int bitsPerRGB)
+/*
+ * DESCRIPTION
+ * Based on a given value, performs a linear interpolation
+ * on the intensities between two IntensityRec structures.
+ * Note that the bitsPerRGB parameter is ignored.
+ *
+ * RETURNS
+ * Returns 0 if failed; otherwise non-zero.
+ */
+{
+ XcmsFloat ratio;
+
+ ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) /
+ ((XcmsFloat)hi->value - (XcmsFloat)lo->value);
+ answer->value = key->value;
+ answer->intensity = (hi->intensity - lo->intensity) * ratio;
+ answer->intensity += lo->intensity;
+ return (XcmsSuccess);
+}
+
+/*
+ * NAME
+ * IntensityInterpolation
+ *
+ * SYNOPSIS
+ */
+static int
+_XcmsIntensityInterpolation(
+ IntensityRec *key, IntensityRec *lo, IntensityRec *hi, IntensityRec *answer,
+ int bitsPerRGB)
+/*
+ * DESCRIPTION
+ * Based on a given intensity, performs a linear interpolation
+ * on the values between two IntensityRec structures.
+ * The bitsPerRGB parameter is necessary to perform rounding
+ * to the correct number of significant bits.
+ *
+ * RETURNS
+ * Returns 0 if failed; otherwise non-zero.
+ */
+{
+ XcmsFloat ratio;
+ long target, up, down;
+ int shift = 16 - bitsPerRGB;
+ int max_color = (1 << bitsPerRGB) - 1;
+
+ ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity);
+ answer->intensity = key->intensity;
+ target = hi->value - lo->value;
+ target *= ratio;
+ target += lo->value;
+
+ /*
+ * Ok now, lets find the closest in respects to bits per RGB
+ */
+ up = ((target >> shift) * 0xFFFF) / max_color;
+ if (up < target) {
+ down = up;
+ up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color;
+ } else {
+ down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color;
+ }
+ answer->value = ((up - target) < (target - down) ? up : down);
+ answer->value &= MASK[bitsPerRGB];
+ return (XcmsSuccess);
+}
+
+
+
+typedef int (*comparProcp)(
+ char *p1,
+ char *p2);
+typedef int (*interpolProcp)(
+ char *key,
+ char *lo,
+ char *hi,
+ char *answer,
+ int bitsPerRGB);
+
+/*
+ * NAME
+ * _XcmsTableSearch
+ *
+ * SYNOPSIS
+ */
+static int
+_XcmsTableSearch(
+ char *key,
+ int bitsPerRGB,
+ char *base,
+ unsigned nel,
+ unsigned nKeyPtrSize,
+ int (*compar)(
+ char *p1,
+ char *p2),
+ int (*interpol)(
+ char *key,
+ char *lo,
+ char *hi,
+ char *answer,
+ int bitsPerRGB),
+ char *answer)
+
+/*
+ * DESCRIPTION
+ * A binary search through the specificied table.
+ *
+ * RETURNS
+ * Returns 0 if failed; otherwise non-zero.
+ *
+ */
+{
+ char *hi, *lo, *mid, *last;
+ int result;
+
+ last = hi = base + ((nel - 1) * nKeyPtrSize);
+ mid = lo = base;
+
+ /* use only the significants bits, then scale into 16 bits */
+ ((IntensityRec *)key)->value = ((unsigned long)
+ (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF)
+ / ((1 << bitsPerRGB) - 1);
+
+ /* Special case so that zero intensity always maps to zero value */
+ if ((*compar) (key,lo) <= 0) {
+ memcpy (answer, lo, nKeyPtrSize);
+ ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
+ return XcmsSuccess;
+ }
+ while (mid != last) {
+ last = mid;
+ mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize;
+ result = (*compar) (key, mid);
+ if (result == 0) {
+
+ memcpy(answer, mid, nKeyPtrSize);
+ ((IntensityRec *)answer)->value &= MASK[bitsPerRGB];
+ return (XcmsSuccess);
+ } else if (result < 0) {
+ hi = mid;
+ } else {
+ lo = mid;
+ }
+ }
+
+ /*
+ * If we got to here, we didn't find a solution, so we
+ * need to apply interpolation.
+ */
+ return ((*interpol)(key, lo, hi, answer, bitsPerRGB));
+}
+
+
+/*
+ * NAME
+ * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector
+ *
+ * SYNOPSIS
+ */
+static void _XcmsMatVec(
+ XcmsFloat *pMat, XcmsFloat *pIn, XcmsFloat *pOut)
+/*
+ * DESCRIPTION
+ * Multiply the passed vector by the passed matrix to return a
+ * vector. Matrix is 3x3, vectors are of length 3.
+ *
+ * RETURNS
+ * void
+ */
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ pOut[i] = 0.0;
+ for (j = 0; j < 3; j++)
+ pOut[i] += *(pMat+(i*3)+j) * pIn[j];
+ }
+}
+
+
+/************************************************************************
+ * *
+ * PUBLIC ROUTINES *
+ * *
+ ************************************************************************/
+
+
+/*
+ * NAME
+ * XcmsLRGB_RGB_ParseString
+ *
+ * SYNOPSIS
+ */
+static int
+XcmsLRGB_RGB_ParseString(
+ register char *spec,
+ XcmsColor *pColor)
+/*
+ * DESCRIPTION
+ * This routines takes a string and attempts to convert
+ * it into a XcmsColor structure with XcmsRGBFormat.
+ *
+ * RETURNS
+ * 0 if failed, non-zero otherwise.
+ */
+{
+ register int n, i;
+ unsigned short r, g, b;
+ char c;
+ char *pchar;
+ unsigned short *pShort;
+
+ /*
+ * Check for old # format
+ */
+ if (*spec == '#') {
+ /*
+ * Attempt to parse the value portion.
+ */
+ spec++;
+ n = strlen(spec);
+ if (n != 3 && n != 6 && n != 9 && n != 12) {
+ return(XcmsFailure);
+ }
+
+ n /= 3;
+ g = b = 0;
+ do {
+ r = g;
+ g = b;
+ b = 0;
+ for (i = n; --i >= 0; ) {
+ c = *spec++;
+ b <<= 4;
+ if (c >= '0' && c <= '9')
+ b |= c - '0';
+ /* assume string in lowercase
+ else if (c >= 'A' && c <= 'F')
+ b |= c - ('A' - 10);
+ */
+ else if (c >= 'a' && c <= 'f')
+ b |= c - ('a' - 10);
+ else return (XcmsFailure);
+ }
+ } while (*spec != '\0');
+
+ /*
+ * Succeeded !
+ */
+ n <<= 2;
+ n = 16 - n;
+ /* shift instead of scale, to match old broken semantics */
+ pColor->spec.RGB.red = r << n;
+ pColor->spec.RGB.green = g << n;
+ pColor->spec.RGB.blue = b << n;
+ } else {
+ if ((pchar = strchr(spec, ':')) == NULL) {
+ return(XcmsFailure);
+ }
+ n = (int)(pchar - spec);
+
+ /*
+ * Check for proper prefix.
+ */
+ if (strncmp(spec, _XcmsRGB_prefix, n) != 0) {
+ return(XcmsFailure);
+ }
+
+ /*
+ * Attempt to parse the value portion.
+ */
+ spec += (n + 1);
+ pShort = &pColor->spec.RGB.red;
+ for (i = 0; i < 3; i++, pShort++, spec++) {
+ n = 0;
+ *pShort = 0;
+ while (*spec != '/' && *spec != '\0') {
+ if (++n > 4) {
+ return(XcmsFailure);
+ }
+ c = *spec++;
+ *pShort <<= 4;
+ if (c >= '0' && c <= '9')
+ *pShort |= c - '0';
+ /* assume string in lowercase
+ else if (c >= 'A' && c <= 'F')
+ *pShort |= c - ('A' - 10);
+ */
+ else if (c >= 'a' && c <= 'f')
+ *pShort |= c - ('a' - 10);
+ else return (XcmsFailure);
+ }
+ if (n == 0)
+ return (XcmsFailure);
+ if (n < 4) {
+ *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1);
+ }
+ }
+ }
+ pColor->format = XcmsRGBFormat;
+ pColor->pixel = 0;
+ return (XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * XcmsLRGB_RGBi_ParseString
+ *
+ * SYNOPSIS
+ */
+static int
+XcmsLRGB_RGBi_ParseString(
+ register char *spec,
+ XcmsColor *pColor)
+/*
+ * DESCRIPTION
+ * This routines takes a string and attempts to convert
+ * it into a XcmsColor structure with XcmsRGBiFormat.
+ * The assumed RGBi string syntax is:
+ * RGBi:<r>/<g>/<b>
+ * Where r, g, and b are in string input format for floats
+ * consisting of:
+ * a. an optional sign
+ * b. a string of numbers possibly containing a decimal point,
+ * c. an optional exponent field containing an 'E' or 'e'
+ * followed by a possibly signed integer string.
+ *
+ * RETURNS
+ * 0 if failed, non-zero otherwise.
+ */
+{
+ int n;
+ char *pchar;
+
+ if ((pchar = strchr(spec, ':')) == NULL) {
+ return(XcmsFailure);
+ }
+ n = (int)(pchar - spec);
+
+ /*
+ * Check for proper prefix.
+ */
+ if (strncmp(spec, _XcmsRGBi_prefix, n) != 0) {
+ return(XcmsFailure);
+ }
+
+ /*
+ * Attempt to parse the value portion.
+ */
+ if (sscanf(spec + n + 1, "%lf/%lf/%lf",
+ &pColor->spec.RGBi.red,
+ &pColor->spec.RGBi.green,
+ &pColor->spec.RGBi.blue) != 3) {
+ char *s; /* Maybe failed due to locale */
+ int f;
+ if ((s = strdup(spec))) {
+ for (f = 0; s[f]; ++f)
+ if (s[f] == '.')
+ s[f] = ',';
+ else if (s[f] == ',')
+ s[f] = '.';
+ if (sscanf(s + n + 1, "%lf/%lf/%lf",
+ &pColor->spec.RGBi.red,
+ &pColor->spec.RGBi.green,
+ &pColor->spec.RGBi.blue) != 3) {
+ free(s);
+ return(XcmsFailure);
+ }
+ free(s);
+ } else
+ return(XcmsFailure);
+ }
+
+ /*
+ * Succeeded !
+ */
+ pColor->format = XcmsRGBiFormat;
+ pColor->pixel = 0;
+ return (XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * XcmsCIEXYZToRGBi - convert CIE XYZ to RGB
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+Status
+XcmsCIEXYZToRGBi(
+ XcmsCCC ccc,
+ XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
+ unsigned int nColors, /* Number of colors */
+ Bool *pCompressed) /* pointer to an array of Bool */
+/*
+ * DESCRIPTION
+ * Converts color specifications in an array of XcmsColor
+ * structures from RGB format to RGBi format.
+ *
+ * RETURNS
+ * XcmsFailure if failed,
+ * XcmsSuccess if succeeded without gamut compression.
+ * XcmsSuccessWithCompression if succeeded with gamut
+ * compression.
+ */
+{
+ LINEAR_RGB_SCCData *pScreenData;
+ XcmsFloat tmp[3];
+ int hasCompressed = 0;
+ unsigned int i;
+ XcmsColor *pColor = pXcmsColors_in_out;
+
+ if (ccc == NULL) {
+ return(XcmsFailure);
+ }
+
+ pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+ /*
+ * XcmsColors should be White Point Adjusted, if necessary, by now!
+ */
+
+ /*
+ * NEW!!! for extended gamut compression
+ *
+ * 1. Need to zero out pCompressed
+ *
+ * 2. Need to save initial address of pColor
+ *
+ * 3. Need to save initial address of pCompressed
+ */
+
+ for (i = 0; i < nColors; i++) {
+
+ /* Make sure format is XcmsCIEXYZFormat */
+ if (pColor->format != XcmsCIEXYZFormat) {
+ return(XcmsFailure);
+ }
+
+ /* Multiply [A]-1 * [XYZ] to get RGB intensity */
+ _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
+ (XcmsFloat *) &pColor->spec, tmp);
+
+ if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
+ (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
+
+ /*
+ * RGBi out of screen's gamut
+ */
+
+ if (ccc->gamutCompProc == NULL) {
+ /*
+ * Aha!! Here's that little trick that will allow
+ * gamut compression routines to get the out of bound
+ * RGBi.
+ */
+ memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
+ pColor->format = XcmsRGBiFormat;
+ return(XcmsFailure);
+ } else if ((*ccc->gamutCompProc)(ccc, pXcmsColors_in_out, nColors,
+ i, pCompressed) == 0) {
+ return(XcmsFailure);
+ }
+
+ /*
+ * The gamut compression function should return colors in CIEXYZ
+ * Also check again to if the new color is within gamut.
+ */
+ if (pColor->format != XcmsCIEXYZFormat) {
+ return(XcmsFailure);
+ }
+ _XcmsMatVec((XcmsFloat *) pScreenData->XYZtoRGBmatrix,
+ (XcmsFloat *) &pColor->spec, tmp);
+ if ((MIN3 (tmp[0], tmp[1], tmp[2]) < -EPS) ||
+ (MAX3 (tmp[0], tmp[1], tmp[2]) > (1.0 + EPS))) {
+ return(XcmsFailure);
+ }
+ hasCompressed++;
+ }
+ memcpy((char *)&pColor->spec, (char *)tmp, sizeof(tmp));
+ /* These if statements are done to ensure the fudge factor is */
+ /* is taken into account. */
+ if (pColor->spec.RGBi.red < 0.0) {
+ pColor->spec.RGBi.red = 0.0;
+ } else if (pColor->spec.RGBi.red > 1.0) {
+ pColor->spec.RGBi.red = 1.0;
+ }
+ if (pColor->spec.RGBi.green < 0.0) {
+ pColor->spec.RGBi.green = 0.0;
+ } else if (pColor->spec.RGBi.green > 1.0) {
+ pColor->spec.RGBi.green = 1.0;
+ }
+ if (pColor->spec.RGBi.blue < 0.0) {
+ pColor->spec.RGBi.blue = 0.0;
+ } else if (pColor->spec.RGBi.blue > 1.0) {
+ pColor->spec.RGBi.blue = 1.0;
+ }
+ (pColor++)->format = XcmsRGBiFormat;
+ }
+ return (hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * LINEAR_RGBi_to_CIEXYZ - convert RGBi to CIEXYZ
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+Status
+XcmsRGBiToCIEXYZ(
+ XcmsCCC ccc,
+ XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
+ unsigned int nColors, /* Number of colors */
+ Bool *pCompressed) /* pointer to a bit array */
+/*
+ * DESCRIPTION
+ * Converts color specifications in an array of XcmsColor
+ * structures from RGBi format to CIEXYZ format.
+ *
+ * RETURNS
+ * XcmsFailure if failed,
+ * XcmsSuccess if succeeded.
+ */
+{
+ LINEAR_RGB_SCCData *pScreenData;
+ XcmsFloat tmp[3];
+
+ /*
+ * pCompressed ignored in this function.
+ */
+
+ if (ccc == NULL) {
+ return(XcmsFailure);
+ }
+
+ pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+ /*
+ * XcmsColors should be White Point Adjusted, if necessary, by now!
+ */
+
+ while (nColors--) {
+
+ /* Multiply [A]-1 * [XYZ] to get RGB intensity */
+ _XcmsMatVec((XcmsFloat *) pScreenData->RGBtoXYZmatrix,
+ (XcmsFloat *) &pXcmsColors_in_out->spec, tmp);
+
+ memcpy((char *)&pXcmsColors_in_out->spec, (char *)tmp, sizeof(tmp));
+ (pXcmsColors_in_out++)->format = XcmsCIEXYZFormat;
+ }
+ return(XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * XcmsRGBiToRGB
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+Status
+XcmsRGBiToRGB(
+ XcmsCCC ccc,
+ XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
+ unsigned int nColors, /* Number of colors */
+ Bool *pCompressed) /* pointer to a bit array */
+/*
+ * DESCRIPTION
+ * Converts color specifications in an array of XcmsColor
+ * structures from RGBi format to RGB format.
+ *
+ * RETURNS
+ * XcmsFailure if failed,
+ * XcmsSuccess if succeeded without gamut compression.
+ * XcmsSuccessWithCompression if succeeded with gamut
+ * compression.
+ */
+{
+ LINEAR_RGB_SCCData *pScreenData;
+ XcmsRGB tmpRGB;
+ IntensityRec keyIRec, answerIRec;
+
+ /*
+ * pCompressed ignored in this function.
+ */
+
+ if (ccc == NULL) {
+ return(XcmsFailure);
+ }
+
+ pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+ while (nColors--) {
+
+ /* Make sure format is XcmsRGBiFormat */
+ if (pXcmsColors_in_out->format != XcmsRGBiFormat) {
+ return(XcmsFailure);
+ }
+
+ keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.red;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pRedTbl->pBase,
+ (unsigned)pScreenData->pRedTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGB.red = answerIRec.value;
+
+ keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.green;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pGreenTbl->pBase,
+ (unsigned)pScreenData->pGreenTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGB.green = answerIRec.value;
+
+ keyIRec.intensity = pXcmsColors_in_out->spec.RGBi.blue;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pBlueTbl->pBase,
+ (unsigned)pScreenData->pBlueTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsIntensityCmp, (interpolProcp)_XcmsIntensityInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGB.blue = answerIRec.value;
+
+ memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGB, sizeof(XcmsRGB));
+ (pXcmsColors_in_out++)->format = XcmsRGBFormat;
+ }
+ return(XcmsSuccess);
+}
+
+
+/*
+ * NAME
+ * XcmsRGBToRGBi
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+Status
+XcmsRGBToRGBi(
+ XcmsCCC ccc,
+ XcmsColor *pXcmsColors_in_out,/* pointer to XcmsColors to convert */
+ unsigned int nColors, /* Number of colors */
+ Bool *pCompressed) /* pointer to a bit array */
+/*
+ * DESCRIPTION
+ * Converts color specifications in an array of XcmsColor
+ * structures from RGB format to RGBi format.
+ *
+ * RETURNS
+ * XcmsFailure if failed,
+ * XcmsSuccess if succeeded.
+ */
+{
+ LINEAR_RGB_SCCData *pScreenData;
+ XcmsRGBi tmpRGBi;
+ IntensityRec keyIRec, answerIRec;
+
+ /*
+ * pCompressed ignored in this function.
+ */
+
+ if (ccc == NULL) {
+ return(XcmsFailure);
+ }
+
+ pScreenData = (LINEAR_RGB_SCCData *)ccc->pPerScrnInfo->screenData;
+
+ while (nColors--) {
+
+ /* Make sure format is XcmsRGBFormat */
+ if (pXcmsColors_in_out->format != XcmsRGBFormat) {
+ return(XcmsFailure);
+ }
+
+ keyIRec.value = pXcmsColors_in_out->spec.RGB.red;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pRedTbl->pBase,
+ (unsigned)pScreenData->pRedTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGBi.red = answerIRec.intensity;
+
+ keyIRec.value = pXcmsColors_in_out->spec.RGB.green;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pGreenTbl->pBase,
+ (unsigned)pScreenData->pGreenTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGBi.green = answerIRec.intensity;
+
+ keyIRec.value = pXcmsColors_in_out->spec.RGB.blue;
+ if (!_XcmsTableSearch((char *)&keyIRec, ccc->visual->bits_per_rgb,
+ (char *)pScreenData->pBlueTbl->pBase,
+ (unsigned)pScreenData->pBlueTbl->nEntries,
+ (unsigned)sizeof(IntensityRec),
+ (comparProcp)_XcmsValueCmp, (interpolProcp)_XcmsValueInterpolation, (char *)&answerIRec)) {
+ return(XcmsFailure);
+ }
+ tmpRGBi.blue = answerIRec.intensity;
+
+ memcpy((char *)&pXcmsColors_in_out->spec, (char *)&tmpRGBi, sizeof(XcmsRGBi));
+ (pXcmsColors_in_out++)->format = XcmsRGBiFormat;
+ }
+ return(XcmsSuccess);
+}
+
+/*
+ * NAME
+ * _XcmsInitScrnDefaultInfo
+ *
+ * SYNOPSIS
+ */
+/* ARGSUSED */
+int
+_XcmsLRGB_InitScrnDefault(
+ Display *dpy,
+ int screenNumber,
+ XcmsPerScrnInfo *pPerScrnInfo)
+/*
+ * DESCRIPTION
+ * Given a display and screen number, this routine attempts
+ * to initialize the Xcms per Screen Info structure
+ * (XcmsPerScrnInfo) with defaults.
+ *
+ * RETURNS
+ * Returns zero if initialization failed; non-zero otherwise.
+ */
+{
+ pPerScrnInfo->screenData = (XPointer)&Default_RGB_SCCData;
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.X =
+ Default_RGB_SCCData.RGBtoXYZmatrix[0][0] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[0][1] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[0][2];
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y =
+ Default_RGB_SCCData.RGBtoXYZmatrix[1][0] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[1][1] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[1][2];
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Z =
+ Default_RGB_SCCData.RGBtoXYZmatrix[2][0] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[2][1] +
+ Default_RGB_SCCData.RGBtoXYZmatrix[2][2];
+ if ((pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y < (1.0 - EPS) )
+ || (pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y > (1.0 + EPS))) {
+ pPerScrnInfo->screenData = (XPointer)NULL;
+ pPerScrnInfo->state = XcmsInitNone;
+ return(0);
+ }
+ pPerScrnInfo->screenWhitePt.spec.CIEXYZ.Y = 1.0;
+ pPerScrnInfo->screenWhitePt.format = XcmsCIEXYZFormat;
+ pPerScrnInfo->screenWhitePt.pixel = 0;
+ pPerScrnInfo->functionSet = (XPointer)&XcmsLinearRGBFunctionSet;
+ pPerScrnInfo->state = XcmsInitFailure; /* default initialization */
+ return(1);
+}
diff --git a/libX11/src/xcms/PrOfId.c b/libX11/src/xcms/PrOfId.c index a96d28cec..1ec36d96c 100644 --- a/libX11/src/xcms/PrOfId.c +++ b/libX11/src/xcms/PrOfId.c @@ -1,97 +1,97 @@ - -/* - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System. Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation. TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose. It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. - * - * - * NAME - * XcmsPrOfId.c - * - * DESCRIPTION - * Source for XcmsPrefixOfFormat() - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xcmsint.h" -#include "Cv.h" - - -/* - * NAME - * XcmsPrefixOfId - * - * SYNOPSIS - */ -char * -XcmsPrefixOfFormat( - XcmsColorFormat id) -/* - * DESCRIPTION - * Returns the color space prefix for the specified color - * space ID if the color space is found in the Color - * Conversion Context. - * - * RETURNS - * Returns a color space prefix. - * - * CAVEATS - * Space is allocated for the returned string, therefore, - * the application is responsible for freeing (using XFree) - * the space. - * - */ -{ - XcmsColorSpace **papColorSpaces; - - /* - * First try Device-Independent color spaces - */ - papColorSpaces = _XcmsDIColorSpaces; - if (papColorSpaces != NULL) { - while (*papColorSpaces != NULL) { - if ((*papColorSpaces)->id == id) { - return strdup((*papColorSpaces)->prefix); - } - papColorSpaces++; - } - } - - /* - * Next try Device-Dependent color spaces - */ - papColorSpaces = _XcmsDDColorSpaces; - if (papColorSpaces != NULL) { - while (*papColorSpaces != NULL) { - if ((*papColorSpaces)->id == id) { - return strdup((*papColorSpaces)->prefix); - } - papColorSpaces++; - } - } - - return(NULL); -} +
+/*
+ * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
+ * All Rights Reserved
+ *
+ * This file is a component of an X Window System-specific implementation
+ * of Xcms based on the TekColor Color Management System. Permission is
+ * hereby granted to use, copy, modify, sell, and otherwise distribute this
+ * software and its documentation for any purpose and without fee, provided
+ * that this copyright, permission, and disclaimer notice is reproduced in
+ * all copies of this software and in supporting documentation. TekColor
+ * is a trademark of Tektronix, Inc.
+ *
+ * Tektronix makes no representation about the suitability of this software
+ * for any purpose. It is provided "as is" and with all faults.
+ *
+ * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
+ * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE.
+ *
+ *
+ * NAME
+ * XcmsPrOfId.c
+ *
+ * DESCRIPTION
+ * Source for XcmsPrefixOfFormat()
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xcmsint.h"
+#include "Cv.h"
+
+
+/*
+ * NAME
+ * XcmsPrefixOfId
+ *
+ * SYNOPSIS
+ */
+char *
+XcmsPrefixOfFormat(
+ XcmsColorFormat id)
+/*
+ * DESCRIPTION
+ * Returns the color space prefix for the specified color
+ * space ID if the color space is found in the Color
+ * Conversion Context.
+ *
+ * RETURNS
+ * Returns a color space prefix.
+ *
+ * CAVEATS
+ * Space is allocated for the returned string, therefore,
+ * the application is responsible for freeing (using XFree)
+ * the space.
+ *
+ */
+{
+ XcmsColorSpace **papColorSpaces;
+
+ /*
+ * First try Device-Independent color spaces
+ */
+ papColorSpaces = _XcmsDIColorSpaces;
+ if (papColorSpaces != NULL) {
+ while (*papColorSpaces != NULL) {
+ if ((*papColorSpaces)->id == id) {
+ return strdup((*papColorSpaces)->prefix);
+ }
+ papColorSpaces++;
+ }
+ }
+
+ /*
+ * Next try Device-Dependent color spaces
+ */
+ papColorSpaces = _XcmsDDColorSpaces;
+ if (papColorSpaces != NULL) {
+ while (*papColorSpaces != NULL) {
+ if ((*papColorSpaces)->id == id) {
+ return strdup((*papColorSpaces)->prefix);
+ }
+ papColorSpaces++;
+ }
+ }
+
+ return(NULL);
+}
diff --git a/libX11/src/xcms/cmsProp.c b/libX11/src/xcms/cmsProp.c index 2826ee7be..b732b800f 100644 --- a/libX11/src/xcms/cmsProp.c +++ b/libX11/src/xcms/cmsProp.c @@ -1,149 +1,149 @@ - -/* - * - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System. Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation. TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose. It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE. - * - * NAME - * XcmsProp.c - * - * DESCRIPTION - * This utility routines for manipulating properties. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xatom.h> -#include "Xlibint.h" -#include "Xcmsint.h" -#include "Cv.h" - - -/************************************************************************ - * * - * API PRIVATE ROUTINES * - * * - ************************************************************************/ - - -/* - * NAME - * _XcmsGetElement -- get an element value from the property passed - * - * SYNOPSIS - */ -unsigned long -_XcmsGetElement( - int format, - char **pValue, - unsigned long *pCount) -/* - * DESCRIPTION - * Get the next element from the property and return it. - * Also increment the pointer the amount needed. - * - * Returns - * unsigned long - */ -{ - unsigned long value; - - switch (format) { - case 32: - value = *((unsigned long *)(*pValue)) & 0xFFFFFFFF; - *pValue += sizeof(unsigned long); - *pCount -= 1; - break; - case 16: - value = *((unsigned short *)(*pValue)); - *pValue += sizeof(unsigned short); - *pCount -= 1; - break; - case 8: - value = *((unsigned char *) (*pValue)); - *pValue += 1; - *pCount -= 1; - break; - default: - value = 0; - break; - } - return(value); -} - - -/* - * NAME - * _XcmsGetProperty -- Determine the existance of a property - * - * SYNOPSIS - */ -int -_XcmsGetProperty( - Display *pDpy, - Window w, - Atom property, - int *pFormat, - unsigned long *pNItems, - unsigned long *pNBytes, - char **pValue) -/* - * DESCRIPTION - * - * Returns - * 0 if property does not exist. - * 1 if property exists. - */ -{ - char *prop_ret; - int format_ret; - long len = 6516; - unsigned long nitems_ret, after_ret; - Atom atom_ret; - int xgwp_ret; - - while (True) { - xgwp_ret = XGetWindowProperty (pDpy, w, property, 0, len, False, - XA_INTEGER, &atom_ret, &format_ret, - &nitems_ret, &after_ret, - (unsigned char **)&prop_ret); - if (xgwp_ret == Success && after_ret > 0) { - len += nitems_ret * (format_ret >> 3); - XFree (prop_ret); - } else { - break; - } - } - if (xgwp_ret != Success || format_ret == 0 || nitems_ret == 0) { - /* the property does not exist or is of an unexpected type or - getting window property failed */ - return(XcmsFailure); - } - - *pFormat = format_ret; - *pNItems = nitems_ret; - *pNBytes = nitems_ret * (format_ret >> 3); - *pValue = prop_ret; - return(XcmsSuccess); -} +
+/*
+ *
+ * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
+ * All Rights Reserved
+ *
+ * This file is a component of an X Window System-specific implementation
+ * of Xcms based on the TekColor Color Management System. Permission is
+ * hereby granted to use, copy, modify, sell, and otherwise distribute this
+ * software and its documentation for any purpose and without fee, provided
+ * that this copyright, permission, and disclaimer notice is reproduced in
+ * all copies of this software and in supporting documentation. TekColor
+ * is a trademark of Tektronix, Inc.
+ *
+ * Tektronix makes no representation about the suitability of this software
+ * for any purpose. It is provided "as is" and with all faults.
+ *
+ * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
+ * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE.
+ *
+ * NAME
+ * XcmsProp.c
+ *
+ * DESCRIPTION
+ * This utility routines for manipulating properties.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xatom.h>
+#include "Xlibint.h"
+#include "Xcmsint.h"
+#include "Cv.h"
+
+
+/************************************************************************
+ * *
+ * API PRIVATE ROUTINES *
+ * *
+ ************************************************************************/
+
+
+/*
+ * NAME
+ * _XcmsGetElement -- get an element value from the property passed
+ *
+ * SYNOPSIS
+ */
+unsigned long
+_XcmsGetElement(
+ int format,
+ char **pValue,
+ unsigned long *pCount)
+/*
+ * DESCRIPTION
+ * Get the next element from the property and return it.
+ * Also increment the pointer the amount needed.
+ *
+ * Returns
+ * unsigned long
+ */
+{
+ unsigned long value;
+
+ switch (format) {
+ case 32:
+ value = *((unsigned long *)(*pValue)) & 0xFFFFFFFF;
+ *pValue += sizeof(unsigned long);
+ *pCount -= 1;
+ break;
+ case 16:
+ value = *((unsigned short *)(*pValue));
+ *pValue += sizeof(unsigned short);
+ *pCount -= 1;
+ break;
+ case 8:
+ value = *((unsigned char *) (*pValue));
+ *pValue += 1;
+ *pCount -= 1;
+ break;
+ default:
+ value = 0;
+ break;
+ }
+ return(value);
+}
+
+
+/*
+ * NAME
+ * _XcmsGetProperty -- Determine the existance of a property
+ *
+ * SYNOPSIS
+ */
+int
+_XcmsGetProperty(
+ Display *pDpy,
+ Window w,
+ Atom property,
+ int *pFormat,
+ unsigned long *pNItems,
+ unsigned long *pNBytes,
+ char **pValue)
+/*
+ * DESCRIPTION
+ *
+ * Returns
+ * 0 if property does not exist.
+ * 1 if property exists.
+ */
+{
+ char *prop_ret;
+ int format_ret;
+ long len = 6516;
+ unsigned long nitems_ret, after_ret;
+ Atom atom_ret;
+ int xgwp_ret;
+
+ while (True) {
+ xgwp_ret = XGetWindowProperty (pDpy, w, property, 0, len, False,
+ XA_INTEGER, &atom_ret, &format_ret,
+ &nitems_ret, &after_ret,
+ (unsigned char **)&prop_ret);
+ if (xgwp_ret == Success && after_ret > 0) {
+ len += nitems_ret * (format_ret >> 3);
+ XFree (prop_ret);
+ } else {
+ break;
+ }
+ }
+ if (xgwp_ret != Success || format_ret == 0 || nitems_ret == 0) {
+ /* the property does not exist or is of an unexpected type or
+ getting window property failed */
+ return(XcmsFailure);
+ }
+
+ *pFormat = format_ret;
+ *pNItems = nitems_ret;
+ *pNBytes = nitems_ret * (format_ret >> 3);
+ *pValue = prop_ret;
+ return(XcmsSuccess);
+}
diff --git a/libX11/src/xcms/config.h b/libX11/src/xcms/config.h new file mode 100644 index 000000000..a01921855 --- /dev/null +++ b/libX11/src/xcms/config.h @@ -0,0 +1,2 @@ +#include <string.h> +#include <unistd.h> diff --git a/libX11/src/xcms/makefile b/libX11/src/xcms/makefile new file mode 100644 index 000000000..00fab124a --- /dev/null +++ b/libX11/src/xcms/makefile @@ -0,0 +1,71 @@ +LIBRARY = libxcms + +DEFINES += HAVE_CONFIG_H + +CSRCS = \ + AddDIC.c \ + AddSF.c \ + CCC.c \ + CvColW.c \ + CvCols.c \ + HVC.c \ + HVCGcC.c \ + HVCGcV.c \ + HVCGcVC.c \ + HVCMnV.c \ + HVCMxC.c \ + HVCMxV.c \ + HVCMxVC.c \ + HVCMxVs.c \ + HVCWpAj.c \ + IdOfPr.c \ + LRGB.c \ + Lab.c \ + LabGcC.c \ + LabGcL.c \ + LabGcLC.c \ + LabMnL.c \ + LabMxC.c \ + LabMxL.c \ + LabMxLC.c \ + LabWpAj.c \ + Luv.c \ + LuvGcC.c \ + LuvGcL.c \ + LuvGcLC.c \ + LuvMnL.c \ + LuvMxC.c \ + LuvMxL.c \ + LuvMxLC.c \ + LuvWpAj.c \ + OfCCC.c \ + PrOfId.c \ + QBlack.c \ + QBlue.c \ + QGreen.c \ + QRed.c \ + QWhite.c \ + QuCol.c \ + QuCols.c \ + SetCCC.c \ + SetGetCols.c \ + StCol.c \ + StCols.c \ + UNDEFINED.c \ + XRGB.c \ + XYZ.c \ + cmsAllCol.c \ + cmsAllNCol.c \ + cmsCmap.c \ + cmsColNm.c \ + cmsGlobls.c \ + cmsInt.c \ + cmsLkCol.c \ + cmsMath.c \ + cmsProp.c \ + cmsTrig.c \ + uvY.c \ + xyY.c + +INCLUDES += ..\..\include\X11 ..\..\src\xlibi18n ..\..\src + diff --git a/libX11/src/xkb/Makefile b/libX11/src/xkb/Makefile new file mode 100644 index 000000000..0f6b7e859 --- /dev/null +++ b/libX11/src/xkb/Makefile @@ -0,0 +1,27 @@ +LIBRARY = libxkb + +CSRCS = \ + XKB.c \ + XKBBind.c \ + XKBCompat.c \ + XKBCtrls.c \ + XKBCvt.c \ + XKBGetMap.c \ + XKBGetByName.c \ + XKBNames.c \ + XKBRdBuf.c \ + XKBSetMap.c \ + XKBUse.c \ + XKBleds.c \ + XKBBell.c \ + XKBGeom.c \ + XKBSetGeom.c \ + XKBExtDev.c \ + XKBList.c \ + XKBMisc.c \ + XKBMAlloc.c \ + XKBGAlloc.c \ + XKBAlloc.c + +INCLUDES += ..\..\include\X11 ..\..\src\xlibi18n + diff --git a/libX11/src/xkb/XKB.c b/libX11/src/xkb/XKB.c index f926cb997..374e27d2d 100644 --- a/libX11/src/xkb/XKB.c +++ b/libX11/src/xkb/XKB.c @@ -28,6 +28,11 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <config.h> #endif #include <stdio.h> + +#ifdef XKB_IN_SERVER +#define XkbVirtualModsToReal SrvXkbVirtualModsToReal +#endif + #include "Xlibint.h" #include <X11/extensions/XKBproto.h> #include "XKBlibint.h" diff --git a/libX11/src/xkb/XKBBind.c b/libX11/src/xkb/XKBBind.c index 2e4b1fe68..4904b461f 100644 --- a/libX11/src/xkb/XKBBind.c +++ b/libX11/src/xkb/XKBBind.c @@ -31,6 +31,34 @@ from The Open Group. #ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "XKBlib.h"
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
diff --git a/libX11/src/xkb/XKBGAlloc.c b/libX11/src/xkb/XKBGAlloc.c index 7679496e3..9dd1e4912 100644 --- a/libX11/src/xkb/XKBGAlloc.c +++ b/libX11/src/xkb/XKBGAlloc.c @@ -1,1011 +1,1012 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, 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 Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS 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. - -********************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#elif defined(HAVE_CONFIG_H) -#include <config.h> -#endif - -#ifndef XKB_IN_SERVER - -#include <stdio.h> -#include "Xlibint.h" -#include "XKBlibint.h" -#include <X11/extensions/XKBgeom.h> -#include <X11/extensions/XKBproto.h> - -#else - -#include <stdio.h> -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "inputstr.h" -#include <X11/extensions/XKBsrv.h> -#include <X11/extensions/XKBgeom.h> - -#endif /* XKB_IN_SERVER */ - -#ifdef X_NOT_POSIX -#define Size_t unsigned int -#else -#define Size_t size_t -#endif - -/***====================================================================***/ - -static void -_XkbFreeGeomLeafElems( Bool freeAll, - int first, - int count, - unsigned short * num_inout, - unsigned short * sz_inout, - char ** elems, - unsigned int elem_sz) -{ - if ((freeAll)||(*elems==NULL)) { - *num_inout= *sz_inout= 0; - if (*elems!=NULL) { - _XkbFree(*elems); - *elems= NULL; - } - return; - } - - if ((first>=(*num_inout))||(first<0)||(count<1)) - return; - - if (first+count>=(*num_inout)) { - /* truncating the array is easy */ - (*num_inout)= first; - } - else { - char * ptr; - int extra; - ptr= *elems; - extra= ((*num_inout)-(first+count))*elem_sz; - if (extra>0) - memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra); - (*num_inout)-= count; - } - return; -} - -typedef void (*ContentsClearFunc)( - char * /* priv */ -); - -static void -_XkbFreeGeomNonLeafElems( Bool freeAll, - int first, - int count, - unsigned short * num_inout, - unsigned short * sz_inout, - char ** elems, - unsigned int elem_sz, - ContentsClearFunc freeFunc) -{ -register int i; -register char *ptr; - - if (freeAll) { - first= 0; - count= (*num_inout); - } - else if ((first>=(*num_inout))||(first<0)||(count<1)) - return; - else if (first+count>(*num_inout)) - count= (*num_inout)-first; - if (*elems==NULL) - return; - - if (freeFunc) { - ptr= *elems; - ptr+= first*elem_sz; - for (i=0;i<count;i++) { - (*freeFunc)(ptr); - ptr+= elem_sz; - } - } - if (freeAll) { - (*num_inout)= (*sz_inout)= 0; - if (*elems) { - _XkbFree(*elems); - *elems= NULL; - } - } - else if (first+count>=(*num_inout)) - *num_inout= first; - else { - i= ((*num_inout)-(first+count))*elem_sz; - ptr= *elems; - memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i); - (*num_inout)-= count; - } - return; -} - -/***====================================================================***/ - -static void -_XkbClearProperty(char *prop_in) -{ -XkbPropertyPtr prop= (XkbPropertyPtr)prop_in; - - if (prop->name) { - _XkbFree(prop->name); - prop->name= NULL; - } - if (prop->value) { - _XkbFree(prop->value); - prop->value= NULL; - } - return; -} - -void -XkbFreeGeomProperties( XkbGeometryPtr geom, - int first, - int count, - Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &geom->num_properties,&geom->sz_properties, - (char **)&geom->properties, - sizeof(XkbPropertyRec),_XkbClearProperty); - return; -} - -/***====================================================================***/ - -void -XkbFreeGeomKeyAliases( XkbGeometryPtr geom, - int first, - int count, - Bool freeAll) -{ - _XkbFreeGeomLeafElems(freeAll,first,count, - &geom->num_key_aliases,&geom->sz_key_aliases, - (char **)&geom->key_aliases, - sizeof(XkbKeyAliasRec)); - return; -} - -/***====================================================================***/ - -static void -_XkbClearColor(char *color_in) -{ -XkbColorPtr color= (XkbColorPtr)color_in; - - if (color->spec) - _XkbFree(color->spec); - return; -} - -void -XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &geom->num_colors,&geom->sz_colors, - (char **)&geom->colors, - sizeof(XkbColorRec),_XkbClearColor); - return; -} - -/***====================================================================***/ - -void -XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll) -{ - _XkbFreeGeomLeafElems(freeAll,first,count, - &outline->num_points,&outline->sz_points, - (char **)&outline->points, - sizeof(XkbPointRec)); - return; -} - -/***====================================================================***/ - -static void -_XkbClearOutline(char *outline_in) -{ -XkbOutlinePtr outline= (XkbOutlinePtr)outline_in; - - if (outline->points!=NULL) - XkbFreeGeomPoints(outline,0,outline->num_points,True); - return; -} - -void -XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &shape->num_outlines,&shape->sz_outlines, - (char **)&shape->outlines, - sizeof(XkbOutlineRec),_XkbClearOutline); - - return; -} - -/***====================================================================***/ - -static void -_XkbClearShape(char *shape_in) -{ -XkbShapePtr shape= (XkbShapePtr)shape_in; - - if (shape->outlines) - XkbFreeGeomOutlines(shape,0,shape->num_outlines,True); - return; -} - -void -XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &geom->num_shapes,&geom->sz_shapes, - (char **)&geom->shapes, - sizeof(XkbShapeRec),_XkbClearShape); - return; -} - -/***====================================================================***/ - -void -XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll) -{ - _XkbFreeGeomLeafElems(freeAll,first,count, - &row->num_keys,&row->sz_keys, - (char **)&row->keys, - sizeof(XkbOverlayKeyRec)); - return; -} - -/***====================================================================***/ - -static void -_XkbClearOverlayRow(char *row_in) -{ -XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in; - - if (row->keys!=NULL) - XkbFreeGeomOverlayKeys(row,0,row->num_keys,True); - return; -} - -void -XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &overlay->num_rows,&overlay->sz_rows, - (char **)&overlay->rows, - sizeof(XkbOverlayRowRec),_XkbClearOverlayRow); - return; -} - -/***====================================================================***/ - -static void -_XkbClearOverlay(char *overlay_in) -{ -XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in; - - if (overlay->rows!=NULL) - XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True); - return; -} - -void -XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - §ion->num_overlays,§ion->sz_overlays, - (char **)§ion->overlays, - sizeof(XkbOverlayRec),_XkbClearOverlay); - return; -} - -/***====================================================================***/ - -void -XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll) -{ - _XkbFreeGeomLeafElems(freeAll,first,count, - &row->num_keys,&row->sz_keys, - (char **)&row->keys, - sizeof(XkbKeyRec)); - return; -} - -/***====================================================================***/ - -static void -_XkbClearRow(char *row_in) -{ -XkbRowPtr row= (XkbRowPtr)row_in; - - if (row->keys!=NULL) - XkbFreeGeomKeys(row,0,row->num_keys,True); - return; -} - -void -XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - §ion->num_rows,§ion->sz_rows, - (char **)§ion->rows, - sizeof(XkbRowRec),_XkbClearRow); -} - -/***====================================================================***/ - -static void -_XkbClearSection(char *section_in) -{ -XkbSectionPtr section= (XkbSectionPtr)section_in; - - if (section->rows!=NULL) - XkbFreeGeomRows(section,0,section->num_rows,True); - if (section->doodads!=NULL) { - XkbFreeGeomDoodads(section->doodads,section->num_doodads,True); - section->doodads= NULL; - } - return; -} - -void -XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll) -{ - _XkbFreeGeomNonLeafElems(freeAll,first,count, - &geom->num_sections,&geom->sz_sections, - (char **)&geom->sections, - sizeof(XkbSectionRec),_XkbClearSection); - return; -} - -/***====================================================================***/ - -static void -_XkbClearDoodad(char *doodad_in) -{ -XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in; - - switch (doodad->any.type) { - case XkbTextDoodad: - { - if (doodad->text.text!=NULL) { - _XkbFree(doodad->text.text); - doodad->text.text= NULL; - } - if (doodad->text.font!=NULL) { - _XkbFree(doodad->text.font); - doodad->text.font= NULL; - } - } - break; - case XkbLogoDoodad: - { - if (doodad->logo.logo_name!=NULL) { - _XkbFree(doodad->logo.logo_name); - doodad->logo.logo_name= NULL; - } - } - break; - } - return; -} - -void -XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll) -{ -register int i; -register XkbDoodadPtr doodad; - - if (doodads) { - for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) { - _XkbClearDoodad((char *)doodad); - } - if (freeAll) - _XkbFree(doodads); - } - return; -} - -void -XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap) -{ - if (geom==NULL) - return; - if (freeMap) - which= XkbGeomAllMask; - if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL)) - XkbFreeGeomProperties(geom,0,geom->num_properties,True); - if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL)) - XkbFreeGeomColors(geom,0,geom->num_colors,True); - if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL)) - XkbFreeGeomShapes(geom,0,geom->num_shapes,True); - if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL)) - XkbFreeGeomSections(geom,0,geom->num_sections,True); - if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) { - XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True); - geom->doodads= NULL; - geom->num_doodads= geom->sz_doodads= 0; - } - if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL)) - XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True); - if (freeMap) { - if (geom->label_font!=NULL) { - _XkbFree(geom->label_font); - geom->label_font= NULL; - } - _XkbFree(geom); - } - return; -} - -/***====================================================================***/ - -static Status -_XkbGeomAlloc( XPointer * old, - unsigned short * num, - unsigned short * total, - int num_new, - Size_t sz_elem) -{ - if (num_new<1) - return Success; - if ((*old)==NULL) - *num= *total= 0; - - if ((*num)+num_new<=(*total)) - return Success; - - *total= (*num)+num_new; - if ((*old)!=NULL) - (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem); - else (*old)= (XPointer)_XkbCalloc((*total),sz_elem); - if ((*old)==NULL) { - *total= *num= 0; - return BadAlloc; - } - - if (*num>0) { - char *tmp= (char *)(*old); - bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem)); - } - return Success; -} - -#define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\ - &(g)->num_properties,&(g)->sz_properties,\ - (n),sizeof(XkbPropertyRec)) -#define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\ - &(g)->num_colors,&(g)->sz_colors,\ - (n),sizeof(XkbColorRec)) -#define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\ - &(g)->num_shapes,&(g)->sz_shapes,\ - (n),sizeof(XkbShapeRec)) -#define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\ - &(g)->num_sections,&(g)->sz_sections,\ - (n),sizeof(XkbSectionRec)) -#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\ - &(g)->num_doodads,&(g)->sz_doodads,\ - (n),sizeof(XkbDoodadRec)) -#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\ - &(g)->num_key_aliases,&(g)->sz_key_aliases,\ - (n),sizeof(XkbKeyAliasRec)) - -#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\ - &(s)->num_outlines,&(s)->sz_outlines,\ - (n),sizeof(XkbOutlineRec)) -#define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\ - &(s)->num_rows,&(s)->sz_rows,\ - (n),sizeof(XkbRowRec)) -#define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\ - &(o)->num_points,&(o)->sz_points,\ - (n),sizeof(XkbPointRec)) -#define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\ - &(r)->num_keys,&(r)->sz_keys,\ - (n),sizeof(XkbKeyRec)) -#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\ - &(s)->num_overlays,&(s)->sz_overlays,\ - (n),sizeof(XkbOverlayRec)) -#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\ - &(o)->num_rows,&(o)->sz_rows,\ - (n),sizeof(XkbOverlayRowRec)) -#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\ - &(r)->num_keys,&(r)->sz_keys,\ - (n),sizeof(XkbOverlayKeyRec)) - -Status -XkbAllocGeomProps(XkbGeometryPtr geom,int nProps) -{ - return _XkbAllocProps(geom,nProps); -} - -Status -XkbAllocGeomColors(XkbGeometryPtr geom,int nColors) -{ - return _XkbAllocColors(geom,nColors); -} - -Status -XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases) -{ - return _XkbAllocKeyAliases(geom,nKeyAliases); -} - -Status -XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes) -{ - return _XkbAllocShapes(geom,nShapes); -} - -Status -XkbAllocGeomSections(XkbGeometryPtr geom,int nSections) -{ - return _XkbAllocSections(geom,nSections); -} - -Status -XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays) -{ - return _XkbAllocOverlays(section,nOverlays); -} - -Status -XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows) -{ - return _XkbAllocOverlayRows(overlay,nRows); -} - -Status -XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys) -{ - return _XkbAllocOverlayKeys(row,nKeys); -} - -Status -XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads) -{ - return _XkbAllocDoodads(geom,nDoodads); -} - -Status -XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads) -{ - return _XkbAllocDoodads(section,nDoodads); -} - -Status -XkbAllocGeomOutlines(XkbShapePtr shape,int nOL) -{ - return _XkbAllocOutlines(shape,nOL); -} - -Status -XkbAllocGeomRows(XkbSectionPtr section,int nRows) -{ - return _XkbAllocRows(section,nRows); -} - -Status -XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts) -{ - return _XkbAllocPoints(ol,nPts); -} - -Status -XkbAllocGeomKeys(XkbRowPtr row,int nKeys) -{ - return _XkbAllocKeys(row,nKeys); -} - -Status -XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes) -{ -XkbGeometryPtr geom; -Status rtrn; - - if (xkb->geom==NULL) { - xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec); - if (!xkb->geom) - return BadAlloc; - } - geom= xkb->geom; - if ((sizes->which&XkbGeomPropertiesMask)&& - ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) { - goto BAIL; - } - if ((sizes->which&XkbGeomColorsMask)&& - ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) { - goto BAIL; - } - if ((sizes->which&XkbGeomShapesMask)&& - ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) { - goto BAIL; - } - if ((sizes->which&XkbGeomSectionsMask)&& - ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) { - goto BAIL; - } - if ((sizes->which&XkbGeomDoodadsMask)&& - ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) { - goto BAIL; - } - if ((sizes->which&XkbGeomKeyAliasesMask)&& - ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) { - goto BAIL; - } - return Success; -BAIL: - XkbFreeGeometry(geom,XkbGeomAllMask,True); - xkb->geom= NULL; - return rtrn; -} - -/***====================================================================***/ - -XkbPropertyPtr -XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value) -{ -register int i; -register XkbPropertyPtr prop; - - if ((!geom)||(!name)||(!value)) - return NULL; - for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { - if ((prop->name)&&(strcmp(name,prop->name)==0)) { - if (prop->value) - _XkbFree(prop->value); - prop->value= strdup(value); - return prop; - } - } - if ((geom->num_properties>=geom->sz_properties)&& - (_XkbAllocProps(geom,1)!=Success)) { - return NULL; - } - prop= &geom->properties[geom->num_properties]; - prop->name= strdup(name); - if (!prop->name) - return NULL; - prop->value= strdup(value); - if (!prop->value) { - _XkbFree(prop->name); - prop->name= NULL; - return NULL; - } - geom->num_properties++; - return prop; -} - -XkbKeyAliasPtr -XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr) -{ -register int i; -register XkbKeyAliasPtr alias; - - if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0])) - return NULL; - for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) { - if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) { - bzero(alias->real,XkbKeyNameLength); - strncpy(alias->real,realStr,XkbKeyNameLength); - return alias; - } - } - if ((geom->num_key_aliases>=geom->sz_key_aliases)&& - (_XkbAllocKeyAliases(geom,1)!=Success)) { - return NULL; - } - alias= &geom->key_aliases[geom->num_key_aliases]; - bzero(alias,sizeof(XkbKeyAliasRec)); - strncpy(alias->alias,aliasStr,XkbKeyNameLength); - strncpy(alias->real,realStr,XkbKeyNameLength); - geom->num_key_aliases++; - return alias; -} - -XkbColorPtr -XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel) -{ -register int i; -register XkbColorPtr color; - - if ((!geom)||(!spec)) - return NULL; - for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { - if ((color->spec)&&(strcmp(color->spec,spec)==0)) { - color->pixel= pixel; - return color; - } - } - if ((geom->num_colors>=geom->sz_colors)&& - (_XkbAllocColors(geom,1)!=Success)) { - return NULL; - } - color= &geom->colors[geom->num_colors]; - color->pixel= pixel; - color->spec= strdup(spec); - if (!color->spec) - return NULL; - geom->num_colors++; - return color; -} - -XkbOutlinePtr -XkbAddGeomOutline(XkbShapePtr shape,int sz_points) -{ -XkbOutlinePtr outline; - - if ((!shape)||(sz_points<0)) - return NULL; - if ((shape->num_outlines>=shape->sz_outlines)&& - (_XkbAllocOutlines(shape,1)!=Success)) { - return NULL; - } - outline= &shape->outlines[shape->num_outlines]; - bzero(outline,sizeof(XkbOutlineRec)); - if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success)) - return NULL; - shape->num_outlines++; - return outline; -} - -XkbShapePtr -XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines) -{ -XkbShapePtr shape; -register int i; - - if ((!geom)||(!name)||(sz_outlines<0)) - return NULL; - if (geom->num_shapes>0) { - for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { - if (name==shape->name) - return shape; - } - } - if ((geom->num_shapes>=geom->sz_shapes)&& - (_XkbAllocShapes(geom,1)!=Success)) - return NULL; - shape= &geom->shapes[geom->num_shapes]; - bzero(shape,sizeof(XkbShapeRec)); - if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success)) - return NULL; - shape->name= name; - shape->primary= shape->approx= NULL; - geom->num_shapes++; - return shape; -} - -XkbKeyPtr -XkbAddGeomKey(XkbRowPtr row) -{ -XkbKeyPtr key; - if (!row) - return NULL; - if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success)) - return NULL; - key= &row->keys[row->num_keys++]; - bzero(key,sizeof(XkbKeyRec)); - return key; -} - -XkbRowPtr -XkbAddGeomRow(XkbSectionPtr section,int sz_keys) -{ -XkbRowPtr row; - - if ((!section)||(sz_keys<0)) - return NULL; - if ((section->num_rows>=section->sz_rows)&& - (_XkbAllocRows(section,1)!=Success)) - return NULL; - row= §ion->rows[section->num_rows]; - bzero(row,sizeof(XkbRowRec)); - if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success)) - return NULL; - section->num_rows++; - return row; -} - -XkbSectionPtr -XkbAddGeomSection( XkbGeometryPtr geom, - Atom name, - int sz_rows, - int sz_doodads, - int sz_over) -{ -register int i; -XkbSectionPtr section; - - if ((!geom)||(name==None)||(sz_rows<0)) - return NULL; - for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { - if (section->name!=name) - continue; - if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))|| - ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))|| - ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success))) - return NULL; - return section; - } - if ((geom->num_sections>=geom->sz_sections)&& - (_XkbAllocSections(geom,1)!=Success)) - return NULL; - section= &geom->sections[geom->num_sections]; - if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success)) - return NULL; - if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) { - if (section->rows) { - _XkbFree(section->rows); - section->rows= NULL; - section->sz_rows= section->num_rows= 0; - } - return NULL; - } - section->name= name; - geom->num_sections++; - return section; -} - -XkbDoodadPtr -XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name) -{ -XkbDoodadPtr old,doodad; -register int i,nDoodads; - - if ((!geom)||(name==None)) - return NULL; - if ((section!=NULL)&&(section->num_doodads>0)) { - old= section->doodads; - nDoodads= section->num_doodads; - } - else { - old= geom->doodads; - nDoodads= geom->num_doodads; - } - for (i=0,doodad=old;i<nDoodads;i++,doodad++) { - if (doodad->any.name==name) - return doodad; - } - if (section) { - if ((section->num_doodads>=geom->sz_doodads)&& - (_XkbAllocDoodads(section,1)!=Success)) { - return NULL; - } - doodad= §ion->doodads[section->num_doodads++]; - } - else { - if ((geom->num_doodads>=geom->sz_doodads)&& - (_XkbAllocDoodads(geom,1)!=Success)) - return NULL; - doodad= &geom->doodads[geom->num_doodads++]; - } - bzero(doodad,sizeof(XkbDoodadRec)); - doodad->any.name= name; - return doodad; -} - -XkbOverlayKeyPtr -XkbAddGeomOverlayKey( XkbOverlayPtr overlay, - XkbOverlayRowPtr row, - char * over, - char * under) -{ -register int i; -XkbOverlayKeyPtr key; -XkbSectionPtr section; -XkbRowPtr row_under; -Bool found; - - if ((!overlay)||(!row)||(!over)||(!under)) - return NULL; - section= overlay->section_under; - if (row->row_under>=section->num_rows) - return NULL; - row_under= §ion->rows[row->row_under]; - for (i=0,found=False;i<row_under->num_keys;i++) { - if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) { - found= True; - break; - } - } - if (!found) - return NULL; - if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success)) - return NULL; - key= &row->keys[row->num_keys]; - strncpy(key->under.name,under,XkbKeyNameLength); - strncpy(key->over.name,over,XkbKeyNameLength); - row->num_keys++; - return key; -} - -XkbOverlayRowPtr -XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys) -{ -register int i; -XkbOverlayRowPtr row; - - if ((!overlay)||(sz_keys<0)) - return NULL; - if (row_under>=overlay->section_under->num_rows) - return NULL; - for (i=0;i<overlay->num_rows;i++) { - if (overlay->rows[i].row_under==row_under) { - row= &overlay->rows[i]; - if ((row->sz_keys<sz_keys)&& - (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) { - return NULL; - } - return &overlay->rows[i]; - } - } - if ((overlay->num_rows>=overlay->sz_rows)&& - (_XkbAllocOverlayRows(overlay,1)!=Success)) - return NULL; - row= &overlay->rows[overlay->num_rows]; - bzero(row,sizeof(XkbOverlayRowRec)); - if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success)) - return NULL; - row->row_under= row_under; - overlay->num_rows++; - return row; -} - -XkbOverlayPtr -XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows) -{ -register int i; -XkbOverlayPtr overlay; - - if ((!section)||(name==None)||(sz_rows==0)) - return NULL; - - for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) { - if (overlay->name==name) { - if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) - return NULL; - return overlay; - } - } - if ((section->num_overlays>=section->sz_overlays)&& - (_XkbAllocOverlays(section,1)!=Success)) - return NULL; - overlay= §ion->overlays[section->num_overlays]; - if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success)) - return NULL; - overlay->name= name; - overlay->section_under= section; - section->num_overlays++; - return overlay; -} +/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, 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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef XKB_IN_SERVER
+
+#include "Xlibint.h"
+#include "XKBlibint.h"
+#include <X11/extensions/XKBgeom.h>
+#include <X11/extensions/XKBproto.h>
+
+#else
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#include <X11/extensions/XKBgeom.h>
+
+#endif /* XKB_IN_SERVER */
+
+#ifdef X_NOT_POSIX
+#define Size_t unsigned int
+#else
+#define Size_t size_t
+#endif
+
+/***====================================================================***/
+
+static void
+_XkbFreeGeomLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz)
+{
+ if ((freeAll)||(*elems==NULL)) {
+ *num_inout= *sz_inout= 0;
+ if (*elems!=NULL) {
+ _XkbFree(*elems);
+ *elems= NULL;
+ }
+ return;
+ }
+
+ if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+
+ if (first+count>=(*num_inout)) {
+ /* truncating the array is easy */
+ (*num_inout)= first;
+ }
+ else {
+ char * ptr;
+ int extra;
+ ptr= *elems;
+ extra= ((*num_inout)-(first+count))*elem_sz;
+ if (extra>0)
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+typedef void (*ContentsClearFunc)(
+ char * /* priv */
+);
+
+static void
+_XkbFreeGeomNonLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz,
+ ContentsClearFunc freeFunc)
+{
+register int i;
+register char *ptr;
+
+ if (freeAll) {
+ first= 0;
+ count= (*num_inout);
+ }
+ else if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+ else if (first+count>(*num_inout))
+ count= (*num_inout)-first;
+ if (*elems==NULL)
+ return;
+
+ if (freeFunc) {
+ ptr= *elems;
+ ptr+= first*elem_sz;
+ for (i=0;i<count;i++) {
+ (*freeFunc)(ptr);
+ ptr+= elem_sz;
+ }
+ }
+ if (freeAll) {
+ (*num_inout)= (*sz_inout)= 0;
+ if (*elems) {
+ _XkbFree(*elems);
+ *elems= NULL;
+ }
+ }
+ else if (first+count>=(*num_inout))
+ *num_inout= first;
+ else {
+ i= ((*num_inout)-(first+count))*elem_sz;
+ ptr= *elems;
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearProperty(char *prop_in)
+{
+XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
+
+ if (prop->name) {
+ _XkbFree(prop->name);
+ prop->name= NULL;
+ }
+ if (prop->value) {
+ _XkbFree(prop->value);
+ prop->value= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomProperties( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_properties,&geom->sz_properties,
+ (char **)&geom->properties,
+ sizeof(XkbPropertyRec),_XkbClearProperty);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &geom->num_key_aliases,&geom->sz_key_aliases,
+ (char **)&geom->key_aliases,
+ sizeof(XkbKeyAliasRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearColor(char *color_in)
+{
+XkbColorPtr color= (XkbColorPtr)color_in;
+
+ if (color->spec)
+ _XkbFree(color->spec);
+ return;
+}
+
+void
+XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_colors,&geom->sz_colors,
+ (char **)&geom->colors,
+ sizeof(XkbColorRec),_XkbClearColor);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &outline->num_points,&outline->sz_points,
+ (char **)&outline->points,
+ sizeof(XkbPointRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOutline(char *outline_in)
+{
+XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
+
+ if (outline->points!=NULL)
+ XkbFreeGeomPoints(outline,0,outline->num_points,True);
+ return;
+}
+
+void
+XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &shape->num_outlines,&shape->sz_outlines,
+ (char **)&shape->outlines,
+ sizeof(XkbOutlineRec),_XkbClearOutline);
+
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearShape(char *shape_in)
+{
+XkbShapePtr shape= (XkbShapePtr)shape_in;
+
+ if (shape->outlines)
+ XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
+ return;
+}
+
+void
+XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_shapes,&geom->sz_shapes,
+ (char **)&geom->shapes,
+ sizeof(XkbShapeRec),_XkbClearShape);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbOverlayKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlayRow(char *row_in)
+{
+XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
+ return;
+}
+
+void
+XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &overlay->num_rows,&overlay->sz_rows,
+ (char **)&overlay->rows,
+ sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlay(char *overlay_in)
+{
+XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
+
+ if (overlay->rows!=NULL)
+ XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
+ return;
+}
+
+void
+XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ §ion->num_overlays,§ion->sz_overlays,
+ (char **)§ion->overlays,
+ sizeof(XkbOverlayRec),_XkbClearOverlay);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearRow(char *row_in)
+{
+XkbRowPtr row= (XkbRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomKeys(row,0,row->num_keys,True);
+ return;
+}
+
+void
+XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ §ion->num_rows,§ion->sz_rows,
+ (char **)§ion->rows,
+ sizeof(XkbRowRec),_XkbClearRow);
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearSection(char *section_in)
+{
+XkbSectionPtr section= (XkbSectionPtr)section_in;
+
+ if (section->rows!=NULL)
+ XkbFreeGeomRows(section,0,section->num_rows,True);
+ if (section->doodads!=NULL) {
+ XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
+ section->doodads= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_sections,&geom->sz_sections,
+ (char **)&geom->sections,
+ sizeof(XkbSectionRec),_XkbClearSection);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearDoodad(char *doodad_in)
+{
+XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
+
+ switch (doodad->any.type) {
+ case XkbTextDoodad:
+ {
+ if (doodad->text.text!=NULL) {
+ _XkbFree(doodad->text.text);
+ doodad->text.text= NULL;
+ }
+ if (doodad->text.font!=NULL) {
+ _XkbFree(doodad->text.font);
+ doodad->text.font= NULL;
+ }
+ }
+ break;
+ case XkbLogoDoodad:
+ {
+ if (doodad->logo.logo_name!=NULL) {
+ _XkbFree(doodad->logo.logo_name);
+ doodad->logo.logo_name= NULL;
+ }
+ }
+ break;
+ }
+ return;
+}
+
+void
+XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
+{
+register int i;
+register XkbDoodadPtr doodad;
+
+ if (doodads) {
+ for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
+ _XkbClearDoodad((char *)doodad);
+ }
+ if (freeAll)
+ _XkbFree(doodads);
+ }
+ return;
+}
+
+void
+XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
+{
+ if (geom==NULL)
+ return;
+ if (freeMap)
+ which= XkbGeomAllMask;
+ if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
+ XkbFreeGeomProperties(geom,0,geom->num_properties,True);
+ if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
+ XkbFreeGeomColors(geom,0,geom->num_colors,True);
+ if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
+ XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
+ if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
+ XkbFreeGeomSections(geom,0,geom->num_sections,True);
+ if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
+ XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
+ geom->doodads= NULL;
+ geom->num_doodads= geom->sz_doodads= 0;
+ }
+ if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
+ XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
+ if (freeMap) {
+ if (geom->label_font!=NULL) {
+ _XkbFree(geom->label_font);
+ geom->label_font= NULL;
+ }
+ _XkbFree(geom);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+_XkbGeomAlloc( XPointer * old,
+ unsigned short * num,
+ unsigned short * total,
+ int num_new,
+ Size_t sz_elem)
+{
+ if (num_new<1)
+ return Success;
+ if ((*old)==NULL)
+ *num= *total= 0;
+
+ if ((*num)+num_new<=(*total))
+ return Success;
+
+ *total= (*num)+num_new;
+ if ((*old)!=NULL)
+ (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
+ else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
+ if ((*old)==NULL) {
+ *total= *num= 0;
+ return BadAlloc;
+ }
+
+ if (*num>0) {
+ char *tmp= (char *)(*old);
+ bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
+ }
+ return Success;
+}
+
+#define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
+ &(g)->num_properties,&(g)->sz_properties,\
+ (n),sizeof(XkbPropertyRec))
+#define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
+ &(g)->num_colors,&(g)->sz_colors,\
+ (n),sizeof(XkbColorRec))
+#define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
+ &(g)->num_shapes,&(g)->sz_shapes,\
+ (n),sizeof(XkbShapeRec))
+#define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
+ &(g)->num_sections,&(g)->sz_sections,\
+ (n),sizeof(XkbSectionRec))
+#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
+ &(g)->num_doodads,&(g)->sz_doodads,\
+ (n),sizeof(XkbDoodadRec))
+#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
+ &(g)->num_key_aliases,&(g)->sz_key_aliases,\
+ (n),sizeof(XkbKeyAliasRec))
+
+#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
+ &(s)->num_outlines,&(s)->sz_outlines,\
+ (n),sizeof(XkbOutlineRec))
+#define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
+ &(s)->num_rows,&(s)->sz_rows,\
+ (n),sizeof(XkbRowRec))
+#define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
+ &(o)->num_points,&(o)->sz_points,\
+ (n),sizeof(XkbPointRec))
+#define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbKeyRec))
+#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
+ &(s)->num_overlays,&(s)->sz_overlays,\
+ (n),sizeof(XkbOverlayRec))
+#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
+ &(o)->num_rows,&(o)->sz_rows,\
+ (n),sizeof(XkbOverlayRowRec))
+#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbOverlayKeyRec))
+
+Status
+XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
+{
+ return _XkbAllocProps(geom,nProps);
+}
+
+Status
+XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
+{
+ return _XkbAllocColors(geom,nColors);
+}
+
+Status
+XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
+{
+ return _XkbAllocKeyAliases(geom,nKeyAliases);
+}
+
+Status
+XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
+{
+ return _XkbAllocShapes(geom,nShapes);
+}
+
+Status
+XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
+{
+ return _XkbAllocSections(geom,nSections);
+}
+
+Status
+XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
+{
+ return _XkbAllocOverlays(section,nOverlays);
+}
+
+Status
+XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
+{
+ return _XkbAllocOverlayRows(overlay,nRows);
+}
+
+Status
+XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
+{
+ return _XkbAllocOverlayKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
+{
+ return _XkbAllocDoodads(geom,nDoodads);
+}
+
+Status
+XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
+{
+ return _XkbAllocDoodads(section,nDoodads);
+}
+
+Status
+XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
+{
+ return _XkbAllocOutlines(shape,nOL);
+}
+
+Status
+XkbAllocGeomRows(XkbSectionPtr section,int nRows)
+{
+ return _XkbAllocRows(section,nRows);
+}
+
+Status
+XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
+{
+ return _XkbAllocPoints(ol,nPts);
+}
+
+Status
+XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
+{
+ return _XkbAllocKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
+{
+XkbGeometryPtr geom;
+Status rtrn;
+
+ if (xkb->geom==NULL) {
+ xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
+ if (!xkb->geom)
+ return BadAlloc;
+ }
+ geom= xkb->geom;
+ if ((sizes->which&XkbGeomPropertiesMask)&&
+ ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomColorsMask)&&
+ ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomShapesMask)&&
+ ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomSectionsMask)&&
+ ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomDoodadsMask)&&
+ ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomKeyAliasesMask)&&
+ ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
+ goto BAIL;
+ }
+ return Success;
+BAIL:
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= NULL;
+ return rtrn;
+}
+
+/***====================================================================***/
+
+XkbPropertyPtr
+XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ if ((!geom)||(!name)||(!value))
+ return NULL;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ if ((prop->name)&&(strcmp(name,prop->name)==0)) {
+ if (prop->value)
+ _XkbFree(prop->value);
+ prop->value= strdup(value);
+ return prop;
+ }
+ }
+ if ((geom->num_properties>=geom->sz_properties)&&
+ (_XkbAllocProps(geom,1)!=Success)) {
+ return NULL;
+ }
+ prop= &geom->properties[geom->num_properties];
+ prop->name= strdup(name);
+ if (!prop->name)
+ return NULL;
+ prop->value= strdup(value);
+ if (!prop->value) {
+ _XkbFree(prop->name);
+ prop->name= NULL;
+ return NULL;
+ }
+ geom->num_properties++;
+ return prop;
+}
+
+XkbKeyAliasPtr
+XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
+{
+register int i;
+register XkbKeyAliasPtr alias;
+
+ if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
+ return NULL;
+ for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
+ if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
+ bzero(alias->real,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ return alias;
+ }
+ }
+ if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
+ (_XkbAllocKeyAliases(geom,1)!=Success)) {
+ return NULL;
+ }
+ alias= &geom->key_aliases[geom->num_key_aliases];
+ bzero(alias,sizeof(XkbKeyAliasRec));
+ strncpy(alias->alias,aliasStr,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ geom->num_key_aliases++;
+ return alias;
+}
+
+XkbColorPtr
+XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
+{
+register int i;
+register XkbColorPtr color;
+
+ if ((!geom)||(!spec))
+ return NULL;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
+ color->pixel= pixel;
+ return color;
+ }
+ }
+ if ((geom->num_colors>=geom->sz_colors)&&
+ (_XkbAllocColors(geom,1)!=Success)) {
+ return NULL;
+ }
+ color= &geom->colors[geom->num_colors];
+ color->pixel= pixel;
+ color->spec= strdup(spec);
+ if (!color->spec)
+ return NULL;
+ geom->num_colors++;
+ return color;
+}
+
+XkbOutlinePtr
+XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
+{
+XkbOutlinePtr outline;
+
+ if ((!shape)||(sz_points<0))
+ return NULL;
+ if ((shape->num_outlines>=shape->sz_outlines)&&
+ (_XkbAllocOutlines(shape,1)!=Success)) {
+ return NULL;
+ }
+ outline= &shape->outlines[shape->num_outlines];
+ bzero(outline,sizeof(XkbOutlineRec));
+ if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
+ return NULL;
+ shape->num_outlines++;
+ return outline;
+}
+
+XkbShapePtr
+XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
+{
+XkbShapePtr shape;
+register int i;
+
+ if ((!geom)||(!name)||(sz_outlines<0))
+ return NULL;
+ if (geom->num_shapes>0) {
+ for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+ if (name==shape->name)
+ return shape;
+ }
+ }
+ if ((geom->num_shapes>=geom->sz_shapes)&&
+ (_XkbAllocShapes(geom,1)!=Success))
+ return NULL;
+ shape= &geom->shapes[geom->num_shapes];
+ bzero(shape,sizeof(XkbShapeRec));
+ if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
+ return NULL;
+ shape->name= name;
+ shape->primary= shape->approx= NULL;
+ geom->num_shapes++;
+ return shape;
+}
+
+XkbKeyPtr
+XkbAddGeomKey(XkbRowPtr row)
+{
+XkbKeyPtr key;
+ if (!row)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys++];
+ bzero(key,sizeof(XkbKeyRec));
+ return key;
+}
+
+XkbRowPtr
+XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
+{
+XkbRowPtr row;
+
+ if ((!section)||(sz_keys<0))
+ return NULL;
+ if ((section->num_rows>=section->sz_rows)&&
+ (_XkbAllocRows(section,1)!=Success))
+ return NULL;
+ row= §ion->rows[section->num_rows];
+ bzero(row,sizeof(XkbRowRec));
+ if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
+ return NULL;
+ section->num_rows++;
+ return row;
+}
+
+XkbSectionPtr
+XkbAddGeomSection( XkbGeometryPtr geom,
+ Atom name,
+ int sz_rows,
+ int sz_doodads,
+ int sz_over)
+{
+register int i;
+XkbSectionPtr section;
+
+ if ((!geom)||(name==None)||(sz_rows<0))
+ return NULL;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ if (section->name!=name)
+ continue;
+ if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
+ ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
+ ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
+ return NULL;
+ return section;
+ }
+ if ((geom->num_sections>=geom->sz_sections)&&
+ (_XkbAllocSections(geom,1)!=Success))
+ return NULL;
+ section= &geom->sections[geom->num_sections];
+ if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
+ return NULL;
+ if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
+ if (section->rows) {
+ _XkbFree(section->rows);
+ section->rows= NULL;
+ section->sz_rows= section->num_rows= 0;
+ }
+ return NULL;
+ }
+ section->name= name;
+ geom->num_sections++;
+ return section;
+}
+
+XkbDoodadPtr
+XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
+{
+XkbDoodadPtr old,doodad;
+register int i,nDoodads;
+
+ if ((!geom)||(name==None))
+ return NULL;
+ if ((section!=NULL)&&(section->num_doodads>0)) {
+ old= section->doodads;
+ nDoodads= section->num_doodads;
+ }
+ else {
+ old= geom->doodads;
+ nDoodads= geom->num_doodads;
+ }
+ for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
+ if (doodad->any.name==name)
+ return doodad;
+ }
+ if (section) {
+ if ((section->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(section,1)!=Success)) {
+ return NULL;
+ }
+ doodad= §ion->doodads[section->num_doodads++];
+ }
+ else {
+ if ((geom->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(geom,1)!=Success))
+ return NULL;
+ doodad= &geom->doodads[geom->num_doodads++];
+ }
+ bzero(doodad,sizeof(XkbDoodadRec));
+ doodad->any.name= name;
+ return doodad;
+}
+
+XkbOverlayKeyPtr
+XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
+ XkbOverlayRowPtr row,
+ char * over,
+ char * under)
+{
+register int i;
+XkbOverlayKeyPtr key;
+XkbSectionPtr section;
+XkbRowPtr row_under;
+Bool found;
+
+ if ((!overlay)||(!row)||(!over)||(!under))
+ return NULL;
+ section= overlay->section_under;
+ if (row->row_under>=section->num_rows)
+ return NULL;
+ row_under= §ion->rows[row->row_under];
+ for (i=0,found=False;i<row_under->num_keys;i++) {
+ if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
+ found= True;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys];
+ strncpy(key->under.name,under,XkbKeyNameLength);
+ strncpy(key->over.name,over,XkbKeyNameLength);
+ row->num_keys++;
+ return key;
+}
+
+XkbOverlayRowPtr
+XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
+{
+register int i;
+XkbOverlayRowPtr row;
+
+ if ((!overlay)||(sz_keys<0))
+ return NULL;
+ if (row_under>=overlay->section_under->num_rows)
+ return NULL;
+ for (i=0;i<overlay->num_rows;i++) {
+ if (overlay->rows[i].row_under==row_under) {
+ row= &overlay->rows[i];
+ if ((row->sz_keys<sz_keys)&&
+ (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
+ return NULL;
+ }
+ return &overlay->rows[i];
+ }
+ }
+ if ((overlay->num_rows>=overlay->sz_rows)&&
+ (_XkbAllocOverlayRows(overlay,1)!=Success))
+ return NULL;
+ row= &overlay->rows[overlay->num_rows];
+ bzero(row,sizeof(XkbOverlayRowRec));
+ if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
+ return NULL;
+ row->row_under= row_under;
+ overlay->num_rows++;
+ return row;
+}
+
+XkbOverlayPtr
+XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
+{
+register int i;
+XkbOverlayPtr overlay;
+
+ if ((!section)||(name==None)||(sz_rows==0))
+ return NULL;
+
+ for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
+ if (overlay->name==name) {
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ return overlay;
+ }
+ }
+ if ((section->num_overlays>=section->sz_overlays)&&
+ (_XkbAllocOverlays(section,1)!=Success))
+ return NULL;
+ overlay= §ion->overlays[section->num_overlays];
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ overlay->name= name;
+ overlay->section_under= section;
+ section->num_overlays++;
+ return overlay;
+}
diff --git a/libX11/src/xkb/XKBGeom.c b/libX11/src/xkb/XKBGeom.c index 7594a3de4..d8fe3ce32 100644 --- a/libX11/src/xkb/XKBGeom.c +++ b/libX11/src/xkb/XKBGeom.c @@ -1,692 +1,688 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, 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 Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS 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. - -********************************************************/ - -#ifdef DEBUG -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#endif - -#define NEED_MAP_READERS -#include "Xlibint.h" -#include <X11/extensions/XKBgeom.h> -#include <X11/extensions/XKBproto.h> -#include "XKBlibint.h" - -#ifndef MINSHORT -#define MINSHORT -32768 -#endif -#ifndef MAXSHORT -#define MAXSHORT 32767 -#endif - -/***====================================================================***/ - -static void -_XkbCheckBounds(XkbBoundsPtr bounds,int x,int y) -{ - if (x<bounds->x1) bounds->x1= x; - if (x>bounds->x2) bounds->x2= x; - if (y<bounds->y1) bounds->y1= y; - if (y>bounds->y2) bounds->y2= y; - return; -} - -Bool -XkbComputeShapeBounds(XkbShapePtr shape) -{ -register int o,p; -XkbOutlinePtr outline; -XkbPointPtr pt; - - if ((!shape)||(shape->num_outlines<1)) - return False; - shape->bounds.x1= shape->bounds.y1= MAXSHORT; - shape->bounds.x2= shape->bounds.y2= MINSHORT; - for (outline=shape->outlines,o=0;o<shape->num_outlines;o++,outline++) { - for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) { - _XkbCheckBounds(&shape->bounds,pt->x,pt->y); - } - if (outline->num_points<2) { - _XkbCheckBounds(&shape->bounds,0,0); - } - } - return True; -} - -Bool -XkbComputeShapeTop(XkbShapePtr shape,XkbBoundsPtr bounds) -{ -register int p; -XkbOutlinePtr outline; -XkbPointPtr pt; - - if ((!shape)||(shape->num_outlines<1)) - return False; - if (shape->approx) outline= shape->approx; - else outline= &shape->outlines[shape->num_outlines-1]; - if (outline->num_points<2) { - bounds->x1= bounds->y1= 0; - bounds->x2= bounds->y2= 0; - } - else { - bounds->x1= bounds->y1= MAXSHORT; - bounds->x2= bounds->y2= MINSHORT; - } - for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) { - _XkbCheckBounds(bounds,pt->x,pt->y); - } - return True; -} - -Bool -XkbComputeRowBounds(XkbGeometryPtr geom,XkbSectionPtr section,XkbRowPtr row) -{ -register int k,pos; -XkbKeyPtr key; -XkbBoundsPtr bounds,sbounds; - - if ((!geom)||(!section)||(!row)) - return False; - bounds= &row->bounds; - bzero(bounds,sizeof(XkbBoundsRec)); - for (key=row->keys,pos=k=0;k<row->num_keys;k++,key++) { - sbounds= &XkbKeyShape(geom,key)->bounds; - _XkbCheckBounds(bounds,pos,0); - if (!row->vertical) { - if (key->gap!=0) { - pos+= key->gap; - _XkbCheckBounds(bounds,pos,0); - } - _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); - _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); - pos+= sbounds->x2; - } - else { - if (key->gap!=0) { - pos+= key->gap; - _XkbCheckBounds(bounds,0,pos); - } - _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1); - _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2); - pos+= sbounds->y2; - } - } - return True; -} - -Bool -XkbComputeSectionBounds(XkbGeometryPtr geom,XkbSectionPtr section) -{ -register int i; -XkbShapePtr shape; -XkbRowPtr row; -XkbDoodadPtr doodad; -XkbBoundsPtr bounds,rbounds; - - if ((!geom)||(!section)) - return False; - bounds= §ion->bounds; - bzero(bounds,sizeof(XkbBoundsRec)); - for (i=0,row=section->rows;i<section->num_rows;i++,row++) { - if (!XkbComputeRowBounds(geom,section,row)) - return False; - rbounds= &row->bounds; - _XkbCheckBounds(bounds,row->left+rbounds->x1,row->top+rbounds->y1); - _XkbCheckBounds(bounds,row->left+rbounds->x2,row->top+rbounds->y2); - } - for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { - static XkbBoundsRec tbounds; - switch (doodad->any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - shape= XkbShapeDoodadShape(geom,&doodad->shape); - rbounds= &shape->bounds; - break; - case XkbTextDoodad: - tbounds.x1= doodad->text.left; - tbounds.y1= doodad->text.top; - tbounds.x2= tbounds.x1+doodad->text.width; - tbounds.y2= tbounds.y1+doodad->text.height; - rbounds= &tbounds; - break; - case XkbIndicatorDoodad: - shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); - rbounds= &shape->bounds; - break; - case XkbLogoDoodad: - shape= XkbLogoDoodadShape(geom,&doodad->logo); - rbounds= &shape->bounds; - break; - default: - tbounds.x1= tbounds.x2= doodad->any.left; - tbounds.y1= tbounds.y2= doodad->any.top; - rbounds= &tbounds; - break; - } - _XkbCheckBounds(bounds,rbounds->x1,rbounds->y1); - _XkbCheckBounds(bounds,rbounds->x2,rbounds->y2); - } - return True; -} - -/***====================================================================***/ - -char * -XkbFindOverlayForKey(XkbGeometryPtr geom,XkbSectionPtr wanted,char *under) -{ -int s; -XkbSectionPtr section; - - if ((geom==NULL)||(under==NULL)||(geom->num_sections<1)) - return NULL; - - if (wanted) - section= wanted; - else section= geom->sections; - - for (s=0;s<geom->num_sections;s++,section++) { - XkbOverlayPtr ol; - int o; - - if (section->num_overlays<1) - continue; - for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { - XkbOverlayRowPtr row; - int r; - - for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { - XkbOverlayKeyPtr key; - int k; - for (k=0,key=row->keys;k<row->num_keys;k++,key++) { - if (strncmp(under,key->under.name,XkbKeyNameLength)==0) - return key->over.name; - } - } - } - if (wanted!=NULL) - break; - } - return NULL; -} - -/***====================================================================***/ - -static Status -_XkbReadGeomProperties( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -Status rtrn; - - if (rep->nProperties<1) - return Success; - if ((rtrn=XkbAllocGeomProps(geom,rep->nProperties))==Success) { - register int i; - register Bool ok; - char *name,*value; - ok= True; - for (i=0;(i<rep->nProperties)&&ok;i++) { - name=NULL; - value=NULL; - ok= _XkbGetReadBufferCountedString(buf,&name)&&ok; - ok= _XkbGetReadBufferCountedString(buf,&value)&&ok; - ok= ok&&(XkbAddGeomProperty(geom,name,value)!=NULL); - if (name) - _XkbFree(name); - if (value) - _XkbFree(value); - } - if (ok) rtrn= Success; - else rtrn= BadLength; - } - return rtrn; -} - -static Status -_XkbReadGeomKeyAliases( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -Status rtrn; - - if (rep->nKeyAliases<1) - return Success; - if ((rtrn=XkbAllocGeomKeyAliases(geom,rep->nKeyAliases))==Success) { - if (!_XkbCopyFromReadBuffer(buf,(char *)geom->key_aliases, - (rep->nKeyAliases*XkbKeyNameLength*2))) - return BadLength; - geom->num_key_aliases= rep->nKeyAliases; - return Success; - } - else { /* alloc failed, just skip the aliases */ - _XkbSkipReadBufferData(buf,(rep->nKeyAliases*XkbKeyNameLength*2)); - } - return rtrn; -} - -static Status -_XkbReadGeomColors( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -Status rtrn; - - if (rep->nColors<1) - return Success; - if ((rtrn=XkbAllocGeomColors(geom,rep->nColors))==Success) { - register int i; - char *spec; - for (i=0;i<rep->nColors;i++) { - spec = NULL; - if (!_XkbGetReadBufferCountedString(buf,&spec)) - rtrn = BadLength; - else if (XkbAddGeomColor(geom,spec,geom->num_colors)==NULL) - rtrn = BadAlloc; - if (spec) - _XkbFree(spec); - if (rtrn != Success) - return rtrn; - } - return Success; - } - return rtrn; -} - -static Status -_XkbReadGeomShapes( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -register int i; -Status rtrn; - - if (rep->nShapes<1) - return Success; - if ((rtrn=XkbAllocGeomShapes(geom,rep->nShapes))!=Success) - return rtrn; - for (i=0;i<rep->nShapes;i++) { - xkbShapeWireDesc *shapeWire; - XkbShapePtr shape; - register int o; - shapeWire= (xkbShapeWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbShapeWireDesc)); - if (!shapeWire) - return BadLength; - shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); - if (!shape) - return BadAlloc; - for (o=0;o<shapeWire->nOutlines;o++) { - xkbOutlineWireDesc *olWire; - XkbOutlinePtr ol; - register int p; - XkbPointPtr pt; - olWire= (xkbOutlineWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbOutlineWireDesc)); - if (!olWire) - return BadLength; - ol= XkbAddGeomOutline(shape,olWire->nPoints); - if (!ol) - return BadAlloc; - ol->corner_radius= olWire->cornerRadius; - for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { - xkbPointWireDesc * ptWire; - ptWire= (xkbPointWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbPointWireDesc)); - if (!ptWire) - return BadLength; - pt->x= ptWire->x; - pt->y= ptWire->y; - } - ol->num_points= olWire->nPoints; - } - if (shapeWire->primaryNdx!=XkbNoShape) - shape->primary= &shape->outlines[shapeWire->primaryNdx]; - else shape->primary= NULL; - if (shapeWire->approxNdx!=XkbNoShape) - shape->approx= &shape->outlines[shapeWire->approxNdx]; - else shape->approx= NULL; - XkbComputeShapeBounds(shape); - } - return Success; -} - -static Status -_XkbReadGeomDoodad( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - XkbSectionPtr section) -{ -XkbDoodadPtr doodad; -xkbDoodadWireDesc * doodadWire; - - doodadWire= (xkbDoodadWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbDoodadWireDesc)); - if (!doodadWire) - return BadLength; - doodad= XkbAddGeomDoodad(geom,section,doodadWire->any.name); - if (!doodad) - return BadAlloc; - doodad->any.type= doodadWire->any.type; - doodad->any.priority= doodadWire->any.priority; - doodad->any.top= doodadWire->any.top; - doodad->any.left= doodadWire->any.left; - doodad->any.angle= doodadWire->any.angle; - switch (doodad->any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - doodad->shape.color_ndx= doodadWire->shape.colorNdx; - doodad->shape.shape_ndx= doodadWire->shape.shapeNdx; - break; - case XkbTextDoodad: - doodad->text.width= doodadWire->text.width; - doodad->text.height= doodadWire->text.height; - doodad->text.color_ndx= doodadWire->text.colorNdx; - if (!_XkbGetReadBufferCountedString(buf,&doodad->text.text)) - return BadLength; - if (!_XkbGetReadBufferCountedString(buf,&doodad->text.font)) - return BadLength; - break; - case XkbIndicatorDoodad: - doodad->indicator.shape_ndx= doodadWire->indicator.shapeNdx; - doodad->indicator.on_color_ndx= doodadWire->indicator.onColorNdx; - doodad->indicator.off_color_ndx= doodadWire->indicator.offColorNdx; - break; - case XkbLogoDoodad: - doodad->logo.color_ndx= doodadWire->logo.colorNdx; - doodad->logo.shape_ndx= doodadWire->logo.shapeNdx; - if (!_XkbGetReadBufferCountedString(buf,&doodad->logo.logo_name)) - return BadLength; - break; - default: - return BadValue; - } - return Success; -} - -static Status -_XkbReadGeomOverlay( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - XkbSectionPtr section) -{ -XkbOverlayPtr ol; -xkbOverlayWireDesc * olWire; -register int r; - - olWire= (xkbOverlayWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayWireDesc)); - if (olWire==NULL) - return BadLength; - ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); - if (ol==NULL) - return BadLength; - for (r=0;r<olWire->nRows;r++) { - register int k; - XkbOverlayRowPtr row; - xkbOverlayRowWireDesc * rowWire; - xkbOverlayKeyWireDesc * keyWire; - rowWire= (xkbOverlayRowWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayRowWireDesc)); - if (rowWire==NULL) - return BadLength; - row= XkbAddGeomOverlayRow(ol,rowWire->rowUnder,rowWire->nKeys); - row->row_under= rowWire->rowUnder; - if (!row) - return BadAlloc; - if (rowWire->nKeys<1) - continue; - keyWire= (xkbOverlayKeyWireDesc *) - _XkbGetReadBufferPtr(buf, - SIZEOF(xkbOverlayKeyWireDesc)*rowWire->nKeys); - if (keyWire==NULL) - return BadLength; - for (k=0;k<rowWire->nKeys;k++,keyWire++,row->num_keys++) { - memcpy(row->keys[row->num_keys].over.name,keyWire->over, - XkbKeyNameLength); - memcpy(row->keys[row->num_keys].under.name,keyWire->under, - XkbKeyNameLength); - } - } - return Success; -} - -static Status -_XkbReadGeomSections( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -register int s; -XkbSectionPtr section; -xkbSectionWireDesc * sectionWire; -Status rtrn; - - if (rep->nSections<1) - return Success; - if ((rtrn=XkbAllocGeomSections(geom,rep->nSections))!=Success) - return rtrn; - for (s=0;s<rep->nSections;s++) { - sectionWire= (xkbSectionWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbSectionWireDesc)); - if (!sectionWire) - return BadLength; - section= XkbAddGeomSection(geom,sectionWire->name,sectionWire->nRows, - sectionWire->nDoodads, - sectionWire->nOverlays); - if (!section) - return BadAlloc; - section->top= sectionWire->top; - section->left= sectionWire->left; - section->width= sectionWire->width; - section->height= sectionWire->height; - section->angle= sectionWire->angle; - section->priority= sectionWire->priority; - if (sectionWire->nRows>0) { - register int r; - XkbRowPtr row; - xkbRowWireDesc * rowWire; - for (r=0;r<sectionWire->nRows;r++) { - rowWire= (xkbRowWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbRowWireDesc)); - if (!rowWire) - return BadLength; - row= XkbAddGeomRow(section,rowWire->nKeys); - if (!row) - return BadAlloc; - row->top= rowWire->top; - row->left= rowWire->left; - row->vertical= rowWire->vertical; - if (rowWire->nKeys>0) { - register int k; - XkbKeyPtr key; - xkbKeyWireDesc * keyWire; - for (k=0;k<rowWire->nKeys;k++) { - keyWire= (xkbKeyWireDesc *) - _XkbGetReadBufferPtr(buf,SIZEOF(xkbKeyWireDesc)); - if (!keyWire) - return BadLength; - key= XkbAddGeomKey(row); - if (!key) - return BadAlloc; - memcpy(key->name.name,keyWire->name,XkbKeyNameLength); - key->gap= keyWire->gap; - key->shape_ndx= keyWire->shapeNdx; - key->color_ndx= keyWire->colorNdx; - } - } - } - } - if (sectionWire->nDoodads>0) { - register int d; - for (d=0;d<sectionWire->nDoodads;d++) { - if ((rtrn=_XkbReadGeomDoodad(buf,geom,section))!=Success) - return rtrn; - } - } - if (sectionWire->nOverlays>0) { - register int o; - for (o=0;o<sectionWire->nOverlays;o++) { - if ((rtrn=_XkbReadGeomOverlay(buf,geom,section))!=Success) - return rtrn; - } - } - } - return Success; -} - -static Status -_XkbReadGeomDoodads( XkbReadBufferPtr buf, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep) -{ -register int d; -Status rtrn; - - if (rep->nDoodads<1) - return Success; - if ((rtrn=XkbAllocGeomDoodads(geom,rep->nDoodads))!=Success) - return rtrn; - for (d=0;d<rep->nDoodads;d++) { - if ((rtrn=_XkbReadGeomDoodad(buf,geom,NULL))!=Success) - return rtrn; - } - return Success; -} - -Status -_XkbReadGetGeometryReply( Display * dpy, - xkbGetGeometryReply * rep, - XkbDescPtr xkb, - int * nread_rtrn) -{ -XkbGeometryPtr geom; - - geom= _XkbTypedCalloc(1,XkbGeometryRec); - if (!geom) - return BadAlloc; - if (xkb->geom) - XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True); - xkb->geom= geom; - - geom->name= rep->name; - geom->width_mm= rep->widthMM; - geom->height_mm= rep->heightMM; - if (rep->length) { - XkbReadBufferRec buf; - int left; - if (_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) { - Status status= Success; - if (nread_rtrn) - *nread_rtrn= (int)rep->length*4; - if (!_XkbGetReadBufferCountedString(&buf,&geom->label_font)) - status= BadLength; - if (status==Success) - status= _XkbReadGeomProperties(&buf,geom,rep); - if (status==Success) - status= _XkbReadGeomColors(&buf,geom,rep); - if (status==Success) - status= _XkbReadGeomShapes(&buf,geom,rep); - if (status==Success) - status= _XkbReadGeomSections(&buf,geom,rep); - if (status==Success) - status= _XkbReadGeomDoodads(&buf,geom,rep); - if (status==Success) - status= _XkbReadGeomKeyAliases(&buf,geom,rep); - left= _XkbFreeReadBuffer(&buf); - if ((status!=Success) || left || buf.error) { - if (status==Success) - status= BadLength; - XkbFreeGeometry(geom,XkbGeomAllMask,True); - xkb->geom= NULL; - return status; - } - geom->base_color= &geom->colors[rep->baseColorNdx]; - geom->label_color= &geom->colors[rep->labelColorNdx]; - } - else { - XkbFreeGeometry(geom,XkbGeomAllMask,True); - xkb->geom= NULL; - return BadAlloc; - } - } - return Success; -} - -Status -XkbGetGeometry(Display *dpy,XkbDescPtr xkb) -{ -xkbGetGeometryReq *req; -xkbGetGeometryReply rep; -Status status; - - if ( (!xkb) || (dpy->flags & XlibDisplayNoXkb) || - (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) - return BadAccess; - - LockDisplay(dpy); - GetReq(kbGetGeometry, req); - req->reqType = dpy->xkb_info->codes->major_opcode; - req->xkbReqType = X_kbGetGeometry; - req->deviceSpec = xkb->device_spec; - req->name= None; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) - status = BadImplementation; - else if (!rep.found) - status = BadName; - else - status = _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL); - UnlockDisplay(dpy); - SyncHandle(); - return status; -} - -Status -XkbGetNamedGeometry(Display *dpy,XkbDescPtr xkb,Atom name) -{ -xkbGetGeometryReq *req; -xkbGetGeometryReply rep; -Status status; - - if ( (name==None) || (dpy->flags & XlibDisplayNoXkb) || - (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) ) - return BadAccess; - - LockDisplay(dpy); - GetReq(kbGetGeometry, req); - req->reqType = dpy->xkb_info->codes->major_opcode; - req->xkbReqType = X_kbGetGeometry; - req->deviceSpec = xkb->device_spec; - req->name= (CARD32)name; - if ((!_XReply(dpy, (xReply *)&rep, 0, xFalse))||(!rep.found)) - status = BadImplementation; - else if (!rep.found) - status = BadName; - else - status = _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL); - UnlockDisplay(dpy); - SyncHandle(); - return status; -} - +/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, 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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef DEBUG
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#endif
+
+#define NEED_MAP_READERS
+#include "Xlibint.h"
+#include <X11/extensions/XKBgeom.h>
+#include <X11/extensions/XKBproto.h>
+#include "XKBlibint.h"
+
+#define MINSHORT -32768
+#define MAXSHORT 32767
+
+/***====================================================================***/
+
+static void
+_XkbCheckBounds(XkbBoundsPtr bounds,int x,int y)
+{
+ if (x<bounds->x1) bounds->x1= x;
+ if (x>bounds->x2) bounds->x2= x;
+ if (y<bounds->y1) bounds->y1= y;
+ if (y>bounds->y2) bounds->y2= y;
+ return;
+}
+
+Bool
+XkbComputeShapeBounds(XkbShapePtr shape)
+{
+register int o,p;
+XkbOutlinePtr outline;
+XkbPointPtr pt;
+
+ if ((!shape)||(shape->num_outlines<1))
+ return False;
+ shape->bounds.x1= shape->bounds.y1= MAXSHORT;
+ shape->bounds.x2= shape->bounds.y2= MINSHORT;
+ for (outline=shape->outlines,o=0;o<shape->num_outlines;o++,outline++) {
+ for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) {
+ _XkbCheckBounds(&shape->bounds,pt->x,pt->y);
+ }
+ if (outline->num_points<2) {
+ _XkbCheckBounds(&shape->bounds,0,0);
+ }
+ }
+ return True;
+}
+
+Bool
+XkbComputeShapeTop(XkbShapePtr shape,XkbBoundsPtr bounds)
+{
+register int p;
+XkbOutlinePtr outline;
+XkbPointPtr pt;
+
+ if ((!shape)||(shape->num_outlines<1))
+ return False;
+ if (shape->approx) outline= shape->approx;
+ else outline= &shape->outlines[shape->num_outlines-1];
+ if (outline->num_points<2) {
+ bounds->x1= bounds->y1= 0;
+ bounds->x2= bounds->y2= 0;
+ }
+ else {
+ bounds->x1= bounds->y1= MAXSHORT;
+ bounds->x2= bounds->y2= MINSHORT;
+ }
+ for (pt=outline->points,p=0;p<outline->num_points;p++,pt++) {
+ _XkbCheckBounds(bounds,pt->x,pt->y);
+ }
+ return True;
+}
+
+Bool
+XkbComputeRowBounds(XkbGeometryPtr geom,XkbSectionPtr section,XkbRowPtr row)
+{
+register int k,pos;
+XkbKeyPtr key;
+XkbBoundsPtr bounds,sbounds;
+
+ if ((!geom)||(!section)||(!row))
+ return False;
+ bounds= &row->bounds;
+ bzero(bounds,sizeof(XkbBoundsRec));
+ for (key=row->keys,pos=k=0;k<row->num_keys;k++,key++) {
+ sbounds= &XkbKeyShape(geom,key)->bounds;
+ _XkbCheckBounds(bounds,pos,0);
+ if (!row->vertical) {
+ if (key->gap!=0) {
+ pos+= key->gap;
+ _XkbCheckBounds(bounds,pos,0);
+ }
+ _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1);
+ _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2);
+ pos+= sbounds->x2;
+ }
+ else {
+ if (key->gap!=0) {
+ pos+= key->gap;
+ _XkbCheckBounds(bounds,0,pos);
+ }
+ _XkbCheckBounds(bounds,pos+sbounds->x1,sbounds->y1);
+ _XkbCheckBounds(bounds,pos+sbounds->x2,sbounds->y2);
+ pos+= sbounds->y2;
+ }
+ }
+ return True;
+}
+
+Bool
+XkbComputeSectionBounds(XkbGeometryPtr geom,XkbSectionPtr section)
+{
+register int i;
+XkbShapePtr shape;
+XkbRowPtr row;
+XkbDoodadPtr doodad;
+XkbBoundsPtr bounds,rbounds;
+
+ if ((!geom)||(!section))
+ return False;
+ bounds= §ion->bounds;
+ bzero(bounds,sizeof(XkbBoundsRec));
+ for (i=0,row=section->rows;i<section->num_rows;i++,row++) {
+ if (!XkbComputeRowBounds(geom,section,row))
+ return False;
+ rbounds= &row->bounds;
+ _XkbCheckBounds(bounds,row->left+rbounds->x1,row->top+rbounds->y1);
+ _XkbCheckBounds(bounds,row->left+rbounds->x2,row->top+rbounds->y2);
+ }
+ for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) {
+ static XkbBoundsRec tbounds;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ shape= XkbShapeDoodadShape(geom,&doodad->shape);
+ rbounds= &shape->bounds;
+ break;
+ case XkbTextDoodad:
+ tbounds.x1= doodad->text.left;
+ tbounds.y1= doodad->text.top;
+ tbounds.x2= tbounds.x1+doodad->text.width;
+ tbounds.y2= tbounds.y1+doodad->text.height;
+ rbounds= &tbounds;
+ break;
+ case XkbIndicatorDoodad:
+ shape= XkbIndicatorDoodadShape(geom,&doodad->indicator);
+ rbounds= &shape->bounds;
+ break;
+ case XkbLogoDoodad:
+ shape= XkbLogoDoodadShape(geom,&doodad->logo);
+ rbounds= &shape->bounds;
+ break;
+ default:
+ tbounds.x1= tbounds.x2= doodad->any.left;
+ tbounds.y1= tbounds.y2= doodad->any.top;
+ rbounds= &tbounds;
+ break;
+ }
+ _XkbCheckBounds(bounds,rbounds->x1,rbounds->y1);
+ _XkbCheckBounds(bounds,rbounds->x2,rbounds->y2);
+ }
+ return True;
+}
+
+/***====================================================================***/
+
+char *
+XkbFindOverlayForKey(XkbGeometryPtr geom,XkbSectionPtr wanted,char *under)
+{
+int s;
+XkbSectionPtr section;
+
+ if ((geom==NULL)||(under==NULL)||(geom->num_sections<1))
+ return NULL;
+
+ if (wanted)
+ section= wanted;
+ else section= geom->sections;
+
+ for (s=0;s<geom->num_sections;s++,section++) {
+ XkbOverlayPtr ol;
+ int o;
+
+ if (section->num_overlays<1)
+ continue;
+ for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
+ XkbOverlayRowPtr row;
+ int r;
+
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ XkbOverlayKeyPtr key;
+ int k;
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ if (strncmp(under,key->under.name,XkbKeyNameLength)==0)
+ return key->over.name;
+ }
+ }
+ }
+ if (wanted!=NULL)
+ break;
+ }
+ return NULL;
+}
+
+/***====================================================================***/
+
+static Status
+_XkbReadGeomProperties( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+Status rtrn;
+
+ if (rep->nProperties<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomProps(geom,rep->nProperties))==Success) {
+ register int i;
+ register Bool ok;
+ char *name,*value;
+ ok= True;
+ for (i=0;(i<rep->nProperties)&&ok;i++) {
+ name=NULL;
+ value=NULL;
+ ok= _XkbGetReadBufferCountedString(buf,&name)&&ok;
+ ok= _XkbGetReadBufferCountedString(buf,&value)&&ok;
+ ok= ok&&(XkbAddGeomProperty(geom,name,value)!=NULL);
+ if (name)
+ _XkbFree(name);
+ if (value)
+ _XkbFree(value);
+ }
+ if (ok) rtrn= Success;
+ else rtrn= BadLength;
+ }
+ return rtrn;
+}
+
+static Status
+_XkbReadGeomKeyAliases( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+Status rtrn;
+
+ if (rep->nKeyAliases<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomKeyAliases(geom,rep->nKeyAliases))==Success) {
+ if (!_XkbCopyFromReadBuffer(buf,(char *)geom->key_aliases,
+ (rep->nKeyAliases*XkbKeyNameLength*2)))
+ return BadLength;
+ geom->num_key_aliases= rep->nKeyAliases;
+ return Success;
+ }
+ else { /* alloc failed, just skip the aliases */
+ _XkbSkipReadBufferData(buf,(rep->nKeyAliases*XkbKeyNameLength*2));
+ }
+ return rtrn;
+}
+
+static Status
+_XkbReadGeomColors( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+Status rtrn;
+
+ if (rep->nColors<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomColors(geom,rep->nColors))==Success) {
+ register int i;
+ char *spec;
+ for (i=0;i<rep->nColors;i++) {
+ spec = NULL;
+ if (!_XkbGetReadBufferCountedString(buf,&spec))
+ rtrn = BadLength;
+ else if (XkbAddGeomColor(geom,spec,geom->num_colors)==NULL)
+ rtrn = BadAlloc;
+ if (spec)
+ _XkbFree(spec);
+ if (rtrn != Success)
+ return rtrn;
+ }
+ return Success;
+ }
+ return rtrn;
+}
+
+static Status
+_XkbReadGeomShapes( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+register int i;
+Status rtrn;
+
+ if (rep->nShapes<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomShapes(geom,rep->nShapes))!=Success)
+ return rtrn;
+ for (i=0;i<rep->nShapes;i++) {
+ xkbShapeWireDesc *shapeWire;
+ XkbShapePtr shape;
+ register int o;
+ shapeWire= (xkbShapeWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbShapeWireDesc));
+ if (!shapeWire)
+ return BadLength;
+ shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
+ if (!shape)
+ return BadAlloc;
+ for (o=0;o<shapeWire->nOutlines;o++) {
+ xkbOutlineWireDesc *olWire;
+ XkbOutlinePtr ol;
+ register int p;
+ XkbPointPtr pt;
+ olWire= (xkbOutlineWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbOutlineWireDesc));
+ if (!olWire)
+ return BadLength;
+ ol= XkbAddGeomOutline(shape,olWire->nPoints);
+ if (!ol)
+ return BadAlloc;
+ ol->corner_radius= olWire->cornerRadius;
+ for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
+ xkbPointWireDesc * ptWire;
+ ptWire= (xkbPointWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbPointWireDesc));
+ if (!ptWire)
+ return BadLength;
+ pt->x= ptWire->x;
+ pt->y= ptWire->y;
+ }
+ ol->num_points= olWire->nPoints;
+ }
+ if (shapeWire->primaryNdx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire->primaryNdx];
+ else shape->primary= NULL;
+ if (shapeWire->approxNdx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire->approxNdx];
+ else shape->approx= NULL;
+ XkbComputeShapeBounds(shape);
+ }
+ return Success;
+}
+
+static Status
+_XkbReadGeomDoodad( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+XkbDoodadPtr doodad;
+xkbDoodadWireDesc * doodadWire;
+
+ doodadWire= (xkbDoodadWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbDoodadWireDesc));
+ if (!doodadWire)
+ return BadLength;
+ doodad= XkbAddGeomDoodad(geom,section,doodadWire->any.name);
+ if (!doodad)
+ return BadAlloc;
+ doodad->any.type= doodadWire->any.type;
+ doodad->any.priority= doodadWire->any.priority;
+ doodad->any.top= doodadWire->any.top;
+ doodad->any.left= doodadWire->any.left;
+ doodad->any.angle= doodadWire->any.angle;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodad->shape.color_ndx= doodadWire->shape.colorNdx;
+ doodad->shape.shape_ndx= doodadWire->shape.shapeNdx;
+ break;
+ case XkbTextDoodad:
+ doodad->text.width= doodadWire->text.width;
+ doodad->text.height= doodadWire->text.height;
+ doodad->text.color_ndx= doodadWire->text.colorNdx;
+ if (!_XkbGetReadBufferCountedString(buf,&doodad->text.text))
+ return BadLength;
+ if (!_XkbGetReadBufferCountedString(buf,&doodad->text.font))
+ return BadLength;
+ break;
+ case XkbIndicatorDoodad:
+ doodad->indicator.shape_ndx= doodadWire->indicator.shapeNdx;
+ doodad->indicator.on_color_ndx= doodadWire->indicator.onColorNdx;
+ doodad->indicator.off_color_ndx= doodadWire->indicator.offColorNdx;
+ break;
+ case XkbLogoDoodad:
+ doodad->logo.color_ndx= doodadWire->logo.colorNdx;
+ doodad->logo.shape_ndx= doodadWire->logo.shapeNdx;
+ if (!_XkbGetReadBufferCountedString(buf,&doodad->logo.logo_name))
+ return BadLength;
+ break;
+ default:
+ return BadValue;
+ }
+ return Success;
+}
+
+static Status
+_XkbReadGeomOverlay( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+XkbOverlayPtr ol;
+xkbOverlayWireDesc * olWire;
+register int r;
+
+ olWire= (xkbOverlayWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayWireDesc));
+ if (olWire==NULL)
+ return BadLength;
+ ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
+ if (ol==NULL)
+ return BadLength;
+ for (r=0;r<olWire->nRows;r++) {
+ register int k;
+ XkbOverlayRowPtr row;
+ xkbOverlayRowWireDesc * rowWire;
+ xkbOverlayKeyWireDesc * keyWire;
+ rowWire= (xkbOverlayRowWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbOverlayRowWireDesc));
+ if (rowWire==NULL)
+ return BadLength;
+ row= XkbAddGeomOverlayRow(ol,rowWire->rowUnder,rowWire->nKeys);
+ row->row_under= rowWire->rowUnder;
+ if (!row)
+ return BadAlloc;
+ if (rowWire->nKeys<1)
+ continue;
+ keyWire= (xkbOverlayKeyWireDesc *)
+ _XkbGetReadBufferPtr(buf,
+ SIZEOF(xkbOverlayKeyWireDesc)*rowWire->nKeys);
+ if (keyWire==NULL)
+ return BadLength;
+ for (k=0;k<rowWire->nKeys;k++,keyWire++,row->num_keys++) {
+ memcpy(row->keys[row->num_keys].over.name,keyWire->over,
+ XkbKeyNameLength);
+ memcpy(row->keys[row->num_keys].under.name,keyWire->under,
+ XkbKeyNameLength);
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadGeomSections( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+register int s;
+XkbSectionPtr section;
+xkbSectionWireDesc * sectionWire;
+Status rtrn;
+
+ if (rep->nSections<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomSections(geom,rep->nSections))!=Success)
+ return rtrn;
+ for (s=0;s<rep->nSections;s++) {
+ sectionWire= (xkbSectionWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbSectionWireDesc));
+ if (!sectionWire)
+ return BadLength;
+ section= XkbAddGeomSection(geom,sectionWire->name,sectionWire->nRows,
+ sectionWire->nDoodads,
+ sectionWire->nOverlays);
+ if (!section)
+ return BadAlloc;
+ section->top= sectionWire->top;
+ section->left= sectionWire->left;
+ section->width= sectionWire->width;
+ section->height= sectionWire->height;
+ section->angle= sectionWire->angle;
+ section->priority= sectionWire->priority;
+ if (sectionWire->nRows>0) {
+ register int r;
+ XkbRowPtr row;
+ xkbRowWireDesc * rowWire;
+ for (r=0;r<sectionWire->nRows;r++) {
+ rowWire= (xkbRowWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbRowWireDesc));
+ if (!rowWire)
+ return BadLength;
+ row= XkbAddGeomRow(section,rowWire->nKeys);
+ if (!row)
+ return BadAlloc;
+ row->top= rowWire->top;
+ row->left= rowWire->left;
+ row->vertical= rowWire->vertical;
+ if (rowWire->nKeys>0) {
+ register int k;
+ XkbKeyPtr key;
+ xkbKeyWireDesc * keyWire;
+ for (k=0;k<rowWire->nKeys;k++) {
+ keyWire= (xkbKeyWireDesc *)
+ _XkbGetReadBufferPtr(buf,SIZEOF(xkbKeyWireDesc));
+ if (!keyWire)
+ return BadLength;
+ key= XkbAddGeomKey(row);
+ if (!key)
+ return BadAlloc;
+ memcpy(key->name.name,keyWire->name,XkbKeyNameLength);
+ key->gap= keyWire->gap;
+ key->shape_ndx= keyWire->shapeNdx;
+ key->color_ndx= keyWire->colorNdx;
+ }
+ }
+ }
+ }
+ if (sectionWire->nDoodads>0) {
+ register int d;
+ for (d=0;d<sectionWire->nDoodads;d++) {
+ if ((rtrn=_XkbReadGeomDoodad(buf,geom,section))!=Success)
+ return rtrn;
+ }
+ }
+ if (sectionWire->nOverlays>0) {
+ register int o;
+ for (o=0;o<sectionWire->nOverlays;o++) {
+ if ((rtrn=_XkbReadGeomOverlay(buf,geom,section))!=Success)
+ return rtrn;
+ }
+ }
+ }
+ return Success;
+}
+
+static Status
+_XkbReadGeomDoodads( XkbReadBufferPtr buf,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep)
+{
+register int d;
+Status rtrn;
+
+ if (rep->nDoodads<1)
+ return Success;
+ if ((rtrn=XkbAllocGeomDoodads(geom,rep->nDoodads))!=Success)
+ return rtrn;
+ for (d=0;d<rep->nDoodads;d++) {
+ if ((rtrn=_XkbReadGeomDoodad(buf,geom,NULL))!=Success)
+ return rtrn;
+ }
+ return Success;
+}
+
+Status
+_XkbReadGetGeometryReply( Display * dpy,
+ xkbGetGeometryReply * rep,
+ XkbDescPtr xkb,
+ int * nread_rtrn)
+{
+XkbGeometryPtr geom;
+
+ geom= _XkbTypedCalloc(1,XkbGeometryRec);
+ if (!geom)
+ return BadAlloc;
+ if (xkb->geom)
+ XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True);
+ xkb->geom= geom;
+
+ geom->name= rep->name;
+ geom->width_mm= rep->widthMM;
+ geom->height_mm= rep->heightMM;
+ if (rep->length) {
+ XkbReadBufferRec buf;
+ int left;
+ if (_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) {
+ Status status= Success;
+ if (nread_rtrn)
+ *nread_rtrn= (int)rep->length*4;
+ if (!_XkbGetReadBufferCountedString(&buf,&geom->label_font))
+ status= BadLength;
+ if (status==Success)
+ status= _XkbReadGeomProperties(&buf,geom,rep);
+ if (status==Success)
+ status= _XkbReadGeomColors(&buf,geom,rep);
+ if (status==Success)
+ status= _XkbReadGeomShapes(&buf,geom,rep);
+ if (status==Success)
+ status= _XkbReadGeomSections(&buf,geom,rep);
+ if (status==Success)
+ status= _XkbReadGeomDoodads(&buf,geom,rep);
+ if (status==Success)
+ status= _XkbReadGeomKeyAliases(&buf,geom,rep);
+ left= _XkbFreeReadBuffer(&buf);
+ if ((status!=Success) || left || buf.error) {
+ if (status==Success)
+ status= BadLength;
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= NULL;
+ return status;
+ }
+ geom->base_color= &geom->colors[rep->baseColorNdx];
+ geom->label_color= &geom->colors[rep->labelColorNdx];
+ }
+ else {
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= NULL;
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+Status
+XkbGetGeometry(Display *dpy,XkbDescPtr xkb)
+{
+xkbGetGeometryReq *req;
+xkbGetGeometryReply rep;
+Status status;
+
+ if ( (!xkb) || (dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
+ return BadAccess;
+
+ LockDisplay(dpy);
+ GetReq(kbGetGeometry, req);
+ req->reqType = dpy->xkb_info->codes->major_opcode;
+ req->xkbReqType = X_kbGetGeometry;
+ req->deviceSpec = xkb->device_spec;
+ req->name= None;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
+ status = BadImplementation;
+ else if (!rep.found)
+ status = BadName;
+ else
+ status = _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+Status
+XkbGetNamedGeometry(Display *dpy,XkbDescPtr xkb,Atom name)
+{
+xkbGetGeometryReq *req;
+xkbGetGeometryReply rep;
+Status status;
+
+ if ( (name==None) || (dpy->flags & XlibDisplayNoXkb) ||
+ (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)) )
+ return BadAccess;
+
+ LockDisplay(dpy);
+ GetReq(kbGetGeometry, req);
+ req->reqType = dpy->xkb_info->codes->major_opcode;
+ req->xkbReqType = X_kbGetGeometry;
+ req->deviceSpec = xkb->device_spec;
+ req->name= (CARD32)name;
+ if ((!_XReply(dpy, (xReply *)&rep, 0, xFalse))||(!rep.found))
+ status = BadImplementation;
+ else if (!rep.found)
+ status = BadName;
+ else
+ status = _XkbReadGetGeometryReply(dpy,&rep,xkb,NULL);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
diff --git a/libX11/src/xkb/XKBGetMap.c b/libX11/src/xkb/XKBGetMap.c index eff088341..96370c6d3 100644 --- a/libX11/src/xkb/XKBGetMap.c +++ b/libX11/src/xkb/XKBGetMap.c @@ -28,6 +28,34 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "Xlibint.h"
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
diff --git a/libX11/src/xkb/XKBMisc.c b/libX11/src/xkb/XKBMisc.c index 4aa1f733a..ac1e8c062 100644 --- a/libX11/src/xkb/XKBMisc.c +++ b/libX11/src/xkb/XKBMisc.c @@ -42,6 +42,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <stdio.h> #include <X11/X.h> +#define XkbVirtualModsToReal SrvXkbVirtualModsToReal #include <X11/Xproto.h> #include "misc.h" #include "inputstr.h" diff --git a/libX11/src/xkb/XKBSetGeom.c b/libX11/src/xkb/XKBSetGeom.c index 439b75e01..5b9f5887c 100644 --- a/libX11/src/xkb/XKBSetGeom.c +++ b/libX11/src/xkb/XKBSetGeom.c @@ -36,12 +36,8 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <X11/extensions/XKBgeom.h>
#include <X11/extensions/XKBproto.h>
-#ifndef MINSHORT
#define MINSHORT -32768
-#endif
-#ifndef MAXSHORT
#define MAXSHORT 32767
-#endif
/***====================================================================***/
diff --git a/libX11/src/xkb/XKBUse.c b/libX11/src/xkb/XKBUse.c index efca018f6..a16d6963a 100644 --- a/libX11/src/xkb/XKBUse.c +++ b/libX11/src/xkb/XKBUse.c @@ -29,6 +29,34 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif
#include <stdio.h>
#include <ctype.h>
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "Xlibint.h"
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
diff --git a/libX11/src/xlibi18n/XDefaultIMIF.c b/libX11/src/xlibi18n/XDefaultIMIF.c index e97d2f444..80199669e 100644 --- a/libX11/src/xlibi18n/XDefaultIMIF.c +++ b/libX11/src/xlibi18n/XDefaultIMIF.c @@ -1,469 +1,470 @@ -/* -Copyright 1985, 1986, 1987, 1991, 1998 The Open Group - -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 -OPEN GROUP 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 -EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. - - -Except as contained in this notice, the name of The Open Group 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 Open Group. - - -X Window System is a trademark of The Open Group - -OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF -logo, LBX, X Window System, and Xinerama are trademarks of the Open -Group. All other trademarks and registered trademarks mentioned herein -are the property of their respective owners. No right, title or -interest in or to any trademark, service mark, logo or trade name of -Sun Microsystems, Inc. or its licensors is granted. - -*/ -/* - * Copyright 2000 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include "Xlibint.h" -#include "Xlcint.h" -#include "XlcGeneric.h" - -#ifndef MAXINT -#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1)) -#endif /* !MAXINT */ - -typedef struct _StaticXIM *StaticXIM; - -typedef struct _XIMStaticXIMRec { - /* for CT => MB,WC converter */ - XlcConv ctom_conv; - XlcConv ctow_conv; -} XIMStaticXIMRec; - -typedef enum { - CREATE_IC = 1, - SET_ICVAL = 2, - GET_ICVAL = 3 -} XICOp_t; - -typedef struct _StaticXIM { - XIMMethods methods; - XIMCoreRec core; - XIMStaticXIMRec *private; -} StaticXIMRec; - -static Status _CloseIM( - XIM -); - -static char *_SetIMValues( - XIM, XIMArg * -); - -static char *_GetIMValues( - XIM, XIMArg* -); - -static XIC _CreateIC( - XIM, XIMArg* -); - -static _Xconst XIMMethodsRec local_im_methods = { - _CloseIM, /* close */ - _SetIMValues, /* set_values */ - _GetIMValues, /* get_values */ - _CreateIC, /* create_ic */ - NULL, /* ctstombs */ - NULL /* ctstowcs */ -}; - -static void _DestroyIC( - XIC -); -static void _SetFocus( - XIC -); -static void _UnsetFocus( - XIC -); -static char* _SetICValues( - XIC, XIMArg * -); -static char* _GetICValues( - XIC, XIMArg * -); -static char *_MbReset( - XIC -); -static wchar_t *_WcReset( - XIC -); -static int _MbLookupString( - XIC, XKeyEvent *, char *, int, KeySym *, Status * -); -static int _WcLookupString( - XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status * -); - -static _Xconst XICMethodsRec local_ic_methods = { - _DestroyIC, /* destroy */ - _SetFocus, /* set_focus */ - _UnsetFocus, /* unset_focus */ - _SetICValues, /* set_values */ - _GetICValues, /* get_values */ - _MbReset, /* mb_reset */ - _WcReset, /* wc_reset */ - NULL, /* utf8_reset */ /* ??? */ - _MbLookupString, /* mb_lookup_string */ - _WcLookupString, /* wc_lookup_string */ - NULL /* utf8_lookup_string */ /* ??? */ -}; - -XIM -_XDefaultOpenIM( - XLCd lcd, - Display *dpy, - XrmDatabase rdb, - char *res_name, - char *res_class) -{ - StaticXIM im; - XIMStaticXIMRec *local_impart; - XlcConv ctom_conv, ctow_conv; - int i; - char *mod; - char buf[BUFSIZ]; - - if (!(ctom_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNMultiByte))) { - return((XIM)NULL); - } - - if (!(ctow_conv = _XlcOpenConverter(lcd, - XlcNCompoundText, lcd, XlcNWideChar))) { - return((XIM)NULL); - } - - if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) { - return((XIM)NULL); - } - if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec))) - == (XIMStaticXIMRec *)NULL) { - Xfree(im); - return((XIM)NULL); - } - memset(im, 0, sizeof(StaticXIMRec)); - memset(local_impart, 0, sizeof(XIMStaticXIMRec)); - - buf[0] = '\0'; - i = 0; - if ((lcd->core->modifiers) && (*lcd->core->modifiers)) { -#define MODIFIER "@im=" - mod = strstr(lcd->core->modifiers, MODIFIER); - if (mod) { - mod += strlen(MODIFIER); - while (*mod && *mod != '@' && i < BUFSIZ - 1) { - buf[i++] = *mod++; - } - buf[i] = '\0'; - } - } -#undef MODIFIER - if ((im->core.im_name = Xmalloc(i+1)) == NULL) - goto Error2; - strcpy(im->core.im_name, buf); - - im->private = local_impart; - im->methods = (XIMMethods)&local_im_methods; - im->core.lcd = lcd; - im->core.ic_chain = (XIC)NULL; - im->core.display = dpy; - im->core.rdb = rdb; - im->core.res_name = NULL; - im->core.res_class = NULL; - - local_impart->ctom_conv = ctom_conv; - local_impart->ctow_conv = ctow_conv; - - if ((res_name != NULL) && (*res_name != '\0')){ - im->core.res_name = strdup(res_name); - } - if ((res_class != NULL) && (*res_class != '\0')){ - im->core.res_class = strdup(res_class); - } - - return (XIM)im; -Error2 : - Xfree(im->private); - Xfree(im->core.im_name); - Xfree(im); - _XlcCloseConverter(ctom_conv); - _XlcCloseConverter(ctow_conv); - return(NULL); -} - -static Status -_CloseIM(XIM xim) -{ - StaticXIM im = (StaticXIM)xim; - _XlcCloseConverter(im->private->ctom_conv); - _XlcCloseConverter(im->private->ctow_conv); - XFree(im->private); - XFree(im->core.im_name); - if (im->core.res_name) XFree(im->core.res_name); - if (im->core.res_class) XFree(im->core.res_class); - return 1; /*bugID 4163122*/ -} - -static char * -_SetIMValues( - XIM xim, - XIMArg *arg) -{ - return(arg->name); /* evil */ -} - -static char * -_GetIMValues( - XIM xim, - XIMArg *values) -{ - XIMArg *p; - XIMStyles *styles; - - for (p = values; p->name != NULL; p++) { - if (strcmp(p->name, XNQueryInputStyle) == 0) { - styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles)); - *(XIMStyles **)p->value = styles; - styles->count_styles = 1; - styles->supported_styles = - (XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle)); - styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone); - } else { - break; - } - } - return (p->name); -} - -static char* -_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode) -{ - XIMArg *p; - char *return_name = NULL; - - for (p = values; p != NULL && p->name != NULL; p++) { - if(strcmp(p->name, XNInputStyle) == 0) { - if (mode == CREATE_IC) - ic->core.input_style = (XIMStyle)p->value; - } else if (strcmp(p->name, XNClientWindow) == 0) { - ic->core.client_window = (Window)p->value ; - } else if (strcmp(p->name, XNFocusWindow) == 0) { - ic->core.focus_window = (Window)p->value ; - } else if (strcmp(p->name, XNPreeditAttributes) == 0 - || strcmp(p->name, XNStatusAttributes) == 0) { - return_name = _SetICValueData(ic, (XIMArg*)p->value, mode); - if (return_name) break; - } else { - return_name = p->name; - break; - } - } - return(return_name); -} - -static char* -_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode) -{ - XIMArg *p; - char *return_name = NULL; - - for (p = values; p->name != NULL; p++) { - if(strcmp(p->name, XNInputStyle) == 0) { - *((XIMStyle *)(p->value)) = ic->core.input_style; - } else if (strcmp(p->name, XNClientWindow) == 0) { - *((Window *)(p->value)) = ic->core.client_window; - } else if (strcmp(p->name, XNFocusWindow) == 0) { - *((Window *)(p->value)) = ic->core.focus_window; - } else if (strcmp(p->name, XNFilterEvents) == 0) { - *((unsigned long *)(p->value))= ic->core.filter_events; - } else if (strcmp(p->name, XNPreeditAttributes) == 0 - || strcmp(p->name, XNStatusAttributes) == 0) { - return_name = _GetICValueData(ic, (XIMArg*)p->value, mode); - if (return_name) break; - } else { - return_name = p->name; - break; - } - } - return(return_name); -} - -static XIC -_CreateIC(XIM im, XIMArg *arg) -{ - XIC ic; - - if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) { - return ((XIC)NULL); - } - memset(ic, 0, sizeof(XICRec)); - - ic->methods = (XICMethods)&local_ic_methods; - ic->core.im = im; - ic->core.filter_events = KeyPressMask; - - if (_SetICValueData(ic, arg, CREATE_IC) != NULL) - goto err_return; - if (!(ic->core.input_style)) - goto err_return; - - return (XIC)ic; -err_return: - XFree(ic); - return ((XIC)NULL); -} - -static void -_DestroyIC(XIC ic) -{ -/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already. - if(ic) - XFree(ic); */ -} - -static void -_SetFocus(XIC ic) -{ -} - -static void -_UnsetFocus(XIC ic) -{ -} - -static char* -_SetICValues(XIC ic, XIMArg *args) -{ - char *ret = NULL; - if (!ic) { - return (args->name); - } - ret = _SetICValueData(ic, args, SET_ICVAL); - return(ret); -} - -static char* -_GetICValues(XIC ic, XIMArg *args) -{ - char *ret = NULL; - if (!ic) { - return (args->name); - } - ret = _GetICValueData(ic, args, GET_ICVAL); - return(ret); -} - -static char * -_MbReset(XIC xic) -{ - return(NULL); -} - -static wchar_t * -_WcReset(XIC xic) -{ - return(NULL); -} - -static int -_MbLookupString( - XIC xic, - XKeyEvent *ev, - char * buffer, - int bytes, - KeySym *keysym, - Status *status) -{ - XComposeStatus NotSupportedYet ; - int length; - - length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet); - - if (keysym && *keysym == NoSymbol){ - *status = XLookupNone; - } else if (length > 0) { - *status = XLookupBoth; - } else { - *status = XLookupKeySym; - } - return(length); -} - -static int -_WcLookupString( - XIC xic, - XKeyEvent *ev, - wchar_t * buffer, - int wlen, - KeySym *keysym, - Status *status) -{ - XComposeStatus NotSupportedYet ; - int length; - /* In single-byte, mb_len = wc_len */ - char *mb_buf = (char *)Xmalloc(wlen); - - length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet); - - if (keysym && *keysym == NoSymbol){ - *status = XLookupNone; - } else if (length > 0) { - *status = XLookupBoth; - } else { - *status = XLookupKeySym; - } - mbstowcs(buffer, mb_buf, length); - XFree(mb_buf); - return(length); -} +/*
+Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
+
+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
+OPEN GROUP 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
+EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Except as contained in this notice, the name of The Open Group 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 Open Group.
+
+
+X Window System is a trademark of The Open Group
+
+OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
+logo, LBX, X Window System, and Xinerama are trademarks of the Open
+Group. All other trademarks and registered trademarks mentioned herein
+are the property of their respective owners. No right, title or
+interest in or to any trademark, service mark, logo or trade name of
+Sun Microsystems, Inc. or its licensors is granted.
+
+*/
+/*
+ * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcGeneric.h"
+
+#ifndef MAXINT
+#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1))
+#endif /* !MAXINT */
+
+typedef struct _StaticXIM *StaticXIM;
+
+typedef struct _XIMStaticXIMRec {
+ /* for CT => MB,WC converter */
+ XlcConv ctom_conv;
+ XlcConv ctow_conv;
+} XIMStaticXIMRec;
+
+typedef enum {
+ CREATE_IC = 1,
+ SET_ICVAL = 2,
+ GET_ICVAL = 3
+} XICOp_t;
+
+typedef struct _StaticXIM {
+ XIMMethods methods;
+ XIMCoreRec core;
+ XIMStaticXIMRec *private;
+} StaticXIMRec;
+
+static Status _CloseIM(
+ XIM
+);
+
+static char *_SetIMValues(
+ XIM, XIMArg *
+);
+
+static char *_GetIMValues(
+ XIM, XIMArg*
+);
+
+static XIC _CreateIC(
+ XIM, XIMArg*
+);
+
+static _Xconst XIMMethodsRec local_im_methods = {
+ _CloseIM, /* close */
+ _SetIMValues, /* set_values */
+ _GetIMValues, /* get_values */
+ _CreateIC, /* create_ic */
+ NULL, /* ctstombs */
+ NULL /* ctstowcs */
+};
+
+static void _DestroyIC(
+ XIC
+);
+static void _SetFocus(
+ XIC
+);
+static void _UnsetFocus(
+ XIC
+);
+static char* _SetICValues(
+ XIC, XIMArg *
+);
+static char* _GetICValues(
+ XIC, XIMArg *
+);
+static char *_MbReset(
+ XIC
+);
+static wchar_t *_WcReset(
+ XIC
+);
+static int _MbLookupString(
+ XIC, XKeyEvent *, char *, int, KeySym *, Status *
+);
+static int _WcLookupString(
+ XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *
+);
+
+static _Xconst XICMethodsRec local_ic_methods = {
+ _DestroyIC, /* destroy */
+ _SetFocus, /* set_focus */
+ _UnsetFocus, /* unset_focus */
+ _SetICValues, /* set_values */
+ _GetICValues, /* get_values */
+ _MbReset, /* mb_reset */
+ _WcReset, /* wc_reset */
+ NULL, /* utf8_reset */ /* ??? */
+ _MbLookupString, /* mb_lookup_string */
+ _WcLookupString, /* wc_lookup_string */
+ NULL /* utf8_lookup_string */ /* ??? */
+};
+
+XIM
+_XDefaultOpenIM(
+ XLCd lcd,
+ Display *dpy,
+ XrmDatabase rdb,
+ char *res_name,
+ char *res_class)
+{
+ StaticXIM im;
+ XIMStaticXIMRec *local_impart;
+ XlcConv ctom_conv, ctow_conv;
+ int i;
+ char *mod;
+ char buf[BUFSIZ];
+
+ if (!(ctom_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNMultiByte))) {
+ return((XIM)NULL);
+ }
+
+ if (!(ctow_conv = _XlcOpenConverter(lcd,
+ XlcNCompoundText, lcd, XlcNWideChar))) {
+ return((XIM)NULL);
+ }
+
+ if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) {
+ return((XIM)NULL);
+ }
+ if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec)))
+ == (XIMStaticXIMRec *)NULL) {
+ Xfree(im);
+ return((XIM)NULL);
+ }
+ memset(im, 0, sizeof(StaticXIMRec));
+ memset(local_impart, 0, sizeof(XIMStaticXIMRec));
+
+ buf[0] = '\0';
+ i = 0;
+ if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
+#define MODIFIER "@im="
+ mod = strstr(lcd->core->modifiers, MODIFIER);
+ if (mod) {
+ mod += strlen(MODIFIER);
+ while (*mod && *mod != '@' && i < BUFSIZ - 1) {
+ buf[i++] = *mod++;
+ }
+ buf[i] = '\0';
+ }
+ }
+#undef MODIFIER
+ if ((im->core.im_name = Xmalloc(i+1)) == NULL)
+ goto Error2;
+ strcpy(im->core.im_name, buf);
+
+ im->private = local_impart;
+ im->methods = (XIMMethods)&local_im_methods;
+ im->core.lcd = lcd;
+ im->core.ic_chain = (XIC)NULL;
+ im->core.display = dpy;
+ im->core.rdb = rdb;
+ im->core.res_name = NULL;
+ im->core.res_class = NULL;
+
+ local_impart->ctom_conv = ctom_conv;
+ local_impart->ctow_conv = ctow_conv;
+
+ if ((res_name != NULL) && (*res_name != '\0')){
+ im->core.res_name = strdup(res_name);
+ }
+ if ((res_class != NULL) && (*res_class != '\0')){
+ im->core.res_class = strdup(res_class);
+ }
+
+ return (XIM)im;
+Error2 :
+ Xfree(im->private);
+ Xfree(im->core.im_name);
+ Xfree(im);
+ _XlcCloseConverter(ctom_conv);
+ _XlcCloseConverter(ctow_conv);
+ return(NULL);
+}
+
+static Status
+_CloseIM(XIM xim)
+{
+ StaticXIM im = (StaticXIM)xim;
+ _XlcCloseConverter(im->private->ctom_conv);
+ _XlcCloseConverter(im->private->ctow_conv);
+ XFree(im->private);
+ XFree(im->core.im_name);
+ if (im->core.res_name) XFree(im->core.res_name);
+ if (im->core.res_class) XFree(im->core.res_class);
+ return 1; /*bugID 4163122*/
+}
+
+static char *
+_SetIMValues(
+ XIM xim,
+ XIMArg *arg)
+{
+ return(arg->name); /* evil */
+}
+
+static char *
+_GetIMValues(
+ XIM xim,
+ XIMArg *values)
+{
+ XIMArg *p;
+ XIMStyles *styles;
+
+ for (p = values; p->name != NULL; p++) {
+ if (strcmp(p->name, XNQueryInputStyle) == 0) {
+ styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
+ *(XIMStyles **)p->value = styles;
+ styles->count_styles = 1;
+ styles->supported_styles =
+ (XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle));
+ styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
+ } else {
+ break;
+ }
+ }
+ return (p->name);
+}
+
+static char*
+_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
+{
+ XIMArg *p;
+ char *return_name = NULL;
+
+ for (p = values; p != NULL && p->name != NULL; p++) {
+ if(strcmp(p->name, XNInputStyle) == 0) {
+ if (mode == CREATE_IC)
+ ic->core.input_style = (XIMStyle)p->value;
+ } else if (strcmp(p->name, XNClientWindow) == 0) {
+ ic->core.client_window = (Window)p->value ;
+ } else if (strcmp(p->name, XNFocusWindow) == 0) {
+ ic->core.focus_window = (Window)p->value ;
+ } else if (strcmp(p->name, XNPreeditAttributes) == 0
+ || strcmp(p->name, XNStatusAttributes) == 0) {
+ return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
+ if (return_name) break;
+ } else {
+ return_name = p->name;
+ break;
+ }
+ }
+ return(return_name);
+}
+
+static char*
+_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
+{
+ XIMArg *p;
+ char *return_name = NULL;
+
+ for (p = values; p->name != NULL; p++) {
+ if(strcmp(p->name, XNInputStyle) == 0) {
+ *((XIMStyle *)(p->value)) = ic->core.input_style;
+ } else if (strcmp(p->name, XNClientWindow) == 0) {
+ *((Window *)(p->value)) = ic->core.client_window;
+ } else if (strcmp(p->name, XNFocusWindow) == 0) {
+ *((Window *)(p->value)) = ic->core.focus_window;
+ } else if (strcmp(p->name, XNFilterEvents) == 0) {
+ *((unsigned long *)(p->value))= ic->core.filter_events;
+ } else if (strcmp(p->name, XNPreeditAttributes) == 0
+ || strcmp(p->name, XNStatusAttributes) == 0) {
+ return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
+ if (return_name) break;
+ } else {
+ return_name = p->name;
+ break;
+ }
+ }
+ return(return_name);
+}
+
+static XIC
+_CreateIC(XIM im, XIMArg *arg)
+{
+ XIC ic;
+
+ if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) {
+ return ((XIC)NULL);
+ }
+ memset(ic, 0, sizeof(XICRec));
+
+ ic->methods = (XICMethods)&local_ic_methods;
+ ic->core.im = im;
+ ic->core.filter_events = KeyPressMask;
+
+ if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
+ goto err_return;
+ if (!(ic->core.input_style))
+ goto err_return;
+
+ return (XIC)ic;
+err_return:
+ XFree(ic);
+ return ((XIC)NULL);
+}
+
+static void
+_DestroyIC(XIC ic)
+{
+/*BugId4255571. This Xfree() should be removed because XDestroyIC() still need ic after invoking _DestroyIC() and there is a XFree(ic) at the end of XDestroyIC() already.
+ if(ic)
+ XFree(ic); */
+}
+
+static void
+_SetFocus(XIC ic)
+{
+}
+
+static void
+_UnsetFocus(XIC ic)
+{
+}
+
+static char*
+_SetICValues(XIC ic, XIMArg *args)
+{
+ char *ret = NULL;
+ if (!ic) {
+ return (args->name);
+ }
+ ret = _SetICValueData(ic, args, SET_ICVAL);
+ return(ret);
+}
+
+static char*
+_GetICValues(XIC ic, XIMArg *args)
+{
+ char *ret = NULL;
+ if (!ic) {
+ return (args->name);
+ }
+ ret = _GetICValueData(ic, args, GET_ICVAL);
+ return(ret);
+}
+
+static char *
+_MbReset(XIC xic)
+{
+ return(NULL);
+}
+
+static wchar_t *
+_WcReset(XIC xic)
+{
+ return(NULL);
+}
+
+static int
+_MbLookupString(
+ XIC xic,
+ XKeyEvent *ev,
+ char * buffer,
+ int bytes,
+ KeySym *keysym,
+ Status *status)
+{
+ XComposeStatus NotSupportedYet ;
+ int length;
+
+ length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
+
+ if (keysym && *keysym == NoSymbol){
+ *status = XLookupNone;
+ } else if (length > 0) {
+ *status = XLookupBoth;
+ } else {
+ *status = XLookupKeySym;
+ }
+ return(length);
+}
+
+static int
+_WcLookupString(
+ XIC xic,
+ XKeyEvent *ev,
+ wchar_t * buffer,
+ int wlen,
+ KeySym *keysym,
+ Status *status)
+{
+ XComposeStatus NotSupportedYet ;
+ int length;
+ /* In single-byte, mb_len = wc_len */
+ char *mb_buf = (char *)Xmalloc(wlen);
+
+ length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
+
+ if (keysym && *keysym == NoSymbol){
+ *status = XLookupNone;
+ } else if (length > 0) {
+ *status = XLookupBoth;
+ } else {
+ *status = XLookupKeySym;
+ }
+ mbstowcs(buffer, mb_buf, length);
+ XFree(mb_buf);
+ return(length);
+}
diff --git a/libX11/src/xlibi18n/XDefaultOMIF.c b/libX11/src/xlibi18n/XDefaultOMIF.c index b1dc66df6..ad1983a0d 100644 --- a/libX11/src/xlibi18n/XDefaultOMIF.c +++ b/libX11/src/xlibi18n/XDefaultOMIF.c @@ -1,1261 +1,1263 @@ -/* -Copyright 1985, 1986, 1987, 1991, 1998 The Open Group - -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 -OPEN GROUP 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 -EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. - - -Except as contained in this notice, the name of The Open Group 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 Open Group. - - -X Window System is a trademark of The Open Group - -OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF -logo, LBX, X Window System, and Xinerama are trademarks of the Open -Group. All other trademarks and registered trademarks mentioned herein -are the property of their respective owners. No right, title or -interest in or to any trademark, service mark, logo or trade name of -Sun Microsystems, Inc. or its licensors is granted. - -*/ -/* - * Copyright 2000 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include "XlcPublic.h" -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include <stdio.h> - -#define MAXFONTS 100 - -#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) -#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) - -#define DefineLocalBuf char local_buf[BUFSIZ] -#define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf) -#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) - -typedef struct _FontDataRec { - char *name; -} FontDataRec, *FontData; - -typedef struct _OMDataRec { - int font_data_count; - FontData font_data; -} OMDataRec, *OMData; - -typedef struct _XOMGenericPart { - OMData data; -} XOMGenericPart; - -typedef struct _XOMGenericRec { - XOMMethods methods; - XOMCoreRec core; - XOMGenericPart gen; -} XOMGenericRec, *XOMGeneric; - -typedef struct _FontSetRec { - int id; - int font_data_count; - FontData font_data; - char *font_name; - XFontStruct *info; - XFontStruct *font; -} FontSetRec, *FontSet; - -typedef struct _XOCGenericPart { - XlcConv wcs_to_cs; - FontSet font_set; -} XOCGenericPart; - -typedef struct _XOCGenericRec { - XOCMethods methods; - XOCCoreRec core; - XOCGenericPart gen; -} XOCGenericRec, *XOCGeneric; - -static Bool -init_fontset( - XOC oc) -{ - XOCGenericPart *gen; - FontSet font_set; - OMData data; - - data = XOM_GENERIC(oc->core.om)->data; - - font_set = Xcalloc(1, sizeof(FontSetRec)); - if (font_set == NULL) - return False; - - gen = XOC_GENERIC(oc); - gen->font_set = font_set; - - font_set->font_data_count = data->font_data_count; - font_set->font_data = data->font_data; - - return True; -} - -static char * -get_prop_name( - Display *dpy, - XFontStruct *fs) -{ - unsigned long fp; - - if (XGetFontProperty(fs, XA_FONT, &fp)) - return XGetAtomName(dpy, fp); - - return (char *) NULL; -} - -static FontData -check_charset( - FontSet font_set, - char *font_name) -{ - FontData font_data; - char *last; - int count; - ssize_t length, name_len; - - name_len = strlen(font_name); - last = font_name + name_len; - - count = font_set->font_data_count; - font_data = font_set->font_data; - - for ( ; count-- > 0; font_data++) { - length = strlen(font_data->name); - - if (length > name_len) - return(NULL); - - if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) - return font_data; - } - return (FontData) NULL; -} - -#if 0 /* Unused */ -static int -check_fontname( - XOC oc, - char *name) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - FontData data; - FontSet font_set; - XFontStruct *fs_list; - char **fn_list, *fname, *prop_fname = NULL; - int list_num, i; - int list2_num; - char **fn2_list = NULL; - int found_num = 0; - - fn_list = XListFonts(dpy, name, MAXFONTS, &list_num); - if (fn_list == NULL) - return found_num; - - for (i = 0; i < list_num; i++) { - fname = fn_list[i]; - - font_set = gen->font_set; - - if ((data = check_charset(font_set, fname)) == NULL) { - if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS, - &list2_num, &fs_list)) - && (prop_fname = get_prop_name(dpy, fs_list)) - && (data = check_charset(font_set, prop_fname))) - fname = prop_fname; - } - if (data) { - font_set->font_name = strdup(fname); - if (font_set->font_name) { - found_num++; - } - } - if (fn2_list) { - XFreeFontInfo(fn2_list, fs_list, list2_num); - fn2_list = NULL; - if (prop_fname) { - Xfree(prop_fname); - prop_fname = NULL; - } - } - if (found_num == 1) - break; - } - XFreeFontNames(fn_list); - return found_num; -} -#endif - -static Bool -load_font( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - - if (font_set->font_name == NULL) - return False; - - if (font_set->font == NULL) { - font_set->font = XLoadQueryFont(dpy, font_set->font_name); - if (font_set->font == NULL) - return False; - } - return True; -} - -#if 0 -static Bool -load_font_info( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - char **fn_list; - int fn_num; - - if (font_set->font_name == NULL) - return False; - - if (font_set->info == NULL) { - fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, - &font_set->info); - if (font_set->info == NULL) - return False; - if (fn_num > 0) - font_set->info->fid = XLoadFont(dpy, font_set->font_name); - - if (fn_list) XFreeFontNames(fn_list); - } - return True; -} -#endif - -static void -set_fontset_extents( - XOC oc) -{ - XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; - XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; - XFontStruct **font_list, *font; - XCharStruct overall; - int logical_ascent, logical_descent; - - font_list = oc->core.font_info.font_struct_list; - font = *font_list++; - overall = font->max_bounds; - overall.lbearing = font->min_bounds.lbearing; - logical_ascent = font->ascent; - logical_descent = font->descent; - - ink->x = overall.lbearing; - ink->y = -(overall.ascent); - ink->width = overall.rbearing - overall.lbearing; - ink->height = overall.ascent + overall.descent; - - logical->x = 0; - logical->y = -(logical_ascent); - logical->width = overall.width; - logical->height = logical_ascent + logical_descent; -} - -static Bool -init_core_part( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - XFontStruct **font_struct_list; - char **font_name_list, *font_name_buf; - int count, length; - - font_set = gen->font_set; - count = length = 0; - - if (font_set->font_name != NULL) { - length += strlen(font_set->font_name) + 1; - count++; - } - if (count == 0) - return False; - - font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *)); - if (font_struct_list == NULL) - return False; - - font_name_list = (char **) Xmalloc(sizeof(char *)); - if (font_name_list == NULL) - goto err; - - font_name_buf = (char *) Xmalloc(length); - if (font_name_buf == NULL) - goto err; - - oc->core.font_info.num_font = 1; - oc->core.font_info.font_name_list = font_name_list; - oc->core.font_info.font_struct_list = font_struct_list; - - font_set = gen->font_set; - - if (font_set->font_name != NULL) { - font_set->id = 1; - if (font_set->font) - *font_struct_list++ = font_set->font; - else - *font_struct_list++ = font_set->info; - strcpy(font_name_buf, font_set->font_name); - Xfree(font_set->font_name); - *font_name_list++ = font_set->font_name = font_name_buf; - font_name_buf += strlen(font_name_buf) + 1; - } - - set_fontset_extents(oc); - - return True; - -err: - if (font_name_list) - Xfree(font_name_list); - Xfree(font_struct_list); - - return False; -} - -static char * -get_font_name( - XOC oc, - char *pattern) -{ - char **list, *name; - int count; - XFontStruct *fs; - Display *dpy = oc->core.om->core.display; - - list = XListFonts(dpy, pattern, 1, &count); - if (list != NULL) { - name = strdup(*list); - - XFreeFontNames(list); - } else { - fs = XLoadQueryFont(dpy, pattern); - if (fs == NULL) return NULL; - - name = get_prop_name(dpy, fs); - XFreeFont(dpy, fs); - } - return name; -} - -static int -parse_fontname( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - FontData font_data; - char *pattern, *last, buf[BUFSIZ]; - int font_data_count, found_num = 0; - ssize_t length; - int count, num_fields; - char *base_name, *font_name, **name_list, **cur_name_list; - char *charset_p = NULL; - Bool append_charset; - /* - append_charset flag should be set to True when the XLFD fontname - doesn't contain a chaset part. - */ - - name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); - if (name_list == NULL) - return -1; - cur_name_list = name_list; - - while (count-- > 0) { - pattern = *cur_name_list++; - if (pattern == NULL || *pattern == '\0') - continue; - - append_charset = False; - - if (strchr(pattern, '*') == NULL && - (font_name = get_font_name(oc, pattern))) { - - font_set = gen->font_set; - - font_data = check_charset(font_set, font_name); - if (font_data == NULL) { - Display *dpy = oc->core.om->core.display; - char **fn_list = NULL, *prop_fname = NULL; - int list_num; - XFontStruct *fs_list; - if ((fn_list = XListFontsWithInfo(dpy, font_name, - MAXFONTS, - &list_num, &fs_list)) - && (prop_fname = get_prop_name(dpy, fs_list)) - && (font_data = check_charset(font_set, prop_fname))) { - if (fn_list) { - XFreeFontInfo(fn_list, fs_list, list_num); - fn_list = NULL; - } - font_name = prop_fname; - } - } - if (font_data == NULL) - continue; - - font_set->font_name = strdup(font_name); - Xfree(font_name); - if (font_set->font_name == NULL) { - goto err; - } - found_num++; - goto found; - } -/* -1266793 -Limit the length of the string copy to prevent stack corruption. - strcpy(buf, pattern); -*/ - strncpy(buf, pattern, BUFSIZ); - buf[BUFSIZ-1] = '\0'; - length = strlen(buf); - last = buf + length - 1; - - for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) - if (*base_name == '-') num_fields++; - if (strchr(pattern, '*') == NULL) { - if (num_fields == 12) { - append_charset = True; - *++last = '-'; - last++; - } else - continue; - } else { - if (num_fields == 13 || num_fields == 14) { - /* - * There are 14 fields in an XLFD name -- make certain the - * charset (& encoding) is placed in the correct field. - */ - append_charset = True; - last = strrchr (buf, '-'); - if (num_fields == 14) { - *last = '\0'; - last = strrchr (buf, '-'); - } - last++; - } else if (*last == '*') { - append_charset = True; - if (length > 3 && *(last-3) == '-' && *(last-2) == '*' - && *(last-1) == '-') { - last -= 2; - } - *++last = '-'; - last++; - } else { - last = strrchr (buf, '-'); - charset_p = last; - charset_p = strrchr (buf, '-'); - while (*(--charset_p) != '-'); - charset_p++; - } - } - - font_set = gen->font_set; - - font_data = font_set->font_data; - font_data_count = font_set->font_data_count; - for ( ; font_data_count-- > 0; font_data++) { - if (append_charset) - { -/* -1266793 -Limit the length of the string copy to prevent stack corruption. - strcpy(last, font_data->name); -*/ - strncpy(last, font_data->name, BUFSIZ - length); - buf[BUFSIZ-1] = '\0'; - } - else { - if (_XlcCompareISOLatin1(charset_p, - font_data->name)) { - continue; - } - } - if ((font_set->font_name = get_font_name(oc, buf))) - break; - } - if (font_set->font_name != NULL) { - found_num++; - goto found; - } - } - found: - base_name = strdup(oc->core.base_name_list); - if (base_name == NULL) - goto err; - - oc->core.base_name_list = base_name; - - XFreeStringList(name_list); - - return found_num; -err: - XFreeStringList(name_list); - - return -1; -} - -static Bool -set_missing_list( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - char **charset_list, *charset_buf; - int count, length; - - font_set = gen->font_set; - count = length = 0; - - if (!font_set->info && !font_set->font) { - length += strlen(font_set->font_data->name) + 1; - count++; - } - - if (count == 0) - return True; - - charset_list = (char **) Xmalloc(sizeof(char *)); - if (charset_list == NULL) - return False; - - charset_buf = (char *) Xmalloc(length); - if (charset_buf == NULL) { - Xfree(charset_list); - return False; - } - - oc->core.missing_list.charset_list = charset_list; - - font_set = gen->font_set; - - if (!font_set->info && !font_set->font) { - strcpy(charset_buf, font_set->font_data->name); - *charset_list++ = charset_buf; - charset_buf += strlen(charset_buf) + 1; - } - return True; -} - -static Bool -create_fontset( - XOC oc) -{ - int found_num; - - if (init_fontset(oc) == False) - return False; - - found_num = parse_fontname(oc); - if (found_num <= 0) { - if (found_num == 0) - set_missing_list(oc); - return False; - } - - if (load_font(oc) == False) - return False; - - if (init_core_part(oc) == False) - return False; - - if (set_missing_list(oc) == False) - return False; - - return True; -} - -static void -destroy_oc( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - XFontStruct **font_list, *font; - - if (gen->font_set) - Xfree(gen->font_set); - - if (oc->core.base_name_list) - Xfree(oc->core.base_name_list); - - if (oc->core.font_info.font_name_list) - XFreeStringList(oc->core.font_info.font_name_list); - - if ((font_list = oc->core.font_info.font_struct_list)) { - if ((font = *font_list)) { - if (font->fid) - XFreeFont(dpy, font); - else - XFreeFontInfo(NULL, font, 1); - } - Xfree(oc->core.font_info.font_struct_list); - } - - if (oc->core.missing_list.charset_list) - XFreeStringList(oc->core.missing_list.charset_list); - -#ifdef notdef - if (oc->core.res_name) - Xfree(oc->core.res_name); - if (oc->core.res_class) - Xfree(oc->core.res_class); -#endif - - Xfree(oc); -} - -static char * -set_oc_values( - XOC oc, - XlcArgList args, - int num_args) -{ - if (oc->core.resources == NULL) - return NULL; - - return _XlcSetValues((XPointer) oc, oc->core.resources, - oc->core.num_resources, args, num_args, XlcSetMask); -} - -static char * -get_oc_values( - XOC oc, - XlcArgList args, - int num_args) -{ - if (oc->core.resources == NULL) - return NULL; - - return _XlcGetValues((XPointer) oc, oc->core.resources, - oc->core.num_resources, args, num_args, XlcGetMask); -} - -static Bool -wcs_to_mbs( - XOC oc, - char *to, - _Xconst wchar_t *from, - int length) -{ - XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs; - XLCd lcd; - int ret, to_left = length; - - if (conv == NULL) { - lcd = oc->core.om->core.lcd; - conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); - if (conv == NULL) - return False; - XOC_GENERIC(oc)->wcs_to_cs = conv; - } else - _XlcResetConverter(conv); - - ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, - &to_left, NULL, 0); - if (ret != 0 || length > 0) - return False; - - return True; -} - -static int -_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) -{ - return XTextWidth(*oc->core.font_info.font_struct_list, text, length); -} - -static int -_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) -{ - DefineLocalBuf; - char *buf = AllocLocalBuf(length); - int ret = 0; - - if (buf == NULL) - return 0; - - if (wcs_to_mbs(oc, buf, text, length) == False) - goto err; - - ret = _XmbDefaultTextEscapement(oc, buf, length); - -err: - FreeLocalBuf(buf); - - return ret; -} - -static int -_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, - XRectangle *overall_ink, XRectangle *overall_logical) -{ - int direction, logical_ascent, logical_descent; - XCharStruct overall; - - XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, - &logical_ascent, &logical_descent, &overall); - - if (overall_ink) { - overall_ink->x = overall.lbearing; - overall_ink->y = -(overall.ascent); - overall_ink->width = overall.rbearing - overall.lbearing; - overall_ink->height = overall.ascent + overall.descent; - } - - if (overall_logical) { - overall_logical->x = 0; - overall_logical->y = -(logical_ascent); - overall_logical->width = overall.width; - overall_logical->height = logical_ascent + logical_descent; - } - - return overall.width; -} - -static int -_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, - XRectangle *overall_ink, XRectangle *overall_logical) -{ - DefineLocalBuf; - char *buf = AllocLocalBuf(length); - int ret = 0; - - if (buf == NULL) - return 0; - - if (wcs_to_mbs(oc, buf, text, length) == False) - goto err; - - ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); - -err: - FreeLocalBuf(buf); - - return ret; -} - -static Status -_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, - XRectangle *ink_buf, XRectangle *logical_buf, - int buf_size, int *num_chars, - XRectangle *overall_ink, - XRectangle *overall_logical) -{ - XFontStruct *font = *oc->core.font_info.font_struct_list; - XCharStruct *def, *cs, overall; - Bool first = True; - - if (buf_size < length) - return 0; - - bzero((char *) &overall, sizeof(XCharStruct)); - *num_chars = 0; - - CI_GET_DEFAULT_INFO_1D(font, def) - - while (length-- > 0) { - CI_GET_CHAR_INFO_1D(font, *text, def, cs) - text++; - if (cs == NULL) - continue; - - ink_buf->x = overall.width + cs->lbearing; - ink_buf->y = -(cs->ascent); - ink_buf->width = cs->rbearing - cs->lbearing; - ink_buf->height = cs->ascent + cs->descent; - ink_buf++; - - logical_buf->x = overall.width; - logical_buf->y = -(font->ascent); - logical_buf->width = cs->width; - logical_buf->height = font->ascent + font->descent; - logical_buf++; - - if (first) { - overall = *cs; - first = False; - } else { - overall.ascent = max(overall.ascent, cs->ascent); - overall.descent = max(overall.descent, cs->descent); - overall.lbearing = min(overall.lbearing, overall.width + - cs->lbearing); - overall.rbearing = max(overall.rbearing, overall.width + - cs->rbearing); - overall.width += cs->width; - } - (*num_chars)++; - } - - if (overall_ink) { - overall_ink->x = overall.lbearing; - overall_ink->y = -(overall.ascent); - overall_ink->width = overall.rbearing - overall.lbearing; - overall_ink->height = overall.ascent + overall.descent; - } - - if (overall_logical) { - overall_logical->x = 0; - overall_logical->y = -(font->ascent); - overall_logical->width = overall.width; - overall_logical->height = font->ascent + font->descent; - } - - return 1; -} - -static Status -_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, - XRectangle *ink_buf, XRectangle *logical_buf, - int buf_size, int *num_chars, - XRectangle *overall_ink, - XRectangle *overall_logical) -{ - DefineLocalBuf; - char *buf = AllocLocalBuf(length); - Status ret = 0; - - if (buf == NULL) - return 0; - - if (wcs_to_mbs(oc, buf, text, length) == False) - goto err; - - ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, - buf_size, num_chars, overall_ink, - overall_logical); - -err: - FreeLocalBuf(buf); - - return ret; -} - -static int -_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, - _Xconst char *text, int length) -{ - XFontStruct *font = *oc->core.font_info.font_struct_list; - - XSetFont(dpy, gc, font->fid); - XDrawString(dpy, d, gc, x, y, text, length); - - return XTextWidth(font, text, length); -} - -static int -_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, - _Xconst wchar_t *text, int length) -{ - DefineLocalBuf; - char *buf = AllocLocalBuf(length); - int ret = 0; - - if (buf == NULL) - return 0; - - if (wcs_to_mbs(oc, buf, text, length) == False) - goto err; - - ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); - -err: - FreeLocalBuf(buf); - - return ret; -} - -static void -_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, - int y, _Xconst char *text, int length) -{ - XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); - XDrawImageString(dpy, d, gc, x, y, text, length); -} - -static void -_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, - int y, _Xconst wchar_t *text, int length) -{ - DefineLocalBuf; - char *buf = AllocLocalBuf(length); - - if (buf == NULL) - return; - - if (wcs_to_mbs(oc, buf, text, length) == False) - goto err; - - _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); - -err: - FreeLocalBuf(buf); -} - -static _Xconst XOCMethodsRec oc_default_methods = { - destroy_oc, - set_oc_values, - get_oc_values, - _XmbDefaultTextEscapement, - _XmbDefaultTextExtents, - _XmbDefaultTextPerCharExtents, - _XmbDefaultDrawString, - _XmbDefaultDrawImageString, - _XwcDefaultTextEscapement, - _XwcDefaultTextExtents, - _XwcDefaultTextPerCharExtents, - _XwcDefaultDrawString, - _XwcDefaultDrawImageString -}; - -static XlcResource oc_resources[] = { - { XNBaseFontName, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, - { XNOMAutomatic, NULLQUARK, sizeof(Bool), - XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, - { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), - XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, - { XNDefaultString, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.default_string), XlcGetMask }, - { XNOrientation, NULLQUARK, sizeof(XOrientation), - XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask }, - { XNResourceName, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, - { XNResourceClass, NULLQUARK, sizeof(char *), - XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, - { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), - XOffsetOf(XOCRec, core.font_info), XlcGetMask } -}; - -static XOC -create_oc( - XOM om, - XlcArgList args, - int num_args) -{ - XOC oc; - - oc = Xcalloc(1, sizeof(XOCGenericRec)); - if (oc == NULL) - return (XOC) NULL; - - oc->core.om = om; - - if (oc_resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); - - if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), - args, num_args, XlcCreateMask | XlcDefaultMask)) - goto err; - - if (oc->core.base_name_list == NULL) - goto err; - - oc->core.resources = oc_resources; - oc->core.num_resources = XlcNumber(oc_resources); - - if (create_fontset(oc) == False) - goto err; - - oc->methods = (XOCMethods)&oc_default_methods; - - return oc; - -err: - destroy_oc(oc); - - return (XOC) NULL; -} - -static Status -close_om( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - FontData font_data; - int count; - - if ((data = gen->data)) { - if (data->font_data) { - for (font_data = data->font_data, count = data->font_data_count; - count-- > 0 ; font_data++) { - if (font_data->name) - Xfree(font_data->name); - } - Xfree(data->font_data); - } - Xfree(gen->data); - } - - if (om->core.res_name) - Xfree(om->core.res_name); - if (om->core.res_class) - Xfree(om->core.res_class); - if (om->core.required_charset.charset_list) - XFreeStringList(om->core.required_charset.charset_list); - else - Xfree((char*)om->core.required_charset.charset_list); - if (om->core.orientation_list.orientation) - Xfree(om->core.orientation_list.orientation); - - Xfree(om); - - return 1; -} - -static char * -set_om_values( - XOM om, - XlcArgList args, - int num_args) -{ - if (om->core.resources == NULL) - return NULL; - - return _XlcSetValues((XPointer) om, om->core.resources, - om->core.num_resources, args, num_args, XlcSetMask); -} - -static char * -get_om_values( - XOM om, - XlcArgList args, - int num_args) -{ - if (om->core.resources == NULL) - return NULL; - - return _XlcGetValues((XPointer) om, om->core.resources, - om->core.num_resources, args, num_args, XlcGetMask); -} - -static _Xconst XOMMethodsRec methods = { - close_om, - set_om_values, - get_om_values, - create_oc -}; - -static XlcResource om_resources[] = { - { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), - XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, - { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), - XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, - { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), - XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, - { XNContextualDrawing, NULLQUARK, sizeof(Bool), - XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } -}; - -static OMData -add_data( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData new; - - new = Xcalloc(1, sizeof(OMDataRec)); - - if (new == NULL) - return NULL; - - gen->data = new; - - return new; -} - -static _Xconst char *supported_charset_list[] = { - "ISO8859-1", -/* fix for bug4332979 */ - "adobe-fontspecific", -/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from - supported_charset_list because it is not a supported_charset for C locale - "JISX0201.1976-0", */ - "SUNOLCURSOR-1", - "SUNOLGLYPH-1" -}; - -static Bool -init_om( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - FontData font_data; - char **required_list; - XOrientation *orientation; - char **value, buf[BUFSIZ], *bufptr; - int count, length = 0; - - value = (char**)supported_charset_list; - count = XlcNumber(supported_charset_list); - - data = add_data(om); - if (data == NULL) - return False; - - font_data = Xcalloc(count, sizeof(FontDataRec)); - if (font_data == NULL) - return False; - data->font_data = font_data; - data->font_data_count = count; - - for ( ; count-- > 0; font_data++) { -/* -1266793 -This one is fine. *value points to one of the local strings in -supported_charset_list[]. -*/ - strcpy(buf, *value++); - font_data->name = strdup(buf); - if (font_data->name == NULL) - return False; - } - - length += strlen(data->font_data->name) + 1; - - /* required charset list */ - required_list = (char **) Xmalloc(sizeof(char *)); - if (required_list == NULL) - return False; - - bufptr = (char *) Xmalloc(length); - if (bufptr == NULL) { - Xfree(required_list); - return False; - } - - om->core.required_charset.charset_list = required_list; - om->core.required_charset.charset_count = 1; /* always 1 */ - - data = gen->data; - - strcpy(bufptr, data->font_data->name); - *required_list++ = bufptr; - bufptr += strlen(bufptr) + 1; - - /* orientation list */ - orientation = (XOrientation *) Xmalloc(sizeof(XOrientation)); - if (orientation == NULL) - return False; - - *orientation = XOMOrientation_LTR_TTB; - om->core.orientation_list.orientation = orientation; - om->core.orientation_list.num_orientation = 1; - - /* directional dependent drawing */ - om->core.directional_dependent = False; - - /* contexual drawing */ - om->core.contextual_drawing = False; - - /* context dependent */ - om->core.context_dependent = False; - - return True; -} - -XOM -_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, - _Xconst char *res_name, _Xconst char *res_class) -{ - XOM om; - - om = Xcalloc(1, sizeof(XOMGenericRec)); - if (om == NULL) - return (XOM) NULL; - - om->methods = (XOMMethods)&methods; - om->core.lcd = lcd; - om->core.display = dpy; - om->core.rdb = rdb; - if (res_name) { - om->core.res_name = strdup(res_name); - if (om->core.res_name == NULL) - goto err; - } - if (res_class) { - om->core.res_class = strdup(res_class); - if (om->core.res_class == NULL) - goto err; - } - - if (om_resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); - - om->core.resources = om_resources; - om->core.num_resources = XlcNumber(om_resources); - - if (init_om(om) == False) - goto err; - - return om; -err: - close_om(om); - - return (XOM) NULL; -} +/*
+Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
+
+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
+OPEN GROUP 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
+EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Except as contained in this notice, the name of The Open Group 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 Open Group.
+
+
+X Window System is a trademark of The Open Group
+
+OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
+logo, LBX, X Window System, and Xinerama are trademarks of the Open
+Group. All other trademarks and registered trademarks mentioned herein
+are the property of their respective owners. No right, title or
+interest in or to any trademark, service mark, logo or trade name of
+Sun Microsystems, Inc. or its licensors is granted.
+
+*/
+/*
+ * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "XlcPublic.h"
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#define MAXFONTS 100
+
+#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen)
+#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen)
+
+#define DefineLocalBuf char local_buf[BUFSIZ]
+#define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf)
+#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr)
+
+typedef struct _FontDataRec {
+ char *name;
+} FontDataRec, *FontData;
+
+typedef struct _OMDataRec {
+ int font_data_count;
+ FontData font_data;
+} OMDataRec, *OMData;
+
+typedef struct _XOMGenericPart {
+ OMData data;
+} XOMGenericPart;
+
+typedef struct _XOMGenericRec {
+ XOMMethods methods;
+ XOMCoreRec core;
+ XOMGenericPart gen;
+} XOMGenericRec, *XOMGeneric;
+
+typedef struct _FontSetRec {
+ int id;
+ int font_data_count;
+ FontData font_data;
+ char *font_name;
+ XFontStruct *info;
+ XFontStruct *font;
+} FontSetRec, *FontSet;
+
+typedef struct _XOCGenericPart {
+ XlcConv wcs_to_cs;
+ FontSet font_set;
+} XOCGenericPart;
+
+typedef struct _XOCGenericRec {
+ XOCMethods methods;
+ XOCCoreRec core;
+ XOCGenericPart gen;
+} XOCGenericRec, *XOCGeneric;
+
+static Bool
+init_fontset(
+ XOC oc)
+{
+ XOCGenericPart *gen;
+ FontSet font_set;
+ OMData data;
+
+ data = XOM_GENERIC(oc->core.om)->data;
+
+ font_set = Xcalloc(1, sizeof(FontSetRec));
+ if (font_set == NULL)
+ return False;
+
+ gen = XOC_GENERIC(oc);
+ gen->font_set = font_set;
+
+ font_set->font_data_count = data->font_data_count;
+ font_set->font_data = data->font_data;
+
+ return True;
+}
+
+static char *
+get_prop_name(
+ Display *dpy,
+ XFontStruct *fs)
+{
+ unsigned long fp;
+
+ if (XGetFontProperty(fs, XA_FONT, &fp))
+ return XGetAtomName(dpy, fp);
+
+ return (char *) NULL;
+}
+
+static FontData
+check_charset(
+ FontSet font_set,
+ char *font_name)
+{
+ FontData font_data;
+ char *last;
+ int count;
+ ssize_t length, name_len;
+
+ name_len = strlen(font_name);
+ last = font_name + name_len;
+
+ count = font_set->font_data_count;
+ font_data = font_set->font_data;
+
+ for ( ; count-- > 0; font_data++) {
+ length = strlen(font_data->name);
+
+ if (length > name_len)
+ return(NULL);
+
+ if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
+ return font_data;
+ }
+ return (FontData) NULL;
+}
+
+#if 0 /* Unused */
+static int
+check_fontname(
+ XOC oc,
+ char *name)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontData data;
+ FontSet font_set;
+ XFontStruct *fs_list;
+ char **fn_list, *fname, *prop_fname = NULL;
+ int list_num, i;
+ int list2_num;
+ char **fn2_list = NULL;
+ int found_num = 0;
+
+ fn_list = XListFonts(dpy, name, MAXFONTS, &list_num);
+ if (fn_list == NULL)
+ return found_num;
+
+ for (i = 0; i < list_num; i++) {
+ fname = fn_list[i];
+
+ font_set = gen->font_set;
+
+ if ((data = check_charset(font_set, fname)) == NULL) {
+ if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS,
+ &list2_num, &fs_list))
+ && (prop_fname = get_prop_name(dpy, fs_list))
+ && (data = check_charset(font_set, prop_fname)))
+ fname = prop_fname;
+ }
+ if (data) {
+ font_set->font_name = strdup(fname);
+ if (font_set->font_name) {
+ found_num++;
+ }
+ }
+ if (fn2_list) {
+ XFreeFontInfo(fn2_list, fs_list, list2_num);
+ fn2_list = NULL;
+ if (prop_fname) {
+ Xfree(prop_fname);
+ prop_fname = NULL;
+ }
+ }
+ if (found_num == 1)
+ break;
+ }
+ XFreeFontNames(fn_list);
+ return found_num;
+}
+#endif
+
+static Bool
+load_font(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+
+ if (font_set->font_name == NULL)
+ return False;
+
+ if (font_set->font == NULL) {
+ font_set->font = XLoadQueryFont(dpy, font_set->font_name);
+ if (font_set->font == NULL)
+ return False;
+ }
+ return True;
+}
+
+#if 0
+static Bool
+load_font_info(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ char **fn_list;
+ int fn_num;
+
+ if (font_set->font_name == NULL)
+ return False;
+
+ if (font_set->info == NULL) {
+ fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
+ &font_set->info);
+ if (font_set->info == NULL)
+ return False;
+ if (fn_num > 0)
+ font_set->info->fid = XLoadFont(dpy, font_set->font_name);
+
+ if (fn_list) XFreeFontNames(fn_list);
+ }
+ return True;
+}
+#endif
+
+static void
+set_fontset_extents(
+ XOC oc)
+{
+ XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
+ XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
+ XFontStruct **font_list, *font;
+ XCharStruct overall;
+ int logical_ascent, logical_descent;
+
+ font_list = oc->core.font_info.font_struct_list;
+ font = *font_list++;
+ overall = font->max_bounds;
+ overall.lbearing = font->min_bounds.lbearing;
+ logical_ascent = font->ascent;
+ logical_descent = font->descent;
+
+ ink->x = overall.lbearing;
+ ink->y = -(overall.ascent);
+ ink->width = overall.rbearing - overall.lbearing;
+ ink->height = overall.ascent + overall.descent;
+
+ logical->x = 0;
+ logical->y = -(logical_ascent);
+ logical->width = overall.width;
+ logical->height = logical_ascent + logical_descent;
+}
+
+static Bool
+init_core_part(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ XFontStruct **font_struct_list;
+ char **font_name_list, *font_name_buf;
+ int count, length;
+
+ font_set = gen->font_set;
+ count = length = 0;
+
+ if (font_set->font_name != NULL) {
+ length += strlen(font_set->font_name) + 1;
+ count++;
+ }
+ if (count == 0)
+ return False;
+
+ font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *));
+ if (font_struct_list == NULL)
+ return False;
+
+ font_name_list = (char **) Xmalloc(sizeof(char *));
+ if (font_name_list == NULL)
+ goto err;
+
+ font_name_buf = (char *) Xmalloc(length);
+ if (font_name_buf == NULL)
+ goto err;
+
+ oc->core.font_info.num_font = 1;
+ oc->core.font_info.font_name_list = font_name_list;
+ oc->core.font_info.font_struct_list = font_struct_list;
+
+ font_set = gen->font_set;
+
+ if (font_set->font_name != NULL) {
+ font_set->id = 1;
+ if (font_set->font)
+ *font_struct_list++ = font_set->font;
+ else
+ *font_struct_list++ = font_set->info;
+ strcpy(font_name_buf, font_set->font_name);
+ Xfree(font_set->font_name);
+ *font_name_list++ = font_set->font_name = font_name_buf;
+ font_name_buf += strlen(font_name_buf) + 1;
+ }
+
+ set_fontset_extents(oc);
+
+ return True;
+
+err:
+ if (font_name_list)
+ Xfree(font_name_list);
+ Xfree(font_struct_list);
+
+ return False;
+}
+
+static char *
+get_font_name(
+ XOC oc,
+ char *pattern)
+{
+ char **list, *name;
+ int count;
+ XFontStruct *fs;
+ Display *dpy = oc->core.om->core.display;
+
+ list = XListFonts(dpy, pattern, 1, &count);
+ if (list != NULL) {
+ name = strdup(*list);
+
+ XFreeFontNames(list);
+ } else {
+ fs = XLoadQueryFont(dpy, pattern);
+ if (fs == NULL) return NULL;
+
+ name = get_prop_name(dpy, fs);
+ XFreeFont(dpy, fs);
+ }
+ return name;
+}
+
+static int
+parse_fontname(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ FontData font_data;
+ char *pattern, *last, buf[BUFSIZ];
+ int font_data_count, found_num = 0;
+ ssize_t length;
+ int count, num_fields;
+ char *base_name, *font_name, **name_list, **cur_name_list;
+ char *charset_p = NULL;
+ Bool append_charset;
+ /*
+ append_charset flag should be set to True when the XLFD fontname
+ doesn't contain a chaset part.
+ */
+
+ name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
+ if (name_list == NULL)
+ return -1;
+ cur_name_list = name_list;
+
+ while (count-- > 0) {
+ pattern = *cur_name_list++;
+ if (pattern == NULL || *pattern == '\0')
+ continue;
+
+ append_charset = False;
+
+ if (strchr(pattern, '*') == NULL &&
+ (font_name = get_font_name(oc, pattern))) {
+
+ font_set = gen->font_set;
+
+ font_data = check_charset(font_set, font_name);
+ if (font_data == NULL) {
+ Display *dpy = oc->core.om->core.display;
+ char **fn_list = NULL, *prop_fname = NULL;
+ int list_num;
+ XFontStruct *fs_list;
+ if ((fn_list = XListFontsWithInfo(dpy, font_name,
+ MAXFONTS,
+ &list_num, &fs_list))
+ && (prop_fname = get_prop_name(dpy, fs_list))
+ && (font_data = check_charset(font_set, prop_fname))) {
+ if (fn_list) {
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ fn_list = NULL;
+ }
+ font_name = prop_fname;
+ }
+ }
+ if (font_data == NULL)
+ continue;
+
+ font_set->font_name = strdup(font_name);
+ Xfree(font_name);
+ if (font_set->font_name == NULL) {
+ goto err;
+ }
+ found_num++;
+ goto found;
+ }
+/*
+1266793
+Limit the length of the string copy to prevent stack corruption.
+ strcpy(buf, pattern);
+*/
+ strncpy(buf, pattern, BUFSIZ);
+ buf[BUFSIZ-1] = '\0';
+ length = strlen(buf);
+ last = buf + length - 1;
+
+ for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
+ if (*base_name == '-') num_fields++;
+ if (strchr(pattern, '*') == NULL) {
+ if (num_fields == 12) {
+ append_charset = True;
+ *++last = '-';
+ last++;
+ } else
+ continue;
+ } else {
+ if (num_fields == 13 || num_fields == 14) {
+ /*
+ * There are 14 fields in an XLFD name -- make certain the
+ * charset (& encoding) is placed in the correct field.
+ */
+ append_charset = True;
+ last = strrchr (buf, '-');
+ if (num_fields == 14) {
+ *last = '\0';
+ last = strrchr (buf, '-');
+ }
+ last++;
+ } else if (*last == '*') {
+ append_charset = True;
+ if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
+ && *(last-1) == '-') {
+ last -= 2;
+ }
+ *++last = '-';
+ last++;
+ } else {
+ last = strrchr (buf, '-');
+ charset_p = last;
+ charset_p = strrchr (buf, '-');
+ while (*(--charset_p) != '-');
+ charset_p++;
+ }
+ }
+
+ font_set = gen->font_set;
+
+ font_data = font_set->font_data;
+ font_data_count = font_set->font_data_count;
+ for ( ; font_data_count-- > 0; font_data++) {
+ if (append_charset)
+ {
+/*
+1266793
+Limit the length of the string copy to prevent stack corruption.
+ strcpy(last, font_data->name);
+*/
+ strncpy(last, font_data->name, BUFSIZ - length);
+ buf[BUFSIZ-1] = '\0';
+ }
+ else {
+ if (_XlcCompareISOLatin1(charset_p,
+ font_data->name)) {
+ continue;
+ }
+ }
+ if ((font_set->font_name = get_font_name(oc, buf)))
+ break;
+ }
+ if (font_set->font_name != NULL) {
+ found_num++;
+ goto found;
+ }
+ }
+ found:
+ base_name = strdup(oc->core.base_name_list);
+ if (base_name == NULL)
+ goto err;
+
+ oc->core.base_name_list = base_name;
+
+ XFreeStringList(name_list);
+
+ return found_num;
+err:
+ XFreeStringList(name_list);
+
+ return -1;
+}
+
+static Bool
+set_missing_list(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ char **charset_list, *charset_buf;
+ int count, length;
+
+ font_set = gen->font_set;
+ count = length = 0;
+
+ if (!font_set->info && !font_set->font) {
+ length += strlen(font_set->font_data->name) + 1;
+ count++;
+ }
+
+ if (count == 0)
+ return True;
+
+ charset_list = (char **) Xmalloc(sizeof(char *));
+ if (charset_list == NULL)
+ return False;
+
+ charset_buf = (char *) Xmalloc(length);
+ if (charset_buf == NULL) {
+ Xfree(charset_list);
+ return False;
+ }
+
+ oc->core.missing_list.charset_list = charset_list;
+
+ font_set = gen->font_set;
+
+ if (!font_set->info && !font_set->font) {
+ strcpy(charset_buf, font_set->font_data->name);
+ *charset_list++ = charset_buf;
+ charset_buf += strlen(charset_buf) + 1;
+ }
+ return True;
+}
+
+static Bool
+create_fontset(
+ XOC oc)
+{
+ int found_num;
+
+ if (init_fontset(oc) == False)
+ return False;
+
+ found_num = parse_fontname(oc);
+ if (found_num <= 0) {
+ if (found_num == 0)
+ set_missing_list(oc);
+ return False;
+ }
+
+ if (load_font(oc) == False)
+ return False;
+
+ if (init_core_part(oc) == False)
+ return False;
+
+ if (set_missing_list(oc) == False)
+ return False;
+
+ return True;
+}
+
+static void
+destroy_oc(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ XFontStruct **font_list, *font;
+
+ if (gen->font_set)
+ Xfree(gen->font_set);
+
+ if (oc->core.base_name_list)
+ Xfree(oc->core.base_name_list);
+
+ if (oc->core.font_info.font_name_list)
+ XFreeStringList(oc->core.font_info.font_name_list);
+
+ if ((font_list = oc->core.font_info.font_struct_list)) {
+ if ((font = *font_list)) {
+ if (font->fid)
+ XFreeFont(dpy, font);
+ else
+ XFreeFontInfo(NULL, font, 1);
+ }
+ Xfree(oc->core.font_info.font_struct_list);
+ }
+
+ if (oc->core.missing_list.charset_list)
+ XFreeStringList(oc->core.missing_list.charset_list);
+
+#ifdef notdef
+ if (oc->core.res_name)
+ Xfree(oc->core.res_name);
+ if (oc->core.res_class)
+ Xfree(oc->core.res_class);
+#endif
+
+ Xfree(oc);
+}
+
+static char *
+set_oc_values(
+ XOC oc,
+ XlcArgList args,
+ int num_args)
+{
+ if (oc->core.resources == NULL)
+ return NULL;
+
+ return _XlcSetValues((XPointer) oc, oc->core.resources,
+ oc->core.num_resources, args, num_args, XlcSetMask);
+}
+
+static char *
+get_oc_values(
+ XOC oc,
+ XlcArgList args,
+ int num_args)
+{
+ if (oc->core.resources == NULL)
+ return NULL;
+
+ return _XlcGetValues((XPointer) oc, oc->core.resources,
+ oc->core.num_resources, args, num_args, XlcGetMask);
+}
+
+static Bool
+wcs_to_mbs(
+ XOC oc,
+ char *to,
+ _Xconst wchar_t *from,
+ int length)
+{
+ XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
+ XLCd lcd;
+ int ret, to_left = length;
+
+ if (conv == NULL) {
+ lcd = oc->core.om->core.lcd;
+ conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
+ if (conv == NULL)
+ return False;
+ XOC_GENERIC(oc)->wcs_to_cs = conv;
+ } else
+ _XlcResetConverter(conv);
+
+ ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
+ &to_left, NULL, 0);
+ if (ret != 0 || length > 0)
+ return False;
+
+ return True;
+}
+
+static int
+_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
+{
+ return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
+}
+
+static int
+_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
+{
+ DefineLocalBuf;
+ char *buf = AllocLocalBuf(length);
+ int ret = 0;
+
+ if (buf == NULL)
+ return 0;
+
+ if (wcs_to_mbs(oc, buf, text, length) == False)
+ goto err;
+
+ ret = _XmbDefaultTextEscapement(oc, buf, length);
+
+err:
+ FreeLocalBuf(buf);
+
+ return ret;
+}
+
+static int
+_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
+ XRectangle *overall_ink, XRectangle *overall_logical)
+{
+ int direction, logical_ascent, logical_descent;
+ XCharStruct overall;
+
+ XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
+ &logical_ascent, &logical_descent, &overall);
+
+ if (overall_ink) {
+ overall_ink->x = overall.lbearing;
+ overall_ink->y = -(overall.ascent);
+ overall_ink->width = overall.rbearing - overall.lbearing;
+ overall_ink->height = overall.ascent + overall.descent;
+ }
+
+ if (overall_logical) {
+ overall_logical->x = 0;
+ overall_logical->y = -(logical_ascent);
+ overall_logical->width = overall.width;
+ overall_logical->height = logical_ascent + logical_descent;
+ }
+
+ return overall.width;
+}
+
+static int
+_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
+ XRectangle *overall_ink, XRectangle *overall_logical)
+{
+ DefineLocalBuf;
+ char *buf = AllocLocalBuf(length);
+ int ret = 0;
+
+ if (buf == NULL)
+ return 0;
+
+ if (wcs_to_mbs(oc, buf, text, length) == False)
+ goto err;
+
+ ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
+
+err:
+ FreeLocalBuf(buf);
+
+ return ret;
+}
+
+static Status
+_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
+ XRectangle *ink_buf, XRectangle *logical_buf,
+ int buf_size, int *num_chars,
+ XRectangle *overall_ink,
+ XRectangle *overall_logical)
+{
+ XFontStruct *font = *oc->core.font_info.font_struct_list;
+ XCharStruct *def, *cs, overall;
+ Bool first = True;
+
+ if (buf_size < length)
+ return 0;
+
+ bzero((char *) &overall, sizeof(XCharStruct));
+ *num_chars = 0;
+
+ CI_GET_DEFAULT_INFO_1D(font, def)
+
+ while (length-- > 0) {
+ CI_GET_CHAR_INFO_1D(font, *text, def, cs)
+ text++;
+ if (cs == NULL)
+ continue;
+
+ ink_buf->x = overall.width + cs->lbearing;
+ ink_buf->y = -(cs->ascent);
+ ink_buf->width = cs->rbearing - cs->lbearing;
+ ink_buf->height = cs->ascent + cs->descent;
+ ink_buf++;
+
+ logical_buf->x = overall.width;
+ logical_buf->y = -(font->ascent);
+ logical_buf->width = cs->width;
+ logical_buf->height = font->ascent + font->descent;
+ logical_buf++;
+
+ if (first) {
+ overall = *cs;
+ first = False;
+ } else {
+ overall.ascent = max(overall.ascent, cs->ascent);
+ overall.descent = max(overall.descent, cs->descent);
+ overall.lbearing = min(overall.lbearing, overall.width +
+ cs->lbearing);
+ overall.rbearing = max(overall.rbearing, overall.width +
+ cs->rbearing);
+ overall.width += cs->width;
+ }
+ (*num_chars)++;
+ }
+
+ if (overall_ink) {
+ overall_ink->x = overall.lbearing;
+ overall_ink->y = -(overall.ascent);
+ overall_ink->width = overall.rbearing - overall.lbearing;
+ overall_ink->height = overall.ascent + overall.descent;
+ }
+
+ if (overall_logical) {
+ overall_logical->x = 0;
+ overall_logical->y = -(font->ascent);
+ overall_logical->width = overall.width;
+ overall_logical->height = font->ascent + font->descent;
+ }
+
+ return 1;
+}
+
+static Status
+_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
+ XRectangle *ink_buf, XRectangle *logical_buf,
+ int buf_size, int *num_chars,
+ XRectangle *overall_ink,
+ XRectangle *overall_logical)
+{
+ DefineLocalBuf;
+ char *buf = AllocLocalBuf(length);
+ Status ret = 0;
+
+ if (buf == NULL)
+ return 0;
+
+ if (wcs_to_mbs(oc, buf, text, length) == False)
+ goto err;
+
+ ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
+ buf_size, num_chars, overall_ink,
+ overall_logical);
+
+err:
+ FreeLocalBuf(buf);
+
+ return ret;
+}
+
+static int
+_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
+ _Xconst char *text, int length)
+{
+ XFontStruct *font = *oc->core.font_info.font_struct_list;
+
+ XSetFont(dpy, gc, font->fid);
+ XDrawString(dpy, d, gc, x, y, text, length);
+
+ return XTextWidth(font, text, length);
+}
+
+static int
+_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
+ _Xconst wchar_t *text, int length)
+{
+ DefineLocalBuf;
+ char *buf = AllocLocalBuf(length);
+ int ret = 0;
+
+ if (buf == NULL)
+ return 0;
+
+ if (wcs_to_mbs(oc, buf, text, length) == False)
+ goto err;
+
+ ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
+
+err:
+ FreeLocalBuf(buf);
+
+ return ret;
+}
+
+static void
+_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
+ int y, _Xconst char *text, int length)
+{
+ XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
+ XDrawImageString(dpy, d, gc, x, y, text, length);
+}
+
+static void
+_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
+ int y, _Xconst wchar_t *text, int length)
+{
+ DefineLocalBuf;
+ char *buf = AllocLocalBuf(length);
+
+ if (buf == NULL)
+ return;
+
+ if (wcs_to_mbs(oc, buf, text, length) == False)
+ goto err;
+
+ _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
+
+err:
+ FreeLocalBuf(buf);
+}
+
+static _Xconst XOCMethodsRec oc_default_methods = {
+ destroy_oc,
+ set_oc_values,
+ get_oc_values,
+ _XmbDefaultTextEscapement,
+ _XmbDefaultTextExtents,
+ _XmbDefaultTextPerCharExtents,
+ _XmbDefaultDrawString,
+ _XmbDefaultDrawImageString,
+ _XwcDefaultTextEscapement,
+ _XwcDefaultTextExtents,
+ _XwcDefaultTextPerCharExtents,
+ _XwcDefaultDrawString,
+ _XwcDefaultDrawImageString
+};
+
+static XlcResource oc_resources[] = {
+ { XNBaseFontName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
+ { XNOMAutomatic, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
+ { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
+ XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
+ { XNDefaultString, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.default_string), XlcGetMask },
+ { XNOrientation, NULLQUARK, sizeof(XOrientation),
+ XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
+ { XNResourceName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
+ { XNResourceClass, NULLQUARK, sizeof(char *),
+ XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
+ { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
+ XOffsetOf(XOCRec, core.font_info), XlcGetMask }
+};
+
+static XOC
+create_oc(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ XOC oc;
+
+ oc = Xcalloc(1, sizeof(XOCGenericRec));
+ if (oc == NULL)
+ return (XOC) NULL;
+
+ oc->core.om = om;
+
+ if (oc_resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
+
+ if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
+ args, num_args, XlcCreateMask | XlcDefaultMask))
+ goto err;
+
+ if (oc->core.base_name_list == NULL)
+ goto err;
+
+ oc->core.resources = oc_resources;
+ oc->core.num_resources = XlcNumber(oc_resources);
+
+ if (create_fontset(oc) == False)
+ goto err;
+
+ oc->methods = (XOCMethods)&oc_default_methods;
+
+ return oc;
+
+err:
+ destroy_oc(oc);
+
+ return (XOC) NULL;
+}
+
+static Status
+close_om(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ FontData font_data;
+ int count;
+
+ if ((data = gen->data)) {
+ if (data->font_data) {
+ for (font_data = data->font_data, count = data->font_data_count;
+ count-- > 0 ; font_data++) {
+ if (font_data->name)
+ Xfree(font_data->name);
+ }
+ Xfree(data->font_data);
+ }
+ Xfree(gen->data);
+ }
+
+ if (om->core.res_name)
+ Xfree(om->core.res_name);
+ if (om->core.res_class)
+ Xfree(om->core.res_class);
+ if (om->core.required_charset.charset_list)
+ XFreeStringList(om->core.required_charset.charset_list);
+ else
+ Xfree((char*)om->core.required_charset.charset_list);
+ if (om->core.orientation_list.orientation)
+ Xfree(om->core.orientation_list.orientation);
+
+ Xfree(om);
+
+ return 1;
+}
+
+static char *
+set_om_values(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ if (om->core.resources == NULL)
+ return NULL;
+
+ return _XlcSetValues((XPointer) om, om->core.resources,
+ om->core.num_resources, args, num_args, XlcSetMask);
+}
+
+static char *
+get_om_values(
+ XOM om,
+ XlcArgList args,
+ int num_args)
+{
+ if (om->core.resources == NULL)
+ return NULL;
+
+ return _XlcGetValues((XPointer) om, om->core.resources,
+ om->core.num_resources, args, num_args, XlcGetMask);
+}
+
+static _Xconst XOMMethodsRec methods = {
+ close_om,
+ set_om_values,
+ get_om_values,
+ create_oc
+};
+
+static XlcResource om_resources[] = {
+ { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
+ XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
+ { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
+ XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
+ { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
+ { XNContextualDrawing, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
+};
+
+static OMData
+add_data(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData new;
+
+ new = Xcalloc(1, sizeof(OMDataRec));
+
+ if (new == NULL)
+ return NULL;
+
+ gen->data = new;
+
+ return new;
+}
+
+static _Xconst char *supported_charset_list[] = {
+ "ISO8859-1",
+/* fix for bug4332979 */
+ "adobe-fontspecific",
+/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from
+ supported_charset_list because it is not a supported_charset for C locale
+ "JISX0201.1976-0", */
+ "SUNOLCURSOR-1",
+ "SUNOLGLYPH-1"
+};
+
+static Bool
+init_om(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ FontData font_data;
+ char **required_list;
+ XOrientation *orientation;
+ char **value, buf[BUFSIZ], *bufptr;
+ int count, length = 0;
+
+ value = (char**)supported_charset_list;
+ count = XlcNumber(supported_charset_list);
+
+ data = add_data(om);
+ if (data == NULL)
+ return False;
+
+ font_data = Xcalloc(count, sizeof(FontDataRec));
+ if (font_data == NULL)
+ return False;
+ data->font_data = font_data;
+ data->font_data_count = count;
+
+ for ( ; count-- > 0; font_data++) {
+/*
+1266793
+This one is fine. *value points to one of the local strings in
+supported_charset_list[].
+*/
+ strcpy(buf, *value++);
+ font_data->name = strdup(buf);
+ if (font_data->name == NULL)
+ return False;
+ }
+
+ length += strlen(data->font_data->name) + 1;
+
+ /* required charset list */
+ required_list = (char **) Xmalloc(sizeof(char *));
+ if (required_list == NULL)
+ return False;
+
+ bufptr = (char *) Xmalloc(length);
+ if (bufptr == NULL) {
+ Xfree(required_list);
+ return False;
+ }
+
+ om->core.required_charset.charset_list = required_list;
+ om->core.required_charset.charset_count = 1; /* always 1 */
+
+ data = gen->data;
+
+ strcpy(bufptr, data->font_data->name);
+ *required_list++ = bufptr;
+ bufptr += strlen(bufptr) + 1;
+
+ /* orientation list */
+ orientation = (XOrientation *) Xmalloc(sizeof(XOrientation));
+ if (orientation == NULL)
+ return False;
+
+ *orientation = XOMOrientation_LTR_TTB;
+ om->core.orientation_list.orientation = orientation;
+ om->core.orientation_list.num_orientation = 1;
+
+ /* directional dependent drawing */
+ om->core.directional_dependent = False;
+
+ /* contexual drawing */
+ om->core.contextual_drawing = False;
+
+ /* context dependent */
+ om->core.context_dependent = False;
+
+ return True;
+}
+
+XOM
+_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
+ _Xconst char *res_name, _Xconst char *res_class)
+{
+ XOM om;
+
+ om = Xcalloc(1, sizeof(XOMGenericRec));
+ if (om == NULL)
+ return (XOM) NULL;
+
+ om->methods = (XOMMethods)&methods;
+ om->core.lcd = lcd;
+ om->core.display = dpy;
+ om->core.rdb = rdb;
+ if (res_name) {
+ om->core.res_name = strdup(res_name);
+ if (om->core.res_name == NULL)
+ goto err;
+ }
+ if (res_class) {
+ om->core.res_class = strdup(res_class);
+ if (om->core.res_class == NULL)
+ goto err;
+ }
+
+ if (om_resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(om_resources, XlcNumber(om_resources));
+
+ om->core.resources = om_resources;
+ om->core.num_resources = XlcNumber(om_resources);
+
+ if (init_om(om) == False)
+ goto err;
+
+ return om;
+err:
+ close_om(om);
+
+ return (XOM) NULL;
+}
diff --git a/libX11/src/xlibi18n/XimProto.h b/libX11/src/xlibi18n/XimProto.h index 6b0096dd6..9551301a2 100644 --- a/libX11/src/xlibi18n/XimProto.h +++ b/libX11/src/xlibi18n/XimProto.h @@ -143,6 +143,13 @@ PERFORMANCE OF THIS SOFTWARE. /* * byte order */ +#ifdef BIGENDIAN +#undef BIGENDIAN +#endif +#ifdef LITTLEENDIAN +#undef LITTLEENDIAN +#endif + #define BIGENDIAN (CARD8)0x42 /* MSB first */ #define LITTLEENDIAN (CARD8)0x6c /* LSB first */ diff --git a/libX11/src/xlibi18n/XlcDL.c b/libX11/src/xlibi18n/XlcDL.c index 75e193c05..4a05c40e4 100644 --- a/libX11/src/xlibi18n/XlcDL.c +++ b/libX11/src/xlibi18n/XlcDL.c @@ -1,612 +1,612 @@ -/* -Copyright 1985, 1986, 1987, 1991, 1998 The Open Group - -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 -OPEN GROUP 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 -EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. - - -Except as contained in this notice, the name of The Open Group 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 Open Group. - - -X Window System is a trademark of The Open Group - -OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF -logo, LBX, X Window System, and Xinerama are trademarks of the Open -Group. All other trademarks and registered trademarks mentioned herein -are the property of their respective owners. No right, title or -interest in or to any trademark, service mark, logo or trade name of -Sun Microsystems, Inc. or its licensors is granted. - -*/ -/* - * Copyright 2000 Oracle and/or its affiliates. All rights reserved. - * - * 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 (including the next - * paragraph) 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 OR COPYRIGHT HOLDERS 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. - */ - - -#ifdef HAVE_CONFIG_H -# include <config.h> -#else -# if defined(hpux) -# define HAVE_DL_H -# else -# define HAVE_DLFCN_H -# endif -#endif - -#include <stdio.h> - -#ifdef HAVE_DL_H -#include <dl.h> -#endif - -#ifdef HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <ctype.h> - -#include "Xlibint.h" -#include "XlcPublic.h" -#include "XlcPubI.h" - -#define XI18N_DLREL 2 - -#define iscomment(ch) ((ch) == '\0' || (ch) == '#') - -typedef enum { - XLC_OBJECT, - XIM_OBJECT, - XOM_OBJECT -} XI18NDLType; - -typedef struct { - XI18NDLType type; - int locale_name_len; - char *locale_name; - char *dl_name; - char *open; - char *im_register; - char *im_unregister; - int dl_release; - unsigned int refcount; -#if defined(hpux) - shl_t dl_module; -#else - void *dl_module; -#endif -} XI18NObjectsListRec, *XI18NObjectsList; - -#define OBJECT_INIT_LEN 8 -#define OBJECT_INC_LEN 4 -static int lc_len = 0; -static XI18NObjectsListRec *xi18n_objects_list = NULL; -static int lc_count = 0; - -static int -parse_line(char *line, char **argv, int argsize) -{ - int argc = 0; - char *p = line; - - while (argc < argsize) { - while (isspace(*p)) { - ++p; - } - if (iscomment(*p)){ - break; - } - argv[argc++] = p; - while (!isspace(*p)) { - ++p; - } - if (iscomment(*p)) { - break; - } - *p++ = '\0'; - } - return argc; -} - -static char * -strdup_with_underscore(const char *symbol) -{ - char *result; - - if ((result = malloc(strlen(symbol) + 2)) == NULL) - return NULL; - result[0] = '_'; - strcpy(result + 1, symbol); - return result; -} - -#ifndef hpux -static void * -try_both_dlsym (void *handle, char *name) -{ - void *ret; - - ret = dlsym (handle, name); - if (!ret) - { - name = strdup_with_underscore (name); - if (name) - { - ret = dlsym (handle, name); - free (name); - } - } - return ret; -} -#endif - -static void -resolve_object(char *path, const char *lc_name) -{ - char filename[BUFSIZ]; - FILE *fp; - char buf[BUFSIZ]; - - if (lc_len == 0) { /* True only for the 1st time */ - lc_len = OBJECT_INIT_LEN; - xi18n_objects_list = (XI18NObjectsList) - Xmalloc(sizeof(XI18NObjectsListRec) * lc_len); - if (!xi18n_objects_list) return; - } -/* -1266793 -Limit the length of path to prevent stack buffer corruption. - sprintf(filename, "%s/%s", path, "XI18N_OBJS"); -*/ - sprintf(filename, "%.*s/%s", BUFSIZ - 12, path, "XI18N_OBJS"); - fp = fopen(filename, "r"); - if (fp == (FILE *)NULL){ - return; - } - - while (fgets(buf, BUFSIZ, fp) != NULL){ - char *p = buf; - int n; - char *args[6]; - while (isspace(*p)){ - ++p; - } - if (iscomment(*p)){ - continue; - } - - if (lc_count == lc_len) { - lc_len += OBJECT_INC_LEN; - xi18n_objects_list = (XI18NObjectsList) - Xrealloc(xi18n_objects_list, - sizeof(XI18NObjectsListRec) * lc_len); - if (!xi18n_objects_list) return; - } - n = parse_line(p, args, 6); - - if (n == 3 || n == 5) { - if (!strcmp(args[0], "XLC")){ - xi18n_objects_list[lc_count].type = XLC_OBJECT; - } else if (!strcmp(args[0], "XOM")){ - xi18n_objects_list[lc_count].type = XOM_OBJECT; - } else if (!strcmp(args[0], "XIM")){ - xi18n_objects_list[lc_count].type = XIM_OBJECT; - } - xi18n_objects_list[lc_count].dl_name = strdup(args[1]); - xi18n_objects_list[lc_count].open = strdup(args[2]); - xi18n_objects_list[lc_count].dl_release = XI18N_DLREL; - xi18n_objects_list[lc_count].locale_name = strdup(lc_name); - xi18n_objects_list[lc_count].refcount = 0; - xi18n_objects_list[lc_count].dl_module = (void*)NULL; - if (n == 5) { - xi18n_objects_list[lc_count].im_register = strdup(args[3]); - xi18n_objects_list[lc_count].im_unregister = strdup(args[4]); - } else { - xi18n_objects_list[lc_count].im_register = NULL; - xi18n_objects_list[lc_count].im_unregister = NULL; - } - lc_count++; - } - } - fclose(fp); -} - -static char* -__lc_path(const char *dl_name, const char *lc_dir) -{ - char *path; - size_t len; - - /* - * reject this for possible security issue - */ - if (strstr (dl_name, "../")) - return NULL; - - len = (lc_dir ? strlen(lc_dir) : 0 ) + - (dl_name ? strlen(dl_name) : 0) + 10; -#if defined POSTLOCALELIBDIR - len += (strlen(POSTLOCALELIBDIR) + 1); -#endif - path = Xmalloc(len + 1); - - if (strchr(dl_name, '/') != NULL) { - char *slash_p; - slash_p = strrchr(lc_dir, '/'); - *slash_p = '\0'; - strcpy(path, lc_dir); strcat(path, "/"); -#if defined POSTLOCALELIBDIR - strcat(path, POSTLOCALELIBDIR); strcat(path, "/"); -#endif - strcat(path, dl_name); strcat(path, ".so.2"); - *slash_p = '/'; - } else { - strcpy(path, lc_dir); strcat(path, "/"); -#if defined POSTLOCALELIBDIR - strcat(path, POSTLOCALELIBDIR); strcat(path, "/"); -#endif - strcat(path, dl_name); strcat(path, ".so.2"); - } - return path; -} - -/* We reference count dlopen() and dlclose() of modules; unfortunately, - * since XCloseIM, XCloseOM, XlcClose aren't wrapped, but directly - * call the close method of the object, we leak a reference count every - * time we open then close a module. Fixing this would require - * either creating proxy objects or hooks for close_im/close_om - * in XLCd - */ -static Bool -open_object( - XI18NObjectsList object, - char *lc_dir) -{ - char *path; - - if (object->refcount == 0) { - path = __lc_path(object->dl_name, lc_dir); - if (!path) - return False; -#if defined(hpux) - object->dl_module = shl_load(path, BIND_DEFERRED, 0L); -#else - object->dl_module = dlopen(path, RTLD_LAZY); -#endif - Xfree(path); - - if (!object->dl_module) - return False; - } - - object->refcount++; - return True; -} - -static void * -fetch_symbol( - XI18NObjectsList object, - char *symbol) -{ - void *result = NULL; -#if defined(hpux) - int getsyms_cnt, i; - struct shl_symbol *symbols; -#endif - - if (symbol == NULL) - return NULL; - -#if defined(hpux) - getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE, - EXPORT_SYMBOLS, malloc, &symbols); - - for(i=0; i<getsyms_cnt; i++) { - if(!strcmp(symbols[i].name, symbol)) { - result = symbols[i].value; - break; - } - } - - if(getsyms_cnt > 0) { - free(symbols); - } -#else - result = try_both_dlsym(object->dl_module, symbol); -#endif - - return result; -} - -static void -close_object(XI18NObjectsList object) -{ - object->refcount--; - if (object->refcount == 0) - { -#if defined(hpux) - shl_unload(object->dl_module); -#else - dlclose(object->dl_module); -#endif - object->dl_module = NULL; - } -} - - -typedef XLCd (*dynamicLoadProc)(const char *); - -XLCd -_XlcDynamicLoad(const char *lc_name) -{ - XLCd lcd = (XLCd)NULL; - dynamicLoadProc lc_loader = (dynamicLoadProc)NULL; - int count; - XI18NObjectsList objects_list; - char lc_dir[BUFSIZE], lc_lib_dir[BUFSIZE]; - - if (lc_name == NULL) return (XLCd)NULL; - - if (_XlcLocaleDirName(lc_dir, BUFSIZE, (char *)lc_name) == (char *)NULL) - return (XLCd)NULL; - if (_XlcLocaleLibDirName(lc_lib_dir, BUFSIZE, (char *)lc_name) == (char*)NULL) - return (XLCd)NULL; - - resolve_object(lc_dir, lc_name); - resolve_object(lc_lib_dir, lc_name); - - objects_list = xi18n_objects_list; - count = lc_count; - for (; count-- > 0; objects_list++) { - if (objects_list->type != XLC_OBJECT || - strcmp(objects_list->locale_name, lc_name)) continue; - if (!open_object (objects_list, lc_dir) && \ - !open_object (objects_list, lc_lib_dir)) - continue; - - lc_loader = (dynamicLoadProc)fetch_symbol (objects_list, objects_list->open); - if (!lc_loader) continue; - lcd = (*lc_loader)(lc_name); - if (lcd != (XLCd)NULL) { - break; - } - - close_object (objects_list); - } - return (XLCd)lcd; -} - - -typedef XIM (*dynamicOpenProcp)(XLCd, Display *, XrmDatabase, char *, char *); - -static XIM -_XDynamicOpenIM(XLCd lcd, Display *display, XrmDatabase rdb, - char *res_name, char *res_class) -{ - XIM im = (XIM)NULL; - char lc_dir[BUFSIZE]; - char *lc_name; - dynamicOpenProcp im_openIM = (dynamicOpenProcp)NULL; - int count; - XI18NObjectsList objects_list = xi18n_objects_list; - - lc_name = lcd->core->name; - - if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return (XIM)0; - - count = lc_count; - for (; count-- > 0; objects_list++) { - if (objects_list->type != XIM_OBJECT || - strcmp(objects_list->locale_name, lc_name)) continue; - - if (!open_object (objects_list, lc_dir)) - continue; - - im_openIM = (dynamicOpenProcp)fetch_symbol(objects_list, objects_list->open); - if (!im_openIM) continue; - im = (*im_openIM)(lcd, display, rdb, res_name, res_class); - if (im != (XIM)NULL) { - break; - } - - close_object (objects_list); - } - return (XIM)im; -} - -typedef Bool (*dynamicRegisterCBProcp)( - XLCd, Display *, XrmDatabase, char *, char *, XIDProc, XPointer); - -static Bool -_XDynamicRegisterIMInstantiateCallback( - XLCd lcd, - Display *display, - XrmDatabase rdb, - char *res_name, - char *res_class, - XIDProc callback, - XPointer client_data) -{ - char lc_dir[BUFSIZE]; - char *lc_name; - dynamicRegisterCBProcp im_registerIM = (dynamicRegisterCBProcp)NULL; - Bool ret_flag = False; - int count; - XI18NObjectsList objects_list = xi18n_objects_list; -#if defined(hpux) - int getsyms_cnt, i; - struct shl_symbol *symbols; -#endif - - lc_name = lcd->core->name; - - if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return False; - - count = lc_count; - for (; count-- > 0; objects_list++) { - if (objects_list->type != XIM_OBJECT || - strcmp(objects_list->locale_name, lc_name)) continue; - - if (!open_object (objects_list, lc_dir)) - continue; - im_registerIM = (dynamicRegisterCBProcp)fetch_symbol(objects_list, - objects_list->im_register); - if (!im_registerIM) continue; - ret_flag = (*im_registerIM)(lcd, display, rdb, - res_name, res_class, - callback, client_data); - if (ret_flag) break; - - close_object (objects_list); - } - return (Bool)ret_flag; -} - -typedef Bool (*dynamicUnregisterProcp)( - XLCd, Display *, XrmDatabase, char *, char *, XIDProc, XPointer); - -static Bool -_XDynamicUnRegisterIMInstantiateCallback( - XLCd lcd, - Display *display, - XrmDatabase rdb, - char *res_name, - char *res_class, - XIDProc callback, - XPointer client_data) -{ - char lc_dir[BUFSIZE]; - char *lc_name; - dynamicUnregisterProcp im_unregisterIM = (dynamicUnregisterProcp)NULL; - Bool ret_flag = False; - int count; - XI18NObjectsList objects_list = xi18n_objects_list; -#if defined(hpux) - int getsyms_cnt, i; - struct shl_symbol *symbols; -#endif - - lc_name = lcd->core->name; - if (_XlcLocaleDirName(lc_dir, BUFSIZE, lc_name) == NULL) return False; - - count = lc_count; - for (; count-- > 0; objects_list++) { - if (objects_list->type != XIM_OBJECT || - strcmp(objects_list->locale_name, lc_name)) continue; - - if (!objects_list->refcount) /* Must already be opened */ - continue; - - im_unregisterIM = (dynamicUnregisterProcp)fetch_symbol(objects_list, - objects_list->im_unregister); - - if (!im_unregisterIM) continue; - ret_flag = (*im_unregisterIM)(lcd, display, rdb, - res_name, res_class, - callback, client_data); - if (ret_flag) { - close_object (objects_list); /* opened in RegisterIMInstantiateCallback */ - break; - } - } - return (Bool)ret_flag; -} - -Bool -_XInitDynamicIM(XLCd lcd) -{ - if(lcd == (XLCd)NULL) - return False; - lcd->methods->open_im = _XDynamicOpenIM; - lcd->methods->register_callback = _XDynamicRegisterIMInstantiateCallback; - lcd->methods->unregister_callback = _XDynamicUnRegisterIMInstantiateCallback; - return True; -} - - -typedef XOM (*dynamicIOpenProcp)( - XLCd, Display *, XrmDatabase, _Xconst char *, _Xconst char *); - -static XOM -_XDynamicOpenOM(XLCd lcd, Display *display, XrmDatabase rdb, - _Xconst char *res_name, _Xconst char *res_class) -{ - XOM om = (XOM)NULL; - int count; - char lc_dir[BUFSIZE]; - char *lc_name; - dynamicIOpenProcp om_openOM = (dynamicIOpenProcp)NULL; - XI18NObjectsList objects_list = xi18n_objects_list; -#if defined(hpux) - int getsyms_cnt, i; - struct shl_symbol *symbols; -#endif - - lc_name = lcd->core->name; - - if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return (XOM)0; - - count = lc_count; - for (; count-- > 0; objects_list++) { - if (objects_list->type != XOM_OBJECT || - strcmp(objects_list->locale_name, lc_name)) continue; - if (!open_object (objects_list, lc_dir)) - continue; - - om_openOM = (dynamicIOpenProcp)fetch_symbol(objects_list, objects_list->open); - if (!om_openOM) continue; - om = (*om_openOM)(lcd, display, rdb, res_name, res_class); - if (om != (XOM)NULL) { - break; - } - close_object(objects_list); - } - return (XOM)om; -} - -Bool -_XInitDynamicOM(XLCd lcd) -{ - if(lcd == (XLCd)NULL) - return False; - - lcd->methods->open_om = _XDynamicOpenOM; - - return True; -} +/*
+Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
+
+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
+OPEN GROUP 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
+EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Except as contained in this notice, the name of The Open Group 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 Open Group.
+
+
+X Window System is a trademark of The Open Group
+
+OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
+logo, LBX, X Window System, and Xinerama are trademarks of the Open
+Group. All other trademarks and registered trademarks mentioned herein
+are the property of their respective owners. No right, title or
+interest in or to any trademark, service mark, logo or trade name of
+Sun Microsystems, Inc. or its licensors is granted.
+
+*/
+/*
+ * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 OR COPYRIGHT HOLDERS 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#else
+# if defined(hpux)
+# define HAVE_DL_H
+# else
+# define HAVE_DLFCN_H
+# endif
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_DL_H
+#include <dl.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <ctype.h>
+
+#include "Xlibint.h"
+#include "XlcPublic.h"
+#include "XlcPubI.h"
+
+#define XI18N_DLREL 2
+
+#define iscomment(ch) ((ch) == '\0' || (ch) == '#')
+
+typedef enum {
+ XLC_OBJECT,
+ XIM_OBJECT,
+ XOM_OBJECT
+} XI18NDLType;
+
+typedef struct {
+ XI18NDLType type;
+ int locale_name_len;
+ char *locale_name;
+ char *dl_name;
+ char *open;
+ char *im_register;
+ char *im_unregister;
+ int dl_release;
+ unsigned int refcount;
+#if defined(hpux)
+ shl_t dl_module;
+#else
+ void *dl_module;
+#endif
+} XI18NObjectsListRec, *XI18NObjectsList;
+
+#define OBJECT_INIT_LEN 8
+#define OBJECT_INC_LEN 4
+static int lc_len = 0;
+static XI18NObjectsListRec *xi18n_objects_list = NULL;
+static int lc_count = 0;
+
+static int
+parse_line(char *line, char **argv, int argsize)
+{
+ int argc = 0;
+ char *p = line;
+
+ while (argc < argsize) {
+ while (isspace(*p)) {
+ ++p;
+ }
+ if (iscomment(*p)){
+ break;
+ }
+ argv[argc++] = p;
+ while (!isspace(*p)) {
+ ++p;
+ }
+ if (iscomment(*p)) {
+ break;
+ }
+ *p++ = '\0';
+ }
+ return argc;
+}
+
+static char *
+strdup_with_underscore(const char *symbol)
+{
+ char *result;
+
+ if ((result = malloc(strlen(symbol) + 2)) == NULL)
+ return NULL;
+ result[0] = '_';
+ strcpy(result + 1, symbol);
+ return result;
+}
+
+#ifndef hpux
+static void *
+try_both_dlsym (void *handle, char *name)
+{
+ void *ret;
+
+ ret = dlsym (handle, name);
+ if (!ret)
+ {
+ name = strdup_with_underscore (name);
+ if (name)
+ {
+ ret = dlsym (handle, name);
+ free (name);
+ }
+ }
+ return ret;
+}
+#endif
+
+static void
+resolve_object(char *path, const char *lc_name)
+{
+ char filename[BUFSIZ];
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ if (lc_len == 0) { /* True only for the 1st time */
+ lc_len = OBJECT_INIT_LEN;
+ xi18n_objects_list = (XI18NObjectsList)
+ Xmalloc(sizeof(XI18NObjectsListRec) * lc_len);
+ if (!xi18n_objects_list) return;
+ }
+/*
+1266793
+Limit the length of path to prevent stack buffer corruption.
+ sprintf(filename, "%s/%s", path, "XI18N_OBJS");
+*/
+ sprintf(filename, "%.*s/%s", BUFSIZ - 12, path, "XI18N_OBJS");
+ fp = fopen(filename, "r");
+ if (fp == (FILE *)NULL){
+ return;
+ }
+
+ while (fgets(buf, BUFSIZ, fp) != NULL){
+ char *p = buf;
+ int n;
+ char *args[6];
+ while (isspace(*p)){
+ ++p;
+ }
+ if (iscomment(*p)){
+ continue;
+ }
+
+ if (lc_count == lc_len) {
+ lc_len += OBJECT_INC_LEN;
+ xi18n_objects_list = (XI18NObjectsList)
+ Xrealloc(xi18n_objects_list,
+ sizeof(XI18NObjectsListRec) * lc_len);
+ if (!xi18n_objects_list) return;
+ }
+ n = parse_line(p, args, 6);
+
+ if (n == 3 || n == 5) {
+ if (!strcmp(args[0], "XLC")){
+ xi18n_objects_list[lc_count].type = XLC_OBJECT;
+ } else if (!strcmp(args[0], "XOM")){
+ xi18n_objects_list[lc_count].type = XOM_OBJECT;
+ } else if (!strcmp(args[0], "XIM")){
+ xi18n_objects_list[lc_count].type = XIM_OBJECT;
+ }
+ xi18n_objects_list[lc_count].dl_name = strdup(args[1]);
+ xi18n_objects_list[lc_count].open = strdup(args[2]);
+ xi18n_objects_list[lc_count].dl_release = XI18N_DLREL;
+ xi18n_objects_list[lc_count].locale_name = strdup(lc_name);
+ xi18n_objects_list[lc_count].refcount = 0;
+ xi18n_objects_list[lc_count].dl_module = (void*)NULL;
+ if (n == 5) {
+ xi18n_objects_list[lc_count].im_register = strdup(args[3]);
+ xi18n_objects_list[lc_count].im_unregister = strdup(args[4]);
+ } else {
+ xi18n_objects_list[lc_count].im_register = NULL;
+ xi18n_objects_list[lc_count].im_unregister = NULL;
+ }
+ lc_count++;
+ }
+ }
+ fclose(fp);
+}
+
+static char*
+__lc_path(const char *dl_name, const char *lc_dir)
+{
+ char *path;
+ size_t len;
+
+ /*
+ * reject this for possible security issue
+ */
+ if (strstr (dl_name, "../"))
+ return NULL;
+
+ len = (lc_dir ? strlen(lc_dir) : 0 ) +
+ (dl_name ? strlen(dl_name) : 0) + 10;
+#if defined POSTLOCALELIBDIR
+ len += (strlen(POSTLOCALELIBDIR) + 1);
+#endif
+ path = Xmalloc(len + 1);
+
+ if (strchr(dl_name, '/') != NULL) {
+ char *slash_p;
+ slash_p = strrchr(lc_dir, '/');
+ *slash_p = '\0';
+ strcpy(path, lc_dir); strcat(path, "/");
+#if defined POSTLOCALELIBDIR
+ strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
+#endif
+ strcat(path, dl_name); strcat(path, ".so.2");
+ *slash_p = '/';
+ } else {
+ strcpy(path, lc_dir); strcat(path, "/");
+#if defined POSTLOCALELIBDIR
+ strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
+#endif
+ strcat(path, dl_name); strcat(path, ".so.2");
+ }
+ return path;
+}
+
+/* We reference count dlopen() and dlclose() of modules; unfortunately,
+ * since XCloseIM, XCloseOM, XlcClose aren't wrapped, but directly
+ * call the close method of the object, we leak a reference count every
+ * time we open then close a module. Fixing this would require
+ * either creating proxy objects or hooks for close_im/close_om
+ * in XLCd
+ */
+static Bool
+open_object(
+ XI18NObjectsList object,
+ char *lc_dir)
+{
+ char *path;
+
+ if (object->refcount == 0) {
+ path = __lc_path(object->dl_name, lc_dir);
+ if (!path)
+ return False;
+#if defined(hpux)
+ object->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+#else
+ object->dl_module = dlopen(path, RTLD_LAZY);
+#endif
+ Xfree(path);
+
+ if (!object->dl_module)
+ return False;
+ }
+
+ object->refcount++;
+ return True;
+}
+
+static void *
+fetch_symbol(
+ XI18NObjectsList object,
+ char *symbol)
+{
+ void *result = NULL;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+#endif
+
+ if (symbol == NULL)
+ return NULL;
+
+#if defined(hpux)
+ getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE,
+ EXPORT_SYMBOLS, malloc, &symbols);
+
+ for(i=0; i<getsyms_cnt; i++) {
+ if(!strcmp(symbols[i].name, symbol)) {
+ result = symbols[i].value;
+ break;
+ }
+ }
+
+ if(getsyms_cnt > 0) {
+ free(symbols);
+ }
+#else
+ result = try_both_dlsym(object->dl_module, symbol);
+#endif
+
+ return result;
+}
+
+static void
+close_object(XI18NObjectsList object)
+{
+ object->refcount--;
+ if (object->refcount == 0)
+ {
+#if defined(hpux)
+ shl_unload(object->dl_module);
+#else
+ dlclose(object->dl_module);
+#endif
+ object->dl_module = NULL;
+ }
+}
+
+
+typedef XLCd (*dynamicLoadProc)(const char *);
+
+XLCd
+_XlcDynamicLoad(const char *lc_name)
+{
+ XLCd lcd = (XLCd)NULL;
+ dynamicLoadProc lc_loader = (dynamicLoadProc)NULL;
+ int count;
+ XI18NObjectsList objects_list;
+ char lc_dir[BUFSIZE], lc_lib_dir[BUFSIZE];
+
+ if (lc_name == NULL) return (XLCd)NULL;
+
+ if (_XlcLocaleDirName(lc_dir, BUFSIZE, (char *)lc_name) == (char *)NULL)
+ return (XLCd)NULL;
+ if (_XlcLocaleLibDirName(lc_lib_dir, BUFSIZE, (char *)lc_name) == (char*)NULL)
+ return (XLCd)NULL;
+
+ resolve_object(lc_dir, lc_name);
+ resolve_object(lc_lib_dir, lc_name);
+
+ objects_list = xi18n_objects_list;
+ count = lc_count;
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XLC_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+ if (!open_object (objects_list, lc_dir) && \
+ !open_object (objects_list, lc_lib_dir))
+ continue;
+
+ lc_loader = (dynamicLoadProc)fetch_symbol (objects_list, objects_list->open);
+ if (!lc_loader) continue;
+ lcd = (*lc_loader)(lc_name);
+ if (lcd != (XLCd)NULL) {
+ break;
+ }
+
+ close_object (objects_list);
+ }
+ return (XLCd)lcd;
+}
+
+
+typedef XIM (*dynamicOpenProcp)(XLCd, Display *, XrmDatabase, char *, char *);
+
+static XIM
+_XDynamicOpenIM(XLCd lcd, Display *display, XrmDatabase rdb,
+ char *res_name, char *res_class)
+{
+ XIM im = (XIM)NULL;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ dynamicOpenProcp im_openIM = (dynamicOpenProcp)NULL;
+ int count;
+ XI18NObjectsList objects_list = xi18n_objects_list;
+
+ lc_name = lcd->core->name;
+
+ if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return (XIM)0;
+
+ count = lc_count;
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+
+ if (!open_object (objects_list, lc_dir))
+ continue;
+
+ im_openIM = (dynamicOpenProcp)fetch_symbol(objects_list, objects_list->open);
+ if (!im_openIM) continue;
+ im = (*im_openIM)(lcd, display, rdb, res_name, res_class);
+ if (im != (XIM)NULL) {
+ break;
+ }
+
+ close_object (objects_list);
+ }
+ return (XIM)im;
+}
+
+typedef Bool (*dynamicRegisterCBProcp)(
+ XLCd, Display *, XrmDatabase, char *, char *, XIDProc, XPointer);
+
+static Bool
+_XDynamicRegisterIMInstantiateCallback(
+ XLCd lcd,
+ Display *display,
+ XrmDatabase rdb,
+ char *res_name,
+ char *res_class,
+ XIDProc callback,
+ XPointer client_data)
+{
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ dynamicRegisterCBProcp im_registerIM = (dynamicRegisterCBProcp)NULL;
+ Bool ret_flag = False;
+ int count;
+ XI18NObjectsList objects_list = xi18n_objects_list;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+#endif
+
+ lc_name = lcd->core->name;
+
+ if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return False;
+
+ count = lc_count;
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+
+ if (!open_object (objects_list, lc_dir))
+ continue;
+ im_registerIM = (dynamicRegisterCBProcp)fetch_symbol(objects_list,
+ objects_list->im_register);
+ if (!im_registerIM) continue;
+ ret_flag = (*im_registerIM)(lcd, display, rdb,
+ res_name, res_class,
+ callback, client_data);
+ if (ret_flag) break;
+
+ close_object (objects_list);
+ }
+ return (Bool)ret_flag;
+}
+
+typedef Bool (*dynamicUnregisterProcp)(
+ XLCd, Display *, XrmDatabase, char *, char *, XIDProc, XPointer);
+
+static Bool
+_XDynamicUnRegisterIMInstantiateCallback(
+ XLCd lcd,
+ Display *display,
+ XrmDatabase rdb,
+ char *res_name,
+ char *res_class,
+ XIDProc callback,
+ XPointer client_data)
+{
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ dynamicUnregisterProcp im_unregisterIM = (dynamicUnregisterProcp)NULL;
+ Bool ret_flag = False;
+ int count;
+ XI18NObjectsList objects_list = xi18n_objects_list;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+#endif
+
+ lc_name = lcd->core->name;
+ if (_XlcLocaleDirName(lc_dir, BUFSIZE, lc_name) == NULL) return False;
+
+ count = lc_count;
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+
+ if (!objects_list->refcount) /* Must already be opened */
+ continue;
+
+ im_unregisterIM = (dynamicUnregisterProcp)fetch_symbol(objects_list,
+ objects_list->im_unregister);
+
+ if (!im_unregisterIM) continue;
+ ret_flag = (*im_unregisterIM)(lcd, display, rdb,
+ res_name, res_class,
+ callback, client_data);
+ if (ret_flag) {
+ close_object (objects_list); /* opened in RegisterIMInstantiateCallback */
+ break;
+ }
+ }
+ return (Bool)ret_flag;
+}
+
+Bool
+_XInitDynamicIM(XLCd lcd)
+{
+ if(lcd == (XLCd)NULL)
+ return False;
+ lcd->methods->open_im = _XDynamicOpenIM;
+ lcd->methods->register_callback = _XDynamicRegisterIMInstantiateCallback;
+ lcd->methods->unregister_callback = _XDynamicUnRegisterIMInstantiateCallback;
+ return True;
+}
+
+
+typedef XOM (*dynamicIOpenProcp)(
+ XLCd, Display *, XrmDatabase, _Xconst char *, _Xconst char *);
+
+static XOM
+_XDynamicOpenOM(XLCd lcd, Display *display, XrmDatabase rdb,
+ _Xconst char *res_name, _Xconst char *res_class)
+{
+ XOM om = (XOM)NULL;
+ int count;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ dynamicIOpenProcp om_openOM = (dynamicIOpenProcp)NULL;
+ XI18NObjectsList objects_list = xi18n_objects_list;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+#endif
+
+ lc_name = lcd->core->name;
+
+ if (_XlcLocaleLibDirName(lc_dir, BUFSIZE, lc_name) == NULL) return (XOM)0;
+
+ count = lc_count;
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XOM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+ if (!open_object (objects_list, lc_dir))
+ continue;
+
+ om_openOM = (dynamicIOpenProcp)fetch_symbol(objects_list, objects_list->open);
+ if (!om_openOM) continue;
+ om = (*om_openOM)(lcd, display, rdb, res_name, res_class);
+ if (om != (XOM)NULL) {
+ break;
+ }
+ close_object(objects_list);
+ }
+ return (XOM)om;
+}
+
+Bool
+_XInitDynamicOM(XLCd lcd)
+{
+ if(lcd == (XLCd)NULL)
+ return False;
+
+ lcd->methods->open_om = _XDynamicOpenOM;
+
+ return True;
+}
diff --git a/libX11/src/xlibi18n/lcCharSet.c b/libX11/src/xlibi18n/lcCharSet.c index 5d287811c..6be5f5d16 100644 --- a/libX11/src/xlibi18n/lcCharSet.c +++ b/libX11/src/xlibi18n/lcCharSet.c @@ -1,225 +1,225 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include "Xlibint.h" -#include "XlcPublic.h" -#include "XlcPubI.h" - -/* The list of all known XlcCharSets. They are identified by their name. */ - -typedef struct _XlcCharSetListRec { - XlcCharSet charset; - struct _XlcCharSetListRec *next; -} XlcCharSetListRec, *XlcCharSetList; - -static XlcCharSetList charset_list = NULL; - -/* Returns the charset with the given name (including side suffix). - Returns NULL if not found. */ -XlcCharSet -_XlcGetCharSet( - const char *name) -{ - XlcCharSetList list; - XrmQuark xrm_name; - - xrm_name = XrmStringToQuark(name); - - for (list = charset_list; list; list = list->next) { - if (xrm_name == list->charset->xrm_name) - return (XlcCharSet) list->charset; - } - - return (XlcCharSet) NULL; -} - -/* Returns the charset with the given encoding (no side suffix) and - responsible for at least the given side (XlcGL or XlcGR). - Returns NULL if not found. */ -XlcCharSet -_XlcGetCharSetWithSide( - const char *encoding_name, - XlcSide side) -{ - XlcCharSetList list; - XrmQuark xrm_encoding_name; - - xrm_encoding_name = XrmStringToQuark(encoding_name); - - for (list = charset_list; list; list = list->next) { - if (list->charset->xrm_encoding_name == xrm_encoding_name - && (list->charset->side == XlcGLGR || list->charset->side == side)) - return (XlcCharSet) list->charset; - } - - return (XlcCharSet) NULL; -} - -/* Registers an XlcCharSet in the list of character sets. - Returns True if successful. */ -Bool -_XlcAddCharSet( - XlcCharSet charset) -{ - XlcCharSetList list; - - if (_XlcGetCharSet(charset->name)) - return False; - - list = (XlcCharSetList) Xmalloc(sizeof(XlcCharSetListRec)); - if (list == NULL) - return False; - - list->charset = charset; - list->next = charset_list; - charset_list = list; - - return True; -} - -/* List of resources for XlcCharSet. */ -static XlcResource resources[] = { - { XlcNName, NULLQUARK, sizeof(char *), - XOffsetOf(XlcCharSetRec, name), XlcGetMask }, - { XlcNEncodingName, NULLQUARK, sizeof(char *), - XOffsetOf(XlcCharSetRec, encoding_name), XlcGetMask }, - { XlcNSide, NULLQUARK, sizeof(XlcSide), - XOffsetOf(XlcCharSetRec, side), XlcGetMask }, - { XlcNCharSize, NULLQUARK, sizeof(int), - XOffsetOf(XlcCharSetRec, char_size), XlcGetMask }, - { XlcNSetSize, NULLQUARK, sizeof(int), - XOffsetOf(XlcCharSetRec, set_size), XlcGetMask }, - { XlcNControlSequence, NULLQUARK, sizeof(char *), - XOffsetOf(XlcCharSetRec, ct_sequence), XlcGetMask } -}; - -/* Retrieves a number of attributes of an XlcCharSet. - Return NULL if successful, otherwise the name of the first argument - specifiying a nonexistent attribute. */ -static char * -get_values( - XlcCharSet charset, - XlcArgList args, - int num_args) -{ - if (resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(resources, XlcNumber(resources)); - - return _XlcGetValues((XPointer) charset, resources, XlcNumber(resources), - args, num_args, XlcGetMask); -} - -/* Retrieves a number of attributes of an XlcCharSet. - Return NULL if successful, otherwise the name of the first argument - specifiying a nonexistent attribute. */ -char * -_XlcGetCSValues(XlcCharSet charset, ...) -{ - va_list var; - XlcArgList args; - char *ret; - int num_args; - - va_start(var, charset); - _XlcCountVaList(var, &num_args); - va_end(var); - - va_start(var, charset); - _XlcVaToArgList(var, num_args, &args); - va_end(var); - - if (args == (XlcArgList) NULL) - return (char *) NULL; - - ret = get_values(charset, args, num_args); - - Xfree(args); - - return ret; -} - -/* Creates a new XlcCharSet, given its name (including side suffix) and - Compound Text ESC sequence (normally at most 4 bytes). */ -XlcCharSet -_XlcCreateDefaultCharSet( - const char *name, - const char *ct_sequence) -{ - XlcCharSet charset; - int name_len, ct_sequence_len; - const char *colon; - char *tmp; - - charset = Xcalloc(1, sizeof(XlcCharSetRec)); - if (charset == NULL) - return (XlcCharSet) NULL; - - name_len = strlen(name); - ct_sequence_len = strlen(ct_sequence); - - /* Fill in name and xrm_name. */ - tmp = (char *) Xmalloc(name_len + 1 + ct_sequence_len + 1); - if (tmp == NULL) { - Xfree((char *) charset); - return (XlcCharSet) NULL; - } - memcpy(tmp, name, name_len+1); - charset->name = tmp; - charset->xrm_name = XrmStringToQuark(charset->name); - - /* Fill in encoding_name and xrm_encoding_name. */ - if ((colon = strchr(charset->name, ':')) != NULL) { - unsigned int length = colon - charset->name; - char *encoding_tmp = (char *) Xmalloc(length + 1); - if (encoding_tmp == NULL) { - Xfree((char *) charset->name); - Xfree((char *) charset); - return (XlcCharSet) NULL; - } - memcpy(encoding_tmp, charset->name, length); - encoding_tmp[length] = '\0'; - charset->encoding_name = encoding_tmp; - charset->xrm_encoding_name = XrmStringToQuark(charset->encoding_name); - } else { - charset->encoding_name = charset->name; - charset->xrm_encoding_name = charset->xrm_name; - } - - /* Fill in ct_sequence. */ - tmp += name_len + 1; - memcpy(tmp, ct_sequence, ct_sequence_len+1); - charset->ct_sequence = tmp; - - /* Fill in side, char_size, set_size. */ - if (!_XlcParseCharSet(charset)) - /* If ct_sequence is not usable in Compound Text, remove it. */ - charset->ct_sequence = ""; - - return (XlcCharSet) charset; -} +/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include "Xlibint.h"
+#include "XlcPublic.h"
+#include "XlcPubI.h"
+
+/* The list of all known XlcCharSets. They are identified by their name. */
+
+typedef struct _XlcCharSetListRec {
+ XlcCharSet charset;
+ struct _XlcCharSetListRec *next;
+} XlcCharSetListRec, *XlcCharSetList;
+
+static XlcCharSetList charset_list = NULL;
+
+/* Returns the charset with the given name (including side suffix).
+ Returns NULL if not found. */
+XlcCharSet
+_XlcGetCharSet(
+ const char *name)
+{
+ XlcCharSetList list;
+ XrmQuark xrm_name;
+
+ xrm_name = XrmStringToQuark(name);
+
+ for (list = charset_list; list; list = list->next) {
+ if (xrm_name == list->charset->xrm_name)
+ return (XlcCharSet) list->charset;
+ }
+
+ return (XlcCharSet) NULL;
+}
+
+/* Returns the charset with the given encoding (no side suffix) and
+ responsible for at least the given side (XlcGL or XlcGR).
+ Returns NULL if not found. */
+XlcCharSet
+_XlcGetCharSetWithSide(
+ const char *encoding_name,
+ XlcSide side)
+{
+ XlcCharSetList list;
+ XrmQuark xrm_encoding_name;
+
+ xrm_encoding_name = XrmStringToQuark(encoding_name);
+
+ for (list = charset_list; list; list = list->next) {
+ if (list->charset->xrm_encoding_name == xrm_encoding_name
+ && (list->charset->side == XlcGLGR || list->charset->side == side))
+ return (XlcCharSet) list->charset;
+ }
+
+ return (XlcCharSet) NULL;
+}
+
+/* Registers an XlcCharSet in the list of character sets.
+ Returns True if successful. */
+Bool
+_XlcAddCharSet(
+ XlcCharSet charset)
+{
+ XlcCharSetList list;
+
+ if (_XlcGetCharSet(charset->name))
+ return False;
+
+ list = (XlcCharSetList) Xmalloc(sizeof(XlcCharSetListRec));
+ if (list == NULL)
+ return False;
+
+ list->charset = charset;
+ list->next = charset_list;
+ charset_list = list;
+
+ return True;
+}
+
+/* List of resources for XlcCharSet. */
+static XlcResource resources[] = {
+ { XlcNName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XlcCharSetRec, name), XlcGetMask },
+ { XlcNEncodingName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XlcCharSetRec, encoding_name), XlcGetMask },
+ { XlcNSide, NULLQUARK, sizeof(XlcSide),
+ XOffsetOf(XlcCharSetRec, side), XlcGetMask },
+ { XlcNCharSize, NULLQUARK, sizeof(int),
+ XOffsetOf(XlcCharSetRec, char_size), XlcGetMask },
+ { XlcNSetSize, NULLQUARK, sizeof(int),
+ XOffsetOf(XlcCharSetRec, set_size), XlcGetMask },
+ { XlcNControlSequence, NULLQUARK, sizeof(char *),
+ XOffsetOf(XlcCharSetRec, ct_sequence), XlcGetMask }
+};
+
+/* Retrieves a number of attributes of an XlcCharSet.
+ Return NULL if successful, otherwise the name of the first argument
+ specifiying a nonexistent attribute. */
+static char *
+get_values(
+ XlcCharSet charset,
+ XlcArgList args,
+ int num_args)
+{
+ if (resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(resources, XlcNumber(resources));
+
+ return _XlcGetValues((XPointer) charset, resources, XlcNumber(resources),
+ args, num_args, XlcGetMask);
+}
+
+/* Retrieves a number of attributes of an XlcCharSet.
+ Return NULL if successful, otherwise the name of the first argument
+ specifiying a nonexistent attribute. */
+char *
+_XlcGetCSValues(XlcCharSet charset, ...)
+{
+ va_list var;
+ XlcArgList args;
+ char *ret;
+ int num_args;
+
+ va_start(var, charset);
+ _XlcCountVaList(var, &num_args);
+ va_end(var);
+
+ va_start(var, charset);
+ _XlcVaToArgList(var, num_args, &args);
+ va_end(var);
+
+ if (args == (XlcArgList) NULL)
+ return (char *) NULL;
+
+ ret = get_values(charset, args, num_args);
+
+ Xfree(args);
+
+ return ret;
+}
+
+/* Creates a new XlcCharSet, given its name (including side suffix) and
+ Compound Text ESC sequence (normally at most 4 bytes). */
+XlcCharSet
+_XlcCreateDefaultCharSet(
+ const char *name,
+ const char *ct_sequence)
+{
+ XlcCharSet charset;
+ int name_len, ct_sequence_len;
+ const char *colon;
+ char *tmp;
+
+ charset = Xcalloc(1, sizeof(XlcCharSetRec));
+ if (charset == NULL)
+ return (XlcCharSet) NULL;
+
+ name_len = strlen(name);
+ ct_sequence_len = strlen(ct_sequence);
+
+ /* Fill in name and xrm_name. */
+ tmp = (char *) Xmalloc(name_len + 1 + ct_sequence_len + 1);
+ if (tmp == NULL) {
+ Xfree((char *) charset);
+ return (XlcCharSet) NULL;
+ }
+ memcpy(tmp, name, name_len+1);
+ charset->name = tmp;
+ charset->xrm_name = XrmStringToQuark(charset->name);
+
+ /* Fill in encoding_name and xrm_encoding_name. */
+ if ((colon = strchr(charset->name, ':')) != NULL) {
+ unsigned int length = colon - charset->name;
+ char *encoding_tmp = (char *) Xmalloc(length + 1);
+ if (encoding_tmp == NULL) {
+ Xfree((char *) charset->name);
+ Xfree((char *) charset);
+ return (XlcCharSet) NULL;
+ }
+ memcpy(encoding_tmp, charset->name, length);
+ encoding_tmp[length] = '\0';
+ charset->encoding_name = encoding_tmp;
+ charset->xrm_encoding_name = XrmStringToQuark(charset->encoding_name);
+ } else {
+ charset->encoding_name = charset->name;
+ charset->xrm_encoding_name = charset->xrm_name;
+ }
+
+ /* Fill in ct_sequence. */
+ tmp += name_len + 1;
+ memcpy(tmp, ct_sequence, ct_sequence_len+1);
+ charset->ct_sequence = tmp;
+
+ /* Fill in side, char_size, set_size. */
+ if (!_XlcParseCharSet(charset))
+ /* If ct_sequence is not usable in Compound Text, remove it. */
+ charset->ct_sequence = "";
+
+ return (XlcCharSet) charset;
+}
diff --git a/libX11/src/xlibi18n/lcDB.c b/libX11/src/xlibi18n/lcDB.c index 97b22ac44..7d3ba88c5 100644 --- a/libX11/src/xlibi18n/lcDB.c +++ b/libX11/src/xlibi18n/lcDB.c @@ -1,1339 +1,1342 @@ -/* - * - * Copyright IBM Corporation 1993 - * - * All Rights Reserved - * - * License to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * 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 IBM not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL - * IBM 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. - * -*/ -/* - * (c) Copyright 1995 FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - */ - - - -#ifndef NOT_X_ENV - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/Xlib.h> -#include <X11/Xresource.h> -#include "Xlibint.h" -#include "XlcPubI.h" - -#else /* NOT_X_ENV */ - -#define Xmalloc malloc -#define Xrealloc realloc -#define Xfree free - -#endif /* NOT_X_ENV */ - -/* specifying NOT_X_ENV allows users to just use - the database parsing routine. */ -/* For UDC/VW */ -#ifndef BUFSIZE -#define BUFSIZE 2048 -#endif - -#ifdef COMMENT -#ifdef BUFSIZE -#undef BUFSIZE -#endif -#define BUFSIZE 6144 /* 2048*3 */ -#endif - -#include <stdio.h> - -typedef struct _DatabaseRec { - char *category; - char *name; - char **value; - int value_num; - struct _DatabaseRec *next; -} DatabaseRec, *Database; - -typedef enum { - S_NULL, /* outside category */ - S_CATEGORY, /* inside category */ - S_NAME, /* has name, expecting values */ - S_VALUE -} ParseState; - -typedef enum { - T_NEWLINE, - T_COMMENT, - T_SEMICOLON, - T_DOUBLE_QUOTE, - T_LEFT_BRACE, - T_RIGHT_BRACE, - T_SPACE, - T_TAB, - T_BACKSLASH, - T_NUMERIC_HEX, - T_NUMERIC_DEC, - T_NUMERIC_OCT, - T_DEFAULT -} Token; - -typedef struct { - Token token; /* token id */ - int len; /* length of token sequence */ -} TokenTable; - -static int f_newline (const char *str, Token token, Database *db); -static int f_comment (const char *str, Token token, Database *db); -static int f_semicolon (const char *str, Token token, Database *db); -static int f_double_quote (const char *str, Token token, Database *db); -static int f_left_brace (const char *str, Token token, Database *db); -static int f_right_brace (const char *str, Token token, Database *db); -static int f_white (const char *str, Token token, Database *db); -static int f_backslash (const char *str, Token token, Database *db); -static int f_numeric (const char *str, Token token, Database *db); -static int f_default (const char *str, Token token, Database *db); - -static const TokenTable token_tbl[] = { - { T_NEWLINE, 1 }, - { T_COMMENT, 1 }, - { T_SEMICOLON, 1 }, - { T_DOUBLE_QUOTE, 1 }, - { T_LEFT_BRACE, 1 }, - { T_RIGHT_BRACE, 1 }, - { T_SPACE, 1 }, - { T_TAB, 1 }, - { T_BACKSLASH, 1 }, - { T_NUMERIC_HEX, 2 }, - { T_NUMERIC_DEC, 2 }, - { T_NUMERIC_OCT, 2 }, - { T_DEFAULT, 1 } /* any character */ -}; - -#define SYM_CR '\r' -#define SYM_NEWLINE '\n' -#define SYM_COMMENT '#' -#define SYM_SEMICOLON ';' -#define SYM_DOUBLE_QUOTE '"' -#define SYM_LEFT_BRACE '{' -#define SYM_RIGHT_BRACE '}' -#define SYM_SPACE ' ' -#define SYM_TAB '\t' -#define SYM_BACKSLASH '\\' - -/************************************************************************/ - -#define MAX_NAME_NEST 64 - -typedef struct { - ParseState pre_state; - char *category; - char *name[MAX_NAME_NEST]; - int nest_depth; - char **value; - int value_len; - int value_num; - int bufsize; /* bufMaxSize >= bufsize >= 0 */ - int bufMaxSize; /* default : BUFSIZE */ - char *buf; -} DBParseInfo; - -static DBParseInfo parse_info; - -static void -init_parse_info (void) -{ - static int allocated /* = 0 */; - char *ptr; - int size; - if (!allocated) { - bzero(&parse_info, sizeof(DBParseInfo)); - parse_info.buf = (char *)Xmalloc(BUFSIZE); - parse_info.bufMaxSize = BUFSIZE; - allocated = 1; - return; - } - ptr = parse_info.buf; - size = parse_info.bufMaxSize; - bzero(&parse_info, sizeof(DBParseInfo)); - parse_info.buf = ptr; - parse_info.bufMaxSize = size; -} - -static void -clear_parse_info (void) -{ - int i; - char *ptr; - int size; - parse_info.pre_state = S_NULL; - if (parse_info.category != NULL) { - Xfree(parse_info.category); - } - for (i = 0; i <= parse_info.nest_depth; ++i) { - if (parse_info.name[i]) { - Xfree(parse_info.name[i]); - } - } - if (parse_info.value) { - if (*parse_info.value) { - Xfree(*parse_info.value); - } - Xfree((char *)parse_info.value); - } - ptr = parse_info.buf; - size = parse_info.bufMaxSize; - bzero(&parse_info, sizeof(DBParseInfo)); - parse_info.buf = ptr; - parse_info.bufMaxSize = size; -} - -static Bool -realloc_parse_info( - int len) -{ - char *p; - - parse_info.bufMaxSize = BUFSIZE * ((parse_info.bufsize + len)/BUFSIZE + 1); - p = (char *)Xrealloc(parse_info.buf, parse_info.bufMaxSize); - if (p == NULL) - return False; - parse_info.buf = p; - - return True; -} - -/************************************************************************/ - -typedef struct _Line { - char *str; - int cursize; - int maxsize; - int seq; -} Line; - -static void -free_line( - Line *line) -{ - if (line->str != NULL) { - Xfree(line->str); - } - bzero(line, sizeof(Line)); -} - -static int -realloc_line( - Line *line, - int size) -{ - char *str = line->str; - - if (str != NULL) { - str = (char *)Xrealloc(str, size); - } else { - str = (char *)Xmalloc(size); - } - if (str == NULL) { - /* malloc error */ - if (line->str != NULL) { - Xfree(line->str); - } - bzero(line, sizeof(Line)); - return 0; - } - line->str = str; - line->maxsize = size; - return 1; -} - -#define iswhite(ch) ((ch) == SYM_SPACE || (ch) == SYM_TAB) - -static void -zap_comment( - char *str, - int *quoted) -{ - char *p = str; -#ifdef never - *quoted = 0; - if (*p == SYM_COMMENT) { - int len = strlen(str); - if (p[len - 1] == SYM_NEWLINE || p[len - 1] == SYM_CR) { - *p++ = SYM_NEWLINE; - } - *p = '\0'; - } -#else - while (*p) { - if (*p == SYM_DOUBLE_QUOTE) { - if (p == str || p[-1] != SYM_BACKSLASH) { - /* unescaped double quote changes quoted state. */ - *quoted = *quoted ? 0 : 1; - } - } - if (*p == SYM_COMMENT && !*quoted) { - int pos = p - str; - if (pos == 0 || - (iswhite(p[-1]) && (pos == 1 || p[-2] != SYM_BACKSLASH))) { - int len = strlen(p); - if (len > 0 && (p[len - 1] == SYM_NEWLINE || p[len-1] == SYM_CR)) { - /* newline is the identifier for finding end of value. - therefore, it should not be removed. */ - *p++ = SYM_NEWLINE; - } - *p = '\0'; - break; - } - } - ++p; - } -#endif -} - -static int -read_line( - FILE *fd, - Line *line) -{ - char buf[BUFSIZE], *p; - int len; - int quoted = 0; /* quoted by double quote? */ - char *str; - int cur; - - str = line->str; - cur = line->cursize = 0; - - while ((p = fgets(buf, BUFSIZE, fd)) != NULL) { - ++line->seq; - zap_comment(p, "ed); /* remove comment line */ - len = strlen(p); - if (len == 0) { - if (cur > 0) { - break; - } - continue; - } - if (cur + len + 1 > line->maxsize) { - /* need to reallocate buffer. */ - if (! realloc_line(line, line->maxsize + BUFSIZE)) { - return -1; /* realloc error. */ - } - str = line->str; - } - strncpy(str + cur, p, len); - - cur += len; - str[cur] = '\0'; -#ifdef __UNIXOS2__ /* Take out carriage returns under OS/2 */ - if (cur>1) { - if (str[cur-2] == '\r' && str[cur-1] == '\n') { - str[cur-2] = '\n'; - str[cur-1] = '\0'; - cur--; - } - } -#endif - if (!quoted && cur > 1 && str[cur - 2] == SYM_BACKSLASH && - (str[cur - 1] == SYM_NEWLINE || str[cur-1] == SYM_CR)) { - /* the line is ended backslash followed by newline. - need to concatinate the next line. */ - cur -= 2; - str[cur] = '\0'; - } else if (len < BUFSIZE - 1 || buf[len - 1] == SYM_NEWLINE || - buf[len - 1] == SYM_CR) { - /* the line is shorter than BUFSIZE. */ - break; - } - } - if (quoted) { - /* error. still in quoted state. */ - return -1; - } - return line->cursize = cur; -} - -/************************************************************************/ - -static Token -get_token( - const char *str) -{ - switch (*str) { - case SYM_NEWLINE: - case SYM_CR: return T_NEWLINE; - case SYM_COMMENT: return T_COMMENT; - case SYM_SEMICOLON: return T_SEMICOLON; - case SYM_DOUBLE_QUOTE: return T_DOUBLE_QUOTE; - case SYM_LEFT_BRACE: return T_LEFT_BRACE; - case SYM_RIGHT_BRACE: return T_RIGHT_BRACE; - case SYM_SPACE: return T_SPACE; - case SYM_TAB: return T_TAB; - case SYM_BACKSLASH: - switch (str[1]) { - case 'x': return T_NUMERIC_HEX; - case 'd': return T_NUMERIC_DEC; - case 'o': return T_NUMERIC_OCT; - } - return T_BACKSLASH; - default: - return T_DEFAULT; - } -} - -static int -get_word( - const char *str, - char *word) -{ - const char *p = str; - char *w = word; - Token token; - int token_len; - - while (*p != '\0') { - token = get_token(p); - token_len = token_tbl[token].len; - if (token == T_BACKSLASH) { - p += token_len; - if (*p == '\0') - break; - token = get_token(p); - token_len = token_tbl[token].len; - } else if (token != T_COMMENT && token != T_DEFAULT) { - break; - } - strncpy(w, p, token_len); - p += token_len; w += token_len; - } - *w = '\0'; - return p - str; /* return number of scanned chars */ -} - -static int -get_quoted_word( - const char *str, - char *word) -{ - const char *p = str; - char *w = word; - Token token; - int token_len; - - if (*p == SYM_DOUBLE_QUOTE) { - ++p; - } - while (*p != '\0') { - token = get_token(p); - token_len = token_tbl[token].len; - if (token == T_DOUBLE_QUOTE) { - p += token_len; - goto found; - } - if (token == T_BACKSLASH) { - p += token_len; - if (*p == '\0') { - break; - } - token = get_token(p); - token_len = token_tbl[token].len; - } - strncpy(w, p, token_len); - p += token_len; w += token_len; - } - /* error. cannot detect next double quote */ - return 0; - - found:; - *w = '\0'; - return p - str; -} - -/************************************************************************/ - -static int -append_value_list (void) -{ - char **value_list = parse_info.value; - char *value; - int value_num = parse_info.value_num; - int value_len = parse_info.value_len; - char *str = parse_info.buf; - int len = parse_info.bufsize; - char *p; - - if (len < 1) { - return 1; /* return with no error */ - } - - if (value_list == (char **)NULL) { - value_list = (char **)Xmalloc(sizeof(char *) * 2); - *value_list = NULL; - } else { - char **prev_list = value_list; - - value_list = (char **) - Xrealloc(value_list, sizeof(char *) * (value_num + 2)); - if (value_list == NULL) { - Xfree(prev_list); - } - } - if (value_list == (char **)NULL) - goto err2; - - value = *value_list; - if (value == NULL) { - value = (char *)Xmalloc(value_len + len + 1); - } else { - char *prev_value = value; - - value = (char *)Xrealloc(value, value_len + len + 1); - if (value == NULL) { - Xfree(prev_value); - } - } - if (value == NULL) { - goto err1; - } - if (value != *value_list) { - int i; - ssize_t delta; - delta = value - *value_list; - *value_list = value; - for (i = 1; i < value_num; ++i) { - value_list[i] += delta; - } - } - - value_list[value_num] = p = &value[value_len]; - value_list[value_num + 1] = NULL; - strncpy(p, str, len); - p[len] = 0; - - parse_info.value = value_list; - parse_info.value_num = value_num + 1; - parse_info.value_len = value_len + len + 1; - parse_info.bufsize = 0; - return 1; - - err1: - if (value_list) { - Xfree((char **)value_list); - } - if (value) { - Xfree(value); - } - err2: - parse_info.value = (char **)NULL; - parse_info.value_num = 0; - parse_info.value_len = 0; - parse_info.bufsize = 0; - return 0; -} - -static int -construct_name( - char *name, - int size) -{ - int i; - int len = 0; - char *p = name; - - for (i = 0; i <= parse_info.nest_depth; ++i) { - len += strlen(parse_info.name[i]) + 1; - } - if (len >= size) - return 0; - - strcpy(p, parse_info.name[0]); - p += strlen(parse_info.name[0]); - for (i = 1; i <= parse_info.nest_depth; ++i) { - *p++ = '.'; - strcpy(p, parse_info.name[i]); - p += strlen(parse_info.name[i]); - } - return *name != '\0'; -} - -static int -store_to_database( - Database *db) -{ - Database new = (Database)NULL; - char name[BUFSIZE]; - - if (parse_info.pre_state == S_VALUE) { - if (! append_value_list()) { - goto err; - } - } - - if (parse_info.name[parse_info.nest_depth] == NULL) { - goto err; - } - - new = Xcalloc(1, sizeof(DatabaseRec)); - if (new == (Database)NULL) { - goto err; - } - - new->category = strdup(parse_info.category); - if (new->category == NULL) { - goto err; - } - - if (! construct_name(name, sizeof(name))) { - goto err; - } - new->name = strdup(name); - if (new->name == NULL) { - goto err; - } - new->next = *db; - new->value = parse_info.value; - new->value_num = parse_info.value_num; - *db = new; - - Xfree(parse_info.name[parse_info.nest_depth]); - parse_info.name[parse_info.nest_depth] = NULL; - - parse_info.value = (char **)NULL; - parse_info.value_num = 0; - parse_info.value_len = 0; - - return 1; - - err: - if (new) { - if (new->category) { - Xfree(new->category); - } - if (new->name) { - Xfree(new->name); - } - Xfree(new); - } - if (parse_info.value) { - if (*parse_info.value) { - Xfree(*parse_info.value); - } - Xfree((char **)parse_info.value); - parse_info.value = (char **)NULL; - parse_info.value_num = 0; - parse_info.value_len = 0; - } - return 0; -} - -#define END_MARK "END" -#define END_MARK_LEN 3 /*strlen(END_MARK)*/ - -static int -check_category_end( - const char *str) -{ - const char *p; - int len; - - p = str; - if (strncmp(p, END_MARK, END_MARK_LEN)) { - return 0; - } - p += END_MARK_LEN; - - while (iswhite(*p)) { - ++p; - } - len = strlen(parse_info.category); - if (strncmp(p, parse_info.category, len)) { - return 0; - } - p += len; - return p - str; -} - -/************************************************************************/ - -static int -f_newline( - const char *str, - Token token, - Database *db) -{ - switch (parse_info.pre_state) { - case S_NULL: - case S_CATEGORY: - break; - case S_NAME: - return 0; /* no value */ - case S_VALUE: - if (!store_to_database(db)) - return 0; - parse_info.pre_state = S_CATEGORY; - break; - default: - return 0; - } - return token_tbl[token].len; -} - -static int -f_comment( - const char *str, - Token token, - Database *db) -{ - /* NOTE: comment is already handled in read_line(), - so this function is not necessary. */ - - const char *p = str; - - while (*p != SYM_NEWLINE && *p != SYM_CR && *p != '\0') { - ++p; /* zap to the end of line */ - } - return p - str; -} - -static int -f_white( - const char *str, - Token token, - Database *db) -{ - const char *p = str; - - while (iswhite(*p)) { - ++p; - } - return p - str; -} - -static int -f_semicolon( - const char *str, - Token token, - Database *db) -{ - switch (parse_info.pre_state) { - case S_NULL: - case S_CATEGORY: - case S_NAME: - return 0; - case S_VALUE: - if (! append_value_list()) - return 0; - parse_info.pre_state = S_VALUE; - break; - default: - return 0; - } - return token_tbl[token].len; -} - -static int -f_left_brace( - const char *str, - Token token, - Database *db) -{ - switch (parse_info.pre_state) { - case S_NULL: - case S_CATEGORY: - case S_VALUE: - return 0; - case S_NAME: - if (parse_info.name[parse_info.nest_depth] == NULL - || parse_info.nest_depth + 1 > MAX_NAME_NEST) - return 0; - ++parse_info.nest_depth; - parse_info.pre_state = S_CATEGORY; - break; - default: - return 0; - } - return token_tbl[token].len; -} - -static int -f_right_brace( - const char *str, - Token token, - Database *db) -{ - if (parse_info.nest_depth < 1) - return 0; - - switch (parse_info.pre_state) { - case S_NULL: - case S_NAME: - return 0; - case S_VALUE: - if (! store_to_database(db)) - return 0; - /* fall into next case */ - case S_CATEGORY: - if (parse_info.name[parse_info.nest_depth] != NULL) { - Xfree(parse_info.name[parse_info.nest_depth]); - parse_info.name[parse_info.nest_depth] = NULL; - } - --parse_info.nest_depth; - parse_info.pre_state = S_CATEGORY; - break; - default: - return 0; - } - return token_tbl[token].len; -} - -static int -f_double_quote( - const char *str, - Token token, - Database *db) -{ - char word[BUFSIZE]; - char* wordp; - int len; - - if ((len = strlen (str)) < sizeof word) - wordp = word; - else - wordp = Xmalloc (len + 1); - if (wordp == NULL) - return 0; - - len = 0; - switch (parse_info.pre_state) { - case S_NULL: - case S_CATEGORY: - goto err; - case S_NAME: - case S_VALUE: - len = get_quoted_word(str, wordp); - if (len < 1) - goto err; - if ((parse_info.bufsize + (int)strlen(wordp) + 1) - >= parse_info.bufMaxSize) { - if (realloc_parse_info(strlen(wordp)+1) == False) { - goto err; - } - } - strcpy(&parse_info.buf[parse_info.bufsize], wordp); - parse_info.bufsize += strlen(wordp); - parse_info.pre_state = S_VALUE; - break; - default: - goto err; - } - if (wordp != word) - Xfree (wordp); - return len; /* including length of token */ - -err: - if (wordp != word) - Xfree (wordp); - return 0; -} - -static int -f_backslash( - const char *str, - Token token, - Database *db) -{ - return f_default(str, token, db); -} - -static int -f_numeric( - const char *str, - Token token, - Database *db) -{ - char word[BUFSIZE]; - const char *p; - char* wordp; - int len; - int token_len; - - if ((len = strlen (str)) < sizeof word) - wordp = word; - else - wordp = Xmalloc (len + 1); - if (wordp == NULL) - return 0; - - switch (parse_info.pre_state) { - case S_NULL: - case S_CATEGORY: - goto err; - case S_NAME: - case S_VALUE: - token_len = token_tbl[token].len; - p = str + token_len; - len = get_word(p, wordp); - if (len < 1) - goto err; - if ((parse_info.bufsize + token_len + (int)strlen(wordp) + 1) - >= parse_info.bufMaxSize) { - if (realloc_parse_info(token_len + strlen(wordp) + 1) == False) - goto err; - } - strncpy(&parse_info.buf[parse_info.bufsize], str, token_len); - strcpy(&parse_info.buf[parse_info.bufsize + token_len], wordp); - parse_info.bufsize += token_len + strlen(wordp); - parse_info.pre_state = S_VALUE; - break; - default: - goto err; - } - if (wordp != word) - Xfree (wordp); - return len + token_len; - -err: - if (wordp != word) - Xfree (wordp); - return 0; -} - -static int -f_default( - const char *str, - Token token, - Database *db) -{ - char word[BUFSIZE], *p; - char* wordp; - int len; - - if ((len = strlen (str)) < sizeof word) - wordp = word; - else - wordp = Xmalloc (len + 1); - if (wordp == NULL) - return 0; - - len = get_word(str, wordp); - if (len < 1) - goto err; - - switch (parse_info.pre_state) { - case S_NULL: - if (parse_info.category != NULL) - goto err; - p = strdup(wordp); - if (p == NULL) - goto err; - parse_info.category = p; - parse_info.pre_state = S_CATEGORY; - break; - case S_CATEGORY: - if (parse_info.nest_depth == 0) { - if (check_category_end(str)) { - /* end of category is detected. - clear context and zap to end of this line */ - clear_parse_info(); - len = strlen(str); - break; - } - } - p = strdup(wordp); - if (p == NULL) - goto err; - if (parse_info.name[parse_info.nest_depth] != NULL) { - Xfree(parse_info.name[parse_info.nest_depth]); - } - parse_info.name[parse_info.nest_depth] = p; - parse_info.pre_state = S_NAME; - break; - case S_NAME: - case S_VALUE: - if ((parse_info.bufsize + (int)strlen(wordp) + 1) - >= parse_info.bufMaxSize) { - if (realloc_parse_info(strlen(wordp) + 1) == False) - goto err; - } - strcpy(&parse_info.buf[parse_info.bufsize], wordp); - parse_info.bufsize += strlen(wordp); - parse_info.pre_state = S_VALUE; - break; - default: - goto err; - } - if (wordp != word) - Xfree (wordp); - return len; - -err: - if (wordp != word) - Xfree (wordp); - return 0; -} - -/************************************************************************/ - -#ifdef DEBUG -static void -PrintDatabase( - Database db) -{ - Database p = db; - int i = 0, j; - - printf("***\n*** BEGIN Database\n***\n"); - while (p) { - printf("%3d: ", i++); - printf("%s, %s, ", p->category, p->name); - printf("\t[%d: ", p->value_num); - for (j = 0; j < p->value_num; ++j) { - printf("%s, ", p->value[j]); - } - printf("]\n"); - p = p->next; - } - printf("***\n*** END Database\n***\n"); -} -#endif - -static void -DestroyDatabase( - Database db) -{ - Database p = db; - - while (p) { - if (p->category != NULL) { - Xfree(p->category); - } - if (p->name != NULL) { - Xfree(p->name); - } - if (p->value != (char **)NULL) { - if (*p->value != NULL) { - Xfree(*p->value); - } - Xfree((char *)p->value); - } - db = p->next; - Xfree((char *)p); - p = db; - } -} - -static int -CountDatabase( - Database db) -{ - Database p = db; - int cnt = 0; - - while (p) { - ++cnt; - p = p->next; - } - return cnt; -} - -static Database -CreateDatabase( - char *dbfile) -{ - Database db = (Database)NULL; - FILE *fd; - Line line; - char *p; - Token token; - int len; - int error = 0; - - fd = _XFopenFile(dbfile, "r"); - if (fd == (FILE *)NULL) - return NULL; - - bzero(&line, sizeof(Line)); - init_parse_info(); - - do { - int rc = read_line(fd, &line); - if (rc < 0) { - error = 1; - break; - } else if (rc == 0) { - break; - } - p = line.str; - while (*p) { - int (*parse_proc)(const char *str, Token token, Database *db) = NULL; - - token = get_token(p); - - switch (token_tbl[token].token) { - case T_NEWLINE: - parse_proc = f_newline; - break; - case T_COMMENT: - parse_proc = f_comment; - break; - case T_SEMICOLON: - parse_proc = f_semicolon; - break; - case T_DOUBLE_QUOTE: - parse_proc = f_double_quote; - break; - case T_LEFT_BRACE: - parse_proc = f_left_brace; - break; - case T_RIGHT_BRACE: - parse_proc = f_right_brace; - break; - case T_SPACE: - case T_TAB: - parse_proc = f_white; - break; - case T_BACKSLASH: - parse_proc = f_backslash; - break; - case T_NUMERIC_HEX: - case T_NUMERIC_DEC: - case T_NUMERIC_OCT: - parse_proc = f_numeric; - break; - case T_DEFAULT: - parse_proc = f_default; - break; - } - - len = parse_proc(p, token, &db); - - if (len < 1) { - error = 1; - break; - } - p += len; - } - } while (!error); - - if (parse_info.pre_state != S_NULL) { - clear_parse_info(); - error = 1; - } - if (error) { -#ifdef DEBUG - fprintf(stderr, "database format error at line %d.\n", line.seq); -#endif - DestroyDatabase(db); - db = (Database)NULL; - } - - fclose(fd); - free_line(&line); - -#ifdef DEBUG - PrintDatabase(db); -#endif - - return db; -} - -/************************************************************************/ - -#ifndef NOT_X_ENV - -/* locale framework functions */ - -typedef struct _XlcDatabaseRec { - XrmQuark category_q; - XrmQuark name_q; - Database db; - struct _XlcDatabaseRec *next; -} XlcDatabaseRec, *XlcDatabase; - -typedef struct _XlcDatabaseListRec { - XrmQuark name_q; - XlcDatabase lc_db; - Database database; - int ref_count; - struct _XlcDatabaseListRec *next; -} XlcDatabaseListRec, *XlcDatabaseList; - -/* database cache list (per file) */ -static XlcDatabaseList _db_list = (XlcDatabaseList)NULL; - -/************************************************************************/ -/* _XlcGetResource(lcd, category, class, value, count) */ -/*----------------------------------------------------------------------*/ -/* This function retrieves XLocale database information. */ -/************************************************************************/ -void -_XlcGetResource( - XLCd lcd, - const char *category, - const char *class, - char ***value, - int *count) -{ - XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); - - (*methods->get_resource)(lcd, category, class, value, count); - return; -} - -/************************************************************************/ -/* _XlcGetLocaleDataBase(lcd, category, class, value, count) */ -/*----------------------------------------------------------------------*/ -/* This function retrieves XLocale database information. */ -/************************************************************************/ -void -_XlcGetLocaleDataBase( - XLCd lcd, - const char *category, - const char *name, - char ***value, - int *count) -{ - XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); - XrmQuark category_q, name_q; - - category_q = XrmStringToQuark(category); - name_q = XrmStringToQuark(name); - for (; lc_db->db; ++lc_db) { - if (category_q == lc_db->category_q && name_q == lc_db->name_q) { - *value = lc_db->db->value; - *count = lc_db->db->value_num; - return; - } - } - *value = (char **)NULL; - *count = 0; -} - -/************************************************************************/ -/* _XlcDestroyLocaleDataBase(lcd) */ -/*----------------------------------------------------------------------*/ -/* This function destroy the XLocale Database that bound to the */ -/* specified lcd. If the XLocale Database is refered from some */ -/* other lcd, this function just decreases reference count of */ -/* the database. If no locale refers the database, this function */ -/* remove it from the cache list and free work area. */ -/************************************************************************/ -void -_XlcDestroyLocaleDataBase( - XLCd lcd) -{ - XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); - XlcDatabaseList p, prev; - - for (p = _db_list, prev = (XlcDatabaseList)NULL; p; - prev = p, p = p->next) { - if (p->lc_db == lc_db) { - if ((-- p->ref_count) < 1) { - if (p->lc_db != (XlcDatabase)NULL) { - Xfree((char *)p->lc_db); - } - DestroyDatabase(p->database); - if (prev == (XlcDatabaseList)NULL) { - _db_list = p->next; - } else { - prev->next = p->next; - } - Xfree((char*)p); - } - break; - } - } - XLC_PUBLIC(lcd, xlocale_db) = (XPointer)NULL; -} - -/************************************************************************/ -/* _XlcCreateLocaleDataBase(lcd) */ -/*----------------------------------------------------------------------*/ -/* This function create an XLocale database which correspond to */ -/* the specified XLCd. */ -/************************************************************************/ -XPointer -_XlcCreateLocaleDataBase( - XLCd lcd) -{ - XlcDatabaseList list, new; - Database p, database = (Database)NULL; - XlcDatabase lc_db = (XlcDatabase)NULL; - XrmQuark name_q; - char *name; - int i, n; - - name = _XlcFileName(lcd, "locale"); - if (name == NULL) - return (XPointer)NULL; - -#ifndef __UNIXOS2__ - name_q = XrmStringToQuark(name); -#else - name_q = XrmStringToQuark((char*)__XOS2RedirRoot(name)); -#endif - for (list = _db_list; list; list = list->next) { - if (name_q == list->name_q) { - list->ref_count++; - Xfree (name); - return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)list->lc_db; - } - } - - database = CreateDatabase(name); - if (database == (Database)NULL) { - Xfree (name); - return (XPointer)NULL; - } - n = CountDatabase(database); - lc_db = Xcalloc(n + 1, sizeof(XlcDatabaseRec)); - if (lc_db == (XlcDatabase)NULL) - goto err; - for (p = database, i = 0; p && i < n; p = p->next, ++i) { - lc_db[i].category_q = XrmStringToQuark(p->category); - lc_db[i].name_q = XrmStringToQuark(p->name); - lc_db[i].db = p; - } - - new = (XlcDatabaseList)Xmalloc(sizeof(XlcDatabaseListRec)); - if (new == (XlcDatabaseList)NULL) { - goto err; - } - new->name_q = name_q; - new->lc_db = lc_db; - new->database = database; - new->ref_count = 1; - new->next = _db_list; - _db_list = new; - - Xfree (name); - return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)lc_db; - - err: - DestroyDatabase(database); - if (lc_db != (XlcDatabase)NULL) { - Xfree((char *)lc_db); - } - Xfree (name); - return (XPointer)NULL; -} - -#endif /* NOT_X_ENV */ +/*
+ *
+ * Copyright IBM Corporation 1993
+ *
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * 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 IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
+ * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/*
+ * (c) Copyright 1995 FUJITSU LIMITED
+ * This is source code modified by FUJITSU LIMITED under the Joint
+ * Development Agreement for the CDE/Motif PST.
+ */
+
+
+
+#ifndef NOT_X_ENV
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include "Xlibint.h"
+#include "XlcPubI.h"
+
+#else /* NOT_X_ENV */
+
+#define Xmalloc malloc
+#define Xrealloc realloc
+#define Xfree free
+
+#endif /* NOT_X_ENV */
+
+#include <stdint.h>
+
+/* specifying NOT_X_ENV allows users to just use
+ the database parsing routine. */
+/* For UDC/VW */
+#ifndef BUFSIZE
+#define BUFSIZE 2048
+#endif
+
+#ifdef COMMENT
+#ifdef BUFSIZE
+#undef BUFSIZE
+#endif
+#define BUFSIZE 6144 /* 2048*3 */
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+
+typedef struct _DatabaseRec {
+ char *category;
+ char *name;
+ char **value;
+ int value_num;
+ struct _DatabaseRec *next;
+} DatabaseRec, *Database;
+
+typedef enum {
+ S_NULL, /* outside category */
+ S_CATEGORY, /* inside category */
+ S_NAME, /* has name, expecting values */
+ S_VALUE
+} ParseState;
+
+typedef enum {
+ T_NEWLINE,
+ T_COMMENT,
+ T_SEMICOLON,
+ T_DOUBLE_QUOTE,
+ T_LEFT_BRACE,
+ T_RIGHT_BRACE,
+ T_SPACE,
+ T_TAB,
+ T_BACKSLASH,
+ T_NUMERIC_HEX,
+ T_NUMERIC_DEC,
+ T_NUMERIC_OCT,
+ T_DEFAULT
+} Token;
+
+typedef struct {
+ Token token; /* token id */
+ int len; /* length of token sequence */
+} TokenTable;
+
+static int f_newline (const char *str, Token token, Database *db);
+static int f_comment (const char *str, Token token, Database *db);
+static int f_semicolon (const char *str, Token token, Database *db);
+static int f_double_quote (const char *str, Token token, Database *db);
+static int f_left_brace (const char *str, Token token, Database *db);
+static int f_right_brace (const char *str, Token token, Database *db);
+static int f_white (const char *str, Token token, Database *db);
+static int f_backslash (const char *str, Token token, Database *db);
+static int f_numeric (const char *str, Token token, Database *db);
+static int f_default (const char *str, Token token, Database *db);
+
+static const TokenTable token_tbl[] = {
+ { T_NEWLINE, 1 },
+ { T_COMMENT, 1 },
+ { T_SEMICOLON, 1 },
+ { T_DOUBLE_QUOTE, 1 },
+ { T_LEFT_BRACE, 1 },
+ { T_RIGHT_BRACE, 1 },
+ { T_SPACE, 1 },
+ { T_TAB, 1 },
+ { T_BACKSLASH, 1 },
+ { T_NUMERIC_HEX, 2 },
+ { T_NUMERIC_DEC, 2 },
+ { T_NUMERIC_OCT, 2 },
+ { T_DEFAULT, 1 } /* any character */
+};
+
+#define SYM_CR '\r'
+#define SYM_NEWLINE '\n'
+#define SYM_COMMENT '#'
+#define SYM_SEMICOLON ';'
+#define SYM_DOUBLE_QUOTE '"'
+#define SYM_LEFT_BRACE '{'
+#define SYM_RIGHT_BRACE '}'
+#define SYM_SPACE ' '
+#define SYM_TAB '\t'
+#define SYM_BACKSLASH '\\'
+
+/************************************************************************/
+
+#define MAX_NAME_NEST 64
+
+typedef struct {
+ ParseState pre_state;
+ char *category;
+ char *name[MAX_NAME_NEST];
+ int nest_depth;
+ char **value;
+ int value_len;
+ int value_num;
+ int bufsize; /* bufMaxSize >= bufsize >= 0 */
+ int bufMaxSize; /* default : BUFSIZE */
+ char *buf;
+} DBParseInfo;
+
+static DBParseInfo parse_info;
+
+static void
+init_parse_info (void)
+{
+ static int allocated /* = 0 */;
+ char *ptr;
+ int size;
+ if (!allocated) {
+ bzero(&parse_info, sizeof(DBParseInfo));
+ parse_info.buf = (char *)Xmalloc(BUFSIZE);
+ parse_info.bufMaxSize = BUFSIZE;
+ allocated = 1;
+ return;
+ }
+ ptr = parse_info.buf;
+ size = parse_info.bufMaxSize;
+ bzero(&parse_info, sizeof(DBParseInfo));
+ parse_info.buf = ptr;
+ parse_info.bufMaxSize = size;
+}
+
+static void
+clear_parse_info (void)
+{
+ int i;
+ char *ptr;
+ int size;
+ parse_info.pre_state = S_NULL;
+ if (parse_info.category != NULL) {
+ Xfree(parse_info.category);
+ }
+ for (i = 0; i <= parse_info.nest_depth; ++i) {
+ if (parse_info.name[i]) {
+ Xfree(parse_info.name[i]);
+ }
+ }
+ if (parse_info.value) {
+ if (*parse_info.value) {
+ Xfree(*parse_info.value);
+ }
+ Xfree((char *)parse_info.value);
+ }
+ ptr = parse_info.buf;
+ size = parse_info.bufMaxSize;
+ bzero(&parse_info, sizeof(DBParseInfo));
+ parse_info.buf = ptr;
+ parse_info.bufMaxSize = size;
+}
+
+static Bool
+realloc_parse_info(
+ int len)
+{
+ char *p;
+
+ parse_info.bufMaxSize = BUFSIZE * ((parse_info.bufsize + len)/BUFSIZE + 1);
+ p = (char *)Xrealloc(parse_info.buf, parse_info.bufMaxSize);
+ if (p == NULL)
+ return False;
+ parse_info.buf = p;
+
+ return True;
+}
+
+/************************************************************************/
+
+typedef struct _Line {
+ char *str;
+ int cursize;
+ int maxsize;
+ int seq;
+} Line;
+
+static void
+free_line(
+ Line *line)
+{
+ if (line->str != NULL) {
+ Xfree(line->str);
+ }
+ bzero(line, sizeof(Line));
+}
+
+static int
+realloc_line(
+ Line *line,
+ int size)
+{
+ char *str = line->str;
+
+ if (str != NULL) {
+ str = (char *)Xrealloc(str, size);
+ } else {
+ str = (char *)Xmalloc(size);
+ }
+ if (str == NULL) {
+ /* malloc error */
+ if (line->str != NULL) {
+ Xfree(line->str);
+ }
+ bzero(line, sizeof(Line));
+ return 0;
+ }
+ line->str = str;
+ line->maxsize = size;
+ return 1;
+}
+
+#define iswhite(ch) ((ch) == SYM_SPACE || (ch) == SYM_TAB)
+
+static void
+zap_comment(
+ char *str,
+ int *quoted)
+{
+ char *p = str;
+#ifdef never
+ *quoted = 0;
+ if (*p == SYM_COMMENT) {
+ int len = strlen(str);
+ if (p[len - 1] == SYM_NEWLINE || p[len - 1] == SYM_CR) {
+ *p++ = SYM_NEWLINE;
+ }
+ *p = '\0';
+ }
+#else
+ while (*p) {
+ if (*p == SYM_DOUBLE_QUOTE) {
+ if (p == str || p[-1] != SYM_BACKSLASH) {
+ /* unescaped double quote changes quoted state. */
+ *quoted = *quoted ? 0 : 1;
+ }
+ }
+ if (*p == SYM_COMMENT && !*quoted) {
+ int pos = p - str;
+ if (pos == 0 ||
+ (iswhite(p[-1]) && (pos == 1 || p[-2] != SYM_BACKSLASH))) {
+ int len = strlen(p);
+ if (len > 0 && (p[len - 1] == SYM_NEWLINE || p[len-1] == SYM_CR)) {
+ /* newline is the identifier for finding end of value.
+ therefore, it should not be removed. */
+ *p++ = SYM_NEWLINE;
+ }
+ *p = '\0';
+ break;
+ }
+ }
+ ++p;
+ }
+#endif
+}
+
+static int
+read_line(
+ FILE *fd,
+ Line *line)
+{
+ char buf[BUFSIZE], *p;
+ int len;
+ int quoted = 0; /* quoted by double quote? */
+ char *str;
+ int cur;
+
+ str = line->str;
+ cur = line->cursize = 0;
+
+ while ((p = fgets(buf, BUFSIZE, fd)) != NULL) {
+ ++line->seq;
+ zap_comment(p, "ed); /* remove comment line */
+ len = strlen(p);
+ if (len == 0) {
+ if (cur > 0) {
+ break;
+ }
+ continue;
+ }
+ if (cur + len + 1 > line->maxsize) {
+ /* need to reallocate buffer. */
+ if (! realloc_line(line, line->maxsize + BUFSIZE)) {
+ return -1; /* realloc error. */
+ }
+ str = line->str;
+ }
+ strncpy(str + cur, p, len);
+
+ cur += len;
+ str[cur] = '\0';
+#ifdef __UNIXOS2__ /* Take out carriage returns under OS/2 */
+ if (cur>1) {
+ if (str[cur-2] == '\r' && str[cur-1] == '\n') {
+ str[cur-2] = '\n';
+ str[cur-1] = '\0';
+ cur--;
+ }
+ }
+#endif
+ if (!quoted && cur > 1 && str[cur - 2] == SYM_BACKSLASH &&
+ (str[cur - 1] == SYM_NEWLINE || str[cur-1] == SYM_CR)) {
+ /* the line is ended backslash followed by newline.
+ need to concatinate the next line. */
+ cur -= 2;
+ str[cur] = '\0';
+ } else if (len < BUFSIZE - 1 || buf[len - 1] == SYM_NEWLINE ||
+ buf[len - 1] == SYM_CR) {
+ /* the line is shorter than BUFSIZE. */
+ break;
+ }
+ }
+ if (quoted) {
+ /* error. still in quoted state. */
+ return -1;
+ }
+ return line->cursize = cur;
+}
+
+/************************************************************************/
+
+static Token
+get_token(
+ const char *str)
+{
+ switch (*str) {
+ case SYM_NEWLINE:
+ case SYM_CR: return T_NEWLINE;
+ case SYM_COMMENT: return T_COMMENT;
+ case SYM_SEMICOLON: return T_SEMICOLON;
+ case SYM_DOUBLE_QUOTE: return T_DOUBLE_QUOTE;
+ case SYM_LEFT_BRACE: return T_LEFT_BRACE;
+ case SYM_RIGHT_BRACE: return T_RIGHT_BRACE;
+ case SYM_SPACE: return T_SPACE;
+ case SYM_TAB: return T_TAB;
+ case SYM_BACKSLASH:
+ switch (str[1]) {
+ case 'x': return T_NUMERIC_HEX;
+ case 'd': return T_NUMERIC_DEC;
+ case 'o': return T_NUMERIC_OCT;
+ }
+ return T_BACKSLASH;
+ default:
+ return T_DEFAULT;
+ }
+}
+
+static int
+get_word(
+ const char *str,
+ char *word)
+{
+ const char *p = str;
+ char *w = word;
+ Token token;
+ int token_len;
+
+ while (*p != '\0') {
+ token = get_token(p);
+ token_len = token_tbl[token].len;
+ if (token == T_BACKSLASH) {
+ p += token_len;
+ if (*p == '\0')
+ break;
+ token = get_token(p);
+ token_len = token_tbl[token].len;
+ } else if (token != T_COMMENT && token != T_DEFAULT) {
+ break;
+ }
+ strncpy(w, p, token_len);
+ p += token_len; w += token_len;
+ }
+ *w = '\0';
+ return p - str; /* return number of scanned chars */
+}
+
+static int
+get_quoted_word(
+ const char *str,
+ char *word)
+{
+ const char *p = str;
+ char *w = word;
+ Token token;
+ int token_len;
+
+ if (*p == SYM_DOUBLE_QUOTE) {
+ ++p;
+ }
+ while (*p != '\0') {
+ token = get_token(p);
+ token_len = token_tbl[token].len;
+ if (token == T_DOUBLE_QUOTE) {
+ p += token_len;
+ goto found;
+ }
+ if (token == T_BACKSLASH) {
+ p += token_len;
+ if (*p == '\0') {
+ break;
+ }
+ token = get_token(p);
+ token_len = token_tbl[token].len;
+ }
+ strncpy(w, p, token_len);
+ p += token_len; w += token_len;
+ }
+ /* error. cannot detect next double quote */
+ return 0;
+
+ found:;
+ *w = '\0';
+ return p - str;
+}
+
+/************************************************************************/
+
+static int
+append_value_list (void)
+{
+ char **value_list = parse_info.value;
+ char *value;
+ int value_num = parse_info.value_num;
+ int value_len = parse_info.value_len;
+ char *str = parse_info.buf;
+ int len = parse_info.bufsize;
+ char *p;
+
+ if (len < 1) {
+ return 1; /* return with no error */
+ }
+
+ if (value_list == (char **)NULL) {
+ value_list = (char **)Xmalloc(sizeof(char *) * 2);
+ *value_list = NULL;
+ } else {
+ char **prev_list = value_list;
+
+ value_list = (char **)
+ Xrealloc(value_list, sizeof(char *) * (value_num + 2));
+ if (value_list == NULL) {
+ Xfree(prev_list);
+ }
+ }
+ if (value_list == (char **)NULL)
+ goto err2;
+
+ value = *value_list;
+ if (value == NULL) {
+ value = (char *)Xmalloc(value_len + len + 1);
+ } else {
+ char *prev_value = value;
+
+ value = (char *)Xrealloc(value, value_len + len + 1);
+ if (value == NULL) {
+ Xfree(prev_value);
+ }
+ }
+ if (value == NULL) {
+ goto err1;
+ }
+ if (value != *value_list) {
+ int i;
+ ssize_t delta;
+ delta = value - *value_list;
+ *value_list = value;
+ for (i = 1; i < value_num; ++i) {
+ value_list[i] += delta;
+ }
+ }
+
+ value_list[value_num] = p = &value[value_len];
+ value_list[value_num + 1] = NULL;
+ strncpy(p, str, len);
+ p[len] = 0;
+
+ parse_info.value = value_list;
+ parse_info.value_num = value_num + 1;
+ parse_info.value_len = value_len + len + 1;
+ parse_info.bufsize = 0;
+ return 1;
+
+ err1:
+ if (value_list) {
+ Xfree((char **)value_list);
+ }
+ if (value) {
+ Xfree(value);
+ }
+ err2:
+ parse_info.value = (char **)NULL;
+ parse_info.value_num = 0;
+ parse_info.value_len = 0;
+ parse_info.bufsize = 0;
+ return 0;
+}
+
+static int
+construct_name(
+ char *name,
+ int size)
+{
+ int i;
+ int len = 0;
+ char *p = name;
+
+ for (i = 0; i <= parse_info.nest_depth; ++i) {
+ len += strlen(parse_info.name[i]) + 1;
+ }
+ if (len >= size)
+ return 0;
+
+ strcpy(p, parse_info.name[0]);
+ p += strlen(parse_info.name[0]);
+ for (i = 1; i <= parse_info.nest_depth; ++i) {
+ *p++ = '.';
+ strcpy(p, parse_info.name[i]);
+ p += strlen(parse_info.name[i]);
+ }
+ return *name != '\0';
+}
+
+static int
+store_to_database(
+ Database *db)
+{
+ Database new = (Database)NULL;
+ char name[BUFSIZE];
+
+ if (parse_info.pre_state == S_VALUE) {
+ if (! append_value_list()) {
+ goto err;
+ }
+ }
+
+ if (parse_info.name[parse_info.nest_depth] == NULL) {
+ goto err;
+ }
+
+ new = Xcalloc(1, sizeof(DatabaseRec));
+ if (new == (Database)NULL) {
+ goto err;
+ }
+
+ new->category = strdup(parse_info.category);
+ if (new->category == NULL) {
+ goto err;
+ }
+
+ if (! construct_name(name, sizeof(name))) {
+ goto err;
+ }
+ new->name = strdup(name);
+ if (new->name == NULL) {
+ goto err;
+ }
+ new->next = *db;
+ new->value = parse_info.value;
+ new->value_num = parse_info.value_num;
+ *db = new;
+
+ Xfree(parse_info.name[parse_info.nest_depth]);
+ parse_info.name[parse_info.nest_depth] = NULL;
+
+ parse_info.value = (char **)NULL;
+ parse_info.value_num = 0;
+ parse_info.value_len = 0;
+
+ return 1;
+
+ err:
+ if (new) {
+ if (new->category) {
+ Xfree(new->category);
+ }
+ if (new->name) {
+ Xfree(new->name);
+ }
+ Xfree(new);
+ }
+ if (parse_info.value) {
+ if (*parse_info.value) {
+ Xfree(*parse_info.value);
+ }
+ Xfree((char **)parse_info.value);
+ parse_info.value = (char **)NULL;
+ parse_info.value_num = 0;
+ parse_info.value_len = 0;
+ }
+ return 0;
+}
+
+#define END_MARK "END"
+#define END_MARK_LEN 3 /*strlen(END_MARK)*/
+
+static int
+check_category_end(
+ const char *str)
+{
+ const char *p;
+ int len;
+
+ p = str;
+ if (strncmp(p, END_MARK, END_MARK_LEN)) {
+ return 0;
+ }
+ p += END_MARK_LEN;
+
+ while (iswhite(*p)) {
+ ++p;
+ }
+ len = strlen(parse_info.category);
+ if (strncmp(p, parse_info.category, len)) {
+ return 0;
+ }
+ p += len;
+ return p - str;
+}
+
+/************************************************************************/
+
+static int
+f_newline(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_CATEGORY:
+ break;
+ case S_NAME:
+ return 0; /* no value */
+ case S_VALUE:
+ if (!store_to_database(db))
+ return 0;
+ parse_info.pre_state = S_CATEGORY;
+ break;
+ default:
+ return 0;
+ }
+ return token_tbl[token].len;
+}
+
+static int
+f_comment(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ /* NOTE: comment is already handled in read_line(),
+ so this function is not necessary. */
+
+ const char *p = str;
+
+ while (*p != SYM_NEWLINE && *p != SYM_CR && *p != '\0') {
+ ++p; /* zap to the end of line */
+ }
+ return p - str;
+}
+
+static int
+f_white(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ const char *p = str;
+
+ while (iswhite(*p)) {
+ ++p;
+ }
+ return p - str;
+}
+
+static int
+f_semicolon(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_CATEGORY:
+ case S_NAME:
+ return 0;
+ case S_VALUE:
+ if (! append_value_list())
+ return 0;
+ parse_info.pre_state = S_VALUE;
+ break;
+ default:
+ return 0;
+ }
+ return token_tbl[token].len;
+}
+
+static int
+f_left_brace(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_CATEGORY:
+ case S_VALUE:
+ return 0;
+ case S_NAME:
+ if (parse_info.name[parse_info.nest_depth] == NULL
+ || parse_info.nest_depth + 1 > MAX_NAME_NEST)
+ return 0;
+ ++parse_info.nest_depth;
+ parse_info.pre_state = S_CATEGORY;
+ break;
+ default:
+ return 0;
+ }
+ return token_tbl[token].len;
+}
+
+static int
+f_right_brace(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ if (parse_info.nest_depth < 1)
+ return 0;
+
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_NAME:
+ return 0;
+ case S_VALUE:
+ if (! store_to_database(db))
+ return 0;
+ /* fall into next case */
+ case S_CATEGORY:
+ if (parse_info.name[parse_info.nest_depth] != NULL) {
+ Xfree(parse_info.name[parse_info.nest_depth]);
+ parse_info.name[parse_info.nest_depth] = NULL;
+ }
+ --parse_info.nest_depth;
+ parse_info.pre_state = S_CATEGORY;
+ break;
+ default:
+ return 0;
+ }
+ return token_tbl[token].len;
+}
+
+static int
+f_double_quote(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ char word[BUFSIZE];
+ char* wordp;
+ int len;
+
+ if ((len = strlen (str)) < sizeof word)
+ wordp = word;
+ else
+ wordp = Xmalloc (len + 1);
+ if (wordp == NULL)
+ return 0;
+
+ len = 0;
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_CATEGORY:
+ goto err;
+ case S_NAME:
+ case S_VALUE:
+ len = get_quoted_word(str, wordp);
+ if (len < 1)
+ goto err;
+ if ((parse_info.bufsize + (int)strlen(wordp) + 1)
+ >= parse_info.bufMaxSize) {
+ if (realloc_parse_info(strlen(wordp)+1) == False) {
+ goto err;
+ }
+ }
+ strcpy(&parse_info.buf[parse_info.bufsize], wordp);
+ parse_info.bufsize += strlen(wordp);
+ parse_info.pre_state = S_VALUE;
+ break;
+ default:
+ goto err;
+ }
+ if (wordp != word)
+ Xfree (wordp);
+ return len; /* including length of token */
+
+err:
+ if (wordp != word)
+ Xfree (wordp);
+ return 0;
+}
+
+static int
+f_backslash(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ return f_default(str, token, db);
+}
+
+static int
+f_numeric(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ char word[BUFSIZE];
+ const char *p;
+ char* wordp;
+ int len;
+ int token_len;
+
+ if ((len = strlen (str)) < sizeof word)
+ wordp = word;
+ else
+ wordp = Xmalloc (len + 1);
+ if (wordp == NULL)
+ return 0;
+
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ case S_CATEGORY:
+ goto err;
+ case S_NAME:
+ case S_VALUE:
+ token_len = token_tbl[token].len;
+ p = str + token_len;
+ len = get_word(p, wordp);
+ if (len < 1)
+ goto err;
+ if ((parse_info.bufsize + token_len + (int)strlen(wordp) + 1)
+ >= parse_info.bufMaxSize) {
+ if (realloc_parse_info(token_len + strlen(wordp) + 1) == False)
+ goto err;
+ }
+ strncpy(&parse_info.buf[parse_info.bufsize], str, token_len);
+ strcpy(&parse_info.buf[parse_info.bufsize + token_len], wordp);
+ parse_info.bufsize += token_len + strlen(wordp);
+ parse_info.pre_state = S_VALUE;
+ break;
+ default:
+ goto err;
+ }
+ if (wordp != word)
+ Xfree (wordp);
+ return len + token_len;
+
+err:
+ if (wordp != word)
+ Xfree (wordp);
+ return 0;
+}
+
+static int
+f_default(
+ const char *str,
+ Token token,
+ Database *db)
+{
+ char word[BUFSIZE], *p;
+ char* wordp;
+ int len;
+
+ if ((len = strlen (str)) < sizeof word)
+ wordp = word;
+ else
+ wordp = Xmalloc (len + 1);
+ if (wordp == NULL)
+ return 0;
+
+ len = get_word(str, wordp);
+ if (len < 1)
+ goto err;
+
+ switch (parse_info.pre_state) {
+ case S_NULL:
+ if (parse_info.category != NULL)
+ goto err;
+ p = strdup(wordp);
+ if (p == NULL)
+ goto err;
+ parse_info.category = p;
+ parse_info.pre_state = S_CATEGORY;
+ break;
+ case S_CATEGORY:
+ if (parse_info.nest_depth == 0) {
+ if (check_category_end(str)) {
+ /* end of category is detected.
+ clear context and zap to end of this line */
+ clear_parse_info();
+ len = strlen(str);
+ break;
+ }
+ }
+ p = strdup(wordp);
+ if (p == NULL)
+ goto err;
+ if (parse_info.name[parse_info.nest_depth] != NULL) {
+ Xfree(parse_info.name[parse_info.nest_depth]);
+ }
+ parse_info.name[parse_info.nest_depth] = p;
+ parse_info.pre_state = S_NAME;
+ break;
+ case S_NAME:
+ case S_VALUE:
+ if ((parse_info.bufsize + (int)strlen(wordp) + 1)
+ >= parse_info.bufMaxSize) {
+ if (realloc_parse_info(strlen(wordp) + 1) == False)
+ goto err;
+ }
+ strcpy(&parse_info.buf[parse_info.bufsize], wordp);
+ parse_info.bufsize += strlen(wordp);
+ parse_info.pre_state = S_VALUE;
+ break;
+ default:
+ goto err;
+ }
+ if (wordp != word)
+ Xfree (wordp);
+ return len;
+
+err:
+ if (wordp != word)
+ Xfree (wordp);
+ return 0;
+}
+
+/************************************************************************/
+
+#ifdef DEBUG
+static void
+PrintDatabase(
+ Database db)
+{
+ Database p = db;
+ int i = 0, j;
+
+ printf("***\n*** BEGIN Database\n***\n");
+ while (p) {
+ printf("%3d: ", i++);
+ printf("%s, %s, ", p->category, p->name);
+ printf("\t[%d: ", p->value_num);
+ for (j = 0; j < p->value_num; ++j) {
+ printf("%s, ", p->value[j]);
+ }
+ printf("]\n");
+ p = p->next;
+ }
+ printf("***\n*** END Database\n***\n");
+}
+#endif
+
+static void
+DestroyDatabase(
+ Database db)
+{
+ Database p = db;
+
+ while (p) {
+ if (p->category != NULL) {
+ Xfree(p->category);
+ }
+ if (p->name != NULL) {
+ Xfree(p->name);
+ }
+ if (p->value != (char **)NULL) {
+ if (*p->value != NULL) {
+ Xfree(*p->value);
+ }
+ Xfree((char *)p->value);
+ }
+ db = p->next;
+ Xfree((char *)p);
+ p = db;
+ }
+}
+
+static int
+CountDatabase(
+ Database db)
+{
+ Database p = db;
+ int cnt = 0;
+
+ while (p) {
+ ++cnt;
+ p = p->next;
+ }
+ return cnt;
+}
+
+static Database
+CreateDatabase(
+ char *dbfile)
+{
+ Database db = (Database)NULL;
+ FILE *fd;
+ Line line;
+ char *p;
+ Token token;
+ int len;
+ int error = 0;
+
+ fd = _XFopenFile(dbfile, "r");
+ if (fd == (FILE *)NULL)
+ return NULL;
+
+ bzero(&line, sizeof(Line));
+ init_parse_info();
+
+ do {
+ int rc = read_line(fd, &line);
+ if (rc < 0) {
+ error = 1;
+ break;
+ } else if (rc == 0) {
+ break;
+ }
+ p = line.str;
+ while (*p) {
+ int (*parse_proc)(const char *str, Token token, Database *db) = NULL;
+
+ token = get_token(p);
+
+ switch (token_tbl[token].token) {
+ case T_NEWLINE:
+ parse_proc = f_newline;
+ break;
+ case T_COMMENT:
+ parse_proc = f_comment;
+ break;
+ case T_SEMICOLON:
+ parse_proc = f_semicolon;
+ break;
+ case T_DOUBLE_QUOTE:
+ parse_proc = f_double_quote;
+ break;
+ case T_LEFT_BRACE:
+ parse_proc = f_left_brace;
+ break;
+ case T_RIGHT_BRACE:
+ parse_proc = f_right_brace;
+ break;
+ case T_SPACE:
+ case T_TAB:
+ parse_proc = f_white;
+ break;
+ case T_BACKSLASH:
+ parse_proc = f_backslash;
+ break;
+ case T_NUMERIC_HEX:
+ case T_NUMERIC_DEC:
+ case T_NUMERIC_OCT:
+ parse_proc = f_numeric;
+ break;
+ case T_DEFAULT:
+ parse_proc = f_default;
+ break;
+ }
+
+ len = parse_proc(p, token, &db);
+
+ if (len < 1) {
+ error = 1;
+ break;
+ }
+ p += len;
+ }
+ } while (!error);
+
+ if (parse_info.pre_state != S_NULL) {
+ clear_parse_info();
+ error = 1;
+ }
+ if (error) {
+#ifdef DEBUG
+ fprintf(stderr, "database format error at line %d.\n", line.seq);
+#endif
+ DestroyDatabase(db);
+ db = (Database)NULL;
+ }
+
+ fclose(fd);
+ free_line(&line);
+
+#ifdef DEBUG
+ PrintDatabase(db);
+#endif
+
+ return db;
+}
+
+/************************************************************************/
+
+#ifndef NOT_X_ENV
+
+/* locale framework functions */
+
+typedef struct _XlcDatabaseRec {
+ XrmQuark category_q;
+ XrmQuark name_q;
+ Database db;
+ struct _XlcDatabaseRec *next;
+} XlcDatabaseRec, *XlcDatabase;
+
+typedef struct _XlcDatabaseListRec {
+ XrmQuark name_q;
+ XlcDatabase lc_db;
+ Database database;
+ int ref_count;
+ struct _XlcDatabaseListRec *next;
+} XlcDatabaseListRec, *XlcDatabaseList;
+
+/* database cache list (per file) */
+static XlcDatabaseList _db_list = (XlcDatabaseList)NULL;
+
+/************************************************************************/
+/* _XlcGetResource(lcd, category, class, value, count) */
+/*----------------------------------------------------------------------*/
+/* This function retrieves XLocale database information. */
+/************************************************************************/
+void
+_XlcGetResource(
+ XLCd lcd,
+ const char *category,
+ const char *class,
+ char ***value,
+ int *count)
+{
+ XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd);
+
+ (*methods->get_resource)(lcd, category, class, value, count);
+ return;
+}
+
+/************************************************************************/
+/* _XlcGetLocaleDataBase(lcd, category, class, value, count) */
+/*----------------------------------------------------------------------*/
+/* This function retrieves XLocale database information. */
+/************************************************************************/
+void
+_XlcGetLocaleDataBase(
+ XLCd lcd,
+ const char *category,
+ const char *name,
+ char ***value,
+ int *count)
+{
+ XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db);
+ XrmQuark category_q, name_q;
+
+ category_q = XrmStringToQuark(category);
+ name_q = XrmStringToQuark(name);
+ for (; lc_db->db; ++lc_db) {
+ if (category_q == lc_db->category_q && name_q == lc_db->name_q) {
+ *value = lc_db->db->value;
+ *count = lc_db->db->value_num;
+ return;
+ }
+ }
+ *value = (char **)NULL;
+ *count = 0;
+}
+
+/************************************************************************/
+/* _XlcDestroyLocaleDataBase(lcd) */
+/*----------------------------------------------------------------------*/
+/* This function destroy the XLocale Database that bound to the */
+/* specified lcd. If the XLocale Database is refered from some */
+/* other lcd, this function just decreases reference count of */
+/* the database. If no locale refers the database, this function */
+/* remove it from the cache list and free work area. */
+/************************************************************************/
+void
+_XlcDestroyLocaleDataBase(
+ XLCd lcd)
+{
+ XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db);
+ XlcDatabaseList p, prev;
+
+ for (p = _db_list, prev = (XlcDatabaseList)NULL; p;
+ prev = p, p = p->next) {
+ if (p->lc_db == lc_db) {
+ if ((-- p->ref_count) < 1) {
+ if (p->lc_db != (XlcDatabase)NULL) {
+ Xfree((char *)p->lc_db);
+ }
+ DestroyDatabase(p->database);
+ if (prev == (XlcDatabaseList)NULL) {
+ _db_list = p->next;
+ } else {
+ prev->next = p->next;
+ }
+ Xfree((char*)p);
+ }
+ break;
+ }
+ }
+ XLC_PUBLIC(lcd, xlocale_db) = (XPointer)NULL;
+}
+
+/************************************************************************/
+/* _XlcCreateLocaleDataBase(lcd) */
+/*----------------------------------------------------------------------*/
+/* This function create an XLocale database which correspond to */
+/* the specified XLCd. */
+/************************************************************************/
+XPointer
+_XlcCreateLocaleDataBase(
+ XLCd lcd)
+{
+ XlcDatabaseList list, new;
+ Database p, database = (Database)NULL;
+ XlcDatabase lc_db = (XlcDatabase)NULL;
+ XrmQuark name_q;
+ char *name;
+ int i, n;
+
+ name = _XlcFileName(lcd, "locale");
+ if (name == NULL)
+ return (XPointer)NULL;
+
+#ifndef __UNIXOS2__
+ name_q = XrmStringToQuark(name);
+#else
+ name_q = XrmStringToQuark((char*)__XOS2RedirRoot(name));
+#endif
+ for (list = _db_list; list; list = list->next) {
+ if (name_q == list->name_q) {
+ list->ref_count++;
+ Xfree (name);
+ return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)list->lc_db;
+ }
+ }
+
+ database = CreateDatabase(name);
+ if (database == (Database)NULL) {
+ Xfree (name);
+ return (XPointer)NULL;
+ }
+ n = CountDatabase(database);
+ lc_db = Xcalloc(n + 1, sizeof(XlcDatabaseRec));
+ if (lc_db == (XlcDatabase)NULL)
+ goto err;
+ for (p = database, i = 0; p && i < n; p = p->next, ++i) {
+ lc_db[i].category_q = XrmStringToQuark(p->category);
+ lc_db[i].name_q = XrmStringToQuark(p->name);
+ lc_db[i].db = p;
+ }
+
+ new = (XlcDatabaseList)Xmalloc(sizeof(XlcDatabaseListRec));
+ if (new == (XlcDatabaseList)NULL) {
+ goto err;
+ }
+ new->name_q = name_q;
+ new->lc_db = lc_db;
+ new->database = database;
+ new->ref_count = 1;
+ new->next = _db_list;
+ _db_list = new;
+
+ Xfree (name);
+ return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)lc_db;
+
+ err:
+ DestroyDatabase(database);
+ if (lc_db != (XlcDatabase)NULL) {
+ Xfree((char *)lc_db);
+ }
+ Xfree (name);
+ return (XPointer)NULL;
+}
+
+#endif /* NOT_X_ENV */
diff --git a/libX11/src/xlibi18n/lcDynamic.c b/libX11/src/xlibi18n/lcDynamic.c index f6df94cbb..8d022d885 100644 --- a/libX11/src/xlibi18n/lcDynamic.c +++ b/libX11/src/xlibi18n/lcDynamic.c @@ -51,7 +51,7 @@ from The Open Group. #include "Xlcint.h" #ifndef XLOCALEDIR -#define XLOCALEDIR "/usr/lib/X11/locale" +#define XLOCALEDIR "locale" #endif #define LCLIBNAME "xi18n.so" diff --git a/libX11/src/xlibi18n/lcFile.c b/libX11/src/xlibi18n/lcFile.c index 4e4439773..5a9b0f4ab 100644 --- a/libX11/src/xlibi18n/lcFile.c +++ b/libX11/src/xlibi18n/lcFile.c @@ -1,829 +1,829 @@ -/* - * - * Copyright IBM Corporation 1993 - * - * All Rights Reserved - * - * License to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * 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 IBM not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND - * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL - * IBM 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. - * -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include "Xlibint.h" -#include "XlcPubI.h" -#include <X11/Xos.h> -#include <unistd.h> - -/************************************************************************/ - -#ifdef __UNIXOS2__ -# define seteuid setuid -#endif -#define iscomment(ch) ((ch) == '#' || (ch) == '\0') -#if defined(WIN32) -#define isreadable(f) (_XAccessFile(f)) -#else -#define isreadable(f) ((access((f), R_OK) != -1) ? 1 : 0) -#endif - -#ifndef __UNIXOS2__ -#define LC_PATHDELIM ':' -#else -#define LC_PATHDELIM ';' -#endif - -#define XLC_BUFSIZE 256 - -#ifndef X_NOT_POSIX -#ifdef _POSIX_SOURCE -#include <limits.h> -#else -#define _POSIX_SOURCE -#include <limits.h> -#undef _POSIX_SOURCE -#endif -#endif -#ifndef PATH_MAX -#ifdef WIN32 -#define PATH_MAX 512 -#else -#include <sys/param.h> -#endif -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif - -#define NUM_LOCALEDIR 64 - -/* Splits a NUL terminated line into constituents, at colons and newline - characters. Leading whitespace is removed from constituents. The - constituents are stored at argv[0..argsize-1]. The number of stored - constituents (<= argsize) is returned. The line is destructively - modified. */ -static int -parse_line( - char *line, - char **argv, - int argsize) -{ - int argc = 0; - char *p = line; - - while (argc < argsize) { - while (isspace(*p)) { - ++p; - } - if (*p == '\0') { - break; - } - argv[argc++] = p; - while (*p != ':' && *p != '\n' && *p != '\0') { - ++p; - } - if (*p == '\0') { - break; - } - *p++ = '\0'; - } - - return argc; -} - -#ifdef __UNIXOS2__ - -/* fg021216: entries in locale files are separated by colons while under - OS/2, path entries are separated by semicolon, so we need two functions */ - -static int -parse_line1( - char *line, - char **argv, - int argsize) -{ - int argc = 0; - char *p = line; - - while (argc < argsize) { - while (isspace(*p)) { - ++p; - } - if (*p == '\0') { - break; - } - argv[argc++] = p; - while (*p != ';' && *p != '\n' && *p != '\0') { - ++p; - } - if (*p == '\0') { - break; - } - *p++ = '\0'; - } - - return argc; -} -#elif defined(WIN32) - -/* this is parse_line but skips drive letters at the beginning of the entry */ -static int -parse_line1( - char *line, - char **argv, - int argsize) -{ - int argc = 0; - char *p = line; - - while (argc < argsize) { - while (isspace(*p)) { - ++p; - } - if (*p == '\0') { - break; - } - argv[argc++] = p; - if (isalpha(*p) && p[1] == ':') { - p+= 2; /* skip drive letters */ - } - while (*p != ':' && *p != '\n' && *p != '\0') { - ++p; - } - if (*p == '\0') { - break; - } - *p++ = '\0'; - } - - return argc; -} - -#endif /* __UNIXOS2__ */ - -/* Splits a colon separated list of directories, and returns the constituent - paths (without trailing slash). At most argsize constituents are stored - at argv[0..argsize-1]. The number of stored constituents is returned. */ -static int -_XlcParsePath( - char *path, - char **argv, - int argsize) -{ - char *p = path; - int n, i; - -#if !defined(__UNIXOS2__) && !defined(WIN32) - n = parse_line(path, argv, argsize); -#else - n = parse_line1(path, argv, argsize); -#endif - for (i = 0; i < n; ++i) { - int len; - p = argv[i]; - len = strlen(p); - if (len > 0 && p[len - 1] == '/') { - /* eliminate trailing slash */ - p[len - 1] = '\0'; - } - } - return n; -} - -#ifndef XLOCALEDIR -#define XLOCALEDIR "/usr/lib/X11/locale" -#endif - -void -xlocaledir( - char *buf, - int buf_len) -{ - char *p = buf; - int len = 0; - -#ifndef NO_XLOCALEDIR - char *dir; - int priv = 1; - - dir = getenv("XLOCALEDIR"); - - if (dir) { -#ifndef WIN32 - /* - * Only use the user-supplied path if the process isn't priviledged. - */ - if (getuid() == geteuid() && getgid() == getegid()) { -#if defined(HASSETUGID) - priv = issetugid(); -#elif defined(HASGETRESUID) - { - uid_t ruid, euid, suid; - gid_t rgid, egid, sgid; - if ((getresuid(&ruid, &euid, &suid) == 0) && - (getresgid(&rgid, &egid, &sgid) == 0)) - priv = (euid != suid) || (egid != sgid); - } -#else - /* - * If there are saved ID's the process might still be priviledged - * even though the above test succeeded. If issetugid() and - * getresgid() aren't available, test this by trying to set - * euid to 0. - * - * Note: this only protects setuid-root clients. It doesn't - * protect other setuid or any setgid clients. If this tradeoff - * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def. - */ - unsigned int oldeuid; - oldeuid = geteuid(); - if (seteuid(0) != 0) { - priv = 0; - } else { - if (seteuid(oldeuid) == -1) { - /* XXX ouch, coudn't get back to original uid - what can we do ??? */ - _exit(127); - } - priv = 1; - } -#endif - } -#else - priv = 0; -#endif - if (!priv) { - len = strlen(dir); - strncpy(p, dir, buf_len); - if (len < buf_len) { - p[len++] = LC_PATHDELIM; - p += len; - } - } - } -#endif /* NO_XLOCALEDIR */ - - if (len < buf_len) -#ifndef __UNIXOS2__ - strncpy(p, XLOCALEDIR, buf_len - len); -#else - strncpy(p,__XOS2RedirRoot(XLOCALEDIR), buf_len - len); -#endif - buf[buf_len-1] = '\0'; -} - -static void -xlocalelibdir( - char *buf, - int buf_len) -{ - char *p = buf; - int len = 0; - -#ifndef NO_XLOCALEDIR - char *dir; - int priv = 1; - - dir = getenv("XLOCALELIBDIR"); - - if (dir) { -#ifndef WIN32 - /* - * Only use the user-supplied path if the process isn't priviledged. - */ - if (getuid() == geteuid() && getgid() == getegid()) { -#if defined(HASSETUGID) - priv = issetugid(); -#elif defined(HASGETRESUID) - { - uid_t ruid, euid, suid; - gid_t rgid, egid, sgid; - if ((getresuid(&ruid, &euid, &suid) == 0) && - (getresgid(&rgid, &egid, &sgid) == 0)) - priv = (euid != suid) || (egid != sgid); - } -#else - /* - * If there are saved ID's the process might still be priviledged - * even though the above test succeeded. If issetugid() and - * getresgid() aren't available, test this by trying to set - * euid to 0. - * - * Note: this only protects setuid-root clients. It doesn't - * protect other setuid or any setgid clients. If this tradeoff - * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def. - */ - unsigned int oldeuid; - oldeuid = geteuid(); - if (seteuid(0) != 0) { - priv = 0; - } else { - if (seteuid(oldeuid) == -1) { - /* XXX ouch, coudn't get back to original uid - what can we do ??? */ - _exit(127); - } - priv = 1; - } -#endif - } -#else - priv = 0; -#endif - if (!priv) { - len = strlen(dir); - strncpy(p, dir, buf_len); - if (len < buf_len) { - p[len++] = LC_PATHDELIM; - p += len; - } - } - } -#endif /* NO_XLOCALEDIR */ - - if (len < buf_len) -#ifndef __UNIXOS2__ - strncpy(p, XLOCALELIBDIR, buf_len - len); -#else - strncpy(p,__XOS2RedirRoot(XLOCALELIBDIR), buf_len - len); -#endif - buf[buf_len-1] = '\0'; -} - -/* Mapping direction */ -typedef enum { - LtoR, /* Map first field to second field */ - RtoL /* Map second field to first field */ -} MapDirection; - -static char * -resolve_name( - const char *lc_name, - char *file_name, - MapDirection direction) -{ - FILE *fp; - char buf[XLC_BUFSIZE], *name = NULL; - - fp = _XFopenFile (file_name, "r"); - if (fp == NULL) - return NULL; - - while (fgets(buf, XLC_BUFSIZE, fp) != NULL) { - char *p = buf; - int n; - char *args[2], *from, *to; -#ifdef __UNIXOS2__ /* Take out CR under OS/2 */ - int len; - - len = strlen(p); - if (len > 1) { - if (*(p+len-2) == '\r' && *(p+len-1) == '\n') { - *(p+len-2) = '\n'; - *(p+len-1) = '\0'; - } - } -#endif - while (isspace(*p)) { - ++p; - } - if (iscomment(*p)) { - continue; - } - n = parse_line(p, args, 2); /* get first 2 fields */ - if (n != 2) { - continue; - } - if (direction == LtoR) { - from = args[0], to = args[1]; /* left to right */ - } else { - from = args[1], to = args[0]; /* right to left */ - } - if (! strcmp(from, lc_name)) { - name = strdup(to); - break; - } - } - fclose(fp); - return name; -} - -#define c_tolower(ch) ((ch) >= 'A' && (ch) <= 'Z' ? (ch) - 'A' + 'a' : (ch)) - -static char * -lowercase( - char *dst, - const char *src) -{ - const char *s; - char *t; - - for (s = src, t = dst; *s; ++s, ++t) - *t = c_tolower(*s); - *t = '\0'; - return dst; -} - -/* - * normalize_lcname(): remove any '_' and '-' and convert any character - * to lower case after the <language>_<territory> part. If result is identical - * to argument, free result and - * return NULL. - */ -static char * -normalize_lcname (const char *name) -{ - char *p, *ret; - const char *tmp = name; - - p = ret = Xmalloc(strlen(name) + 1); - if (!p) - return NULL; - - if (tmp) { - while (*tmp && *tmp != '.' && *tmp != '@') - *p++ = *tmp++; - while (*tmp) { - if (*tmp != '-') - *p++ = c_tolower(*tmp); - tmp++; - } - } - *p = '\0'; - - if (strcmp(ret, name) == 0) { - Xfree(ret); - return NULL; - } - - return ret; -} - -/************************************************************************/ -char * -_XlcFileName( - XLCd lcd, - const char *category) -{ - char *siname; - char cat[XLC_BUFSIZE], dir[XLC_BUFSIZE]; - int i, n; - char *args[NUM_LOCALEDIR]; - char *file_name = NULL; - - if (lcd == (XLCd)NULL) - return NULL; - - siname = XLC_PUBLIC(lcd, siname); - - if (category) - lowercase(cat, category); - else - cat[0] = '\0'; - xlocaledir(dir,XLC_BUFSIZE); - n = _XlcParsePath(dir, args, NUM_LOCALEDIR); - for (i = 0; i < n; ++i) { - char buf[PATH_MAX], *name; - - name = NULL; - if ((5 + (args[i] ? strlen (args[i]) : 0) + strlen(cat)) < PATH_MAX) { - sprintf(buf, "%s/%s.dir", args[i], cat); - name = resolve_name(siname, buf, RtoL); - } - if (name == NULL) { - continue; - } - if (*name == '/') { - /* supposed to be absolute path name */ - file_name = name; - } else { - file_name = Xmalloc(2 + (args[i] ? strlen (args[i]) : 0) + - (name ? strlen (name) : 0)); - if (file_name != NULL) - sprintf(file_name, "%s/%s", args[i], name); - Xfree(name); - } - if (isreadable(file_name)) { - break; - } - Xfree(file_name); - file_name = NULL; - /* Then, try with next dir */ - } - return file_name; -} - -/************************************************************************/ -#ifndef LOCALE_ALIAS -#define LOCALE_ALIAS "locale.alias" -#endif - -int -_XlcResolveLocaleName( - const char* lc_name, - XLCdPublicPart* pub) -{ - char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; - char *dst; - int i, n, sinamelen; - char *args[NUM_LOCALEDIR]; - static const char locale_alias[] = LOCALE_ALIAS; - char *tmp_siname; - char *nlc_name = NULL; - - xlocaledir (dir, PATH_MAX); - n = _XlcParsePath(dir, args, NUM_LOCALEDIR); - for (i = 0; i < n; ++i) { - if ((2 + (args[i] ? strlen (args[i]) : 0) + - strlen (locale_alias)) < PATH_MAX) { - sprintf (buf, "%s/%s", args[i], locale_alias); - name = resolve_name (lc_name, buf, LtoR); - if (!name) { - if (!nlc_name) - nlc_name = normalize_lcname(lc_name); - if (nlc_name) - name = resolve_name (nlc_name, buf, LtoR); - } - } - if (name != NULL) { - break; - } - } - if (nlc_name) Xfree(nlc_name); - - if (name == NULL) { - /* vendor locale name == Xlocale name, no expansion of alias */ - pub->siname = strdup (lc_name); - } else { - pub->siname = name; - } - - sinamelen = strlen (pub->siname); - if (sinamelen == 1 && pub->siname[0] == 'C') { - pub->language = pub->siname; - pub->territory = pub->codeset = NULL; - return 1; - } - - /* - * pub->siname is in the format <lang>_<terr>.<codeset>, typical would - * be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS, - * although it could be ja.SJIS too. - */ - tmp_siname = Xrealloc (pub->siname, 2 * (sinamelen + 1)); - if (tmp_siname == NULL) { - return 0; - } - pub->siname = tmp_siname; - - /* language */ - dst = &pub->siname[sinamelen + 1]; - strcpy (dst, pub->siname); - pub->language = dst; - - /* territory */ - dst = strchr (dst, '_'); - if (dst) { - *dst = '\0'; - pub->territory = ++dst; - } else - dst = &pub->siname[sinamelen + 1]; - - /* codeset */ - dst = strchr (dst, '.'); - if (dst) { - *dst = '\0'; - pub->codeset = ++dst; - } - - return (pub->siname[0] != '\0') ? 1 : 0; -} - -/************************************************************************/ -int -_XlcResolveI18NPath(char *buf, int buf_len) -{ - if (buf != NULL) { - xlocaledir(buf, buf_len); - } - return 1; -} - -char * -_XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name) -{ - char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; - int i, n; - char *args[NUM_LOCALEDIR]; - static char locale_alias[] = LOCALE_ALIAS; - char *target_name = (char*)0; - char *target_dir = (char*)0; - char *nlc_name = NULL; - static char* last_dir_name = 0; - static size_t last_dir_len = 0; - static char* last_lc_name = 0; - - if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0 - && dir_len >= last_dir_len) { - strcpy (dir_name, last_dir_name); - return dir_name; - } - - xlocaledir (dir, PATH_MAX); - n = _XlcParsePath(dir, args, 256); - for (i = 0; i < n; ++i) { - - if ((2 + (args[i] ? strlen(args[i]) : 0) + - strlen(locale_alias)) < PATH_MAX) { - sprintf (buf, "%s/%s", args[i], locale_alias); - name = resolve_name(lc_name, buf, LtoR); - if (!name) { - if (!nlc_name) - nlc_name = normalize_lcname(lc_name); - if (nlc_name) - name = resolve_name (nlc_name, buf, LtoR); - } - } - - /* If name is not an alias, use lc_name for locale.dir search */ - if (name == NULL) - name = lc_name; - - /* look at locale.dir */ - - target_dir = args[i]; - if (!target_dir) { - /* something wrong */ - if (name != lc_name) - Xfree(name); - continue; - } - if ((1 + strlen (target_dir) + strlen("locale.dir")) < PATH_MAX) { - sprintf(buf, "%s/locale.dir", target_dir); - target_name = resolve_name(name, buf, RtoL); - } - if (name != lc_name) - Xfree(name); - if (target_name != NULL) { - char *p = 0; - if ((p = strstr(target_name, "/XLC_LOCALE"))) { - *p = '\0'; - break; - } - Xfree(target_name); - target_name = NULL; - } - name = NULL; - } - if (nlc_name) Xfree(nlc_name); - - if (target_name == NULL) { - /* vendor locale name == Xlocale name, no expansion of alias */ - target_dir = args[0]; - target_name = lc_name; - } - /* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */ - strncpy(dir_name, target_dir, dir_len - 1); - if (strlen(target_dir) >= dir_len - 1) { - dir_name[dir_len - 1] = '\0'; - } else { - strcat(dir_name, "/"); - strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1); - if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) - dir_name[dir_len - 1] = '\0'; - } - if (target_name != lc_name) - Xfree(target_name); - - if (last_dir_name != 0) - Xfree (last_dir_name); - if (last_lc_name != 0) - Xfree (last_lc_name); - last_dir_len = strlen (dir_name) + 1; - last_dir_name = Xmalloc (last_dir_len); - strcpy (last_dir_name, dir_name); - last_lc_name = strdup (lc_name); - - return dir_name; -} - -char * -_XlcLocaleLibDirName(char *dir_name, size_t dir_len, char *lc_name) -{ - char dir[PATH_MAX], buf[PATH_MAX], *name = NULL; - int i, n; - char *args[NUM_LOCALEDIR]; - static char locale_alias[] = LOCALE_ALIAS; - char *target_name = (char*)0; - char *target_dir = (char*)0; - char *nlc_name = NULL; - static char* last_dir_name = 0; - static size_t last_dir_len = 0; - static char* last_lc_name = 0; - - if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0 - && dir_len >= last_dir_len) { - strcpy (dir_name, last_dir_name); - return dir_name; - } - - xlocalelibdir (dir, PATH_MAX); - n = _XlcParsePath(dir, args, 256); - for (i = 0; i < n; ++i) { - - if ((2 + (args[i] ? strlen(args[i]) : 0) + - strlen(locale_alias)) < PATH_MAX) { - sprintf (buf, "%s/%s", args[i], locale_alias); - name = resolve_name(lc_name, buf, LtoR); - if (!name) { - if (!nlc_name) - nlc_name = normalize_lcname(lc_name); - if (nlc_name) - name = resolve_name (nlc_name, buf, LtoR); - } - } - - /* If name is not an alias, use lc_name for locale.dir search */ - if (name == NULL) - name = lc_name; - - /* look at locale.dir */ - - target_dir = args[i]; - if (!target_dir) { - /* something wrong */ - if (name != lc_name) - Xfree(name); - continue; - } - if ((1 + strlen (target_dir) + strlen("locale.dir")) < PATH_MAX) { - sprintf(buf, "%s/locale.dir", target_dir); - target_name = resolve_name(name, buf, RtoL); - } - if (name != lc_name) - Xfree(name); - if (target_name != NULL) { - char *p = 0; - if ((p = strstr(target_name, "/XLC_LOCALE"))) { - *p = '\0'; - break; - } - Xfree(target_name); - target_name = NULL; - } - name = NULL; - } - if (nlc_name) Xfree(nlc_name); - - if (target_name == NULL) { - /* vendor locale name == Xlocale name, no expansion of alias */ - target_dir = args[0]; - target_name = lc_name; - } - /* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */ - strncpy(dir_name, target_dir, dir_len - 1); - if (strlen(target_dir) >= dir_len - 1) { - dir_name[dir_len - 1] = '\0'; - } else { - strcat(dir_name, "/"); - strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1); - if (strlen(target_name) >= dir_len - strlen(dir_name) - 1) - dir_name[dir_len - 1] = '\0'; - } - if (target_name != lc_name) - Xfree(target_name); - - if (last_dir_name != 0) - Xfree (last_dir_name); - if (last_lc_name != 0) - Xfree (last_lc_name); - last_dir_len = strlen (dir_name) + 1; - last_dir_name = Xmalloc (last_dir_len); - strcpy (last_dir_name, dir_name); - last_lc_name = strdup (lc_name); - - return dir_name; -} +/*
+ *
+ * Copyright IBM Corporation 1993
+ *
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * 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 IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
+ * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "Xlibint.h"
+#include "XlcPubI.h"
+#include <X11/Xos.h>
+#include <unistd.h>
+
+/************************************************************************/
+
+#ifdef __UNIXOS2__
+# define seteuid setuid
+#endif
+#define iscomment(ch) ((ch) == '#' || (ch) == '\0')
+#if defined(WIN32)
+#define isreadable(f) (_XAccessFile(f))
+#else
+#define isreadable(f) ((access((f), R_OK) != -1) ? 1 : 0)
+#endif
+
+#ifndef __UNIXOS2__
+#define LC_PATHDELIM ':'
+#else
+#define LC_PATHDELIM ';'
+#endif
+
+#define XLC_BUFSIZE 256
+
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#ifndef PATH_MAX
+#ifdef WIN32
+#define PATH_MAX 512
+#else
+#include <sys/param.h>
+#endif
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+#define NUM_LOCALEDIR 64
+
+/* Splits a NUL terminated line into constituents, at colons and newline
+ characters. Leading whitespace is removed from constituents. The
+ constituents are stored at argv[0..argsize-1]. The number of stored
+ constituents (<= argsize) is returned. The line is destructively
+ modified. */
+static int
+parse_line(
+ char *line,
+ char **argv,
+ int argsize)
+{
+ int argc = 0;
+ char *p = line;
+
+ while (argc < argsize) {
+ while (isspace(*p)) {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ argv[argc++] = p;
+ while (*p != ':' && *p != '\n' && *p != '\0') {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ *p++ = '\0';
+ }
+
+ return argc;
+}
+
+#ifdef __UNIXOS2__
+
+/* fg021216: entries in locale files are separated by colons while under
+ OS/2, path entries are separated by semicolon, so we need two functions */
+
+static int
+parse_line1(
+ char *line,
+ char **argv,
+ int argsize)
+{
+ int argc = 0;
+ char *p = line;
+
+ while (argc < argsize) {
+ while (isspace(*p)) {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ argv[argc++] = p;
+ while (*p != ';' && *p != '\n' && *p != '\0') {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ *p++ = '\0';
+ }
+
+ return argc;
+}
+#elif defined(WIN32)
+
+/* this is parse_line but skips drive letters at the beginning of the entry */
+static int
+parse_line1(
+ char *line,
+ char **argv,
+ int argsize)
+{
+ int argc = 0;
+ char *p = line;
+
+ while (argc < argsize) {
+ while (isspace(*p)) {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ argv[argc++] = p;
+ if (isalpha(*p) && p[1] == ':') {
+ p+= 2; /* skip drive letters */
+ }
+ while (*p != ':' && *p != '\n' && *p != '\0') {
+ ++p;
+ }
+ if (*p == '\0') {
+ break;
+ }
+ *p++ = '\0';
+ }
+
+ return argc;
+}
+
+#endif /* __UNIXOS2__ */
+
+/* Splits a colon separated list of directories, and returns the constituent
+ paths (without trailing slash). At most argsize constituents are stored
+ at argv[0..argsize-1]. The number of stored constituents is returned. */
+static int
+_XlcParsePath(
+ char *path,
+ char **argv,
+ int argsize)
+{
+ char *p = path;
+ int n, i;
+
+#if !defined(__UNIXOS2__) && !defined(WIN32)
+ n = parse_line(path, argv, argsize);
+#else
+ n = parse_line1(path, argv, argsize);
+#endif
+ for (i = 0; i < n; ++i) {
+ int len;
+ p = argv[i];
+ len = strlen(p);
+ if (len > 0 && p[len - 1] == '/') {
+ /* eliminate trailing slash */
+ p[len - 1] = '\0';
+ }
+ }
+ return n;
+}
+
+#ifndef XLOCALEDIR
+#define XLOCALEDIR "locale"
+#endif
+
+void
+xlocaledir(
+ char *buf,
+ int buf_len)
+{
+ char *p = buf;
+ int len = 0;
+
+#ifndef NO_XLOCALEDIR
+ char *dir;
+ int priv = 1;
+
+ dir = getenv("XLOCALEDIR");
+
+ if (dir) {
+#ifndef WIN32
+ /*
+ * Only use the user-supplied path if the process isn't priviledged.
+ */
+ if (getuid() == geteuid() && getgid() == getegid()) {
+#if defined(HASSETUGID)
+ priv = issetugid();
+#elif defined(HASGETRESUID)
+ {
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+ if ((getresuid(&ruid, &euid, &suid) == 0) &&
+ (getresgid(&rgid, &egid, &sgid) == 0))
+ priv = (euid != suid) || (egid != sgid);
+ }
+#else
+ /*
+ * If there are saved ID's the process might still be priviledged
+ * even though the above test succeeded. If issetugid() and
+ * getresgid() aren't available, test this by trying to set
+ * euid to 0.
+ *
+ * Note: this only protects setuid-root clients. It doesn't
+ * protect other setuid or any setgid clients. If this tradeoff
+ * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def.
+ */
+ unsigned int oldeuid;
+ oldeuid = geteuid();
+ if (seteuid(0) != 0) {
+ priv = 0;
+ } else {
+ if (seteuid(oldeuid) == -1) {
+ /* XXX ouch, coudn't get back to original uid
+ what can we do ??? */
+ _exit(127);
+ }
+ priv = 1;
+ }
+#endif
+ }
+#else
+ priv = 0;
+#endif
+ if (!priv) {
+ len = strlen(dir);
+ strncpy(p, dir, buf_len);
+ if (len < buf_len) {
+ p[len++] = LC_PATHDELIM;
+ p += len;
+ }
+ }
+ }
+#endif /* NO_XLOCALEDIR */
+
+ if (len < buf_len)
+#ifndef __UNIXOS2__
+ strncpy(p, XLOCALEDIR, buf_len - len);
+#else
+ strncpy(p,__XOS2RedirRoot(XLOCALEDIR), buf_len - len);
+#endif
+ buf[buf_len-1] = '\0';
+}
+
+static void
+xlocalelibdir(
+ char *buf,
+ int buf_len)
+{
+ char *p = buf;
+ int len = 0;
+
+#ifndef NO_XLOCALEDIR
+ char *dir;
+ int priv = 1;
+
+ dir = getenv("XLOCALELIBDIR");
+
+ if (dir) {
+#ifndef WIN32
+ /*
+ * Only use the user-supplied path if the process isn't priviledged.
+ */
+ if (getuid() == geteuid() && getgid() == getegid()) {
+#if defined(HASSETUGID)
+ priv = issetugid();
+#elif defined(HASGETRESUID)
+ {
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+ if ((getresuid(&ruid, &euid, &suid) == 0) &&
+ (getresgid(&rgid, &egid, &sgid) == 0))
+ priv = (euid != suid) || (egid != sgid);
+ }
+#else
+ /*
+ * If there are saved ID's the process might still be priviledged
+ * even though the above test succeeded. If issetugid() and
+ * getresgid() aren't available, test this by trying to set
+ * euid to 0.
+ *
+ * Note: this only protects setuid-root clients. It doesn't
+ * protect other setuid or any setgid clients. If this tradeoff
+ * isn't acceptable, set DisableXLocaleDirEnv to YES in host.def.
+ */
+ unsigned int oldeuid;
+ oldeuid = geteuid();
+ if (seteuid(0) != 0) {
+ priv = 0;
+ } else {
+ if (seteuid(oldeuid) == -1) {
+ /* XXX ouch, coudn't get back to original uid
+ what can we do ??? */
+ _exit(127);
+ }
+ priv = 1;
+ }
+#endif
+ }
+#else
+ priv = 0;
+#endif
+ if (!priv) {
+ len = strlen(dir);
+ strncpy(p, dir, buf_len);
+ if (len < buf_len) {
+ p[len++] = LC_PATHDELIM;
+ p += len;
+ }
+ }
+ }
+#endif /* NO_XLOCALEDIR */
+
+ if (len < buf_len)
+#ifndef __UNIXOS2__
+ strncpy(p, XLOCALELIBDIR, buf_len - len);
+#else
+ strncpy(p,__XOS2RedirRoot(XLOCALELIBDIR), buf_len - len);
+#endif
+ buf[buf_len-1] = '\0';
+}
+
+/* Mapping direction */
+typedef enum {
+ LtoR, /* Map first field to second field */
+ RtoL /* Map second field to first field */
+} MapDirection;
+
+static char *
+resolve_name(
+ const char *lc_name,
+ char *file_name,
+ MapDirection direction)
+{
+ FILE *fp;
+ char buf[XLC_BUFSIZE], *name = NULL;
+
+ fp = _XFopenFile (file_name, "r");
+ if (fp == NULL)
+ return NULL;
+
+ while (fgets(buf, XLC_BUFSIZE, fp) != NULL) {
+ char *p = buf;
+ int n;
+ char *args[2], *from, *to;
+#ifdef __UNIXOS2__ /* Take out CR under OS/2 */
+ int len;
+
+ len = strlen(p);
+ if (len > 1) {
+ if (*(p+len-2) == '\r' && *(p+len-1) == '\n') {
+ *(p+len-2) = '\n';
+ *(p+len-1) = '\0';
+ }
+ }
+#endif
+ while (isspace(*p)) {
+ ++p;
+ }
+ if (iscomment(*p)) {
+ continue;
+ }
+ n = parse_line(p, args, 2); /* get first 2 fields */
+ if (n != 2) {
+ continue;
+ }
+ if (direction == LtoR) {
+ from = args[0], to = args[1]; /* left to right */
+ } else {
+ from = args[1], to = args[0]; /* right to left */
+ }
+ if (! strcmp(from, lc_name)) {
+ name = strdup(to);
+ break;
+ }
+ }
+ fclose(fp);
+ return name;
+}
+
+#define c_tolower(ch) ((ch) >= 'A' && (ch) <= 'Z' ? (ch) - 'A' + 'a' : (ch))
+
+static char *
+lowercase(
+ char *dst,
+ const char *src)
+{
+ const char *s;
+ char *t;
+
+ for (s = src, t = dst; *s; ++s, ++t)
+ *t = c_tolower(*s);
+ *t = '\0';
+ return dst;
+}
+
+/*
+ * normalize_lcname(): remove any '_' and '-' and convert any character
+ * to lower case after the <language>_<territory> part. If result is identical
+ * to argument, free result and
+ * return NULL.
+ */
+static char *
+normalize_lcname (const char *name)
+{
+ char *p, *ret;
+ const char *tmp = name;
+
+ p = ret = Xmalloc(strlen(name) + 1);
+ if (!p)
+ return NULL;
+
+ if (tmp) {
+ while (*tmp && *tmp != '.' && *tmp != '@')
+ *p++ = *tmp++;
+ while (*tmp) {
+ if (*tmp != '-')
+ *p++ = c_tolower(*tmp);
+ tmp++;
+ }
+ }
+ *p = '\0';
+
+ if (strcmp(ret, name) == 0) {
+ Xfree(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+/************************************************************************/
+char *
+_XlcFileName(
+ XLCd lcd,
+ const char *category)
+{
+ char *siname;
+ char cat[XLC_BUFSIZE], dir[XLC_BUFSIZE];
+ int i, n;
+ char *args[NUM_LOCALEDIR];
+ char *file_name = NULL;
+
+ if (lcd == (XLCd)NULL)
+ return NULL;
+
+ siname = XLC_PUBLIC(lcd, siname);
+
+ if (category)
+ lowercase(cat, category);
+ else
+ cat[0] = '\0';
+ xlocaledir(dir,XLC_BUFSIZE);
+ n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
+ for (i = 0; i < n; ++i) {
+ char buf[PATH_MAX], *name;
+
+ name = NULL;
+ if ((5 + (args[i] ? strlen (args[i]) : 0) + strlen(cat)) < PATH_MAX) {
+ sprintf(buf, "%s/%s.dir", args[i], cat);
+ name = resolve_name(siname, buf, RtoL);
+ }
+ if (name == NULL) {
+ continue;
+ }
+ if (*name == '/') {
+ /* supposed to be absolute path name */
+ file_name = name;
+ } else {
+ file_name = Xmalloc(2 + (args[i] ? strlen (args[i]) : 0) +
+ (name ? strlen (name) : 0));
+ if (file_name != NULL)
+ sprintf(file_name, "%s/%s", args[i], name);
+ Xfree(name);
+ }
+ if (isreadable(file_name)) {
+ break;
+ }
+ Xfree(file_name);
+ file_name = NULL;
+ /* Then, try with next dir */
+ }
+ return file_name;
+}
+
+/************************************************************************/
+#ifndef LOCALE_ALIAS
+#define LOCALE_ALIAS "locale.alias"
+#endif
+
+int
+_XlcResolveLocaleName(
+ const char* lc_name,
+ XLCdPublicPart* pub)
+{
+ char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
+ char *dst;
+ int i, n, sinamelen;
+ char *args[NUM_LOCALEDIR];
+ static const char locale_alias[] = LOCALE_ALIAS;
+ char *tmp_siname;
+ char *nlc_name = NULL;
+
+ xlocaledir (dir, PATH_MAX);
+ n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
+ for (i = 0; i < n; ++i) {
+ if ((2 + (args[i] ? strlen (args[i]) : 0) +
+ strlen (locale_alias)) < PATH_MAX) {
+ sprintf (buf, "%s/%s", args[i], locale_alias);
+ name = resolve_name (lc_name, buf, LtoR);
+ if (!name) {
+ if (!nlc_name)
+ nlc_name = normalize_lcname(lc_name);
+ if (nlc_name)
+ name = resolve_name (nlc_name, buf, LtoR);
+ }
+ }
+ if (name != NULL) {
+ break;
+ }
+ }
+ if (nlc_name) Xfree(nlc_name);
+
+ if (name == NULL) {
+ /* vendor locale name == Xlocale name, no expansion of alias */
+ pub->siname = strdup (lc_name);
+ } else {
+ pub->siname = name;
+ }
+
+ sinamelen = strlen (pub->siname);
+ if (sinamelen == 1 && pub->siname[0] == 'C') {
+ pub->language = pub->siname;
+ pub->territory = pub->codeset = NULL;
+ return 1;
+ }
+
+ /*
+ * pub->siname is in the format <lang>_<terr>.<codeset>, typical would
+ * be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS,
+ * although it could be ja.SJIS too.
+ */
+ tmp_siname = Xrealloc (pub->siname, 2 * (sinamelen + 1));
+ if (tmp_siname == NULL) {
+ return 0;
+ }
+ pub->siname = tmp_siname;
+
+ /* language */
+ dst = &pub->siname[sinamelen + 1];
+ strcpy (dst, pub->siname);
+ pub->language = dst;
+
+ /* territory */
+ dst = strchr (dst, '_');
+ if (dst) {
+ *dst = '\0';
+ pub->territory = ++dst;
+ } else
+ dst = &pub->siname[sinamelen + 1];
+
+ /* codeset */
+ dst = strchr (dst, '.');
+ if (dst) {
+ *dst = '\0';
+ pub->codeset = ++dst;
+ }
+
+ return (pub->siname[0] != '\0') ? 1 : 0;
+}
+
+/************************************************************************/
+int
+_XlcResolveI18NPath(char *buf, int buf_len)
+{
+ if (buf != NULL) {
+ xlocaledir(buf, buf_len);
+ }
+ return 1;
+}
+
+char *
+_XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name)
+{
+ char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
+ int i, n;
+ char *args[NUM_LOCALEDIR];
+ static char locale_alias[] = LOCALE_ALIAS;
+ char *target_name = (char*)0;
+ char *target_dir = (char*)0;
+ char *nlc_name = NULL;
+ static char* last_dir_name = 0;
+ static size_t last_dir_len = 0;
+ static char* last_lc_name = 0;
+
+ if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
+ && dir_len >= last_dir_len) {
+ strcpy (dir_name, last_dir_name);
+ return dir_name;
+ }
+
+ xlocaledir (dir, PATH_MAX);
+ n = _XlcParsePath(dir, args, 256);
+ for (i = 0; i < n; ++i) {
+
+ if ((2 + (args[i] ? strlen(args[i]) : 0) +
+ strlen(locale_alias)) < PATH_MAX) {
+ sprintf (buf, "%s/%s", args[i], locale_alias);
+ name = resolve_name(lc_name, buf, LtoR);
+ if (!name) {
+ if (!nlc_name)
+ nlc_name = normalize_lcname(lc_name);
+ if (nlc_name)
+ name = resolve_name (nlc_name, buf, LtoR);
+ }
+ }
+
+ /* If name is not an alias, use lc_name for locale.dir search */
+ if (name == NULL)
+ name = lc_name;
+
+ /* look at locale.dir */
+
+ target_dir = args[i];
+ if (!target_dir) {
+ /* something wrong */
+ if (name != lc_name)
+ Xfree(name);
+ continue;
+ }
+ if ((1 + strlen (target_dir) + strlen("locale.dir")) < PATH_MAX) {
+ sprintf(buf, "%s/locale.dir", target_dir);
+ target_name = resolve_name(name, buf, RtoL);
+ }
+ if (name != lc_name)
+ Xfree(name);
+ if (target_name != NULL) {
+ char *p = 0;
+ if ((p = strstr(target_name, "/XLC_LOCALE"))) {
+ *p = '\0';
+ break;
+ }
+ Xfree(target_name);
+ target_name = NULL;
+ }
+ name = NULL;
+ }
+ if (nlc_name) Xfree(nlc_name);
+
+ if (target_name == NULL) {
+ /* vendor locale name == Xlocale name, no expansion of alias */
+ target_dir = args[0];
+ target_name = lc_name;
+ }
+ /* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */
+ strncpy(dir_name, target_dir, dir_len - 1);
+ if (strlen(target_dir) >= dir_len - 1) {
+ dir_name[dir_len - 1] = '\0';
+ } else {
+ strcat(dir_name, "/");
+ strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
+ if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
+ dir_name[dir_len - 1] = '\0';
+ }
+ if (target_name != lc_name)
+ Xfree(target_name);
+
+ if (last_dir_name != 0)
+ Xfree (last_dir_name);
+ if (last_lc_name != 0)
+ Xfree (last_lc_name);
+ last_dir_len = strlen (dir_name) + 1;
+ last_dir_name = Xmalloc (last_dir_len);
+ strcpy (last_dir_name, dir_name);
+ last_lc_name = strdup (lc_name);
+
+ return dir_name;
+}
+
+char *
+_XlcLocaleLibDirName(char *dir_name, size_t dir_len, char *lc_name)
+{
+ char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
+ int i, n;
+ char *args[NUM_LOCALEDIR];
+ static char locale_alias[] = LOCALE_ALIAS;
+ char *target_name = (char*)0;
+ char *target_dir = (char*)0;
+ char *nlc_name = NULL;
+ static char* last_dir_name = 0;
+ static size_t last_dir_len = 0;
+ static char* last_lc_name = 0;
+
+ if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
+ && dir_len >= last_dir_len) {
+ strcpy (dir_name, last_dir_name);
+ return dir_name;
+ }
+
+ xlocalelibdir (dir, PATH_MAX);
+ n = _XlcParsePath(dir, args, 256);
+ for (i = 0; i < n; ++i) {
+
+ if ((2 + (args[i] ? strlen(args[i]) : 0) +
+ strlen(locale_alias)) < PATH_MAX) {
+ sprintf (buf, "%s/%s", args[i], locale_alias);
+ name = resolve_name(lc_name, buf, LtoR);
+ if (!name) {
+ if (!nlc_name)
+ nlc_name = normalize_lcname(lc_name);
+ if (nlc_name)
+ name = resolve_name (nlc_name, buf, LtoR);
+ }
+ }
+
+ /* If name is not an alias, use lc_name for locale.dir search */
+ if (name == NULL)
+ name = lc_name;
+
+ /* look at locale.dir */
+
+ target_dir = args[i];
+ if (!target_dir) {
+ /* something wrong */
+ if (name != lc_name)
+ Xfree(name);
+ continue;
+ }
+ if ((1 + strlen (target_dir) + strlen("locale.dir")) < PATH_MAX) {
+ sprintf(buf, "%s/locale.dir", target_dir);
+ target_name = resolve_name(name, buf, RtoL);
+ }
+ if (name != lc_name)
+ Xfree(name);
+ if (target_name != NULL) {
+ char *p = 0;
+ if ((p = strstr(target_name, "/XLC_LOCALE"))) {
+ *p = '\0';
+ break;
+ }
+ Xfree(target_name);
+ target_name = NULL;
+ }
+ name = NULL;
+ }
+ if (nlc_name) Xfree(nlc_name);
+
+ if (target_name == NULL) {
+ /* vendor locale name == Xlocale name, no expansion of alias */
+ target_dir = args[0];
+ target_name = lc_name;
+ }
+ /* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */
+ strncpy(dir_name, target_dir, dir_len - 1);
+ if (strlen(target_dir) >= dir_len - 1) {
+ dir_name[dir_len - 1] = '\0';
+ } else {
+ strcat(dir_name, "/");
+ strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
+ if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
+ dir_name[dir_len - 1] = '\0';
+ }
+ if (target_name != lc_name)
+ Xfree(target_name);
+
+ if (last_dir_name != 0)
+ Xfree (last_dir_name);
+ if (last_lc_name != 0)
+ Xfree (last_lc_name);
+ last_dir_len = strlen (dir_name) + 1;
+ last_dir_name = Xmalloc (last_dir_len);
+ strcpy (last_dir_name, dir_name);
+ last_lc_name = strdup (lc_name);
+
+ return dir_name;
+}
diff --git a/libX11/src/xlibi18n/lcGeneric.c b/libX11/src/xlibi18n/lcGeneric.c index 619cb47f9..7001e69fd 100644 --- a/libX11/src/xlibi18n/lcGeneric.c +++ b/libX11/src/xlibi18n/lcGeneric.c @@ -1,1180 +1,1181 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ -/* - * (c) Copyright 1995 FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include "Xlibint.h" -#include "XlcGeneric.h" - -static XLCd create (const char *name, XLCdMethods methods); -static Bool initialize (XLCd lcd); -static void destroy (XLCd lcd); - -static XLCdPublicMethodsRec genericMethods = { - { NULL }, /* use default methods */ - { - NULL, - create, - initialize, - destroy, - NULL - } -}; - -XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods; - -static XLCd -create( - const char *name, - XLCdMethods methods) -{ - XLCd lcd; - XLCdPublicMethods new; - - lcd = Xcalloc(1, sizeof(XLCdRec)); - if (lcd == NULL) - return (XLCd) NULL; - - lcd->core = Xcalloc(1, sizeof(XLCdGenericRec)); - if (lcd->core == NULL) - goto err; - - new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec)); - if (new == NULL) - goto err; - memcpy(new,methods,sizeof(XLCdPublicMethodsRec)); - lcd->methods = (XLCdMethods) new; - - return lcd; - -err: - Xfree(lcd); - return (XLCd) NULL; -} - -static Bool -string_to_encoding( - const char *str, - char *encoding) -{ - char *next; - long value; - int base; - - while (*str) { - if (*str == '\\') { - switch (*(str + 1)) { - case 'x': - case 'X': - base = 16; - break; - default: - base = 8; - break; - } - value = strtol(str + 2, &next, base); - if (str + 2 != next) { - *((unsigned char *) encoding++) = (unsigned char) value; - str = next; - continue; - } - } - *encoding++ = *str++; - } - - *encoding = '\0'; - - return True; -} - -static Bool -string_to_ulong( - const char *str, - unsigned long *value) -{ - const char *tmp1 = str; - int base; - - if (*tmp1++ != '\\') { - tmp1--; - base = 10; - } else { - switch (*tmp1++) { - case 'x': - base = 16; - break; - case 'o': - base = 8; - break; - case 'd': - base = 10; - break; - default: - return(False); - } - } - *value = (unsigned long) strtol(tmp1, NULL, base); - return(True); -} - - -static Bool -add_charset( - CodeSet codeset, - XlcCharSet charset) -{ - XlcCharSet *new_list; - int num; - - if ((num = codeset->num_charsets)) - new_list = (XlcCharSet *) Xrealloc(codeset->charset_list, - (num + 1) * sizeof(XlcCharSet)); - else - new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet)); - - if (new_list == NULL) - return False; - - new_list[num] = charset; - codeset->charset_list = new_list; - codeset->num_charsets = num + 1; - - return True; -} - -static CodeSet -add_codeset( - XLCdGenericPart *gen) -{ - CodeSet new, *new_list; - int num; - - new = Xcalloc(1, sizeof(CodeSetRec)); - if (new == NULL) - return NULL; - - if ((num = gen->codeset_num)) - new_list = (CodeSet *) Xrealloc(gen->codeset_list, - (num + 1) * sizeof(CodeSet)); - else - new_list = (CodeSet *) Xmalloc(sizeof(CodeSet)); - - if (new_list == NULL) - goto err; - - new_list[num] = new; - gen->codeset_list = new_list; - gen->codeset_num = num + 1; - - return new; - -err: - Xfree(new); - - return NULL; -} - -static Bool -add_parse_list( - XLCdGenericPart *gen, - EncodingType type, - const char *encoding, - CodeSet codeset) -{ - ParseInfo new, *new_list; - char *str; - unsigned char ch; - int num; - - str = strdup(encoding); - if (str == NULL) - return False; - - new = Xcalloc(1, sizeof(ParseInfoRec)); - if (new == NULL) - goto err; - - if (gen->mb_parse_table == NULL) { - gen->mb_parse_table = Xcalloc(1, 256); /* 2^8 */ - if (gen->mb_parse_table == NULL) - goto err; - } - - if ((num = gen->mb_parse_list_num)) - new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list, - (num + 2) * sizeof(ParseInfo)); - else { - new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo)); - } - - if (new_list == NULL) - goto err; - - new_list[num] = new; - new_list[num + 1] = NULL; - gen->mb_parse_list = new_list; - gen->mb_parse_list_num = num + 1; - - ch = (unsigned char) *str; - if (gen->mb_parse_table[ch] == 0) - gen->mb_parse_table[ch] = num + 1; - - new->type = type; - new->encoding = str; - new->codeset = codeset; - - if (codeset->parse_info == NULL) - codeset->parse_info = new; - - return True; - -err: - Xfree(str); - if (new) - Xfree(new); - - return False; -} - -static void -free_charset( - XLCd lcd) -{ - XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); - ParseInfo *parse_info; - int num; - - if (gen->mb_parse_table) - Xfree(gen->mb_parse_table); - if ((num = gen->mb_parse_list_num) > 0) { - for (parse_info = gen->mb_parse_list; num-- > 0; parse_info++) { - if ((*parse_info)->encoding) - Xfree((*parse_info)->encoding); - Xfree(*parse_info); - } - Xfree(gen->mb_parse_list); - } - - if ((num = gen->codeset_num) > 0) - Xfree(gen->codeset_list); -} - -/* For VW/UDC */ - -#define FORWARD (unsigned long)'+' -#define BACKWARD (unsigned long)'-' - -static const char * -getscope( - const char *str, - FontScope scp) -{ - unsigned long start = 0; - unsigned long end = 0; - unsigned long dest = 0; - unsigned long shift = 0; - unsigned long direction = 0; - sscanf(str,"[\\x%lx,\\x%lx]->\\x%lx", &start, &end, &dest); - if (dest) { - if (dest >= start) { - shift = dest - start; - direction = FORWARD ; - } else { - shift = start - dest; - direction = BACKWARD; - } - } - scp->start = start ; - scp->end = end ; - scp->shift = shift ; - scp->shift_direction - = direction ; - /* .......... */ - while (*str) { - if (*str == ',' && *(str+1) == '[') - break; - str++; - } - return str+1; -} - -static int -count_scopemap( - const char *str) -{ - const char *ptr; - int num=0; - for (ptr=str; *ptr; ptr++) { - if (*ptr == ']') { - num++; - } - } - return num; -} - -FontScope -_XlcParse_scopemaps( - const char *str, - int *size) -{ - int num=0,i; - FontScope scope,sc_ptr; - const char *str_sc; - - num = count_scopemap(str); - scope = (FontScope) Xmalloc(num * sizeof(FontScopeRec)); - if (scope == NULL) - return NULL; - - for (i=0, str_sc=str, sc_ptr=scope; i < num; i++, sc_ptr++) { - str_sc = getscope(str_sc, sc_ptr); - } - *size = num; - return scope; -} - -void -_XlcDbg_printValue( - const char *str, - char **value, - int num) -{ -/* - int i; - for (i = 0; i < num; i++) - fprintf(stderr, "%s value[%d] = %s\n", str, i, value[i]); -*/ -} - -static void -dmpscope( - const char* name, - FontScope sc, - int num) -{ -/* - int i; - fprintf(stderr, "dmpscope %s\n", name); - for (i=0; i<num; i++) - fprintf(stderr,"%x %x %x %x \n", - sc[i].start, - sc[i].end, - sc[i].shift, - sc[i].shift_direction); - fprintf(stderr, "dmpscope end\n"); -*/ -} - -static XlcCharSet -srch_charset_define( - const char *name, - int *new) -{ - XlcCharSet charset; - - *new = 0; - charset = _XlcGetCharSet(name); - if (charset == NULL && - (charset = _XlcCreateDefaultCharSet(name, ""))) { - _XlcAddCharSet(charset); - *new = 1; - charset->source = CSsrcXLC; - } - return charset; -} - -static void -read_charset_define( - XLCd lcd, - XLCdGenericPart *gen) -{ - int i; - char csd[16], cset_name[256]; - char name[BUFSIZ]; - XlcCharSet charsetd; - char **value; - int num, new = 0; - XlcSide side = XlcUnknown; - char *tmp; - - for (i=0; ; i++) { /* loop start */ - charsetd = 0; - sprintf(csd, "csd%d", i); - - /* charset_name */ - sprintf(name, "%s.%s", csd, "charset_name"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - _XlcDbg_printValue(name,value,num); - if (num > 0) { - /* hackers will get truncated -- C'est la vie */ - strncpy(cset_name,value[0], sizeof cset_name - 1); - cset_name[(sizeof cset_name) - 1] = '\0'; - sprintf(name, "%s.%s", csd , "side"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - if (!_XlcNCompareISOLatin1(value[0], "none", 4)) { - side = XlcGLGR; - } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) { - side = XlcGL; - strcat(cset_name,":GL"); - } else { - side = XlcGR; - strcat(cset_name,":GR"); - } - if (charsetd == NULL && - (charsetd = srch_charset_define(cset_name,&new)) == NULL) - return; - } - } else { - if (i == 0) - continue; - else - break; - } - if (new) { - tmp = strdup(cset_name); - if (tmp == NULL) - return; - charsetd->name = tmp; - } - /* side */ - charsetd->side = side ; - /* length */ - sprintf(name, "%s.%s", csd, "length"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - charsetd->char_size = atoi(value[0]); - } - /* gc_number */ - sprintf(name, "%s.%s", csd, "gc_number"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - charsetd->set_size = atoi(value[0]); - } - /* string_encoding */ - sprintf(name, "%s.%s", csd, "string_encoding"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - if (!strcmp("False",value[0])) { - charsetd->string_encoding = False; - } else { - charsetd->string_encoding = True; - } - } - /* sequence */ - sprintf(name, "%s.%s", csd, "sequence"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); -/* - if (charsetd->ct_sequence) { - Xfree(charsetd->ct_sequence); - } -*/ - tmp = (char *)Xmalloc(strlen(value[0])+1); - if (tmp == NULL) - return; - charsetd->ct_sequence = tmp; - string_to_encoding(value[0],tmp); - } - /* encoding_name */ - sprintf(name, "%s.%s", csd, "encoding_name"); - _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); -/* - if (charsetd->encoding_name) { - Xfree(charsetd->encoding_name); - } -*/ - tmp = strdup(value[0]); - charsetd->encoding_name = tmp; - charsetd->xrm_encoding_name = XrmStringToQuark(tmp); - } - _XlcAddCT(charsetd->name, charsetd->ct_sequence); - } -} - -static SegConv -add_conversion( - XLCdGenericPart *gen) -{ - SegConv new_list; - int num; - - if ((num = gen->segment_conv_num) > 0) { - new_list = (SegConv) Xrealloc(gen->segment_conv, - (num + 1) * sizeof(SegConvRec)); - } else { - new_list = (SegConv) Xmalloc(sizeof(SegConvRec)); - } - - if (new_list == NULL) - return NULL; - - gen->segment_conv = new_list; - gen->segment_conv_num = num + 1; - - return &new_list[num]; - -} - -static void -read_segmentconversion( - XLCd lcd, - XLCdGenericPart *gen) -{ - int i; - char conv[16]; - char name[BUFSIZ]; - char **value; - int num,new; - SegConv conversion; - for (i=0 ; ; i++) { /* loop start */ - conversion = 0; - sprintf(conv, "conv%d", i); - - /* length */ - sprintf(name, "%s.%s", conv, "length"); - _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); - if (num > 0) { - if (conversion == NULL && - (conversion = add_conversion(gen)) == NULL) { - return; - } - _XlcDbg_printValue(name,value,num); - } else { - if (i == 0) - continue; - else - break; - } - conversion->length = atoi(value[0]); - - /* source_encoding */ - sprintf(name, "%s.%s", conv, "source_encoding"); - _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); - if (num > 0) { - char *tmp; - _XlcDbg_printValue(name,value,num); - tmp = strdup(value[0]); - if (tmp == NULL) - return; - conversion->source_encoding = tmp; - conversion->source = srch_charset_define(tmp,&new); - } - /* destination_encoding */ - sprintf(name, "%s.%s", conv, "destination_encoding"); - _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); - if (num > 0) { - char *tmp; - _XlcDbg_printValue(name,value,num); - tmp = strdup(value[0]); - if (tmp == NULL) - return; - conversion->destination_encoding = tmp; - conversion->dest = srch_charset_define(tmp,&new); - } - /* range */ - sprintf(name, "%s.%s", conv, "range"); - _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - sscanf(value[0],"\\x%lx,\\x%lx", - &(conversion->range.start), &(conversion->range.end)); - } - /* conversion */ - sprintf(name, "%s.%s", conv, "conversion"); - _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - conversion->conv = - _XlcParse_scopemaps(value[0],&conversion->conv_num); - } - } /* loop end */ -} - -static ExtdSegment -create_ctextseg( - char **value, - int num) -{ - ExtdSegment ret; - char* ptr; - char* cset_name = NULL; - int i,new; - FontScope scope; - ret = (ExtdSegment)Xmalloc(sizeof(ExtdSegmentRec)); - if (ret == NULL) - return NULL; - ret->name = strdup(value[0]); - if (ret->name == NULL) { - Xfree (ret); - return NULL; - } - cset_name = (char*) Xmalloc (strlen(ret->name) + 1); - if (cset_name == NULL) { - Xfree (ret->name); - Xfree (ret); - return NULL; - } - if (strchr(value[0],':')) { - ptr = strchr(ret->name,':'); - *ptr = '\0'; - ptr++; - if (!_XlcNCompareISOLatin1(ptr, "GL", 2)) { - ret->side = XlcGL; - sprintf(cset_name,"%s:%s",ret->name,"GL"); - } else { - ret->side = XlcGR; - sprintf(cset_name,"%s:%s",ret->name,"GR"); - } - } else { - ret->side = XlcGLGR; - strcpy(cset_name,ret->name); - } - ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec)); - if (ret->area == NULL) { - Xfree (cset_name); - Xfree (ret->name); - Xfree (ret); - return NULL; - } - ret->area_num = num - 1; - scope = ret->area ; - for (i = 1; i < num; i++) { - sscanf(value[i],"\\x%lx,\\x%lx", - &scope[i-1].start, &scope[i-1].end); - } - ret->charset = srch_charset_define(cset_name,&new); - Xfree (cset_name); - - return ret; -} -/* For VW/UDC end */ - -static Bool -load_generic( - XLCd lcd) -{ - XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); - char **value; - int num; - unsigned long l; - int i; - int M,ii; - XlcCharSet charset; - - gen->codeset_num = 0; - - /***** wc_encoding_mask *****/ - _XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num); - if (num > 0) { - if (string_to_ulong(value[0], &l) == False) - goto err; - gen->wc_encode_mask = l; - } - /***** wc_shift_bits *****/ - _XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num); - if (num > 0) - gen->wc_shift_bits = atoi(value[0]); - if (gen->wc_shift_bits < 1) - gen->wc_shift_bits = 8; - /***** use_stdc_env *****/ - _XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num); - if (num > 0 && !_XlcCompareISOLatin1(value[0], "True")) - gen->use_stdc_env = True; - else - gen->use_stdc_env = False; - /***** force_convert_to_mb *****/ - _XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num); - if (num > 0 && !_XlcCompareISOLatin1(value[0], "True")) - gen->force_convert_to_mb = True; - else - gen->force_convert_to_mb = False; - - for (i = 0; ; i++) { - CodeSetRec *codeset = NULL; - char cs[16]; - char name[BUFSIZ]; - - sprintf(cs, "cs%d", i); - - /***** codeset.side *****/ - sprintf(name, "%s.%s", cs , "side"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - char *tmp; - - if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) - goto err; - - /* 3.4.1 side */ - if (!_XlcNCompareISOLatin1(value[0], "none", 4)) { - codeset->side = XlcNONE; - } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) { - codeset->side = XlcGL; - } else { - codeset->side = XlcGR; - } - - tmp = strrchr(value[0], ':'); - if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) { - if (codeset->side == XlcGR) - gen->initial_state_GR = codeset; - else - gen->initial_state_GL = codeset; - } - } - - /***** codeset.length *****/ - sprintf(name, "%s.%s", cs , "length"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) - goto err; - codeset->length = atoi(value[0]); - if (codeset->length < 1) - codeset->length = 1; - } - - /***** codeset.mb_encoding *****/ - sprintf(name, "%s.%s", cs, "mb_encoding"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - static struct { - const char *str; - EncodingType type; - } shifts[] = { - {"<SS>", E_SS}, - {"<LSL>", E_LSL}, - {"<LSR>", E_LSR}, - {0} - }; - int j; - - if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) - goto err; - for ( ; num-- > 0; value++) { - char encoding[256]; - char *tmp = *value; - EncodingType type = E_SS; /* for BC */ - for (j = 0; shifts[j].str; j++) { - if (!_XlcNCompareISOLatin1(tmp, shifts[j].str, - strlen(shifts[j].str))) { - type = shifts[j].type; - tmp += strlen(shifts[j].str); - break; - } - } - if (strlen (tmp) > sizeof encoding || - string_to_encoding(tmp, encoding) == False) - goto err; - add_parse_list(gen, type, encoding, codeset); - } - } - - /***** codeset.wc_encoding *****/ - sprintf(name, "%s.%s", cs, "wc_encoding"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) - goto err; - if (string_to_ulong(value[0], &l) == False) - goto err; - codeset->wc_encoding = l; - } - - /***** codeset.ct_encoding *****/ - sprintf(name, "%s.%s", cs, "ct_encoding"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - char *encoding; - - if (codeset == NULL && (codeset = add_codeset(gen)) == NULL) - goto err; - for ( ; num-- > 0; value++) { - if (strlen (*value) > sizeof name) - goto err; - string_to_encoding(*value, name); - charset = NULL; - if ((encoding = strchr(name, ':')) && - (encoding = strchr(encoding + 1, ':'))) { - *encoding++ = '\0'; - charset = _XlcAddCT(name, encoding); - } - if (charset == NULL) { - charset = _XlcGetCharSet(name); - if (charset == NULL && - (charset = _XlcCreateDefaultCharSet(name, ""))) { - charset->side = codeset->side; - charset->char_size = codeset->length; - _XlcAddCharSet(charset); - } - } - if (charset) { - if (add_charset(codeset, charset) == False) - goto err; - } - } - } - - if (codeset == NULL) - break; - codeset->cs_num = i; - /* For VW/UDC */ - /***** 3.4.2 byteM (1 <= M <= length)*****/ - for (M=1; M-1 < codeset->length; M++) { - unsigned long start,end; - ByteInfo tmpb; - - sprintf(name,"%s.%s%d",cs,"byte",M); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - - if (M == 1) { - if (num < 1) { - codeset->byteM = NULL; - break ; - } - codeset->byteM = - (ByteInfoListRec *)Xmalloc( - (codeset->length)*sizeof(ByteInfoListRec)); - if (codeset->byteM == NULL) { - goto err; - } - } - - if (num > 0) { - _XlcDbg_printValue(name,value,num); - (codeset->byteM)[M-1].M = M; - (codeset->byteM)[M-1].byteinfo_num = num; - (codeset->byteM)[M-1].byteinfo = - (ByteInfo)Xmalloc( num * sizeof(ByteInfoRec)); - for (ii = 0 ; ii < num ; ii++) { - tmpb = (codeset->byteM)[M-1].byteinfo ; - /* default 0x00 - 0xff */ - sscanf(value[ii],"\\x%lx,\\x%lx",&start,&end); - tmpb[ii].start = (unsigned char)start; - tmpb[ii].end = (unsigned char)end; - } - } - /* .... */ - } - - - /***** codeset.mb_conversion *****/ - sprintf(name, "%s.%s", cs, "mb_conversion"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - codeset->mbconv = Xmalloc(sizeof(ConversionRec)); - codeset->mbconv->convlist = - _XlcParse_scopemaps(value[0],&(codeset->mbconv->conv_num)); - dmpscope("mb_conv",codeset->mbconv->convlist, - codeset->mbconv->conv_num); - /* [\x%x,\x%x]->\x%x,... */ - } - /***** codeset.ct_conversion *****/ - sprintf(name, "%s.%s", cs, "ct_conversion"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - codeset->ctconv = Xmalloc(sizeof(ConversionRec)); - codeset->ctconv->convlist = - _XlcParse_scopemaps(value[0],&(codeset->ctconv->conv_num)); - dmpscope("ctconv",codeset->ctconv->convlist, - codeset->ctconv->conv_num); - /* [\x%x,\x%x]->\x%x,... */ - } - /***** codeset.ct_conversion_file *****/ - sprintf(name, "%s.%s", cs, "ct_conversion_file"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - /* [\x%x,\x%x]->\x%x,... */ - } - /***** codeset.ct_extended_segment *****/ - sprintf(name, "%s.%s", cs, "ct_extended_segment"); - _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num); - if (num > 0) { - _XlcDbg_printValue(name,value,num); - codeset->ctextseg = create_ctextseg(value,num); - /* [\x%x,\x%x]->\x%x,... */ - } - /* For VW/UDC end */ - - } - - read_charset_define(lcd,gen); /* For VW/UDC */ - read_segmentconversion(lcd,gen); /* For VW/UDC */ - - if (gen->initial_state_GL == NULL) { - CodeSetRec *codeset; - for (i = 0; i < gen->codeset_num; i++) { - codeset = gen->codeset_list[i]; - if (codeset->side == XlcGL) - gen->initial_state_GL = codeset; - } - } - - if (gen->initial_state_GR == NULL) { - CodeSetRec *codeset; - for (i = 0; i < gen->codeset_num; i++) { - codeset = gen->codeset_list[i]; - if (codeset->side == XlcGR) - gen->initial_state_GR = codeset; - } - } - - for (i = 0; i < gen->codeset_num; i++) { - CodeSetRec *codeset = gen->codeset_list[i]; - for (ii = 0; ii < codeset->num_charsets; ii++) { - charset = codeset->charset_list[ii]; - if (! strcmp(charset->encoding_name, "ISO8859-1")) - charset->string_encoding = True; - if ( charset->string_encoding ) - codeset->string_encoding = True; - } - } - return True; - -err: - free_charset(lcd); - - return False; -} - -#ifdef USE_DYNAMIC_LC -/* override the open_om and open_im methods which were set by - super_class's initialize method() */ - -static Bool -initialize_core( - XLCd lcd) -{ - _XInitDynamicOM(lcd); - - _XInitDynamicIM(lcd); - - return True; -} -#endif - -static Bool -initialize(XLCd lcd) -{ - XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods; - - XLC_PUBLIC_METHODS(lcd)->superclass = superclass; - - if (superclass->pub.initialize) { - if ((*superclass->pub.initialize)(lcd) == False) - return False; - } - -#ifdef USE_DYNAMIC_LC - if (initialize_core(lcd) == False) - return False; -#endif - - if (load_generic(lcd) == False) - return False; - - return True; -} - -/* VW/UDC start 95.01.08 */ -static void -freeByteM( - CodeSet codeset) -{ - int i; - ByteInfoList blst; - if (codeset->byteM == NULL) { - return ; - } - blst = codeset->byteM; - for (i = 0; i < codeset->length; i++) { - if (blst[i].byteinfo) { - Xfree(blst[i].byteinfo); - blst[i].byteinfo = NULL; - } - } - Xfree(codeset->byteM); - codeset->byteM = NULL; -} - -static void -freeConversion( - CodeSet codeset) -{ - Conversion mbconv,ctconv; - if (codeset->mbconv) { - mbconv = codeset->mbconv; - /* ... */ - if (mbconv->convlist) { - Xfree(mbconv->convlist); - mbconv->convlist = NULL; - } - Xfree(mbconv); - codeset->mbconv = NULL; - } - if (codeset->ctconv) { - ctconv = codeset->ctconv; - /* ... */ - if (ctconv->convlist) { - Xfree(ctconv->convlist); - ctconv->convlist = NULL; - } - Xfree(ctconv); - codeset->ctconv = NULL; - } -} - -static void -freeExtdSegment( - CodeSet codeset) -{ - ExtdSegment ctextseg; - if (codeset->ctextseg == NULL) { - return; - } - ctextseg = codeset->ctextseg; - if (ctextseg->name) { - Xfree(ctextseg->name); - ctextseg->name = NULL; - } - if (ctextseg->area) { - Xfree(ctextseg->area); - ctextseg->area = NULL; - } - Xfree(codeset->ctextseg); - codeset->ctextseg = NULL; -} - -static void -freeParseInfo( - CodeSet codeset) -{ - ParseInfo parse_info; - if (codeset->parse_info == NULL) { - return; - } - parse_info = codeset->parse_info; - if (parse_info->encoding) { - Xfree(parse_info->encoding); - parse_info->encoding = NULL; - } - Xfree(codeset->parse_info); - codeset->parse_info = NULL; -} - -static void -destroy_CodeSetList( - XLCdGenericPart *gen) -{ - CodeSet *codeset = gen->codeset_list; - int i; - if (gen->codeset_num == 0) { - return; - } - for (i=0;i<gen->codeset_num;i++) { - freeByteM(codeset[i]); - freeConversion(codeset[i]); - freeExtdSegment(codeset[i]); - freeParseInfo(codeset[i]); - if (codeset[i]->charset_list) { - Xfree(codeset[i]->charset_list); - codeset[i]->charset_list = NULL; - } - Xfree(codeset[i]); codeset[i]=NULL; - } - Xfree(codeset); gen->codeset_list = NULL; -} - -static void -destroy_SegConv( - XLCdGenericPart *gen) -{ - SegConv seg = gen->segment_conv; - int i; - if (gen->segment_conv_num == 0) { - return; - } - for (i=0;i<gen->segment_conv_num;i++) { - if (seg[i].source_encoding) { - Xfree(seg[i].source_encoding); - seg[i].source_encoding = NULL; - } - if (seg[i].destination_encoding) { - Xfree(seg[i].destination_encoding); - seg[i].destination_encoding = NULL; - } - if (seg[i].conv) { - Xfree(seg[i].conv); seg[i].conv = NULL; - } - } - Xfree(seg); gen->segment_conv = NULL; -} - -static void -destroy_gen( - XLCd lcd) -{ - XLCdGenericPart *gen = XLC_GENERIC_PART(lcd); - destroy_SegConv(gen); - destroy_CodeSetList(gen); - if (gen->mb_parse_table) { - Xfree(gen->mb_parse_table); - gen->mb_parse_table = NULL; - } - if (gen->mb_parse_list) { - Xfree(gen->mb_parse_list); - gen->mb_parse_list = NULL; - } -} -/* VW/UDC end 95.01.08 */ - -static void -destroy( - XLCd lcd) -{ - XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass; - - destroy_gen(lcd); /* ADD 1996.01.08 */ - if (superclass && superclass->pub.destroy) - (*superclass->pub.destroy)(lcd); -} +/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+/*
+ * (c) Copyright 1995 FUJITSU LIMITED
+ * This is source code modified by FUJITSU LIMITED under the Joint
+ * Development Agreement for the CDE/Motif PST.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+
+static XLCd create (const char *name, XLCdMethods methods);
+static Bool initialize (XLCd lcd);
+static void destroy (XLCd lcd);
+
+static XLCdPublicMethodsRec genericMethods = {
+ { NULL }, /* use default methods */
+ {
+ NULL,
+ create,
+ initialize,
+ destroy,
+ NULL
+ }
+};
+
+XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods;
+
+static XLCd
+create(
+ const char *name,
+ XLCdMethods methods)
+{
+ XLCd lcd;
+ XLCdPublicMethods new;
+
+ lcd = Xcalloc(1, sizeof(XLCdRec));
+ if (lcd == NULL)
+ return (XLCd) NULL;
+
+ lcd->core = Xcalloc(1, sizeof(XLCdGenericRec));
+ if (lcd->core == NULL)
+ goto err;
+
+ new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec));
+ if (new == NULL)
+ goto err;
+ memcpy(new,methods,sizeof(XLCdPublicMethodsRec));
+ lcd->methods = (XLCdMethods) new;
+
+ return lcd;
+
+err:
+ Xfree(lcd);
+ return (XLCd) NULL;
+}
+
+static Bool
+string_to_encoding(
+ const char *str,
+ char *encoding)
+{
+ char *next;
+ long value;
+ int base;
+
+ while (*str) {
+ if (*str == '\\') {
+ switch (*(str + 1)) {
+ case 'x':
+ case 'X':
+ base = 16;
+ break;
+ default:
+ base = 8;
+ break;
+ }
+ value = strtol(str + 2, &next, base);
+ if (str + 2 != next) {
+ *((unsigned char *) encoding++) = (unsigned char) value;
+ str = next;
+ continue;
+ }
+ }
+ *encoding++ = *str++;
+ }
+
+ *encoding = '\0';
+
+ return True;
+}
+
+static Bool
+string_to_ulong(
+ const char *str,
+ unsigned long *value)
+{
+ const char *tmp1 = str;
+ int base;
+
+ if (*tmp1++ != '\\') {
+ tmp1--;
+ base = 10;
+ } else {
+ switch (*tmp1++) {
+ case 'x':
+ base = 16;
+ break;
+ case 'o':
+ base = 8;
+ break;
+ case 'd':
+ base = 10;
+ break;
+ default:
+ return(False);
+ }
+ }
+ *value = (unsigned long) strtol(tmp1, NULL, base);
+ return(True);
+}
+
+
+static Bool
+add_charset(
+ CodeSet codeset,
+ XlcCharSet charset)
+{
+ XlcCharSet *new_list;
+ int num;
+
+ if ((num = codeset->num_charsets))
+ new_list = (XlcCharSet *) Xrealloc(codeset->charset_list,
+ (num + 1) * sizeof(XlcCharSet));
+ else
+ new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet));
+
+ if (new_list == NULL)
+ return False;
+
+ new_list[num] = charset;
+ codeset->charset_list = new_list;
+ codeset->num_charsets = num + 1;
+
+ return True;
+}
+
+static CodeSet
+add_codeset(
+ XLCdGenericPart *gen)
+{
+ CodeSet new, *new_list;
+ int num;
+
+ new = Xcalloc(1, sizeof(CodeSetRec));
+ if (new == NULL)
+ return NULL;
+
+ if ((num = gen->codeset_num))
+ new_list = (CodeSet *) Xrealloc(gen->codeset_list,
+ (num + 1) * sizeof(CodeSet));
+ else
+ new_list = (CodeSet *) Xmalloc(sizeof(CodeSet));
+
+ if (new_list == NULL)
+ goto err;
+
+ new_list[num] = new;
+ gen->codeset_list = new_list;
+ gen->codeset_num = num + 1;
+
+ return new;
+
+err:
+ Xfree(new);
+
+ return NULL;
+}
+
+static Bool
+add_parse_list(
+ XLCdGenericPart *gen,
+ EncodingType type,
+ const char *encoding,
+ CodeSet codeset)
+{
+ ParseInfo new, *new_list;
+ char *str;
+ unsigned char ch;
+ int num;
+
+ str = strdup(encoding);
+ if (str == NULL)
+ return False;
+
+ new = Xcalloc(1, sizeof(ParseInfoRec));
+ if (new == NULL)
+ goto err;
+
+ if (gen->mb_parse_table == NULL) {
+ gen->mb_parse_table = Xcalloc(1, 256); /* 2^8 */
+ if (gen->mb_parse_table == NULL)
+ goto err;
+ }
+
+ if ((num = gen->mb_parse_list_num))
+ new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list,
+ (num + 2) * sizeof(ParseInfo));
+ else {
+ new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo));
+ }
+
+ if (new_list == NULL)
+ goto err;
+
+ new_list[num] = new;
+ new_list[num + 1] = NULL;
+ gen->mb_parse_list = new_list;
+ gen->mb_parse_list_num = num + 1;
+
+ ch = (unsigned char) *str;
+ if (gen->mb_parse_table[ch] == 0)
+ gen->mb_parse_table[ch] = num + 1;
+
+ new->type = type;
+ new->encoding = str;
+ new->codeset = codeset;
+
+ if (codeset->parse_info == NULL)
+ codeset->parse_info = new;
+
+ return True;
+
+err:
+ Xfree(str);
+ if (new)
+ Xfree(new);
+
+ return False;
+}
+
+static void
+free_charset(
+ XLCd lcd)
+{
+ XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
+ ParseInfo *parse_info;
+ int num;
+
+ if (gen->mb_parse_table)
+ Xfree(gen->mb_parse_table);
+ if ((num = gen->mb_parse_list_num) > 0) {
+ for (parse_info = gen->mb_parse_list; num-- > 0; parse_info++) {
+ if ((*parse_info)->encoding)
+ Xfree((*parse_info)->encoding);
+ Xfree(*parse_info);
+ }
+ Xfree(gen->mb_parse_list);
+ }
+
+ if ((num = gen->codeset_num) > 0)
+ Xfree(gen->codeset_list);
+}
+
+/* For VW/UDC */
+
+#define FORWARD (unsigned long)'+'
+#define BACKWARD (unsigned long)'-'
+
+static const char *
+getscope(
+ const char *str,
+ FontScope scp)
+{
+ unsigned long start = 0;
+ unsigned long end = 0;
+ unsigned long dest = 0;
+ unsigned long shift = 0;
+ unsigned long direction = 0;
+ sscanf(str,"[\\x%lx,\\x%lx]->\\x%lx", &start, &end, &dest);
+ if (dest) {
+ if (dest >= start) {
+ shift = dest - start;
+ direction = FORWARD ;
+ } else {
+ shift = start - dest;
+ direction = BACKWARD;
+ }
+ }
+ scp->start = start ;
+ scp->end = end ;
+ scp->shift = shift ;
+ scp->shift_direction
+ = direction ;
+ /* .......... */
+ while (*str) {
+ if (*str == ',' && *(str+1) == '[')
+ break;
+ str++;
+ }
+ return str+1;
+}
+
+static int
+count_scopemap(
+ const char *str)
+{
+ const char *ptr;
+ int num=0;
+ for (ptr=str; *ptr; ptr++) {
+ if (*ptr == ']') {
+ num++;
+ }
+ }
+ return num;
+}
+
+FontScope
+_XlcParse_scopemaps(
+ const char *str,
+ int *size)
+{
+ int num=0,i;
+ FontScope scope,sc_ptr;
+ const char *str_sc;
+
+ num = count_scopemap(str);
+ scope = (FontScope) Xmalloc(num * sizeof(FontScopeRec));
+ if (scope == NULL)
+ return NULL;
+
+ for (i=0, str_sc=str, sc_ptr=scope; i < num; i++, sc_ptr++) {
+ str_sc = getscope(str_sc, sc_ptr);
+ }
+ *size = num;
+ return scope;
+}
+
+void
+_XlcDbg_printValue(
+ const char *str,
+ char **value,
+ int num)
+{
+/*
+ int i;
+ for (i = 0; i < num; i++)
+ fprintf(stderr, "%s value[%d] = %s\n", str, i, value[i]);
+*/
+}
+
+static void
+dmpscope(
+ const char* name,
+ FontScope sc,
+ int num)
+{
+/*
+ int i;
+ fprintf(stderr, "dmpscope %s\n", name);
+ for (i=0; i<num; i++)
+ fprintf(stderr,"%x %x %x %x \n",
+ sc[i].start,
+ sc[i].end,
+ sc[i].shift,
+ sc[i].shift_direction);
+ fprintf(stderr, "dmpscope end\n");
+*/
+}
+
+static XlcCharSet
+srch_charset_define(
+ const char *name,
+ int *new)
+{
+ XlcCharSet charset;
+
+ *new = 0;
+ charset = _XlcGetCharSet(name);
+ if (charset == NULL &&
+ (charset = _XlcCreateDefaultCharSet(name, ""))) {
+ _XlcAddCharSet(charset);
+ *new = 1;
+ charset->source = CSsrcXLC;
+ }
+ return charset;
+}
+
+static void
+read_charset_define(
+ XLCd lcd,
+ XLCdGenericPart *gen)
+{
+ int i;
+ char csd[16], cset_name[256];
+ char name[BUFSIZ];
+ XlcCharSet charsetd;
+ char **value;
+ int num, new = 0;
+ XlcSide side = XlcUnknown;
+ char *tmp;
+
+ for (i=0; ; i++) { /* loop start */
+ charsetd = 0;
+ sprintf(csd, "csd%d", i);
+
+ /* charset_name */
+ sprintf(name, "%s.%s", csd, "charset_name");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ _XlcDbg_printValue(name,value,num);
+ if (num > 0) {
+ /* hackers will get truncated -- C'est la vie */
+ strncpy(cset_name,value[0], sizeof cset_name - 1);
+ cset_name[(sizeof cset_name) - 1] = '\0';
+ sprintf(name, "%s.%s", csd , "side");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
+ side = XlcGLGR;
+ } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
+ side = XlcGL;
+ strcat(cset_name,":GL");
+ } else {
+ side = XlcGR;
+ strcat(cset_name,":GR");
+ }
+ if (charsetd == NULL &&
+ (charsetd = srch_charset_define(cset_name,&new)) == NULL)
+ return;
+ }
+ } else {
+ if (i == 0)
+ continue;
+ else
+ break;
+ }
+ if (new) {
+ tmp = strdup(cset_name);
+ if (tmp == NULL)
+ return;
+ charsetd->name = tmp;
+ }
+ /* side */
+ charsetd->side = side ;
+ /* length */
+ sprintf(name, "%s.%s", csd, "length");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ charsetd->char_size = atoi(value[0]);
+ }
+ /* gc_number */
+ sprintf(name, "%s.%s", csd, "gc_number");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ charsetd->set_size = atoi(value[0]);
+ }
+ /* string_encoding */
+ sprintf(name, "%s.%s", csd, "string_encoding");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ if (!strcmp("False",value[0])) {
+ charsetd->string_encoding = False;
+ } else {
+ charsetd->string_encoding = True;
+ }
+ }
+ /* sequence */
+ sprintf(name, "%s.%s", csd, "sequence");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+/*
+ if (charsetd->ct_sequence) {
+ Xfree(charsetd->ct_sequence);
+ }
+*/
+ tmp = (char *)Xmalloc(strlen(value[0])+1);
+ if (tmp == NULL)
+ return;
+ charsetd->ct_sequence = tmp;
+ string_to_encoding(value[0],tmp);
+ }
+ /* encoding_name */
+ sprintf(name, "%s.%s", csd, "encoding_name");
+ _XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+/*
+ if (charsetd->encoding_name) {
+ Xfree(charsetd->encoding_name);
+ }
+*/
+ tmp = strdup(value[0]);
+ charsetd->encoding_name = tmp;
+ charsetd->xrm_encoding_name = XrmStringToQuark(tmp);
+ }
+ _XlcAddCT(charsetd->name, charsetd->ct_sequence);
+ }
+}
+
+static SegConv
+add_conversion(
+ XLCdGenericPart *gen)
+{
+ SegConv new_list;
+ int num;
+
+ if ((num = gen->segment_conv_num) > 0) {
+ new_list = (SegConv) Xrealloc(gen->segment_conv,
+ (num + 1) * sizeof(SegConvRec));
+ } else {
+ new_list = (SegConv) Xmalloc(sizeof(SegConvRec));
+ }
+
+ if (new_list == NULL)
+ return NULL;
+
+ gen->segment_conv = new_list;
+ gen->segment_conv_num = num + 1;
+
+ return &new_list[num];
+
+}
+
+static void
+read_segmentconversion(
+ XLCd lcd,
+ XLCdGenericPart *gen)
+{
+ int i;
+ char conv[16];
+ char name[BUFSIZ];
+ char **value;
+ int num,new;
+ SegConv conversion;
+ for (i=0 ; ; i++) { /* loop start */
+ conversion = 0;
+ sprintf(conv, "conv%d", i);
+
+ /* length */
+ sprintf(name, "%s.%s", conv, "length");
+ _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
+ if (num > 0) {
+ if (conversion == NULL &&
+ (conversion = add_conversion(gen)) == NULL) {
+ return;
+ }
+ _XlcDbg_printValue(name,value,num);
+ } else {
+ if (i == 0)
+ continue;
+ else
+ break;
+ }
+ conversion->length = atoi(value[0]);
+
+ /* source_encoding */
+ sprintf(name, "%s.%s", conv, "source_encoding");
+ _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
+ if (num > 0) {
+ char *tmp;
+ _XlcDbg_printValue(name,value,num);
+ tmp = strdup(value[0]);
+ if (tmp == NULL)
+ return;
+ conversion->source_encoding = tmp;
+ conversion->source = srch_charset_define(tmp,&new);
+ }
+ /* destination_encoding */
+ sprintf(name, "%s.%s", conv, "destination_encoding");
+ _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
+ if (num > 0) {
+ char *tmp;
+ _XlcDbg_printValue(name,value,num);
+ tmp = strdup(value[0]);
+ if (tmp == NULL)
+ return;
+ conversion->destination_encoding = tmp;
+ conversion->dest = srch_charset_define(tmp,&new);
+ }
+ /* range */
+ sprintf(name, "%s.%s", conv, "range");
+ _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ sscanf(value[0],"\\x%lx,\\x%lx",
+ &(conversion->range.start), &(conversion->range.end));
+ }
+ /* conversion */
+ sprintf(name, "%s.%s", conv, "conversion");
+ _XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ conversion->conv =
+ _XlcParse_scopemaps(value[0],&conversion->conv_num);
+ }
+ } /* loop end */
+}
+
+static ExtdSegment
+create_ctextseg(
+ char **value,
+ int num)
+{
+ ExtdSegment ret;
+ char* ptr;
+ char* cset_name = NULL;
+ int i,new;
+ FontScope scope;
+ ret = (ExtdSegment)Xmalloc(sizeof(ExtdSegmentRec));
+ if (ret == NULL)
+ return NULL;
+ ret->name = strdup(value[0]);
+ if (ret->name == NULL) {
+ Xfree (ret);
+ return NULL;
+ }
+ cset_name = (char*) Xmalloc (strlen(ret->name) + 1);
+ if (cset_name == NULL) {
+ Xfree (ret->name);
+ Xfree (ret);
+ return NULL;
+ }
+ if (strchr(value[0],':')) {
+ ptr = strchr(ret->name,':');
+ *ptr = '\0';
+ ptr++;
+ if (!_XlcNCompareISOLatin1(ptr, "GL", 2)) {
+ ret->side = XlcGL;
+ sprintf(cset_name,"%s:%s",ret->name,"GL");
+ } else {
+ ret->side = XlcGR;
+ sprintf(cset_name,"%s:%s",ret->name,"GR");
+ }
+ } else {
+ ret->side = XlcGLGR;
+ strcpy(cset_name,ret->name);
+ }
+ ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec));
+ if (ret->area == NULL) {
+ Xfree (cset_name);
+ Xfree (ret->name);
+ Xfree (ret);
+ return NULL;
+ }
+ ret->area_num = num - 1;
+ scope = ret->area ;
+ for (i = 1; i < num; i++) {
+ sscanf(value[i],"\\x%lx,\\x%lx",
+ &scope[i-1].start, &scope[i-1].end);
+ }
+ ret->charset = srch_charset_define(cset_name,&new);
+ Xfree (cset_name);
+
+ return ret;
+}
+/* For VW/UDC end */
+
+static Bool
+load_generic(
+ XLCd lcd)
+{
+ XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
+ char **value;
+ int num;
+ unsigned long l;
+ int i;
+ int M,ii;
+ XlcCharSet charset;
+
+ gen->codeset_num = 0;
+
+ /***** wc_encoding_mask *****/
+ _XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num);
+ if (num > 0) {
+ if (string_to_ulong(value[0], &l) == False)
+ goto err;
+ gen->wc_encode_mask = l;
+ }
+ /***** wc_shift_bits *****/
+ _XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num);
+ if (num > 0)
+ gen->wc_shift_bits = atoi(value[0]);
+ if (gen->wc_shift_bits < 1)
+ gen->wc_shift_bits = 8;
+ /***** use_stdc_env *****/
+ _XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num);
+ if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
+ gen->use_stdc_env = True;
+ else
+ gen->use_stdc_env = False;
+ /***** force_convert_to_mb *****/
+ _XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num);
+ if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
+ gen->force_convert_to_mb = True;
+ else
+ gen->force_convert_to_mb = False;
+
+ for (i = 0; ; i++) {
+ CodeSetRec *codeset = NULL;
+ char cs[16];
+ char name[BUFSIZ];
+
+ sprintf(cs, "cs%d", i);
+
+ /***** codeset.side *****/
+ sprintf(name, "%s.%s", cs , "side");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ char *tmp;
+
+ if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
+ goto err;
+
+ /* 3.4.1 side */
+ if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
+ codeset->side = XlcNONE;
+ } else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
+ codeset->side = XlcGL;
+ } else {
+ codeset->side = XlcGR;
+ }
+
+ tmp = strrchr(value[0], ':');
+ if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) {
+ if (codeset->side == XlcGR)
+ gen->initial_state_GR = codeset;
+ else
+ gen->initial_state_GL = codeset;
+ }
+ }
+
+ /***** codeset.length *****/
+ sprintf(name, "%s.%s", cs , "length");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
+ goto err;
+ codeset->length = atoi(value[0]);
+ if (codeset->length < 1)
+ codeset->length = 1;
+ }
+
+ /***** codeset.mb_encoding *****/
+ sprintf(name, "%s.%s", cs, "mb_encoding");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ static struct {
+ const char *str;
+ EncodingType type;
+ } shifts[] = {
+ {"<SS>", E_SS},
+ {"<LSL>", E_LSL},
+ {"<LSR>", E_LSR},
+ {0}
+ };
+ int j;
+
+ if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
+ goto err;
+ for ( ; num-- > 0; value++) {
+ char encoding[256];
+ char *tmp = *value;
+ EncodingType type = E_SS; /* for BC */
+ for (j = 0; shifts[j].str; j++) {
+ if (!_XlcNCompareISOLatin1(tmp, shifts[j].str,
+ strlen(shifts[j].str))) {
+ type = shifts[j].type;
+ tmp += strlen(shifts[j].str);
+ break;
+ }
+ }
+ if (strlen (tmp) > sizeof encoding ||
+ string_to_encoding(tmp, encoding) == False)
+ goto err;
+ add_parse_list(gen, type, encoding, codeset);
+ }
+ }
+
+ /***** codeset.wc_encoding *****/
+ sprintf(name, "%s.%s", cs, "wc_encoding");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
+ goto err;
+ if (string_to_ulong(value[0], &l) == False)
+ goto err;
+ codeset->wc_encoding = l;
+ }
+
+ /***** codeset.ct_encoding *****/
+ sprintf(name, "%s.%s", cs, "ct_encoding");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ char *encoding;
+
+ if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
+ goto err;
+ for ( ; num-- > 0; value++) {
+ if (strlen (*value) > sizeof name)
+ goto err;
+ string_to_encoding(*value, name);
+ charset = NULL;
+ if ((encoding = strchr(name, ':')) &&
+ (encoding = strchr(encoding + 1, ':'))) {
+ *encoding++ = '\0';
+ charset = _XlcAddCT(name, encoding);
+ }
+ if (charset == NULL) {
+ charset = _XlcGetCharSet(name);
+ if (charset == NULL &&
+ (charset = _XlcCreateDefaultCharSet(name, ""))) {
+ charset->side = codeset->side;
+ charset->char_size = codeset->length;
+ _XlcAddCharSet(charset);
+ }
+ }
+ if (charset) {
+ if (add_charset(codeset, charset) == False)
+ goto err;
+ }
+ }
+ }
+
+ if (codeset == NULL)
+ break;
+ codeset->cs_num = i;
+ /* For VW/UDC */
+ /***** 3.4.2 byteM (1 <= M <= length)*****/
+ for (M=1; M-1 < codeset->length; M++) {
+ unsigned long start,end;
+ ByteInfo tmpb;
+
+ sprintf(name,"%s.%s%d",cs,"byte",M);
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+
+ if (M == 1) {
+ if (num < 1) {
+ codeset->byteM = NULL;
+ break ;
+ }
+ codeset->byteM =
+ (ByteInfoListRec *)Xmalloc(
+ (codeset->length)*sizeof(ByteInfoListRec));
+ if (codeset->byteM == NULL) {
+ goto err;
+ }
+ }
+
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ (codeset->byteM)[M-1].M = M;
+ (codeset->byteM)[M-1].byteinfo_num = num;
+ (codeset->byteM)[M-1].byteinfo =
+ (ByteInfo)Xmalloc( num * sizeof(ByteInfoRec));
+ for (ii = 0 ; ii < num ; ii++) {
+ tmpb = (codeset->byteM)[M-1].byteinfo ;
+ /* default 0x00 - 0xff */
+ sscanf(value[ii],"\\x%lx,\\x%lx",&start,&end);
+ tmpb[ii].start = (unsigned char)start;
+ tmpb[ii].end = (unsigned char)end;
+ }
+ }
+ /* .... */
+ }
+
+
+ /***** codeset.mb_conversion *****/
+ sprintf(name, "%s.%s", cs, "mb_conversion");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ codeset->mbconv = Xmalloc(sizeof(ConversionRec));
+ codeset->mbconv->convlist =
+ _XlcParse_scopemaps(value[0],&(codeset->mbconv->conv_num));
+ dmpscope("mb_conv",codeset->mbconv->convlist,
+ codeset->mbconv->conv_num);
+ /* [\x%x,\x%x]->\x%x,... */
+ }
+ /***** codeset.ct_conversion *****/
+ sprintf(name, "%s.%s", cs, "ct_conversion");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ codeset->ctconv = Xmalloc(sizeof(ConversionRec));
+ codeset->ctconv->convlist =
+ _XlcParse_scopemaps(value[0],&(codeset->ctconv->conv_num));
+ dmpscope("ctconv",codeset->ctconv->convlist,
+ codeset->ctconv->conv_num);
+ /* [\x%x,\x%x]->\x%x,... */
+ }
+ /***** codeset.ct_conversion_file *****/
+ sprintf(name, "%s.%s", cs, "ct_conversion_file");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ /* [\x%x,\x%x]->\x%x,... */
+ }
+ /***** codeset.ct_extended_segment *****/
+ sprintf(name, "%s.%s", cs, "ct_extended_segment");
+ _XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
+ if (num > 0) {
+ _XlcDbg_printValue(name,value,num);
+ codeset->ctextseg = create_ctextseg(value,num);
+ /* [\x%x,\x%x]->\x%x,... */
+ }
+ /* For VW/UDC end */
+
+ }
+
+ read_charset_define(lcd,gen); /* For VW/UDC */
+ read_segmentconversion(lcd,gen); /* For VW/UDC */
+
+ if (gen->initial_state_GL == NULL) {
+ CodeSetRec *codeset;
+ for (i = 0; i < gen->codeset_num; i++) {
+ codeset = gen->codeset_list[i];
+ if (codeset->side == XlcGL)
+ gen->initial_state_GL = codeset;
+ }
+ }
+
+ if (gen->initial_state_GR == NULL) {
+ CodeSetRec *codeset;
+ for (i = 0; i < gen->codeset_num; i++) {
+ codeset = gen->codeset_list[i];
+ if (codeset->side == XlcGR)
+ gen->initial_state_GR = codeset;
+ }
+ }
+
+ for (i = 0; i < gen->codeset_num; i++) {
+ CodeSetRec *codeset = gen->codeset_list[i];
+ for (ii = 0; ii < codeset->num_charsets; ii++) {
+ charset = codeset->charset_list[ii];
+ if (! strcmp(charset->encoding_name, "ISO8859-1"))
+ charset->string_encoding = True;
+ if ( charset->string_encoding )
+ codeset->string_encoding = True;
+ }
+ }
+ return True;
+
+err:
+ free_charset(lcd);
+
+ return False;
+}
+
+#ifdef USE_DYNAMIC_LC
+/* override the open_om and open_im methods which were set by
+ super_class's initialize method() */
+
+static Bool
+initialize_core(
+ XLCd lcd)
+{
+ _XInitDynamicOM(lcd);
+
+ _XInitDynamicIM(lcd);
+
+ return True;
+}
+#endif
+
+static Bool
+initialize(XLCd lcd)
+{
+ XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods;
+
+ XLC_PUBLIC_METHODS(lcd)->superclass = superclass;
+
+ if (superclass->pub.initialize) {
+ if ((*superclass->pub.initialize)(lcd) == False)
+ return False;
+ }
+
+#ifdef USE_DYNAMIC_LC
+ if (initialize_core(lcd) == False)
+ return False;
+#endif
+
+ if (load_generic(lcd) == False)
+ return False;
+
+ return True;
+}
+
+/* VW/UDC start 95.01.08 */
+static void
+freeByteM(
+ CodeSet codeset)
+{
+ int i;
+ ByteInfoList blst;
+ if (codeset->byteM == NULL) {
+ return ;
+ }
+ blst = codeset->byteM;
+ for (i = 0; i < codeset->length; i++) {
+ if (blst[i].byteinfo) {
+ Xfree(blst[i].byteinfo);
+ blst[i].byteinfo = NULL;
+ }
+ }
+ Xfree(codeset->byteM);
+ codeset->byteM = NULL;
+}
+
+static void
+freeConversion(
+ CodeSet codeset)
+{
+ Conversion mbconv,ctconv;
+ if (codeset->mbconv) {
+ mbconv = codeset->mbconv;
+ /* ... */
+ if (mbconv->convlist) {
+ Xfree(mbconv->convlist);
+ mbconv->convlist = NULL;
+ }
+ Xfree(mbconv);
+ codeset->mbconv = NULL;
+ }
+ if (codeset->ctconv) {
+ ctconv = codeset->ctconv;
+ /* ... */
+ if (ctconv->convlist) {
+ Xfree(ctconv->convlist);
+ ctconv->convlist = NULL;
+ }
+ Xfree(ctconv);
+ codeset->ctconv = NULL;
+ }
+}
+
+static void
+freeExtdSegment(
+ CodeSet codeset)
+{
+ ExtdSegment ctextseg;
+ if (codeset->ctextseg == NULL) {
+ return;
+ }
+ ctextseg = codeset->ctextseg;
+ if (ctextseg->name) {
+ Xfree(ctextseg->name);
+ ctextseg->name = NULL;
+ }
+ if (ctextseg->area) {
+ Xfree(ctextseg->area);
+ ctextseg->area = NULL;
+ }
+ Xfree(codeset->ctextseg);
+ codeset->ctextseg = NULL;
+}
+
+static void
+freeParseInfo(
+ CodeSet codeset)
+{
+ ParseInfo parse_info;
+ if (codeset->parse_info == NULL) {
+ return;
+ }
+ parse_info = codeset->parse_info;
+ if (parse_info->encoding) {
+ Xfree(parse_info->encoding);
+ parse_info->encoding = NULL;
+ }
+ Xfree(codeset->parse_info);
+ codeset->parse_info = NULL;
+}
+
+static void
+destroy_CodeSetList(
+ XLCdGenericPart *gen)
+{
+ CodeSet *codeset = gen->codeset_list;
+ int i;
+ if (gen->codeset_num == 0) {
+ return;
+ }
+ for (i=0;i<gen->codeset_num;i++) {
+ freeByteM(codeset[i]);
+ freeConversion(codeset[i]);
+ freeExtdSegment(codeset[i]);
+ freeParseInfo(codeset[i]);
+ if (codeset[i]->charset_list) {
+ Xfree(codeset[i]->charset_list);
+ codeset[i]->charset_list = NULL;
+ }
+ Xfree(codeset[i]); codeset[i]=NULL;
+ }
+ Xfree(codeset); gen->codeset_list = NULL;
+}
+
+static void
+destroy_SegConv(
+ XLCdGenericPart *gen)
+{
+ SegConv seg = gen->segment_conv;
+ int i;
+ if (gen->segment_conv_num == 0) {
+ return;
+ }
+ for (i=0;i<gen->segment_conv_num;i++) {
+ if (seg[i].source_encoding) {
+ Xfree(seg[i].source_encoding);
+ seg[i].source_encoding = NULL;
+ }
+ if (seg[i].destination_encoding) {
+ Xfree(seg[i].destination_encoding);
+ seg[i].destination_encoding = NULL;
+ }
+ if (seg[i].conv) {
+ Xfree(seg[i].conv); seg[i].conv = NULL;
+ }
+ }
+ Xfree(seg); gen->segment_conv = NULL;
+}
+
+static void
+destroy_gen(
+ XLCd lcd)
+{
+ XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
+ destroy_SegConv(gen);
+ destroy_CodeSetList(gen);
+ if (gen->mb_parse_table) {
+ Xfree(gen->mb_parse_table);
+ gen->mb_parse_table = NULL;
+ }
+ if (gen->mb_parse_list) {
+ Xfree(gen->mb_parse_list);
+ gen->mb_parse_list = NULL;
+ }
+}
+/* VW/UDC end 95.01.08 */
+
+static void
+destroy(
+ XLCd lcd)
+{
+ XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass;
+
+ destroy_gen(lcd); /* ADD 1996.01.08 */
+ if (superclass && superclass->pub.destroy)
+ (*superclass->pub.destroy)(lcd);
+}
diff --git a/libX11/src/xlibi18n/lcPublic.c b/libX11/src/xlibi18n/lcPublic.c index 1b1fb548a..5082f05bb 100644 --- a/libX11/src/xlibi18n/lcPublic.c +++ b/libX11/src/xlibi18n/lcPublic.c @@ -1,314 +1,315 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA 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. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include "Xlibint.h" -#include "XlcPubI.h" - -static const char * -default_string( - XLCd lcd) -{ - return XLC_PUBLIC(lcd, default_string); -} - -static XLCd create (const char *name, XLCdMethods methods); -static Bool initialize (XLCd lcd); -static void destroy (XLCd lcd); -static char *get_values (XLCd lcd, XlcArgList args, int num_args); - -static XLCdPublicMethodsRec publicMethods = { - { - destroy, - _XlcDefaultMapModifiers, - NULL, - NULL, - _XrmDefaultInitParseInfo, - _XmbTextPropertyToTextList, - _XwcTextPropertyToTextList, - _Xutf8TextPropertyToTextList, - _XmbTextListToTextProperty, - _XwcTextListToTextProperty, - _Xutf8TextListToTextProperty, - _XwcFreeStringList, - default_string, - NULL, - NULL - }, - { - NULL, - create, - initialize, - destroy, - get_values, - _XlcGetLocaleDataBase - } -}; - -XLCdMethods _XlcPublicMethods = (XLCdMethods) &publicMethods; - -static XLCd -create( - const char *name, - XLCdMethods methods) -{ - XLCd lcd; - XLCdPublicMethods new; - - lcd = Xcalloc(1, sizeof(XLCdRec)); - if (lcd == NULL) - return (XLCd) NULL; - - lcd->core = Xcalloc(1, sizeof(XLCdPublicRec)); - if (lcd->core == NULL) - goto err; - - new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec)); - if (new == NULL) - goto err; - memcpy(new,methods,sizeof(XLCdPublicMethodsRec)); - lcd->methods = (XLCdMethods) new; - - return lcd; - -err: - Xfree(lcd); - return (XLCd) NULL; -} - -static Bool -load_public( - XLCd lcd) -{ - XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); - char **values, *str; - int num; - - if(_XlcCreateLocaleDataBase(lcd) == NULL) - return False; - - _XlcGetResource(lcd, "XLC_XLOCALE", "mb_cur_max", &values, &num); - if (num > 0) { - pub->mb_cur_max = atoi(values[0]); - if (pub->mb_cur_max < 1) - pub->mb_cur_max = 1; - } else - pub->mb_cur_max = 1; - - _XlcGetResource(lcd, "XLC_XLOCALE", "state_depend_encoding", &values, &num); - if (num > 0 && !_XlcCompareISOLatin1(values[0], "True")) - pub->is_state_depend = True; - else - pub->is_state_depend = False; - - _XlcGetResource(lcd, "XLC_XLOCALE", "encoding_name", &values, &num); - str = (num > 0) ? values[0] : "STRING"; - pub->encoding_name = strdup(str); - if (pub->encoding_name == NULL) - return False; - - return True; -} - -static Bool -initialize_core( - XLCd lcd) -{ - XLCdMethods methods = lcd->methods; - XLCdMethods core = &publicMethods.core; - - if (methods->close == NULL) - methods->close = core->close; - - if (methods->map_modifiers == NULL) - methods->map_modifiers = core->map_modifiers; - - if (methods->open_om == NULL) -#ifdef USE_DYNAMIC_LC - _XInitDefaultOM(lcd); -#else - _XInitOM(lcd); -#endif - - if (methods->open_im == NULL) -#ifdef USE_DYNAMIC_LC - _XInitDefaultIM(lcd); -#else - _XInitIM(lcd); -#endif - - if (methods->init_parse_info == NULL) - methods->init_parse_info = core->init_parse_info; - - if (methods->mb_text_prop_to_list == NULL) - methods->mb_text_prop_to_list = core->mb_text_prop_to_list; - - if (methods->wc_text_prop_to_list == NULL) - methods->wc_text_prop_to_list = core->wc_text_prop_to_list; - - if (methods->utf8_text_prop_to_list == NULL) - methods->utf8_text_prop_to_list = core->utf8_text_prop_to_list; - - if (methods->mb_text_list_to_prop == NULL) - methods->mb_text_list_to_prop = core->mb_text_list_to_prop; - - if (methods->wc_text_list_to_prop == NULL) - methods->wc_text_list_to_prop = core->wc_text_list_to_prop; - - if (methods->utf8_text_list_to_prop == NULL) - methods->utf8_text_list_to_prop = core->utf8_text_list_to_prop; - - if (methods->wc_free_string_list == NULL) - methods->wc_free_string_list = core->wc_free_string_list; - - if (methods->default_string == NULL) - methods->default_string = core->default_string; - - return True; -} - -static Bool -initialize( - XLCd lcd) -{ - XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); - XLCdPublicMethodsPart *pub_methods = &publicMethods.pub; - XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); - char *name; -#if !defined(X_LOCALE) - int len; - char sinamebuf[256]; - char* siname; -#endif - - _XlcInitCTInfo(); - - if (initialize_core(lcd) == False) - return False; - - name = lcd->core->name; -#if !defined(X_LOCALE) - /* - * _XlMapOSLocaleName will return the same string or a substring - * of name, so strlen(name) is okay - */ - if ((len = strlen(name)) < sizeof sinamebuf) - siname = sinamebuf; - else - siname = Xmalloc (len + 1); - if (siname == NULL) - return False; - name = _XlcMapOSLocaleName(name, siname); -#endif - /* _XlcResolveLocaleName will lookup the SI's name for the locale */ - if (_XlcResolveLocaleName(name, pub) == 0) { -#if !defined(X_LOCALE) - if (siname != sinamebuf) Xfree (siname); -#endif - return False; - } -#if !defined(X_LOCALE) - if (siname != sinamebuf) - Xfree (siname); -#endif - - if (pub->default_string == NULL) - pub->default_string = ""; - - if (methods->get_values == NULL) - methods->get_values = pub_methods->get_values; - - if (methods->get_resource == NULL) - methods->get_resource = pub_methods->get_resource; - - return load_public(lcd); -} - -static void -destroy_core( - XLCd lcd) -{ - if (lcd->core) { - if (lcd->core->name) - Xfree(lcd->core->name); - Xfree(lcd->core); - } - - if (lcd->methods) - Xfree(lcd->methods); - - Xfree(lcd); -} - -static void -destroy( - XLCd lcd) -{ - XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd); - - _XlcDestroyLocaleDataBase(lcd); - - if (pub->siname) - Xfree(pub->siname); - if (pub->encoding_name) - Xfree(pub->encoding_name); - - destroy_core(lcd); -} - -static XlcResource resources[] = { - { XlcNCodeset, NULLQUARK, sizeof(char *), - XOffsetOf(XLCdPublicRec, pub.codeset), XlcGetMask }, - { XlcNDefaultString, NULLQUARK, sizeof(char *), - XOffsetOf(XLCdPublicRec, pub.default_string), XlcGetMask }, - { XlcNEncodingName, NULLQUARK, sizeof(char *), - XOffsetOf(XLCdPublicRec, pub.encoding_name), XlcGetMask }, - { XlcNLanguage, NULLQUARK, sizeof(char *), - XOffsetOf(XLCdPublicRec, pub.language), XlcGetMask }, - { XlcNMbCurMax, NULLQUARK, sizeof(int), - XOffsetOf(XLCdPublicRec, pub.mb_cur_max), XlcGetMask }, - { XlcNStateDependentEncoding, NULLQUARK, sizeof(Bool), - XOffsetOf(XLCdPublicRec, pub.is_state_depend), XlcGetMask }, - { XlcNTerritory, NULLQUARK, sizeof(char *), - XOffsetOf(XLCdPublicRec, pub.territory), XlcGetMask } -}; - -static char * -get_values( - XLCd lcd, - XlcArgList args, - int num_args) -{ - XLCdPublic pub = (XLCdPublic) lcd->core; - - if (resources[0].xrm_name == NULLQUARK) - _XlcCompileResourceList(resources, XlcNumber(resources)); - - return _XlcGetValues((XPointer) pub, resources, XlcNumber(resources), args, - num_args, XlcGetMask); -} +/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, 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 TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA 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.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include "Xlibint.h"
+#include "XlcPubI.h"
+
+static const char *
+default_string(
+ XLCd lcd)
+{
+ return XLC_PUBLIC(lcd, default_string);
+}
+
+static XLCd create (const char *name, XLCdMethods methods);
+static Bool initialize (XLCd lcd);
+static void destroy (XLCd lcd);
+static char *get_values (XLCd lcd, XlcArgList args, int num_args);
+
+static XLCdPublicMethodsRec publicMethods = {
+ {
+ destroy,
+ _XlcDefaultMapModifiers,
+ NULL,
+ NULL,
+ _XrmDefaultInitParseInfo,
+ _XmbTextPropertyToTextList,
+ _XwcTextPropertyToTextList,
+ _Xutf8TextPropertyToTextList,
+ _XmbTextListToTextProperty,
+ _XwcTextListToTextProperty,
+ _Xutf8TextListToTextProperty,
+ _XwcFreeStringList,
+ default_string,
+ NULL,
+ NULL
+ },
+ {
+ NULL,
+ create,
+ initialize,
+ destroy,
+ get_values,
+ _XlcGetLocaleDataBase
+ }
+};
+
+XLCdMethods _XlcPublicMethods = (XLCdMethods) &publicMethods;
+
+static XLCd
+create(
+ const char *name,
+ XLCdMethods methods)
+{
+ XLCd lcd;
+ XLCdPublicMethods new;
+
+ lcd = Xcalloc(1, sizeof(XLCdRec));
+ if (lcd == NULL)
+ return (XLCd) NULL;
+
+ lcd->core = Xcalloc(1, sizeof(XLCdPublicRec));
+ if (lcd->core == NULL)
+ goto err;
+
+ new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec));
+ if (new == NULL)
+ goto err;
+ memcpy(new,methods,sizeof(XLCdPublicMethodsRec));
+ lcd->methods = (XLCdMethods) new;
+
+ return lcd;
+
+err:
+ Xfree(lcd);
+ return (XLCd) NULL;
+}
+
+static Bool
+load_public(
+ XLCd lcd)
+{
+ XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
+ char **values, *str;
+ int num;
+
+ if(_XlcCreateLocaleDataBase(lcd) == NULL)
+ return False;
+
+ _XlcGetResource(lcd, "XLC_XLOCALE", "mb_cur_max", &values, &num);
+ if (num > 0) {
+ pub->mb_cur_max = atoi(values[0]);
+ if (pub->mb_cur_max < 1)
+ pub->mb_cur_max = 1;
+ } else
+ pub->mb_cur_max = 1;
+
+ _XlcGetResource(lcd, "XLC_XLOCALE", "state_depend_encoding", &values, &num);
+ if (num > 0 && !_XlcCompareISOLatin1(values[0], "True"))
+ pub->is_state_depend = True;
+ else
+ pub->is_state_depend = False;
+
+ _XlcGetResource(lcd, "XLC_XLOCALE", "encoding_name", &values, &num);
+ str = (num > 0) ? values[0] : "STRING";
+ pub->encoding_name = strdup(str);
+ if (pub->encoding_name == NULL)
+ return False;
+
+ return True;
+}
+
+static Bool
+initialize_core(
+ XLCd lcd)
+{
+ XLCdMethods methods = lcd->methods;
+ XLCdMethods core = &publicMethods.core;
+
+ if (methods->close == NULL)
+ methods->close = core->close;
+
+ if (methods->map_modifiers == NULL)
+ methods->map_modifiers = core->map_modifiers;
+
+ if (methods->open_om == NULL)
+#ifdef USE_DYNAMIC_LC
+ _XInitDefaultOM(lcd);
+#else
+ _XInitOM(lcd);
+#endif
+
+ if (methods->open_im == NULL)
+#ifdef USE_DYNAMIC_LC
+ _XInitDefaultIM(lcd);
+#else
+ _XInitIM(lcd);
+#endif
+
+ if (methods->init_parse_info == NULL)
+ methods->init_parse_info = core->init_parse_info;
+
+ if (methods->mb_text_prop_to_list == NULL)
+ methods->mb_text_prop_to_list = core->mb_text_prop_to_list;
+
+ if (methods->wc_text_prop_to_list == NULL)
+ methods->wc_text_prop_to_list = core->wc_text_prop_to_list;
+
+ if (methods->utf8_text_prop_to_list == NULL)
+ methods->utf8_text_prop_to_list = core->utf8_text_prop_to_list;
+
+ if (methods->mb_text_list_to_prop == NULL)
+ methods->mb_text_list_to_prop = core->mb_text_list_to_prop;
+
+ if (methods->wc_text_list_to_prop == NULL)
+ methods->wc_text_list_to_prop = core->wc_text_list_to_prop;
+
+ if (methods->utf8_text_list_to_prop == NULL)
+ methods->utf8_text_list_to_prop = core->utf8_text_list_to_prop;
+
+ if (methods->wc_free_string_list == NULL)
+ methods->wc_free_string_list = core->wc_free_string_list;
+
+ if (methods->default_string == NULL)
+ methods->default_string = core->default_string;
+
+ return True;
+}
+
+static Bool
+initialize(
+ XLCd lcd)
+{
+ XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd);
+ XLCdPublicMethodsPart *pub_methods = &publicMethods.pub;
+ XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
+ char *name;
+#if !defined(X_LOCALE)
+ int len;
+ char sinamebuf[256];
+ char* siname;
+#endif
+
+ _XlcInitCTInfo();
+
+ if (initialize_core(lcd) == False)
+ return False;
+
+ name = lcd->core->name;
+#if !defined(X_LOCALE)
+ /*
+ * _XlMapOSLocaleName will return the same string or a substring
+ * of name, so strlen(name) is okay
+ */
+ if ((len = strlen(name)) < sizeof sinamebuf)
+ siname = sinamebuf;
+ else
+ siname = Xmalloc (len + 1);
+ if (siname == NULL)
+ return False;
+ name = _XlcMapOSLocaleName(name, siname);
+#endif
+ /* _XlcResolveLocaleName will lookup the SI's name for the locale */
+ if (_XlcResolveLocaleName(name, pub) == 0) {
+#if !defined(X_LOCALE)
+ if (siname != sinamebuf) Xfree (siname);
+#endif
+ return False;
+ }
+#if !defined(X_LOCALE)
+ if (siname != sinamebuf)
+ Xfree (siname);
+#endif
+
+ if (pub->default_string == NULL)
+ pub->default_string = "";
+
+ if (methods->get_values == NULL)
+ methods->get_values = pub_methods->get_values;
+
+ if (methods->get_resource == NULL)
+ methods->get_resource = pub_methods->get_resource;
+
+ return load_public(lcd);
+}
+
+static void
+destroy_core(
+ XLCd lcd)
+{
+ if (lcd->core) {
+ if (lcd->core->name)
+ Xfree(lcd->core->name);
+ Xfree(lcd->core);
+ }
+
+ if (lcd->methods)
+ Xfree(lcd->methods);
+
+ Xfree(lcd);
+}
+
+static void
+destroy(
+ XLCd lcd)
+{
+ XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
+
+ _XlcDestroyLocaleDataBase(lcd);
+
+ if (pub->siname)
+ Xfree(pub->siname);
+ if (pub->encoding_name)
+ Xfree(pub->encoding_name);
+
+ destroy_core(lcd);
+}
+
+static XlcResource resources[] = {
+ { XlcNCodeset, NULLQUARK, sizeof(char *),
+ XOffsetOf(XLCdPublicRec, pub.codeset), XlcGetMask },
+ { XlcNDefaultString, NULLQUARK, sizeof(char *),
+ XOffsetOf(XLCdPublicRec, pub.default_string), XlcGetMask },
+ { XlcNEncodingName, NULLQUARK, sizeof(char *),
+ XOffsetOf(XLCdPublicRec, pub.encoding_name), XlcGetMask },
+ { XlcNLanguage, NULLQUARK, sizeof(char *),
+ XOffsetOf(XLCdPublicRec, pub.language), XlcGetMask },
+ { XlcNMbCurMax, NULLQUARK, sizeof(int),
+ XOffsetOf(XLCdPublicRec, pub.mb_cur_max), XlcGetMask },
+ { XlcNStateDependentEncoding, NULLQUARK, sizeof(Bool),
+ XOffsetOf(XLCdPublicRec, pub.is_state_depend), XlcGetMask },
+ { XlcNTerritory, NULLQUARK, sizeof(char *),
+ XOffsetOf(XLCdPublicRec, pub.territory), XlcGetMask }
+};
+
+static char *
+get_values(
+ XLCd lcd,
+ XlcArgList args,
+ int num_args)
+{
+ XLCdPublic pub = (XLCdPublic) lcd->core;
+
+ if (resources[0].xrm_name == NULLQUARK)
+ _XlcCompileResourceList(resources, XlcNumber(resources));
+
+ return _XlcGetValues((XPointer) pub, resources, XlcNumber(resources), args,
+ num_args, XlcGetMask);
+}
diff --git a/libX11/src/xlibi18n/makefile b/libX11/src/xlibi18n/makefile new file mode 100644 index 000000000..5be81d350 --- /dev/null +++ b/libX11/src/xlibi18n/makefile @@ -0,0 +1,80 @@ +#AM_CFLAGS= \ +# -I$(top_srcdir)/include \ +# -I$(top_srcdir)/include/X11 \ +# -I$(top_builddir)/include \ +# -I$(top_builddir)/include/X11 \ +# -I$(top_srcdir)/src/xcms \ +# -I$(top_srcdir)/src/xkb \ +# -I$(top_srcdir)/src/xlibi18n \ +# -I$(top_srcdir)/src \ +# $(X11_CFLAGS) \ +# $(BIGFONT_CFLAGS) \ +# $(XDMCP_CFLAGS) \ +# -D_BSD_SOURCE \ +# $(XMALLOC_ZERO_CFLAGS) + +LIBRARY = libi18n + + +# +# Dynamic loading code for i18n modules +# +#if XLIB_LOADABLE_I18N +#XI18N_DL_SOURCES = \ +# XlcDL.c \ +# XlcSL.c +#else +# +# Static interfaces to input/output methods +# +#IM_LIBS = \ +# ${top_builddir}/modules/im/ximcp/libximcp.la + +#LC_LIBS = \ +# ${top_builddir}/modules/lc/def/libxlcDef.la \ +# ${top_builddir}/modules/lc/gen/libxlibi18n.la \ +# ${top_builddir}/modules/lc/Utf8/libxlcUTF8Load.la \ +# ${top_builddir}/modules/lc/xlocale/libxlocale.la + +#OM_LIBS = \ +# ${top_builddir}/modules/om/generic/libxomGeneric.la +#endif + +#libi18n_la_LIBADD = \ +# $(IM_LIBS) $(LC_LIBS) $(OM_LIBS) + +INCLUDES += ..\..\include\X11 +DEFINES += XLOCALELIBDIR="\".\"" + +CSRCS = \ + $(XI18N_DL_SOURCES) \ + XDefaultIMIF.c \ + XDefaultOMIF.c \ + xim_trans.c\ + ICWrap.c\ + IMWrap.c\ + imKStoUCS.c\ + lcCT.c\ + lcCharSet.c\ + lcConv.c\ + lcDB.c\ + lcDynamic.c\ + lcFile.c\ + lcGeneric.c\ + lcInit.c\ + lcPrTxt.c\ + lcPubWrap.c\ + lcPublic.c\ + lcRM.c\ + lcStd.c\ + lcTxtPr.c\ + lcUTF8.c\ + lcUtil.c\ + lcWrap.c\ + mbWMProps.c\ + mbWrap.c\ + utf8WMProps.c\ + utf8Wrap.c\ + wcWrap.c + + |
