diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /libxkbfile/src | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'libxkbfile/src')
-rw-r--r-- | libxkbfile/src/Makefile.am | 36 | ||||
-rw-r--r-- | libxkbfile/src/Makefile.in | 535 | ||||
-rw-r--r-- | libxkbfile/src/XKBfileInt.h | 81 | ||||
-rw-r--r-- | libxkbfile/src/cout.c | 1036 | ||||
-rw-r--r-- | libxkbfile/src/magic | 11 | ||||
-rw-r--r-- | libxkbfile/src/maprules.c | 1477 | ||||
-rw-r--r-- | libxkbfile/src/srvmisc.c | 216 | ||||
-rw-r--r-- | libxkbfile/src/xkbatom.c | 245 | ||||
-rw-r--r-- | libxkbfile/src/xkbbells.c | 104 | ||||
-rw-r--r-- | libxkbfile/src/xkbconfig.c | 1355 | ||||
-rw-r--r-- | libxkbfile/src/xkbdraw.c | 135 | ||||
-rw-r--r-- | libxkbfile/src/xkberrs.c | 72 | ||||
-rw-r--r-- | libxkbfile/src/xkbmisc.c | 677 | ||||
-rw-r--r-- | libxkbfile/src/xkbout.c | 1072 | ||||
-rw-r--r-- | libxkbfile/src/xkbtext.c | 1442 | ||||
-rw-r--r-- | libxkbfile/src/xkmout.c | 1389 | ||||
-rw-r--r-- | libxkbfile/src/xkmread.c | 1315 |
17 files changed, 11198 insertions, 0 deletions
diff --git a/libxkbfile/src/Makefile.am b/libxkbfile/src/Makefile.am new file mode 100644 index 000000000..6e3ec5fd2 --- /dev/null +++ b/libxkbfile/src/Makefile.am @@ -0,0 +1,36 @@ +lib_LTLIBRARIES = libxkbfile.la + +libxkbfile_la_SOURCES = \ + cout.c \ + maprules.c \ + srvmisc.c \ + xkbatom.c \ + xkbbells.c \ + xkbconfig.c \ + xkbdraw.c \ + xkberrs.c \ + XKBfileInt.h \ + xkbmisc.c \ + xkbout.c \ + xkbtext.c \ + xkmout.c \ + xkmread.c + +INCLUDES = -I$(top_srcdir)/include/ -I$(top_srcdir)/include/X11/extensions/ + + +libxkbfile_la_LIBADD = @XKBFILE_LIBS@ +AM_CFLAGS = @XKBFILE_CFLAGS@ + +libxkbfile_la_LDFLAGS = -version-number 1:0:2 -no-undefined + +libxkbfileincludedir = $(includedir)/X11/extensions +libxkbfileinclude_HEADERS = \ + $(top_srcdir)/include/X11/extensions/XKM.h\ + $(top_srcdir)/include/X11/extensions/XKBrules.h\ + $(top_srcdir)/include/X11/extensions/XKBbells.h\ + $(top_srcdir)/include/X11/extensions/XKBconfig.h\ + $(top_srcdir)/include/X11/extensions/XKMformat.h\ + $(top_srcdir)/include/X11/extensions/XKBfile.h + +EXTRA_DIST = magic diff --git a/libxkbfile/src/Makefile.in b/libxkbfile/src/Makefile.in new file mode 100644 index 000000000..b90c1b486 --- /dev/null +++ b/libxkbfile/src/Makefile.in @@ -0,0 +1,535 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(libxkbfileinclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" \ + "$(DESTDIR)$(libxkbfileincludedir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libxkbfile_la_DEPENDENCIES = +am_libxkbfile_la_OBJECTS = cout.lo maprules.lo srvmisc.lo xkbatom.lo \ + xkbbells.lo xkbconfig.lo xkbdraw.lo xkberrs.lo xkbmisc.lo \ + xkbout.lo xkbtext.lo xkmout.lo xkmread.lo +libxkbfile_la_OBJECTS = $(am_libxkbfile_la_OBJECTS) +libxkbfile_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libxkbfile_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libxkbfile_la_SOURCES) +DIST_SOURCES = $(libxkbfile_la_SOURCES) +libxkbfileincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(libxkbfileinclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XKBFILE_CFLAGS = @XKBFILE_CFLAGS@ +XKBFILE_LIBS = @XKBFILE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +lib_LTLIBRARIES = libxkbfile.la +libxkbfile_la_SOURCES = \ + cout.c \ + maprules.c \ + srvmisc.c \ + xkbatom.c \ + xkbbells.c \ + xkbconfig.c \ + xkbdraw.c \ + xkberrs.c \ + XKBfileInt.h \ + xkbmisc.c \ + xkbout.c \ + xkbtext.c \ + xkmout.c \ + xkmread.c + +INCLUDES = -I$(top_srcdir)/include/ -I$(top_srcdir)/include/X11/extensions/ +libxkbfile_la_LIBADD = @XKBFILE_LIBS@ +AM_CFLAGS = @XKBFILE_CFLAGS@ +libxkbfile_la_LDFLAGS = -version-number 1:0:2 -no-undefined +libxkbfileincludedir = $(includedir)/X11/extensions +libxkbfileinclude_HEADERS = \ + $(top_srcdir)/include/X11/extensions/XKM.h\ + $(top_srcdir)/include/X11/extensions/XKBrules.h\ + $(top_srcdir)/include/X11/extensions/XKBbells.h\ + $(top_srcdir)/include/X11/extensions/XKBconfig.h\ + $(top_srcdir)/include/X11/extensions/XKMformat.h\ + $(top_srcdir)/include/X11/extensions/XKBfile.h + +EXTRA_DIST = magic +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libxkbfile.la: $(libxkbfile_la_OBJECTS) $(libxkbfile_la_DEPENDENCIES) + $(libxkbfile_la_LINK) -rpath $(libdir) $(libxkbfile_la_OBJECTS) $(libxkbfile_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maprules.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srvmisc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbatom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbbells.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbconfig.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbdraw.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkberrs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbmisc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkbtext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkmout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xkmread.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-libxkbfileincludeHEADERS: $(libxkbfileinclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(libxkbfileincludedir)" || $(MKDIR_P) "$(DESTDIR)$(libxkbfileincludedir)" + @list='$(libxkbfileinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(libxkbfileincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libxkbfileincludedir)/$$f'"; \ + $(libxkbfileincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libxkbfileincludedir)/$$f"; \ + done + +uninstall-libxkbfileincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libxkbfileinclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libxkbfileincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(libxkbfileincludedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libxkbfileincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-libxkbfileincludeHEADERS + +install-dvi: install-dvi-am + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-libxkbfileincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libxkbfileincludeHEADERS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-libLTLIBRARIES \ + uninstall-libxkbfileincludeHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libxkbfile/src/XKBfileInt.h b/libxkbfile/src/XKBfileInt.h new file mode 100644 index 000000000..7eb81a0c0 --- /dev/null +++ b/libxkbfile/src/XKBfileInt.h @@ -0,0 +1,81 @@ +#ifndef _XKBFILEINT_H_ +#define _XKBFILEINT_H_ 1 + +/* $Xorg: XKBfileInt.h,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86$ */ + +#include "XKBfile.h" + +#ifdef DEBUG +#define _XkbLibError(c,l,d) \ + { fprintf(stderr,"xkbfile: %s in %s\n",_XkbErrMessages[c],(l)); \ + _XkbErrCode= (c); _XkbErrLocation= (l); _XkbErrData= (d); } +#else +#define _XkbLibError(c,l,d) \ + { _XkbErrCode= (c); _XkbErrLocation= (l); _XkbErrData= (d); } +#endif + +#ifndef XKB_IN_SERVER + +#define _XkbAlloc(s) malloc((s)) +#define _XkbCalloc(n,s) calloc((n),(s)) +#define _XkbRealloc(o,s) realloc((o),(s)) +#define _XkbTypedAlloc(t) ((t *)malloc(sizeof(t))) +#define _XkbTypedCalloc(n,t) ((t *)calloc((n),sizeof(t))) +#define _XkbTypedRealloc(o,n,t) \ + ((o)?(t *)realloc((o),(n)*sizeof(t)):_XkbTypedCalloc(n,t)) +#define _XkbClearElems(a,f,l,t) bzero(&(a)[f],((l)-(f)+1)*sizeof(t)) +#define _XkbFree(p) free(p) + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif + +#endif + +_XFUNCPROTOBEGIN + +extern char * _XkbDupString( + char * /* old_str */ +); + +#define _XkbStrCaseEqual(s1,s2) (_XkbStrCaseCmp(s1,s2)==0) + +#ifdef NEED_STRCASECMP +extern int _XkbStrCaseCmp(char *s1, char *s2); +#else +#define _XkbStrCaseCmp strcasecmp +#endif + +_XFUNCPROTOEND + +#endif /* _XKBFILEINT_H_ */ diff --git a/libxkbfile/src/cout.c b/libxkbfile/src/cout.c new file mode 100644 index 000000000..161bd0f89 --- /dev/null +++ b/libxkbfile/src/cout.c @@ -0,0 +1,1036 @@ +/* $Xorg: cout.c,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ + /* $XFree86: xc/lib/xkbfile/cout.c,v 3.8 2003/02/03 20:12:00 paulo Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xos.h> +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +#define lowbit(x) ((x) & (-(x))) + +static Bool +WriteCHdrVMods(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register int i,nOut; + + if ((!xkb)||(!xkb->names)||(!xkb->names->vmods)) + return False; + for (i=nOut=0;i<XkbNumVirtualMods;i++) { + if (xkb->names->vmods[i]!=None) { + fprintf(file,"%s#define vmod_%s %d\n",(nOut<1?"\n":""), + XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile), + i); + nOut++; + } + } + for (i=nOut=0;i<XkbNumVirtualMods;i++) { + if (xkb->names->vmods[i]!=None) { + fprintf(file,"%s#define vmod_%sMask (1<<%d)\n", + (nOut<1?"\n":""), + XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile) + ,i); + nOut++; + } + } + if (nOut>0) + fprintf(file,"\n"); + return True; +} + +static Bool +WriteCHdrKeycodes(FILE *file,XkbDescPtr xkb) +{ +Atom kcName; +register unsigned i; +char buf[8]; + + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"WriteCHdrKeycodes",0); + return False; + } + kcName= xkb->names->keycodes; + buf[4]= '\0'; + if (xkb->names->keycodes!=None) + fprintf(file,"/* keycodes name is \"%s\" */\n", + XkbAtomText(xkb->dpy,kcName,XkbMessage)); + fprintf(file,"static XkbKeyNameRec keyNames[NUM_KEYS]= {\n"); + for (i=0;i<=xkb->max_key_code;i++) { + sprintf(buf,"\"%s\"",XkbKeyNameText(xkb->names->keys[i].name,XkbCFile)); + if (i!=xkb->max_key_code) { + fprintf(file," { %6s },",buf); + if ((i&3)==3) + fprintf(file,"\n"); + } + else { + fprintf(file," { %6s }\n",buf); + } + } + fprintf(file,"};\n"); + return True; +} + +static void +WriteTypePreserve( FILE * file, + Display * dpy, + char * prefix, + XkbDescPtr xkb, + XkbKeyTypePtr type) +{ +register unsigned i; +XkbModsPtr pre; + + fprintf(file,"static XkbModsRec preserve_%s[%d]= {\n",prefix, + type->map_count); + for (i=0,pre=type->preserve;i<type->map_count;i++,pre++) { + if (i!=0) + fprintf(file,",\n"); + fprintf(file," { %15s, ",XkbModMaskText(pre->mask,XkbCFile)); + fprintf(file,"%15s, ",XkbModMaskText(pre->real_mods,XkbCFile)); + fprintf(file,"%15s }",XkbVModMaskText(dpy,xkb,0,pre->vmods,XkbCFile)); + } + fprintf(file,"\n};\n"); + return; +} + +static void +WriteTypeInitFunc(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register unsigned i,n; +XkbKeyTypePtr type; +Atom * names; +char prefix[32]; + + fprintf(file,"\n\nstatic void\n"); + fprintf(file,"initTypeNames(DPYTYPE dpy)\n"); + fprintf(file,"{\n"); + for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) { + strcpy(prefix,XkbAtomText(dpy,type->name,XkbCFile)); + if (type->name!=None) + fprintf(file," dflt_types[%d].name= GET_ATOM(dpy,\"%s\");\n",i, + XkbAtomText(dpy,type->name,XkbCFile)); + names= type->level_names; + if (names!=NULL) { + char *tmp; + for (n=0;n<type->num_levels;n++) { + if (names[n]==None) + continue; + tmp= XkbAtomText(dpy,names[n],XkbCFile); + if (tmp==NULL) + continue; + fprintf(file," lnames_%s[%d]= ",prefix,n); + fprintf(file,"GET_ATOM(dpy,\"%s\");\n",tmp); + } + } + } + fprintf(file,"}\n"); + return; +} + +static Bool +WriteCHdrKeyTypes(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register unsigned i,n; +XkbClientMapPtr map; +XkbKeyTypePtr type; +char prefix[32]; + + if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { + _XkbLibError(_XkbErrMissingTypes,"WriteCHdrKeyTypes",0); + return False; + } + if (xkb->map->num_types<XkbNumRequiredTypes) { + _XkbLibError(_XkbErrMissingReqTypes,"WriteCHdrKeyTypes",0); + return 0; + } + map= xkb->map; + if ((xkb->names!=NULL)&&(xkb->names->types!=None)) { + fprintf(file,"/* types name is \"%s\" */\n", + XkbAtomText(dpy,xkb->names->types,XkbCFile)); + } + for (i=0,type=map->types;i<map->num_types;i++,type++) { + strcpy(prefix,XkbAtomText(dpy,type->name,XkbCFile)); + + if (type->map_count>0) { + XkbKTMapEntryPtr entry; + entry= type->map; + fprintf(file,"static XkbKTMapEntryRec map_%s[%d]= {\n",prefix, + type->map_count); + for (n=0;n<(unsigned)type->map_count;n++,entry++) { + if (n!=0) + fprintf(file,",\n"); + fprintf(file," { %d, %6d, { %15s, %15s, %15s } }", + entry->active, + entry->level, + XkbModMaskText(entry->mods.mask,XkbCFile), + XkbModMaskText(entry->mods.real_mods,XkbCFile), + XkbVModMaskText(dpy,xkb,0,entry->mods.vmods,XkbCFile)); + } + fprintf(file,"\n};\n"); + + if (type->preserve) + WriteTypePreserve(file,dpy,prefix,xkb,type); + } + if (type->level_names!=NULL) { + fprintf(file,"static Atom lnames_%s[%d];\n",prefix, + type->num_levels); + } + fprintf(file,"\n"); + } + fprintf(file,"static XkbKeyTypeRec dflt_types[]= {\n"); + for (i=0,type=map->types;i<(unsigned)map->num_types;i++,type++) { + strcpy(prefix,XkbAtomText(dpy,type->name,XkbCFile)); + if (i!=0) fprintf(file,",\n"); + fprintf(file," {\n { %15s, %15s, %15s },\n", + XkbModMaskText(type->mods.mask,XkbCFile), + XkbModMaskText(type->mods.real_mods,XkbCFile), + XkbVModMaskText(dpy,xkb,0,type->mods.vmods,XkbCFile)); + fprintf(file," %d,\n",type->num_levels); + fprintf(file," %d,",type->map_count); + if (type->map_count>0) + fprintf(file," map_%s,",prefix); + else fprintf(file," NULL,"); + if (type->preserve) + fprintf(file," preserve_%s,\n",prefix); + else fprintf(file," NULL,\n"); + if (type->level_names!=NULL) + fprintf(file," None, lnames_%s\n }",prefix); + else fprintf(file," None, NULL\n }"); + } + fprintf(file,"\n};\n"); + fprintf(file,"#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))\n"); + WriteTypeInitFunc(file,dpy,xkb); + return True; +} + +static Bool +WriteCHdrCompatMap(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register unsigned i; +XkbCompatMapPtr compat; +XkbSymInterpretPtr interp; + + if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { + _XkbLibError(_XkbErrMissingSymInterps,"WriteCHdrInterp",0); + return False; + } + compat= xkb->compat; + if ((xkb->names!=NULL)&&(xkb->names->compat!=None)) { + fprintf(file,"/* compat name is \"%s\" */\n", + XkbAtomText(dpy,xkb->names->compat,XkbCFile)); + } + fprintf(file,"static XkbSymInterpretRec dfltSI[%d]= {\n", + compat->num_si); + interp= compat->sym_interpret; + for (i=0;i<compat->num_si;i++,interp++) { + XkbAction *act; + act= (XkbAction *)&interp->act; + if (i!=0) fprintf(file,",\n"); + fprintf(file," { %s, ",XkbKeysymText(interp->sym,XkbCFile)); + fprintf(file,"0x%04x,\n",interp->flags); + fprintf(file," %s, ",XkbSIMatchText(interp->match,XkbCFile)); + fprintf(file,"%s,\n",XkbModMaskText(interp->mods,XkbCFile)); + fprintf(file," %d,\n",interp->virtual_mod); + fprintf(file," %s }",XkbActionText(dpy,xkb,act,XkbCFile)); + } + fprintf(file,"\n};\n"); + fprintf(file, + "#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))\n"); + fprintf(file,"\nstatic XkbCompatMapRec compatMap= {\n"); + fprintf(file," dfltSI,\n"); + fprintf(file," { /* group compatibility */\n "); + for (i=0;i<XkbNumKbdGroups;i++) { + XkbModsPtr gc; + gc= &xkb->compat->groups[i]; + fprintf(file,"%s{ %12s, %12s, %12s }", + ((i==0)?"":",\n "), + XkbModMaskText(gc->mask,XkbCFile), + XkbModMaskText(gc->real_mods,XkbCFile), + XkbVModMaskText(xkb->dpy,xkb,0,gc->vmods,XkbCFile)); + } + fprintf(file,"\n },\n"); + fprintf(file," num_dfltSI, num_dfltSI\n"); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteCHdrSymbols(FILE *file,XkbDescPtr xkb) +{ +register unsigned i; + + if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) { + _XkbLibError(_XkbErrMissingSymbols,"WriteCHdrSymbols",0); + return False; + } + fprintf(file,"#define NUM_SYMBOLS %d\n",xkb->map->num_syms); + if (xkb->map->num_syms>0) { + register KeySym *sym; + sym= xkb->map->syms; + fprintf(file,"static KeySym symCache[NUM_SYMBOLS]= {\n"); + for (i=0;i<xkb->map->num_syms;i++,sym++) { + if (i==0) fprintf(file," "); + else if (i%4==0) fprintf(file,",\n "); + else fprintf(file,", "); + fprintf(file,"%15s",XkbKeysymText(*sym,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + if (xkb->max_key_code>0) { + register XkbSymMapPtr map; + map= xkb->map->key_sym_map; + fprintf(file,"static XkbSymMapRec symMap[NUM_KEYS]= {\n"); + for (i=0;i<=xkb->max_key_code;i++,map++) { + if (i==0) fprintf(file," "); + else if ((i&3)==0) fprintf(file,",\n "); + else fprintf(file,", "); + fprintf(file, "{ %2d, 0x%x, %3d }", + map->kt_index[0], map->group_info, map->offset); + } + fprintf(file,"\n};\n"); + } + return True; +} + +static Bool +WriteCHdrClientMap(FILE *file,Display *dpy,XkbDescPtr xkb) +{ + if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) { + _XkbLibError(_XkbErrMissingSymbols,"WriteCHdrClientMap",0); + return False; + } + if (!WriteCHdrKeyTypes(file,dpy,xkb)) + return False; + if (!WriteCHdrSymbols(file,xkb)) + return False; + fprintf(file,"static XkbClientMapRec clientMap= {\n"); + fprintf(file," NUM_TYPES, NUM_TYPES, types, \n"); + fprintf(file," NUM_SYMBOLS, NUM_SYMBOLS, symCache, symMap\n"); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteCHdrServerMap(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register unsigned i; + + if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) { + _XkbLibError(_XkbErrMissingSymbols,"WriteCHdrServerMap",0); + return False; + } + if (xkb->server->num_acts>0) { + register XkbAnyAction *act; + act= (XkbAnyAction *)xkb->server->acts; + fprintf(file,"#define NUM_ACTIONS %d\n",xkb->server->num_acts); + fprintf(file,"static XkbAnyAction actionCache[NUM_ACTIONS]= {\n"); + for (i=0;i<xkb->server->num_acts;i++,act++) { + if (i==0) fprintf(file," "); + else fprintf(file,",\n "); + fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)act,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + fprintf(file,"static unsigned short keyActions[NUM_KEYS]= {\n"); + for (i=0;i<=xkb->max_key_code;i++) { + if (i==0) fprintf(file," "); + else if ((i&0xf)==0) fprintf(file,",\n "); + else fprintf(file,", "); + fprintf(file,"%2d",xkb->server->key_acts[i]); + } + fprintf(file,"\n};\n"); + fprintf(file,"static XkbBehavior behaviors[NUM_KEYS]= {\n"); + for (i=0;i<=xkb->max_key_code;i++) { + if (i==0) fprintf(file," "); + else if ((i&0x3)==0) fprintf(file,",\n "); + else fprintf(file,", "); + if (xkb->server->behaviors) { + fprintf(file,"%s", + XkbBehaviorText(xkb,&xkb->server->behaviors[i],XkbCFile)); + } + else fprintf(file,"{ 0, 0 }"); + } + fprintf(file,"\n};\n"); + fprintf(file,"static unsigned char explicit_parts[NUM_KEYS]= {\n"); + for (i=0;i<=xkb->max_key_code;i++) { + if (i==0) fprintf(file," "); + else if ((i&0x7)==0) fprintf(file,",\n "); + else fprintf(file,", "); + if ((xkb->server->explicit==NULL)||(xkb->server->explicit[i]==0)) + fprintf(file," 0"); + else fprintf(file,"0x%02x",xkb->server->explicit[i]); + } + fprintf(file,"\n};\n"); + fprintf(file,"static unsigned short vmodmap[NUM_KEYS]= {\n"); + for (i=0;i<xkb->max_key_code;i++) { + if (i==0) fprintf(file," "); + else if ((i&0x7)==0) fprintf(file,",\n "); + else fprintf(file,", "); + if ((xkb->server->vmodmap==NULL)||(xkb->server->vmodmap[i]==0)) + fprintf(file," 0"); + else fprintf(file,"0x%04x",xkb->server->vmodmap[i]); + } + fprintf(file,"};\n"); + fprintf(file,"static XkbServerMapRec serverMap= {\n"); + fprintf(file," %d, %d, (XkbAction *)actionCache,\n", + xkb->server->num_acts,xkb->server->num_acts); + fprintf(file," behaviors, keyActions, explicit_parts,\n"); + for (i=0;i<XkbNumVirtualMods;i++) { + if (i==0) fprintf(file," { "); + else if (i==8) fprintf(file,",\n "); + else fprintf(file,", "); + fprintf(file,"%3d",xkb->server->vmods[i]); + } + fprintf(file," },\n"); + fprintf(file," vmodmap\n"); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteCHdrIndicators(FILE *file,Display *dpy,XkbDescPtr xkb) +{ +register int i,nNames; +XkbIndicatorMapPtr imap; + + if (xkb->indicators==NULL) + return True; + fprintf(file, "static XkbIndicatorRec indicators= {\n"); + fprintf(file, " 0x%lx,\n {\n", + (long)xkb->indicators->phys_indicators); + for (imap=xkb->indicators->maps,i=nNames=0;i<XkbNumIndicators;i++,imap++) { + fprintf(file,"%s { 0x%02x, %s, 0x%02x, %s, { %s, ", + (i!=0?",\n":""), + imap->flags, + XkbIMWhichStateMaskText(imap->which_groups,XkbCFile), + imap->groups, + XkbIMWhichStateMaskText(imap->which_mods,XkbCFile), + XkbModMaskText(imap->mods.mask,XkbCFile)); + fprintf(file," %s, %s }, %s }", + XkbModMaskText(imap->mods.real_mods,XkbCFile), + XkbVModMaskText(dpy,xkb,0,imap->mods.vmods,XkbCFile), + XkbControlsMaskText(imap->ctrls,XkbCFile)); + if (xkb->names && (xkb->names->indicators[i]!=None)) + nNames++; + } + fprintf(file,"\n }\n};\n"); + if (nNames>0) { + fprintf(file,"static void\n"); + fprintf(file,"initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)\n"); + fprintf(file,"{\n"); + for (i=0;i<XkbNumIndicators;i++) { + Atom name; + if (xkb->names->indicators[i]==None) + continue; + name= xkb->names->indicators[i]; + fprintf(file," xkb->names->indicators[%2d]= ",i); + fprintf(file,"GET_ATOM(dpy,\"%s\");\n", + XkbAtomText(dpy,name,XkbCFile)); + } + fprintf(file,"}\n"); + } + return True; +} + +static Bool +WriteCHdrGeomProps(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom) +{ + if (geom->num_properties>0) { + register int i; + fprintf(file,"\nstatic XkbPropertyRec g_props[%d]= {\n", + geom->num_properties); + for (i=0;i<geom->num_properties;i++) { + fprintf(file,"%s { \"%s\", \"%s\" }",(i==0?"":",\n"), + XkbStringText(geom->properties[i].name,XkbCFile), + XkbStringText(geom->properties[i].value,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + return True; +} + +static Bool +WriteCHdrGeomColors(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom) +{ + if (geom->num_colors>0) { + register int i; + fprintf(file,"\nstatic XkbColorRec g_colors[%d]= {\n",geom->num_colors); + for (i=0;i<geom->num_colors;i++) { + fprintf(file,"%s { %3d, \"%s\" }",(i==0?"":",\n"), + geom->colors[i].pixel, + XkbStringText(geom->colors[i].spec,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + return True; +} + +static Bool +WriteCHdrGeomOutlines(FILE *file,int nOL,XkbOutlinePtr ol,int shapeNdx) +{ +register int o,p; + + + for (o=0;o<nOL;o++) { + fprintf(file,"\nstatic XkbPointRec pts_sh%02do%02d[]= {\n",shapeNdx,o); + for (p=0;p<ol[o].num_points;p++) { + if (p==0) fprintf(file," "); + else if ((p&0x3)==0) fprintf(file,",\n "); + else fprintf(file,", "); + fprintf(file,"{ %4d, %4d }", + ol[o].points[p].x,ol[o].points[p].y); + } + fprintf(file,"\n};"); + } + fprintf(file,"\n\nstatic XkbOutlineRec ol_sh%02d[]= {\n",shapeNdx); + for (o=0;o<nOL;o++) { + fprintf(file,"%s { %d, %d, %d, pts_sh%02do%02d }", + (o==0?"":",\n"), + ol[o].num_points,ol[o].num_points, + ol[o].corner_radius,shapeNdx,o); + } + fprintf(file,"\n};\n"); + return True; +} + +static Bool +WriteCHdrGeomShapes(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom) +{ +register int s; +register XkbShapePtr shape; + + for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) { + WriteCHdrGeomOutlines(file,shape->num_outlines,shape->outlines,s); + } + fprintf(file,"\n\nstatic XkbShapeRec g_shapes[%d]= {\n",geom->num_shapes); + for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) { + fprintf(file,"%s { None, %3d, %3d, ol_sh%02d, ", + (s==0?"":",\n"),shape->num_outlines, + shape->num_outlines,s); + if (shape->approx) { + fprintf(file,"&ol_sh%02d[%2d], ",s, + XkbOutlineIndex(shape,shape->approx)); + } + else fprintf(file," NULL, "); + if (shape->primary) { + fprintf(file,"&ol_sh%02d[%2d],\n",s, + XkbOutlineIndex(shape,shape->primary)); + } + else fprintf(file," NULL,\n"); + fprintf(file," { %4d, %4d, %4d, %4d } }", + shape->bounds.x1,shape->bounds.y1, + shape->bounds.x2,shape->bounds.y2); + } + fprintf(file,"\n};\n"); + return True; +} + +static Bool +WriteCHdrGeomDoodads( FILE * file, + XkbDescPtr xkb, + XkbGeometryPtr geom, + XkbSectionPtr section, + int section_num) +{ +int nd,d; +XkbDoodadPtr doodad; +Display * dpy; + + dpy= xkb->dpy; + if (section==NULL) { + if (geom->num_doodads>0) { + fprintf(file,"static XkbDoodadRec g_doodads[%d];\n", + geom->num_doodads); + } + fprintf(file,"static void\n"); + fprintf(file,"_InitGeomDoodads(DPYTYPE dpy,XkbGeometryPtr geom)\n"); + fprintf(file,"{\n"); + fprintf(file,"register XkbDoodadPtr doodads;\n\n"); + fprintf(file," doodads= geom->doodads;\n"); + nd= geom->num_doodads; + doodad= geom->doodads; + } + else { + if (section->num_doodads>0) { + fprintf(file,"static XkbDoodadRec doodads_s%02d[%d];\n", + section_num,section->num_doodads); + } + fprintf(file,"static void\n"); + fprintf(file,"_InitS%02dDoodads(",section_num); + fprintf(file," DPYTYPE dpy,\n"); + fprintf(file," XkbGeometryPtr geom,\n"); + fprintf(file," XkbSectionPtr section)\n"); + fprintf(file,"{\n"); + fprintf(file,"register XkbDoodadPtr doodads;\n\n"); + fprintf(file," doodads= section->doodads;\n"); + nd= geom->num_doodads; + doodad= geom->doodads; + } + for (d=0;d<nd;d++,doodad++) { + if (d!=0) fprintf(file,"\n"); + fprintf(file," doodads[%d].any.name= GET_ATOM(dpy,\"%s\");\n",d, + XkbAtomText(dpy,doodad->any.name,XkbCFile)); + fprintf(file," doodads[%d].any.type= %s;\n",d, + XkbDoodadTypeText(doodad->any.type,XkbCFile)); + fprintf(file," doodads[%d].any.priority= %d;\n",d, + doodad->any.priority); + fprintf(file," doodads[%d].any.top= %d;\n",d,doodad->any.top); + fprintf(file," doodads[%d].any.left= %d;\n",d,doodad->any.left); + fprintf(file," doodads[%d].any.angle= %d;\n",d,doodad->any.angle); + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + fprintf(file," doodads[%d].shape.color_ndx= %d;\n",d, + doodad->shape.color_ndx); + fprintf(file," doodads[%d].shape.shape_ndx= %d;\n",d, + doodad->shape.shape_ndx); + break; + case XkbTextDoodad: + fprintf(file," doodads[%d].text.width= %d;\n",d, + doodad->text.width); + fprintf(file," doodads[%d].text.height= %d;\n",d, + doodad->text.height); + fprintf(file," doodads[%d].text.color_ndx= %d;\n",d, + doodad->text.color_ndx); + fprintf(file," doodads[%d].text.text= \"%s\";\n",d, + XkbStringText(doodad->text.text,XkbCFile)); + fprintf(file," doodads[%d].text.font= \"%s\";\n",d, + XkbStringText(doodad->text.font,XkbCFile)); + break; + case XkbIndicatorDoodad: + fprintf(file," doodads[%d].indicator.shape_ndx= %d;\n",d, + doodad->indicator.shape_ndx); + fprintf(file," doodads[%d].indicator.on_color_ndx= %d;\n",d, + doodad->indicator.on_color_ndx); + fprintf(file," doodads[%d].indicator.off_color_ndx= %d;\n",d, + doodad->indicator.off_color_ndx); + break; + case XkbLogoDoodad: + fprintf(file," doodads[%d].logo.color_ndx= %d;\n",d, + doodad->logo.color_ndx); + fprintf(file," doodads[%d].logo.shape_ndx= %d;\n",d, + doodad->logo.shape_ndx); + fprintf(file," doodads[%d].logo.logo_name= \"%s\";\n",d, + XkbStringText(doodad->logo.logo_name,XkbCFile)); + break; + } + } + fprintf(file,"}\n"); + return True; +} + +static Bool +WriteCHdrGeomOverlays( FILE * file, + XkbDescPtr xkb, + XkbSectionPtr section, + int section_num) +{ +register int o,r,k; +XkbOverlayPtr ol; +XkbOverlayRowPtr row; +XkbOverlayKeyPtr key; + + if (section->num_overlays<1) + return True; + for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + fprintf(file,"static XkbOverlayKeyRec olkeys_s%02dr%02d[%d]= {\n", + section_num,r,row->num_keys); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + fprintf(file,"%s { {\"%s\"}, {\"%s\"} }", + (k==0?"":",\n"), + XkbKeyNameText(key->over.name,XkbCFile), + XkbKeyNameText(key->under.name,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + fprintf(file,"static XkbOverlayRowRec olrows_s%02d[%d]= {\n", + section_num,section->num_rows); + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + fprintf(file,"%s { %4d, %4d, %4d, olkeys_s%02dr%02d }", + (r==0?"":",\n"), + row->row_under,row->num_keys,row->num_keys, + section_num,r); + } + fprintf(file,"\n};\n"); + } + fprintf(file,"static XkbOverlayRec overlays_s%02d[%d]= {\n",section_num, + section->num_overlays); + for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { + fprintf(file,"%s {\n",(o==0?"":",\n")); + fprintf(file," None, /* name */\n"); + fprintf(file," NULL, /* section_under */\n"); + fprintf(file," %4d, /* num_rows */\n",ol->num_rows); + fprintf(file," %4d, /* sz_rows */\n",ol->num_rows); + fprintf(file," olrows_s%02d,\n",section_num); + fprintf(file," NULL /* bounds */\n"); + fprintf(file," }"); + } + fprintf(file,"\n};\n"); + fprintf(file,"static void\n"); + fprintf(file,"_InitS%02dOverlay(",section_num); + fprintf(file," DPYTYPE dpy,\n"); + fprintf(file," XkbGeometryPtr geom,\n"); + fprintf(file," XkbSectionPtr section)\n"); + fprintf(file,"{\n"); + fprintf(file,"XkbOverlayPtr ol;\n\n"); + fprintf(file," ol= section->overlays;\n"); + for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { + fprintf(file," ol[%2d].name= GET_ATOM(dpy,\"%s\");\n",o, + XkbAtomText(xkb->dpy,ol->name,XkbCFile)); + fprintf(file," ol[%2d].section_under= section;\n",o); + } + fprintf(file,"}\n"); + return True; +} + +static Bool +WriteCHdrGeomRows( FILE * file, + XkbDescPtr xkb, + XkbSectionPtr section, + int section_num) +{ +register int k,r; +register XkbRowPtr row; +register XkbKeyPtr key; + + for (r=0,row=section->rows;r<section->num_rows;r++,row++) { + fprintf(file,"static XkbKeyRec keys_s%02dr%02d[]= {\n",section_num,r); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + fprintf(file,"%s { { \"%s\" }, %4d, %4d, %4d }", + (k==0?"":",\n"), + XkbKeyNameText(key->name.name,XkbCFile), + key->gap,key->shape_ndx,key->color_ndx); + } + fprintf(file,"\n};\n"); + } + fprintf(file,"static XkbRowRec rows_s%02d[]= {\n",section_num); + for (r=0,row=section->rows;r<section->num_rows;r++,row++) { + fprintf(file,"%s { %4d, %4d, %2d, %2d, %1d, keys_s%02dr%02d, ", + (r==0?"":",\n"), + row->top,row->left,row->num_keys,row->num_keys, + (row->vertical!=0), + section_num,r); + fprintf(file," { %4d, %4d, %4d, %4d } }", + row->bounds.x1,row->bounds.y1, + row->bounds.x2,row->bounds.y2); + } + fprintf(file,"\n};\n"); + return True; +} + +static Bool +WriteCHdrGeomSections(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom) +{ +register int s; +register XkbSectionPtr section; + + for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) { + WriteCHdrGeomRows(file,xkb,section,s); +#ifdef NOTYET + if (section->num_doodads>0) + WriteCHdrGeomDoodads(file,xkb,geom,section,s); +#endif + if (section->num_overlays>0) + WriteCHdrGeomOverlays(file,xkb,section,s); + } + fprintf(file,"\nstatic XkbSectionRec g_sections[%d]= {\n", + geom->num_sections); + for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) { + if (s!=0) fprintf(file,",\n"); + fprintf(file," {\n None, /* name */\n"); + fprintf(file," %4d, /* priority */\n",section->priority); + fprintf(file," %4d, /* top */\n",section->top); + fprintf(file," %4d, /* left */\n",section->left); + fprintf(file," %4d, /* width */\n",section->width); + fprintf(file," %4d, /* height */\n",section->height); + fprintf(file," %4d, /* angle */\n",section->angle); + fprintf(file," %4d, /* num_rows */\n",section->num_rows); + fprintf(file," %4d, /* num_doodads */\n",section->num_doodads); + fprintf(file," %4d, /* num_overlays */\n",section->num_overlays); + fprintf(file," %4d, /* sz_rows */\n",section->num_rows); + fprintf(file," %4d, /* sz_doodads */\n",section->num_doodads); + fprintf(file," %4d, /* sz_overlays */\n",section->num_overlays); + if (section->num_rows>0) + fprintf(file," rows_s%02d,\n",s); + else fprintf(file," NULL, /* rows */\n"); + if (section->num_doodads>0) + fprintf(file," doodads_s%02d,\n",s); + else fprintf(file," NULL, /* doodads */\n"); + fprintf(file," { %4d, %4d, %4d, %4d }, /* bounds */\n", + section->bounds.x1,section->bounds.y1, + section->bounds.x2,section->bounds.y2); + if (section->num_overlays>0) + fprintf(file," overlays_s%02d\n",s); + else fprintf(file," NULL /* overlays */\n"); + fprintf(file," }"); + } + fprintf(file,"\n};\n"); + fprintf(file,"\nstatic Bool\n"); + fprintf(file,"_InitSections(DPYTYPE dpy,XkbGeometryPtr geom)\n"); + fprintf(file,"{\nXkbSectionPtr sections;\n\n"); + fprintf(file," sections= geom->sections;\n"); + for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) { + if (section->num_doodads>0) { + fprintf(file," _InitS%02dDoodads(dpy,geom,§ions[%d]);\n", + s,s); + } + if (section->num_overlays>0) { + fprintf(file," _InitS%02dOverlays(dpy,geom,§ions[%d]);\n", + s,s); + } + } + fprintf(file,"}\n"); + return True; +} + +static Bool +WriteCHdrGeomAliases(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom) +{ + if (geom->num_key_aliases>0) { + register int i; + fprintf(file,"\nstatic XkbKeyAliasRec g_aliases[%d]= {\n", + geom->num_key_aliases); + for (i=0;i<geom->num_key_aliases;i++) { + fprintf(file,"%s { \"%s\", \"%s\" }",(i==0?"":",\n"), + XkbKeyNameText(geom->key_aliases[i].real,XkbCFile), + XkbKeyNameText(geom->key_aliases[i].alias,XkbCFile)); + } + fprintf(file,"\n};\n"); + } + return True; +} + +static Bool +WriteCHdrGeometry(FILE *file,XkbDescPtr xkb) +{ +XkbGeometryPtr geom; +register int i; + + if ((!xkb)||(!xkb->geom)) { + _XkbLibError(_XkbErrMissingGeometry,"WriteCHdrGeometry",0); + return False; + } + geom= xkb->geom; + WriteCHdrGeomProps(file,xkb,geom); + WriteCHdrGeomColors(file,xkb,geom); + WriteCHdrGeomShapes(file,xkb,geom); + WriteCHdrGeomSections(file,xkb,geom); + WriteCHdrGeomDoodads(file,xkb,geom,NULL,0); + WriteCHdrGeomAliases(file,xkb,geom); + fprintf(file,"\nstatic XkbGeometryRec geom= {\n"); + fprintf(file," None, /* name */\n"); + fprintf(file," %d, %d, /* width, height */\n",geom->width_mm, + geom->height_mm); + if (geom->label_font) { + fprintf(file," \"%s\",/* label font */\n", + XkbStringText(geom->label_font,XkbCFile)); + } + else fprintf(file," NULL, /* label font */\n"); + if (geom->label_color) { + fprintf(file," &g_colors[%d], /* label color */\n", + XkbGeomColorIndex(geom,geom->label_color)); + } + else fprintf(file," NULL, /* label color */\n"); + if (geom->base_color) { + fprintf(file," &g_colors[%d], /* base color */\n", + XkbGeomColorIndex(geom,geom->base_color)); + } + else fprintf(file," NULL, /* base color */\n"); + fprintf(file," %d, %d, %d, /* sz: props, colors, shapes */\n", + geom->num_properties,geom->num_colors, + geom->num_shapes); + fprintf(file," %d, %d, %d, /* sz: sections, doodads, aliases */\n", + geom->num_sections,geom->num_doodads, + geom->num_key_aliases); + fprintf(file," %d, %d, %d, /* num: props, colors, shapes */\n", + geom->num_properties,geom->num_colors, + geom->num_shapes); + fprintf(file," %d, %d, %d, /* num: sections, doodads, aliases */\n", + geom->num_sections,geom->num_doodads, + geom->num_key_aliases); + fprintf(file," %s, %s, %s,\n", + (geom->num_properties>0?"g_props":"NULL"), + (geom->num_colors>0?"g_colors":"NULL"), + (geom->num_shapes>0?"g_shapes":"NULL")); + fprintf(file," %s, %s, %s\n", + (geom->num_sections>0?"g_sections":"NULL"), + (geom->num_doodads>0?"g_doodads":"NULL"), + (geom->num_key_aliases>0?"g_aliases":"NULL")); + fprintf(file,"};\n\n"); + fprintf(file,"static Bool\n"); + fprintf(file,"_InitHdrGeom(DPYTYPE dpy,XkbGeometryPtr geom)\n"); + fprintf(file,"{\n"); + if (geom->name!=None) { + fprintf(file," geom->name= GET_ATOM(dpy,\"%s\");\n", + XkbAtomText(xkb->dpy,geom->name,XkbCFile)); + } + for (i=0;i<geom->num_shapes;i++) { + fprintf(file," geom->shapes[%2d].name= GET_ATOM(dpy,\"%s\");\n",i, + XkbAtomText(xkb->dpy,geom->shapes[i].name,XkbCFile)); + } + if (geom->num_doodads>0) + fprintf(file," _InitGeomDoodads(dpy,geom);\n"); + fprintf(file," _InitSections(dpy,geom);\n"); + fprintf(file,"}\n\n"); + return True; +} + +static Bool +WriteCHdrGeomFile(FILE *file,XkbFileInfo *result) +{ +Bool ok; + + ok= WriteCHdrGeometry(file,result->xkb); + return ok; +} + +static Bool +WriteCHdrLayout(FILE *file,XkbFileInfo *result) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + ok= WriteCHdrVMods(file,xkb->dpy,xkb); + ok= WriteCHdrKeycodes(file,xkb)&&ok; + ok= WriteCHdrSymbols(file,xkb)&&ok; + ok= WriteCHdrGeometry(file,xkb)&&ok; + return ok; +} + +static Bool +WriteCHdrSemantics(FILE *file,XkbFileInfo *result) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + ok= WriteCHdrVMods(file,xkb->dpy,xkb); + ok= WriteCHdrKeyTypes(file,xkb->dpy,xkb)&&ok; + ok= WriteCHdrCompatMap(file,xkb->dpy,xkb)&&ok; + ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok; + return ok; +} + +static Bool +WriteCHdrKeymap(FILE *file,XkbFileInfo *result) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + ok= WriteCHdrVMods(file,xkb->dpy,xkb); + ok= ok&&WriteCHdrKeycodes(file,xkb); + ok= ok&&WriteCHdrClientMap(file,xkb->dpy,xkb); + ok= ok&&WriteCHdrServerMap(file,xkb->dpy,xkb); + ok= ok&&WriteCHdrCompatMap(file,xkb->dpy,xkb); + ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok; + ok= ok&&WriteCHdrGeometry(file,xkb); + return ok; +} + +Bool +XkbWriteCFile(FILE *out,char *name,XkbFileInfo *result) +{ +Bool ok; +XkbDescPtr xkb; +Bool (*func)( + FILE * /* file*/, + XkbFileInfo * /* result */ +); + + switch (result->type) { + case XkmSemanticsFile: + func= WriteCHdrSemantics; + break; + case XkmLayoutFile: + func= WriteCHdrLayout; + break; + case XkmKeymapFile: + func= WriteCHdrKeymap; + break; + case XkmGeometryIndex: + case XkmGeometryFile: + func= WriteCHdrGeomFile; + break; + default: + _XkbLibError(_XkbErrIllegalContents,"XkbWriteCFile",result->type); + return False; + } + xkb= result->xkb; + if (out==NULL) { + _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteCFile",0); + ok= False; + } + else { + char *tmp,*hdrdef; + tmp= (char *)strrchr(name,'/'); + if (tmp==NULL) + tmp= name; + else tmp++; + hdrdef= (char *)_XkbCalloc(strlen(tmp)+1,sizeof(char)); + if (hdrdef) { + strcpy(hdrdef,tmp); + tmp= hdrdef; + while (*tmp) { + if (islower(*tmp)) *tmp= toupper(*tmp); + else if (!isalnum(*tmp)) *tmp= '_'; + tmp++; + } + fprintf(out,"/* This file generated automatically by xkbcomp */\n"); + fprintf(out,"/* DO NOT EDIT */\n"); + fprintf(out,"#ifndef %s\n",hdrdef); + fprintf(out,"#define %s 1\n\n",hdrdef); + } + fprintf(out,"#ifndef XKB_IN_SERVER\n"); + fprintf(out,"#define GET_ATOM(d,s) XInternAtom(d,s,0)\n"); + fprintf(out,"#define DPYTYPE Display *\n"); + fprintf(out,"#else\n"); + fprintf(out,"#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1)\n"); + fprintf(out,"#define DPYTYPE char *\n"); + fprintf(out,"#endif\n"); + fprintf(out,"#define NUM_KEYS %d\n",xkb->max_key_code+1); + ok= (*func)(out,result); + if (hdrdef) + fprintf(out,"#endif /* %s */\n",hdrdef); + } + + if (!ok) { + return False; + } + return True; +} diff --git a/libxkbfile/src/magic b/libxkbfile/src/magic new file mode 100644 index 000000000..9c433ad02 --- /dev/null +++ b/libxkbfile/src/magic @@ -0,0 +1,11 @@ +# $Xorg: magic,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ +# Here are some lines you can add to /etc/magic +# to identify XKM (compiled X keymap) files +# and determine their version and the byte ordering +# with which they were compiled +1 string mkx Compiled XKB Keymap: lsb, +>0 byte >0 version %d +>0 byte =0 obsolete +0 string xkm Compiled XKB Keymap: msb, +>3 byte >0 version %d +>0 byte =0 obsolete diff --git a/libxkbfile/src/maprules.c b/libxkbfile/src/maprules.c new file mode 100644 index 000000000..ab164c6a2 --- /dev/null +++ b/libxkbfile/src/maprules.c @@ -0,0 +1,1477 @@ +/* $Xorg: maprules.c,v 1.4 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1996 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/maprules.c,v 3.17 2002/11/26 01:43:25 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#define X_INCLUDE_STRING_H +#define XOS_USE_NO_LOCKING +#include <X11/Xos_r.h> + +#ifndef XKB_IN_SERVER + +#include <X11/Xproto.h> +#include <X11/Xlib.h> +#include <X11/Xos.h> +#include <X11/Xfuncs.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> +#include "XKMformat.h" +#include "XKBfileInt.h" +#include "XKBrules.h" + +#else + +#define NEED_EVENTS +#include <X11/Xproto.h> +#include <X11/X.h> +#include <X11/Xos.h> +#include <X11/Xfuncs.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" +#include "dix.h" +#include <X11/extensions/XKBstr.h> +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> + +#endif + +#ifdef DEBUG +#define PR_DEBUG(s) fprintf(stderr,s) +#define PR_DEBUG1(s,a) fprintf(stderr,s,a) +#define PR_DEBUG2(s,a,b) fprintf(stderr,s,a,b) +#else +#define PR_DEBUG(s) +#define PR_DEBUG1(s,a) +#define PR_DEBUG2(s,a,b) +#endif + +/***====================================================================***/ + +#define DFLT_LINE_SIZE 128 + +typedef struct { + int line_num; + int sz_line; + int num_line; + char buf[DFLT_LINE_SIZE]; + char * line; +} InputLine; + +static void +InitInputLine(InputLine *line) +{ + line->line_num= 1; + line->num_line= 0; + line->sz_line= DFLT_LINE_SIZE; + line->line= line->buf; + return; +} + +static void +FreeInputLine(InputLine *line) +{ + if (line->line!=line->buf) + _XkbFree(line->line); + line->line_num= 1; + line->num_line= 0; + line->sz_line= DFLT_LINE_SIZE; + line->line= line->buf; + return; +} + +static int +InputLineAddChar(InputLine *line,int ch) +{ + if (line->num_line>=line->sz_line) { + if (line->line==line->buf) { + line->line= (char *)_XkbAlloc(line->sz_line*2); + memcpy(line->line,line->buf,line->sz_line); + } + else { + line->line=(char *)_XkbRealloc((char *)line->line,line->sz_line*2); + } + line->sz_line*= 2; + } + line->line[line->num_line++]= ch; + return ch; +} + +#define ADD_CHAR(l,c) ((l)->num_line<(l)->sz_line?\ + (int)((l)->line[(l)->num_line++]= (c)):\ + InputLineAddChar(l,c)) + +static Bool +GetInputLine(FILE *file,InputLine *line,Bool checkbang) +{ +int ch; +Bool endOfFile,spacePending,slashPending,inComment; + + endOfFile= False; + while ((!endOfFile)&&(line->num_line==0)) { + spacePending= slashPending= inComment= False; + while (((ch=getc(file))!='\n')&&(ch!=EOF)) { + if (ch=='\\') { + if ((ch=getc(file))==EOF) + break; + if (ch=='\n') { + inComment= False; + ch= ' '; + line->line_num++; + } + } + if (inComment) + continue; + if (ch=='/') { + if (slashPending) { + inComment= True; + slashPending= False; + } + else { + slashPending= True; + } + continue; + } + else if (slashPending) { + if (spacePending) { + ADD_CHAR(line,' '); + spacePending= False; + } + ADD_CHAR(line,'/'); + slashPending= False; + } + if (isspace(ch)) { + while (isspace(ch)&&(ch!='\n')&&(ch!=EOF)) { + ch= getc(file); + } + if (ch==EOF) + break; + if ((ch!='\n')&&(line->num_line>0)) + spacePending= True; + ungetc(ch,file); + } + else { + if (spacePending) { + ADD_CHAR(line,' '); + spacePending= False; + } + if (checkbang && ch=='!') { + if (line->num_line!=0) { + PR_DEBUG("The '!' legal only at start of line\n"); + PR_DEBUG("Line containing '!' ignored\n"); + line->num_line= 0; + inComment= 0; + break; + } + + } + ADD_CHAR(line,ch); + } + } + if (ch==EOF) + endOfFile= True; +/* else line->num_line++;*/ + } + if ((line->num_line==0)&&(endOfFile)) + return False; + ADD_CHAR(line,'\0'); + return True; +} + +/***====================================================================***/ + +#define MODEL 0 +#define LAYOUT 1 +#define VARIANT 2 +#define OPTION 3 +#define KEYCODES 4 +#define SYMBOLS 5 +#define TYPES 6 +#define COMPAT 7 +#define GEOMETRY 8 +#define KEYMAP 9 +#define MAX_WORDS 10 + +#define PART_MASK 0x000F +#define COMPONENT_MASK 0x03F0 + +static char * cname[MAX_WORDS] = { + "model", "layout", "variant", "option", + "keycodes", "symbols", "types", "compat", "geometry", "keymap" +}; + +typedef struct _RemapSpec { + int number; + int num_remap; + struct { + int word; + int index; + } remap[MAX_WORDS]; +} RemapSpec; + +typedef struct _FileSpec { + char * name[MAX_WORDS]; + struct _FileSpec * pending; +} FileSpec; + +typedef struct { + char * model; + char * layout[XkbNumKbdGroups+1]; + char * variant[XkbNumKbdGroups+1]; + char * options; +} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr; + +#define NDX_BUFF_SIZE 4 + +/***====================================================================***/ + +static char* +get_index(char *str, int *ndx) +{ + char ndx_buf[NDX_BUFF_SIZE]; + char *end; + + if (*str != '[') { + *ndx = 0; + return str; + } + str++; + end = strchr(str, ']'); + if (end == NULL) { + *ndx = -1; + return str - 1; + } + if ( (end - str) >= NDX_BUFF_SIZE) { + *ndx = -1; + return end + 1; + } + strncpy(ndx_buf, str, end - str); + ndx_buf[end - str] = '\0'; + *ndx = atoi(ndx_buf); + return end + 1; +} + +static void +SetUpRemap(InputLine *line,RemapSpec *remap) +{ +char * tok,*str; +unsigned present, l_ndx_present, v_ndx_present; +register int i; +int len, ndx; +_Xstrtokparams strtok_buf; +#ifdef DEBUG +Bool found; +#endif + + + l_ndx_present = v_ndx_present = present= 0; + str= &line->line[1]; + len = remap->number; + bzero((char *)remap,sizeof(RemapSpec)); + remap->number = len; + while ((tok=_XStrtok(str," ",strtok_buf))!=NULL) { +#ifdef DEBUG + found= False; +#endif + str= NULL; + if (strcmp(tok,"=")==0) + continue; + for (i=0;i<MAX_WORDS;i++) { + len = strlen(cname[i]); + if (strncmp(cname[i],tok,len)==0) { + if(strlen(tok) > len) { + char *end = get_index(tok+len, &ndx); + if ((i != LAYOUT && i != VARIANT) || + *end != '\0' || ndx == -1) + break; + if (ndx < 1 || ndx > XkbNumKbdGroups) { + PR_DEBUG2("Illegal %s index: %d\n", cname[i], ndx); + PR_DEBUG1("Index must be in range 1..%d\n", + XkbNumKbdGroups); + break; + } + } else { + ndx = 0; + } +#ifdef DEBUG + found= True; +#endif + if (present&(1<<i)) { + if ((i == LAYOUT && l_ndx_present&(1<<ndx)) || + (i == VARIANT && v_ndx_present&(1<<ndx)) ) { + PR_DEBUG1("Component \"%s\" listed twice\n",tok); + PR_DEBUG("Second definition ignored\n"); + break; + } + } + present |= (1<<i); + if (i == LAYOUT) + l_ndx_present |= 1 << ndx; + if (i == VARIANT) + v_ndx_present |= 1 << ndx; + remap->remap[remap->num_remap].word= i; + remap->remap[remap->num_remap++].index= ndx; + break; + } + } +#ifdef DEBUG + if (!found) { + fprintf(stderr,"Unknown component \"%s\" ignored\n",tok); + } +#endif + } + if ((present&PART_MASK)==0) { +#ifdef DEBUG + unsigned mask= PART_MASK; + fprintf(stderr,"Mapping needs at least one of "); + for (i=0; (i<MAX_WORDS); i++) { + if ((1L<<i)&mask) { + mask&= ~(1L<<i); + if (mask) fprintf(stderr,"\"%s,\" ",cname[i]); + else fprintf(stderr,"or \"%s\"\n",cname[i]); + } + } + fprintf(stderr,"Illegal mapping ignored\n"); +#endif + remap->num_remap= 0; + return; + } + if ((present&COMPONENT_MASK)==0) { + PR_DEBUG("Mapping needs at least one component\n"); + PR_DEBUG("Illegal mapping ignored\n"); + remap->num_remap= 0; + return; + } + if (((present&COMPONENT_MASK)&(1<<KEYMAP))&& + ((present&COMPONENT_MASK)!=(1<<KEYMAP))) { + PR_DEBUG("Keymap cannot appear with other components\n"); + PR_DEBUG("Illegal mapping ignored\n"); + remap->num_remap= 0; + return; + } + remap->number++; + return; +} + +static Bool +MatchOneOf(char *wanted,char *vals_defined) +{ +char *str,*next; +int want_len= strlen(wanted); + + for (str=vals_defined,next=NULL;str!=NULL;str=next) { + int len; + next= strchr(str,','); + if (next) { + len= next-str; + next++; + } + else { + len= strlen(str); + } + if ((len==want_len)&&(strncmp(wanted,str,len)==0)) + return True; + } + return False; +} + +/***====================================================================***/ + +static Bool +CheckLine( InputLine * line, + RemapSpec * remap, + XkbRF_RulePtr rule, + XkbRF_GroupPtr group) +{ +char * str,*tok; +register int nread, i; +FileSpec tmp; +_Xstrtokparams strtok_buf; +Bool append = False; + + if (line->line[0]=='!') { + if (line->line[1] == '$' || + (line->line[1] == ' ' && line->line[2] == '$')) { + char *gname = strchr(line->line, '$'); + char *words = strchr(gname, ' '); + if(!words) + return False; + *words++ = '\0'; + for (; *words; words++) { + if (*words != '=' && *words != ' ') + break; + } + if (*words == '\0') + return False; + group->name = _XkbDupString(gname); + group->words = _XkbDupString(words); + for (i = 1, words = group->words; *words; words++) { + if ( *words == ' ') { + *words++ = '\0'; + i++; + } + } + group->number = i; + return True; + } else { + SetUpRemap(line,remap); + return False; + } + } + + if (remap->num_remap==0) { + PR_DEBUG("Must have a mapping before first line of data\n"); + PR_DEBUG("Illegal line of data ignored\n"); + return False; + } + bzero((char *)&tmp,sizeof(FileSpec)); + str= line->line; + for (nread= 0;(tok=_XStrtok(str," ",strtok_buf))!=NULL;nread++) { + str= NULL; + if (strcmp(tok,"=")==0) { + nread--; + continue; + } + if (nread>remap->num_remap) { + PR_DEBUG("Too many words on a line\n"); + PR_DEBUG1("Extra word \"%s\" ignored\n",tok); + continue; + } + tmp.name[remap->remap[nread].word]= tok; + if (*tok == '+' || *tok == '|') + append = True; + } + if (nread<remap->num_remap) { + PR_DEBUG1("Too few words on a line: %s\n", line->line); + PR_DEBUG("line ignored\n"); + return False; + } + + rule->flags= 0; + rule->number = remap->number; + if (tmp.name[OPTION]) + rule->flags|= XkbRF_Option; + else if (append) + rule->flags|= XkbRF_Append; + else + rule->flags|= XkbRF_Normal; + rule->model= _XkbDupString(tmp.name[MODEL]); + rule->layout= _XkbDupString(tmp.name[LAYOUT]); + rule->variant= _XkbDupString(tmp.name[VARIANT]); + rule->option= _XkbDupString(tmp.name[OPTION]); + + rule->keycodes= _XkbDupString(tmp.name[KEYCODES]); + rule->symbols= _XkbDupString(tmp.name[SYMBOLS]); + rule->types= _XkbDupString(tmp.name[TYPES]); + rule->compat= _XkbDupString(tmp.name[COMPAT]); + rule->geometry= _XkbDupString(tmp.name[GEOMETRY]); + rule->keymap= _XkbDupString(tmp.name[KEYMAP]); + + rule->layout_num = rule->variant_num = 0; + for (i = 0; i < nread; i++) { + if (remap->remap[i].index) { + if (remap->remap[i].word == LAYOUT) + rule->layout_num = remap->remap[i].index; + if (remap->remap[i].word == VARIANT) + rule->variant_num = remap->remap[i].index; + } + } + return True; +} + +static char * +_Concat(char *str1,char *str2) +{ +int len; + + if ((!str1)||(!str2)) + return str1; + len= strlen(str1)+strlen(str2)+1; + str1= _XkbTypedRealloc(str1,len,char); + if (str1) + strcat(str1,str2); + return str1; +} + +static void +squeeze_spaces(char *p1) +{ + char *p2; + for (p2 = p1; *p2; p2++) { + *p1 = *p2; + if (*p1 != ' ') p1++; + } + *p1 = '\0'; +} + +static Bool +MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs) +{ + + bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec)); + mdefs->model = defs->model; + mdefs->options = _XkbDupString(defs->options); + if (mdefs->options) squeeze_spaces(mdefs->options); + + if (defs->layout) { + if (!strchr(defs->layout, ',')) { + mdefs->layout[0] = defs->layout; + } else { + char *p; + int i; + mdefs->layout[1] = _XkbDupString(defs->layout); + if (mdefs->layout[1] == NULL) + return False; + squeeze_spaces(mdefs->layout[1]); + p = mdefs->layout[1]; + for (i = 2; i <= XkbNumKbdGroups; i++) { + if ((p = strchr(p, ','))) { + *p++ = '\0'; + mdefs->layout[i] = p; + } else { + break; + } + } + if (p && (p = strchr(p, ','))) + *p = '\0'; + } + } + + if (defs->variant) { + if (!strchr(defs->variant, ',')) { + mdefs->variant[0] = defs->variant; + } else { + char *p; + int i; + mdefs->variant[1] = _XkbDupString(defs->variant); + if (mdefs->variant[1] == NULL) + return False; + squeeze_spaces(mdefs->variant[1]); + p = mdefs->variant[1]; + for (i = 2; i <= XkbNumKbdGroups; i++) { + if ((p = strchr(p, ','))) { + *p++ = '\0'; + mdefs->variant[i] = p; + } else { + break; + } + } + if (p && (p = strchr(p, ','))) + *p = '\0'; + } + } + return True; +} + +static void +FreeMultiDefs(XkbRF_MultiDefsPtr defs) +{ + if (defs->options) _XkbFree(defs->options); + if (defs->layout[1]) _XkbFree(defs->layout[1]); + if (defs->variant[1]) _XkbFree(defs->variant[1]); +} + +static void +Apply(char *src, char **dst) +{ + if (src) { + if (*src == '+' || *src == '!') { + *dst= _Concat(*dst, src); + } else { + if (*dst == NULL) + *dst= _XkbDupString(src); + } + } +} + +static void +XkbRF_ApplyRule( XkbRF_RulePtr rule, + XkbComponentNamesPtr names) +{ + rule->flags&= ~XkbRF_PendingMatch; /* clear the flag because it's applied */ + + Apply(rule->keycodes, &names->keycodes); + Apply(rule->symbols, &names->symbols); + Apply(rule->types, &names->types); + Apply(rule->compat, &names->compat); + Apply(rule->geometry, &names->geometry); + Apply(rule->keymap, &names->keymap); +} + +static Bool +CheckGroup( XkbRF_RulesPtr rules, + char * group_name, + char * name) +{ + int i; + char *p; + XkbRF_GroupPtr group; + + for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) { + if (! strcmp(group->name, group_name)) { + break; + } + } + if (i == rules->num_groups) + return False; + for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) { + if (! strcmp(p, name)) { + return True; + } + } + return False; +} + +static int +XkbRF_CheckApplyRule( XkbRF_RulePtr rule, + XkbRF_MultiDefsPtr mdefs, + XkbComponentNamesPtr names, + XkbRF_RulesPtr rules) +{ + Bool pending = False; + + if (rule->model != NULL) { + if(mdefs->model == NULL) + return 0; + if (strcmp(rule->model, "*") == 0) { + pending = True; + } else { + if (rule->model[0] == '$') { + if (!CheckGroup(rules, rule->model, mdefs->model)) + return 0; + } else { + if (strcmp(rule->model, mdefs->model) != 0) + return 0; + } + } + } + if (rule->option != NULL) { + if (mdefs->options == NULL) + return 0; + if ((!MatchOneOf(rule->option,mdefs->options))) + return 0; + } + + if (rule->layout != NULL) { + if(mdefs->layout[rule->layout_num] == NULL || + *mdefs->layout[rule->layout_num] == '\0') + return 0; + if (strcmp(rule->layout, "*") == 0) { + pending = True; + } else { + if (rule->layout[0] == '$') { + if (!CheckGroup(rules, rule->layout, + mdefs->layout[rule->layout_num])) + return 0; + } else { + if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0) + return 0; + } + } + } + if (rule->variant != NULL) { + if (mdefs->variant[rule->variant_num] == NULL || + *mdefs->variant[rule->variant_num] == '\0') + return 0; + if (strcmp(rule->variant, "*") == 0) { + pending = True; + } else { + if (rule->variant[0] == '$') { + if (!CheckGroup(rules, rule->variant, + mdefs->variant[rule->variant_num])) + return 0; + } else { + if (strcmp(rule->variant, + mdefs->variant[rule->variant_num]) != 0) + return 0; + } + } + } + if (pending) { + rule->flags|= XkbRF_PendingMatch; + return rule->number; + } + /* exact match, apply it now */ + XkbRF_ApplyRule(rule,names); + return rule->number; +} + +static void +XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules) +{ +register int i; +XkbRF_RulePtr rule; + + for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) { + rule->flags&= ~XkbRF_PendingMatch; + } +} + +static void +XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules,XkbComponentNamesPtr names) +{ +int i; +XkbRF_RulePtr rule; + + for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) { + if ((rule->flags&XkbRF_PendingMatch)==0) + continue; + XkbRF_ApplyRule(rule,names); + } +} + +static void +XkbRF_CheckApplyRules( XkbRF_RulesPtr rules, + XkbRF_MultiDefsPtr mdefs, + XkbComponentNamesPtr names, + int flags) +{ +int i; +XkbRF_RulePtr rule; +int skip; + + for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) { + if ((rule->flags & flags) != flags) + continue; + skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules); + if (skip && !(flags & XkbRF_Option)) { + for ( ;(i < rules->num_rules) && (rule->number == skip); + rule++, i++); + rule--; i--; + } + } +} + +/***====================================================================***/ + +static char * +XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs) +{ +char *str, *outstr, *orig, *var; +int len, ndx; + + orig= name; + str= index(name,'%'); + if (str==NULL) + return name; + len= strlen(name); + while (str!=NULL) { + char pfx= str[1]; + int extra_len= 0; + if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) { + extra_len= 1; + str++; + } + else if (pfx=='(') { + extra_len= 2; + str++; + } + var = str + 1; + str = get_index(var + 1, &ndx); + if (ndx == -1) { + str = index(str,'%'); + continue; + } + if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) + len+= strlen(mdefs->layout[ndx])+extra_len; + else if ((*var=='m')&&mdefs->model) + len+= strlen(mdefs->model)+extra_len; + else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) + len+= strlen(mdefs->variant[ndx])+extra_len; + if ((pfx=='(')&&(*str==')')) { + str++; + } + str= index(&str[0],'%'); + } + name= (char *)_XkbAlloc(len+1); + str= orig; + outstr= name; + while (*str!='\0') { + if (str[0]=='%') { + char pfx,sfx; + str++; + pfx= str[0]; + sfx= '\0'; + if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) { + str++; + } + else if (pfx=='(') { + sfx= ')'; + str++; + } + else pfx= '\0'; + + var = str; + str = get_index(var + 1, &ndx); + if (ndx == -1) { + continue; + } + if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) { + if (pfx) *outstr++= pfx; + strcpy(outstr,mdefs->layout[ndx]); + outstr+= strlen(mdefs->layout[ndx]); + if (sfx) *outstr++= sfx; + } + else if ((*var=='m')&&(mdefs->model)) { + if (pfx) *outstr++= pfx; + strcpy(outstr,mdefs->model); + outstr+= strlen(mdefs->model); + if (sfx) *outstr++= sfx; + } + else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) { + if (pfx) *outstr++= pfx; + strcpy(outstr,mdefs->variant[ndx]); + outstr+= strlen(mdefs->variant[ndx]); + if (sfx) *outstr++= sfx; + } + if ((pfx=='(')&&(*str==')')) + str++; + } + else { + *outstr++= *str++; + } + } + *outstr++= '\0'; + if (orig!=name) + _XkbFree(orig); + return name; +} + +/***====================================================================***/ + +Bool +XkbRF_GetComponents( XkbRF_RulesPtr rules, + XkbRF_VarDefsPtr defs, + XkbComponentNamesPtr names) +{ + XkbRF_MultiDefsRec mdefs; + + MakeMultiDefs(&mdefs, defs); + + bzero((char *)names,sizeof(XkbComponentNamesRec)); + XkbRF_ClearPartialMatches(rules); + XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal); + XkbRF_ApplyPartialMatches(rules, names); + XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append); + XkbRF_ApplyPartialMatches(rules, names); + XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option); + + if (names->keycodes) + names->keycodes= XkbRF_SubstituteVars(names->keycodes, &mdefs); + if (names->symbols) + names->symbols= XkbRF_SubstituteVars(names->symbols, &mdefs); + if (names->types) + names->types= XkbRF_SubstituteVars(names->types, &mdefs); + if (names->compat) + names->compat= XkbRF_SubstituteVars(names->compat, &mdefs); + if (names->geometry) + names->geometry= XkbRF_SubstituteVars(names->geometry, &mdefs); + if (names->keymap) + names->keymap= XkbRF_SubstituteVars(names->keymap, &mdefs); + + FreeMultiDefs(&mdefs); + return (names->keycodes && names->symbols && names->types && + names->compat && names->geometry ) || names->keymap; +} + +XkbRF_RulePtr +XkbRF_AddRule(XkbRF_RulesPtr rules) +{ + if (rules->sz_rules<1) { + rules->sz_rules= 16; + rules->num_rules= 0; + rules->rules= _XkbTypedCalloc(rules->sz_rules,XkbRF_RuleRec); + } + else if (rules->num_rules>=rules->sz_rules) { + rules->sz_rules*= 2; + rules->rules= _XkbTypedRealloc(rules->rules,rules->sz_rules, + XkbRF_RuleRec); + } + if (!rules->rules) { + rules->sz_rules= rules->num_rules= 0; +#ifdef DEBUG + fprintf(stderr,"Allocation failure in XkbRF_AddRule\n"); +#endif + return NULL; + } + bzero((char *)&rules->rules[rules->num_rules],sizeof(XkbRF_RuleRec)); + return &rules->rules[rules->num_rules++]; +} + +XkbRF_GroupPtr +XkbRF_AddGroup(XkbRF_RulesPtr rules) +{ + if (rules->sz_groups<1) { + rules->sz_groups= 16; + rules->num_groups= 0; + rules->groups= _XkbTypedCalloc(rules->sz_groups,XkbRF_GroupRec); + } + else if (rules->num_groups >= rules->sz_groups) { + rules->sz_groups *= 2; + rules->groups= _XkbTypedRealloc(rules->groups,rules->sz_groups, + XkbRF_GroupRec); + } + if (!rules->groups) { + rules->sz_groups= rules->num_groups= 0; + return NULL; + } + + bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec)); + return &rules->groups[rules->num_groups++]; +} + +Bool +XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules) +{ +InputLine line; +RemapSpec remap; +XkbRF_RuleRec trule,*rule; +XkbRF_GroupRec tgroup,*group; + + if (!(rules && file)) + return False; + bzero((char *)&remap,sizeof(RemapSpec)); + bzero((char *)&tgroup,sizeof(XkbRF_GroupRec)); + InitInputLine(&line); + while (GetInputLine(file,&line,True)) { + if (CheckLine(&line,&remap,&trule,&tgroup)) { + if (tgroup.number) { + if ((group= XkbRF_AddGroup(rules))!=NULL) { + *group= tgroup; + bzero((char *)&tgroup,sizeof(XkbRF_GroupRec)); + } + } else { + if ((rule= XkbRF_AddRule(rules))!=NULL) { + *rule= trule; + bzero((char *)&trule,sizeof(XkbRF_RuleRec)); + } + } + } + line.num_line= 0; + } + FreeInputLine(&line); + return True; +} + +Bool +XkbRF_LoadRulesByName(char *base,char *locale,XkbRF_RulesPtr rules) +{ +FILE * file; +char buf[PATH_MAX]; +Bool ok; + + if ((!base)||(!rules)) + return False; + if (locale) { + if (strlen(base)+strlen(locale)+2 > PATH_MAX) + return False; + sprintf(buf,"%s-%s", base, locale); + } + else { + if (strlen(base)+1 > PATH_MAX) + return False; + strcpy(buf,base); + } + + file= fopen(buf, "r"); + if ((!file)&&(locale)) { /* fallback if locale was specified */ + strcpy(buf,base); + file= fopen(buf, "r"); + } + if (!file) + return False; + ok= XkbRF_LoadRules(file,rules); + fclose(file); + return ok; +} + +/***====================================================================***/ + +#define HEAD_NONE 0 +#define HEAD_MODEL 1 +#define HEAD_LAYOUT 2 +#define HEAD_VARIANT 3 +#define HEAD_OPTION 4 +#define HEAD_EXTRA 5 + +XkbRF_VarDescPtr +XkbRF_AddVarDesc(XkbRF_DescribeVarsPtr vars) +{ + if (vars->sz_desc<1) { + vars->sz_desc= 16; + vars->num_desc= 0; + vars->desc= _XkbTypedCalloc(vars->sz_desc,XkbRF_VarDescRec); + } + else if (vars->num_desc>=vars->sz_desc) { + vars->sz_desc*= 2; + vars->desc= _XkbTypedRealloc(vars->desc,vars->sz_desc,XkbRF_VarDescRec); + } + if (!vars->desc) { + vars->sz_desc= vars->num_desc= 0; + PR_DEBUG("Allocation failure in XkbRF_AddVarDesc\n"); + return NULL; + } + vars->desc[vars->num_desc].name= NULL; + vars->desc[vars->num_desc].desc= NULL; + return &vars->desc[vars->num_desc++]; +} + +XkbRF_VarDescPtr +XkbRF_AddVarDescCopy(XkbRF_DescribeVarsPtr vars,XkbRF_VarDescPtr from) +{ +XkbRF_VarDescPtr nd; + + if ((nd=XkbRF_AddVarDesc(vars))!=NULL) { + nd->name= _XkbDupString(from->name); + nd->desc= _XkbDupString(from->desc); + } + return nd; +} + +XkbRF_DescribeVarsPtr +XkbRF_AddVarToDescribe(XkbRF_RulesPtr rules,char *name) +{ + if (rules->sz_extra<1) { + rules->num_extra= 0; + rules->sz_extra= 1; + rules->extra_names= _XkbTypedCalloc(rules->sz_extra,char *); + rules->extra= _XkbTypedCalloc(rules->sz_extra, XkbRF_DescribeVarsRec); + } + else if (rules->num_extra>=rules->sz_extra) { + rules->sz_extra*= 2; + rules->extra_names= _XkbTypedRealloc(rules->extra_names,rules->sz_extra, + char *); + rules->extra=_XkbTypedRealloc(rules->extra, rules->sz_extra, + XkbRF_DescribeVarsRec); + } + if ((!rules->extra_names)||(!rules->extra)) { + PR_DEBUG("allocation error in extra parts\n"); + rules->sz_extra= rules->num_extra= 0; + rules->extra_names= NULL; + rules->extra= NULL; + return NULL; + } + rules->extra_names[rules->num_extra]= _XkbDupString(name); + bzero(&rules->extra[rules->num_extra],sizeof(XkbRF_DescribeVarsRec)); + return &rules->extra[rules->num_extra++]; +} + +Bool +XkbRF_LoadDescriptions(FILE *file,XkbRF_RulesPtr rules) +{ +InputLine line; +XkbRF_VarDescRec tmp; +char *tok; +int len,headingtype,extra_ndx = 0; + + bzero((char *)&tmp, sizeof(XkbRF_VarDescRec)); + headingtype = HEAD_NONE; + InitInputLine(&line); + for ( ; GetInputLine(file,&line,False); line.num_line= 0) { + if (line.line[0]=='!') { + tok = strtok(&(line.line[1]), " \t"); + if (strcmp(tok,"model") == 0) + headingtype = HEAD_MODEL; + else if (_XkbStrCaseCmp(tok,"layout") == 0) + headingtype = HEAD_LAYOUT; + else if (_XkbStrCaseCmp(tok,"variant") == 0) + headingtype = HEAD_VARIANT; + else if (_XkbStrCaseCmp(tok,"option") == 0) + headingtype = HEAD_OPTION; + else { + int i; + headingtype = HEAD_EXTRA; + extra_ndx= -1; + for (i=0;(i<rules->num_extra)&&(extra_ndx<0);i++) { + if (_XkbStrCaseCmp(tok,rules->extra_names[i])) + extra_ndx= i; + } + if (extra_ndx<0) { + XkbRF_DescribeVarsPtr var; + PR_DEBUG1("Extra heading \"%s\" encountered\n",tok); + var= XkbRF_AddVarToDescribe(rules,tok); + if (var) + extra_ndx= var-rules->extra; + else headingtype= HEAD_NONE; + } + } + continue; + } + + if (headingtype == HEAD_NONE) { + PR_DEBUG("Must have a heading before first line of data\n"); + PR_DEBUG("Illegal line of data ignored\n"); + continue; + } + + len = strlen(line.line); + if ((tmp.name= strtok(line.line, " \t")) == NULL) { + PR_DEBUG("Huh? No token on line\n"); + PR_DEBUG("Illegal line of data ignored\n"); + continue; + } + if (strlen(tmp.name) == len) { + PR_DEBUG("No description found\n"); + PR_DEBUG("Illegal line of data ignored\n"); + continue; + } + + tok = line.line + strlen(tmp.name) + 1; + while ((*tok!='\n')&&isspace(*tok)) + tok++; + if (*tok == '\0') { + PR_DEBUG("No description found\n"); + PR_DEBUG("Illegal line of data ignored\n"); + continue; + } + tmp.desc= tok; + switch (headingtype) { + case HEAD_MODEL: + XkbRF_AddVarDescCopy(&rules->models,&tmp); + break; + case HEAD_LAYOUT: + XkbRF_AddVarDescCopy(&rules->layouts,&tmp); + break; + case HEAD_VARIANT: + XkbRF_AddVarDescCopy(&rules->variants,&tmp); + break; + case HEAD_OPTION: + XkbRF_AddVarDescCopy(&rules->options,&tmp); + break; + case HEAD_EXTRA: + XkbRF_AddVarDescCopy(&rules->extra[extra_ndx],&tmp); + break; + } + } + FreeInputLine(&line); + if ((rules->models.num_desc==0) && (rules->layouts.num_desc==0) && + (rules->variants.num_desc==0) && (rules->options.num_desc==0) && + (rules->num_extra==0)) { + return False; + } + return True; +} + +Bool +XkbRF_LoadDescriptionsByName(char *base,char *locale,XkbRF_RulesPtr rules) +{ +FILE * file; +char buf[PATH_MAX]; +Bool ok; + + if ((!base)||(!rules)) + return False; + if (locale) { + if (strlen(base)+strlen(locale)+6 > PATH_MAX) + return False; + sprintf(buf,"%s-%s.lst", base, locale); + } + else { + if (strlen(base)+5 > PATH_MAX) + return False; + sprintf(buf,"%s.lst", base); + } + + file= fopen(buf, "r"); + if ((!file)&&(locale)) { /* fallback if locale was specified */ + sprintf(buf,"%s.lst", base); + + file= fopen(buf, "r"); + } + if (!file) + return False; + ok= XkbRF_LoadDescriptions(file,rules); + fclose(file); + return ok; +} + +/***====================================================================***/ + +XkbRF_RulesPtr +XkbRF_Load(char *base,char *locale,Bool wantDesc,Bool wantRules) +{ +XkbRF_RulesPtr rules; + + if ((!base)||((!wantDesc)&&(!wantRules))) + return NULL; + if ((rules=_XkbTypedCalloc(1,XkbRF_RulesRec))==NULL) + return NULL; + if (wantDesc&&(!XkbRF_LoadDescriptionsByName(base,locale,rules))) { + XkbRF_Free(rules,True); + return NULL; + } + if (wantRules&&(!XkbRF_LoadRulesByName(base,locale,rules))) { + XkbRF_Free(rules,True); + return NULL; + } + return rules; +} + +XkbRF_RulesPtr +XkbRF_Create(int szRules,int szExtra) +{ +XkbRF_RulesPtr rules; + + if ((rules=_XkbTypedCalloc(1,XkbRF_RulesRec))==NULL) + return NULL; + if (szRules>0) { + rules->sz_rules= szRules; + rules->rules= _XkbTypedCalloc(rules->sz_rules,XkbRF_RuleRec); + if (!rules->rules) { + _XkbFree(rules); + return NULL; + } + } + if (szExtra>0) { + rules->sz_extra= szExtra; + rules->extra= _XkbTypedCalloc(rules->sz_extra,XkbRF_DescribeVarsRec); + if (!rules->extra) { + if (rules->rules) + _XkbFree(rules->rules); + _XkbFree(rules); + return NULL; + } + } + return rules; +} + +/***====================================================================***/ + +static void +XkbRF_ClearVarDescriptions(XkbRF_DescribeVarsPtr var) +{ +register int i; + + for (i=0;i<var->num_desc;i++) { + if (var->desc[i].name) + _XkbFree(var->desc[i].name); + if (var->desc[i].desc) + _XkbFree(var->desc[i].desc); + var->desc[i].name= var->desc[i].desc= NULL; + } + if (var->desc) + _XkbFree(var->desc); + var->desc= NULL; + return; +} + +void +XkbRF_Free(XkbRF_RulesPtr rules,Bool freeRules) +{ +int i; +XkbRF_RulePtr rule; +XkbRF_GroupPtr group; + + if (!rules) + return; + XkbRF_ClearVarDescriptions(&rules->models); + XkbRF_ClearVarDescriptions(&rules->layouts); + XkbRF_ClearVarDescriptions(&rules->variants); + XkbRF_ClearVarDescriptions(&rules->options); + if (rules->extra) { + for (i = 0; i < rules->num_extra; i++) { + XkbRF_ClearVarDescriptions(&rules->extra[i]); + } + _XkbFree(rules->extra); + rules->num_extra= rules->sz_extra= 0; + rules->extra= NULL; + } + if (rules->rules) { + for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) { + if (rule->model) _XkbFree(rule->model); + if (rule->layout) _XkbFree(rule->layout); + if (rule->variant) _XkbFree(rule->variant); + if (rule->option) _XkbFree(rule->option); + if (rule->keycodes) _XkbFree(rule->keycodes); + if (rule->symbols) _XkbFree(rule->symbols); + if (rule->types) _XkbFree(rule->types); + if (rule->compat) _XkbFree(rule->compat); + if (rule->geometry) _XkbFree(rule->geometry); + if (rule->keymap) _XkbFree(rule->keymap); + bzero((char *)rule,sizeof(XkbRF_RuleRec)); + } + _XkbFree(rules->rules); + rules->num_rules= rules->sz_rules= 0; + rules->rules= NULL; + } + + if (rules->groups) { + for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) { + if (group->name) _XkbFree(group->name); + if (group->words) _XkbFree(group->words); + } + _XkbFree(rules->groups); + rules->num_groups= 0; + rules->groups= NULL; + } + if (freeRules) + _XkbFree(rules); + return; +} + +#ifndef XKB_IN_SERVER + +Bool +XkbRF_GetNamesProp(Display *dpy,char **rf_rtrn,XkbRF_VarDefsPtr vd_rtrn) +{ +Atom rules_atom,actual_type; +int fmt; +unsigned long nitems,bytes_after; +unsigned char *data; +char *out, *end; +Status rtrn; + + rules_atom= XInternAtom(dpy,_XKB_RF_NAMES_PROP_ATOM,True); + if (rules_atom==None) /* property cannot exist */ + return False; + rtrn= XGetWindowProperty(dpy,DefaultRootWindow(dpy),rules_atom, + 0L,_XKB_RF_NAMES_PROP_MAXLEN,False, + XA_STRING,&actual_type, + &fmt,&nitems,&bytes_after, + (unsigned char **)&data); + if (rtrn!=Success) + return False; + if (rf_rtrn) + *rf_rtrn= NULL; + (void)bzero((char *)vd_rtrn,sizeof(XkbRF_VarDefsRec)); + if ((bytes_after>0)||(actual_type!=XA_STRING)||(fmt!=8)) { + if (data) XFree(data); + return (fmt==0?True:False); + } + + out=(char*)data; + end=out+nitems; + if (out && (*out) && rf_rtrn) + *rf_rtrn= _XkbDupString(out); + out+=strlen(out)+1; + + if (out<end) { + if (*out) + vd_rtrn->model= _XkbDupString(out); + out+=strlen(out)+1; + } + + if (out<end) { + if (*out) + vd_rtrn->layout= _XkbDupString(out); + out+=strlen(out)+1; + } + + if (out<end) { + if (*out) + vd_rtrn->variant= _XkbDupString(out); + out+=strlen(out)+1; + } + + if (out<end) { + if (*out) + vd_rtrn->options= _XkbDupString(out); + out+=strlen(out)+1; + } + + XFree(data); + return True; +} + +Bool +XkbRF_SetNamesProp(Display *dpy,char *rules_file,XkbRF_VarDefsPtr var_defs) +{ +int len,out; +Atom name; +char * pval; + + len= (rules_file?strlen(rules_file):0); + len+= (var_defs->model?strlen(var_defs->model):0); + len+= (var_defs->layout?strlen(var_defs->layout):0); + len+= (var_defs->variant?strlen(var_defs->variant):0); + len+= (var_defs->options?strlen(var_defs->options):0); + if (len<1) + return True; + + len+= 5; /* trailing NULs */ + + name= XInternAtom(dpy,_XKB_RF_NAMES_PROP_ATOM,False); + if (name==None) { /* should never happen */ + _XkbLibError(_XkbErrXReqFailure,"XkbRF_SetNamesProp",X_InternAtom); + return False; + } + pval= (char *)_XkbAlloc(len); + if (!pval) { + _XkbLibError(_XkbErrBadAlloc,"XkbRF_SetNamesProp",len); + return False; + } + out= 0; + if (rules_file) { + strcpy(&pval[out],rules_file); + out+= strlen(rules_file); + } + pval[out++]= '\0'; + if (var_defs->model) { + strcpy(&pval[out],var_defs->model); + out+= strlen(var_defs->model); + } + pval[out++]= '\0'; + if (var_defs->layout) { + strcpy(&pval[out],var_defs->layout); + out+= strlen(var_defs->layout); + } + pval[out++]= '\0'; + if (var_defs->variant) { + strcpy(&pval[out],var_defs->variant); + out+= strlen(var_defs->variant); + } + pval[out++]= '\0'; + if (var_defs->options) { + strcpy(&pval[out],var_defs->options); + out+= strlen(var_defs->options); + } + pval[out++]= '\0'; + if (out!=len) { + _XkbLibError(_XkbErrBadLength,"XkbRF_SetNamesProp",out); + _XkbFree(pval); + return False; + } + + XChangeProperty(dpy,DefaultRootWindow(dpy),name,XA_STRING,8,PropModeReplace, + (unsigned char *)pval,len); + _XkbFree(pval); + return True; +} + +#endif diff --git a/libxkbfile/src/srvmisc.c b/libxkbfile/src/srvmisc.c new file mode 100644 index 000000000..3e4c73c98 --- /dev/null +++ b/libxkbfile/src/srvmisc.c @@ -0,0 +1,216 @@ +/* $Xorg: srvmisc.c,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/srvmisc.c,v 3.4 2001/10/28 03:32:47 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +Bool +XkbWriteToServer(XkbFileInfo *result) +{ +XkbDescPtr xkb; +Display * dpy; + + if ((result==NULL)||(result->xkb==NULL)||(result->xkb->dpy==NULL)) + return False; + xkb= result->xkb; + dpy= xkb->dpy; + if (!XkbSetMap(dpy,XkbAllMapComponentsMask,xkb)) + return False; + if (!XkbSetIndicatorMap(dpy,~0,xkb)) + return False; +#ifdef NOTYET + if (!XkbSetControls(dpy,XkbAllControlsMask,xkb)) + return False; +#endif + if (!XkbSetCompatMap(dpy,XkbAllCompatMask,xkb,True)) + return False; + if (!XkbSetNames(dpy,XkbAllNamesMask,0,xkb->map->num_types,xkb)) + return False; + if (xkb->geom) { + if (XkbSetGeometry(dpy,xkb->device_spec,xkb->geom)!=Success) + return False; + } + return True; +#ifdef NOTYET + switch (result->type) { + case XkmSemanticsFile: + func= WriteCHdrSemantics; + break; + case XkmLayoutFile: + func= WriteCHdrLayout; + break; + case XkmKeymapFile: + func= WriteCHdrKeymap; + break; + default: + _XkbLibError(_XkbErrIllegalContents,"XkbWriteToServer",result->type); + break; + } + return ok; +#endif +} + +unsigned +XkbReadFromServer(Display *dpy,unsigned need,unsigned want,XkbFileInfo *result) +{ +unsigned which= need|want; +unsigned tmp = 0; + + if ((result==NULL)||(dpy==NULL)) + return which; + + if (which&XkmSymbolsMask) tmp= XkbAllMapComponentsMask; + else if (which&XkmTypesMask) tmp= XkbKeyTypesMask; + if (result->xkb==NULL) { + result->xkb= XkbGetMap(dpy,tmp,XkbUseCoreKbd); + if (!result->xkb) + return which; + else which&= ~(XkmSymbolsMask|XkmTypesMask|XkmVirtualModsMask); + } + else if ((tmp)&&(XkbGetUpdatedMap(dpy,tmp,result->xkb)==Success)) + which&= ~(XkmSymbolsMask|XkmTypesMask|XkmVirtualModsMask); + + if (which&XkmIndicatorsMask) { + if (XkbGetIndicatorMap(dpy,XkbAllIndicatorsMask,result->xkb)==Success) + which&= ~XkmIndicatorsMask; + } + + if (which&XkmCompatMapMask) { + if (XkbGetCompatMap(dpy,XkbAllCompatMask,result->xkb)==Success) + which&= ~XkmCompatMapMask; + } + if (which&XkmGeometryMask) { + if (XkbGetGeometry(dpy,result->xkb)==Success) + which&= ~XkmGeometryMask; + } + XkbGetNames(dpy,XkbAllNamesMask,result->xkb); + return which; +} + +Status +XkbChangeKbdDisplay(Display *newDpy,XkbFileInfo *result) +{ +register int i; +XkbDescPtr xkb; +Display * oldDpy; +Atom * atm; + + if ((result->xkb==NULL)||(result->xkb->dpy==newDpy)) + return Success; + xkb= result->xkb; + oldDpy= xkb->dpy; + if (xkb->names) { + XkbNamesPtr names= xkb->names; + names->keycodes= XkbChangeAtomDisplay(oldDpy,newDpy,names->keycodes); + names->geometry= XkbChangeAtomDisplay(oldDpy,newDpy,names->geometry); + names->symbols= XkbChangeAtomDisplay(oldDpy,newDpy,names->symbols); + names->types= XkbChangeAtomDisplay(oldDpy,newDpy,names->types); + names->compat= XkbChangeAtomDisplay(oldDpy,newDpy,names->compat); + names->phys_symbols= XkbChangeAtomDisplay(oldDpy,newDpy, + names->phys_symbols); + for (i=0,atm=names->vmods;i<XkbNumVirtualMods;i++,atm++) { + *atm= XkbChangeAtomDisplay(oldDpy,newDpy,*atm); + } + for (i=0,atm=names->indicators;i<XkbNumIndicators;i++,atm++) { + *atm= XkbChangeAtomDisplay(oldDpy,newDpy,*atm); + } + for (i=0,atm=names->groups;i<XkbNumKbdGroups;i++,atm++) { + *atm= XkbChangeAtomDisplay(oldDpy,newDpy,*atm); + } + for (i=0,atm=names->radio_groups;i<names->num_rg;i++,atm++) { + *atm= XkbChangeAtomDisplay(oldDpy,newDpy,*atm); + } + } + if (xkb->map) { + register int t; + XkbKeyTypePtr type; + for (t=0,type=xkb->map->types;t<xkb->map->num_types;t++,type++) { + type->name= XkbChangeAtomDisplay(oldDpy,newDpy,type->name); + if (type->level_names!=NULL) { + for (i=0,atm=type->level_names;i<type->num_levels;i++,atm++) { + *atm= XkbChangeAtomDisplay(oldDpy,newDpy,*atm); + } + } + } + } + if (xkb->geom) { + XkbGeometryPtr geom= xkb->geom; + geom->name= XkbChangeAtomDisplay(oldDpy,newDpy,geom->name); + if (geom->shapes) { + register int s; + XkbShapePtr shape; + for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) { + shape->name= XkbChangeAtomDisplay(oldDpy,newDpy,shape->name); + } + } + if (geom->sections) { + register int s; + XkbSectionPtr section; + for (s=0,section=geom->sections;s<geom->num_sections;s++,section++){ + section->name=XkbChangeAtomDisplay(oldDpy,newDpy,section->name); + if (section->doodads) { + register int d; + XkbDoodadPtr doodad; + for (d=0,doodad=section->doodads;d<section->num_doodads; + d++,doodad++) { + doodad->any.name= XkbChangeAtomDisplay(oldDpy,newDpy, + doodad->any.name); + } + } + if (section->overlays) { + register int o; + register XkbOverlayPtr ol; + for (o=0,ol=section->overlays;o<section->num_overlays; + o++,ol++) { + ol->name= XkbChangeAtomDisplay(oldDpy,newDpy,ol->name); + } + } + } + } + if (geom->doodads) { + register int d; + XkbDoodadPtr doodad; + for (d=0,doodad=geom->doodads;d<geom->num_doodads;d++,doodad++) { + doodad->any.name= XkbChangeAtomDisplay(oldDpy,newDpy, + doodad->any.name); + } + } + } + xkb->dpy= newDpy; + return Success; +} diff --git a/libxkbfile/src/xkbatom.c b/libxkbfile/src/xkbatom.c new file mode 100644 index 000000000..24bdcd764 --- /dev/null +++ b/libxkbfile/src/xkbatom.c @@ -0,0 +1,245 @@ +/* $Xorg: xkbatom.c,v 1.4 2001/02/09 02:04:05 xorgcvs Exp $ */ +/*********************************************************** + +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. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + 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 of 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 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbatom.c,v 3.8 2001/12/14 19:57:03 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xos.h> +#include <X11/Xlib.h> +#include <X11/XKBlib.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +/***====================================================================***/ + +#define InitialTableSize 100 + +typedef struct _Node { + struct _Node *left, *right; + Atom a; + unsigned int fingerPrint; + char *string; +} NodeRec, *NodePtr; + +#define BAD_RESOURCE 0xe0000000 + +static Atom lastAtom = None; +static NodePtr atomRoot = (NodePtr)NULL; +static unsigned long tableLength; +static NodePtr *nodeTable; + +static Atom +_XkbMakeAtom(char *string,unsigned len,Bool makeit) +{ + register NodePtr * np; + unsigned i; + int comp; + register unsigned int fp = 0; + + np = &atomRoot; + for (i = 0; i < (len+1)/2; i++) + { + fp = fp * 27 + string[i]; + fp = fp * 27 + string[len - 1 - i]; + } + while (*np != (NodePtr) NULL) + { + if (fp < (*np)->fingerPrint) + np = &((*np)->left); + else if (fp > (*np)->fingerPrint) + np = &((*np)->right); + else + { /* now start testing the strings */ + comp = strncmp(string, (*np)->string, (int)len); + if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string)))) + np = &((*np)->left); + else if (comp > 0) + np = &((*np)->right); + else + return(*np)->a; + } + } + if (makeit) + { + register NodePtr nd; + + nd = (NodePtr) _XkbAlloc(sizeof(NodeRec)); + if (!nd) + return BAD_RESOURCE; + nd->string = (char *) _XkbAlloc(len + 1); + if (!nd->string) { + _XkbFree(nd); + return BAD_RESOURCE; + } + strncpy(nd->string, string, (int)len); + nd->string[len] = 0; + if ((lastAtom + 1) >= tableLength) { + NodePtr *table; + + table = (NodePtr *) _XkbRealloc(nodeTable, + tableLength * (2 * sizeof(NodePtr))); + if (!table) { + if (nd->string != string) + _XkbFree(nd->string); + _XkbFree(nd); + return BAD_RESOURCE; + } + tableLength <<= 1; + nodeTable = table; + } + *np = nd; + nd->left = nd->right = (NodePtr) NULL; + nd->fingerPrint = fp; + nd->a = (++lastAtom); + *(nodeTable+lastAtom) = nd; + return nd->a; + } + else + return None; +} + +static char * +_XkbNameForAtom(Atom atom) +{ + NodePtr node; + if (atom > lastAtom) return 0; + if ((node = nodeTable[atom]) == (NodePtr)NULL) return 0; + return strdup(node->string); +} + +static void +_XkbInitAtoms(void) +{ + tableLength = InitialTableSize; + nodeTable = (NodePtr *)_XkbAlloc(InitialTableSize*sizeof(NodePtr)); + nodeTable[None] = (NodePtr)NULL; +} + +/***====================================================================***/ + +char * +XkbAtomGetString(Display *dpy,Atom atm) +{ + if (atm==None) + return NULL; + if (dpy==NULL) + return _XkbNameForAtom(atm); + return XGetAtomName(dpy,atm); +} + +/***====================================================================***/ + +Atom +XkbInternAtom(Display *dpy,char *name,Bool onlyIfExists) +{ + if (name==NULL) + return None; + if (dpy==NULL) { + return _XkbMakeAtom(name, strlen(name), (!onlyIfExists)); + } + return XInternAtom(dpy,name,onlyIfExists); +} + +/***====================================================================***/ + +Atom +XkbChangeAtomDisplay(Display *oldDpy,Display *newDpy,Atom atm) +{ +char *tmp; + + if (atm!=None) { + tmp= XkbAtomGetString(oldDpy,atm); + if (tmp!=NULL) + return XkbInternAtom(newDpy,tmp,False); + } + return None; +} + +/***====================================================================***/ + +void +XkbInitAtoms(Display *dpy) +{ +static int been_here= 0; + if ((dpy==NULL)&&(!been_here)) { + _XkbInitAtoms(); + been_here= 1; + } + return; +} diff --git a/libxkbfile/src/xkbbells.c b/libxkbfile/src/xkbbells.c new file mode 100644 index 000000000..30b918fb4 --- /dev/null +++ b/libxkbfile/src/xkbbells.c @@ -0,0 +1,104 @@ +/* $Xorg: xkbbells.c,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include "XKBbells.h" + +static char *_xkbStdBellNames[XkbBI_NumBells] = { + "Info", + "Warning", + "MinorError", + "MajorError", + "BadValue", + "InvalidLocation", + "Question", + "Start", + "End", + "Success", + "Failure", + "Wait", + "Proceed", + "Ignore", + "Iconify", + "Deconify", + "Open", + "Close", + "TerminalBell", + "MarginBell", + "CursorStuck", + "NewMail", + "LaunchApp", + "AppDeath", + "ImAlive", + "ClockChimeHour", + "ClockChimeHalf", + "ClockChimeQuarter", + "RepeatingLastBell", + "ComposeFail", + "AX_FeatureOn", + "AX_FeatureOff", + "AX_FeatureChange", + "AX_IndicatorOn", + "AX_IndicatorOff", + "AX_IndicatorChange", + "AX_SlowKeysWarning", + "AX_SlowKeyPress", + "AX_SlowKeyAccept", + "AX_SlowKeyReject", + "AX_SlowKeyRelease", + "AX_BounceKeyReject", + "AX_StickyLatch", + "AX_StickyLock", + "AX_StickyUnlock" +}; + +static Atom _xkbStdBellAtoms[XkbBI_NumBells]; + +Bool +XkbStdBell(Display *dpy,Window win,int percent,int bellDef) +{ + if ((bellDef<0)||(bellDef>=XkbBI_NumBells)) + bellDef= XkbBI_Info; + if (_xkbStdBellAtoms[bellDef]==None) + _xkbStdBellAtoms[bellDef]= XInternAtom(dpy,_xkbStdBellNames[bellDef],0); + return XkbBell(dpy,win,percent,_xkbStdBellAtoms[bellDef]); +} + +Bool +XkbStdBellEvent(Display *dpy,Window win,int percent,int bellDef) +{ + if ((bellDef<0)||(bellDef>=XkbBI_NumBells)) + bellDef= XkbBI_Info; + if (_xkbStdBellAtoms[bellDef]==None) + _xkbStdBellAtoms[bellDef]= XInternAtom(dpy,_xkbStdBellNames[bellDef],0); + return XkbBellEvent(dpy,win,percent,_xkbStdBellAtoms[bellDef]); +} diff --git a/libxkbfile/src/xkbconfig.c b/libxkbfile/src/xkbconfig.c new file mode 100644 index 000000000..7930979eb --- /dev/null +++ b/libxkbfile/src/xkbconfig.c @@ -0,0 +1,1355 @@ +/* $Xorg: xkbconfig.c,v 1.4 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbconfig.c,v 3.7 2001/11/30 12:11:51 eich Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include <X11/Xfuncs.h> + +#include <X11/Xfuncs.h> + +#ifndef XKB_IN_SERVER + +#include <X11/Xos.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> +#include "XKBfileInt.h" + +#else + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/keysym.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "dix.h" +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> +#endif + +#include <X11/extensions/XKBconfig.h> + +/***====================================================================***/ + +#define XKBCF_MAX_STR_LEN 100 +static char _XkbCF_rtrn[XKBCF_MAX_STR_LEN+1]; + +static int +ScanIdent(FILE *file,int ch,XkbCFScanResultPtr val_rtrn) +{ +register int i; +char * str; + + val_rtrn->str= str= _XkbCF_rtrn; + for (i=0;(isalpha(ch)||isdigit(ch)||(ch=='_'));ch=getc(file)) { + if (i<XKBCF_MAX_STR_LEN) + str[i++]= ch; + } + if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t')) + ungetc(ch,file); + str[i]= '\0'; + return XkbCF_Ident; +} + +static int +ScanString(FILE *file,int quote,XkbCFScanResultPtr val_rtrn) +{ +int ch,nInBuf; + + nInBuf = 0; + while ( ((ch=getc(file))!=EOF) && (ch!='\n') && (ch!=quote) ) { + if ( ch == '\\' ) { + if ((ch = getc(file))!=EOF) { + if ( ch=='n' ) ch = '\n'; + else if ( ch == 't' ) ch = '\t'; + else if ( ch == 'v' ) ch = '\v'; + else if ( ch == 'b' ) ch = '\b'; + else if ( ch == 'r' ) ch = '\r'; + else if ( ch == 'f' ) ch = '\f'; + else if ( ch == 'e' ) ch = '\033'; + else if ( ch == '0' ) { + int tmp,stop; + ch = stop = 0; + if (((tmp=getc(file))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,file); + } + if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,file); + } + if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,file); + } + } + } + else return XkbCF_EOF; + } + + if ( nInBuf < XKBCF_MAX_STR_LEN-1 ) + _XkbCF_rtrn[nInBuf++] = ch; + } + if ( ch == quote ) { + _XkbCF_rtrn[nInBuf++] = '\0'; + val_rtrn->str= _XkbCF_rtrn; + return XkbCF_String; + } + return XkbCF_UnterminatedString; +} + +static int +ScanInteger(FILE *file,int ch,XkbCFScanResultPtr val_rtrn) +{ +int i; + + if (isdigit(ch)) + ungetc(ch,file); + if (fscanf(file,"%i",&i)==1) { + val_rtrn->ival= i; + return XkbCF_Integer; + } + return XkbCF_Unknown; +} + +int +XkbCFScan(FILE *file,XkbCFScanResultPtr val_rtrn,XkbConfigRtrnPtr rtrn) +{ +int ch; + + do { + ch= getc(file); + } while ((ch=='\t')||(ch==' ')); + if (isalpha(ch)) + return ScanIdent(file,ch,val_rtrn); + else if (isdigit(ch)) + return ScanInteger(file,ch,val_rtrn); + else if (ch=='"') + return ScanString(file,ch,val_rtrn); + else if (ch=='\n') { + rtrn->line++; + return XkbCF_EOL; + } + else if (ch==';') + return XkbCF_Semi; + else if (ch=='=') + return XkbCF_Equals; + else if (ch=='+') { + ch= getc(file); + if (ch=='=') + return XkbCF_PlusEquals; + if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t')) + ungetc(ch,file); + return XkbCF_Plus; + } + else if (ch=='-') { + ch= getc(file); + if (ch=='=') + return XkbCF_MinusEquals; + if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t')) + ungetc(ch,file); + return XkbCF_Minus; + } + else if (ch==EOF) + return XkbCF_EOF; + else if ((ch=='#')||((ch=='/')&&(getc(file)=='/'))) { + while ((ch!='\n')&&(ch!=EOF)) + ch= getc(file); + rtrn->line++; + return XkbCF_EOL; + } + return XkbCF_Unknown; +} + +/***====================================================================***/ + +#define _XkbCF_Illegal 0 +#define _XkbCF_Keymap 1 +#define _XkbCF_Keycodes 2 +#define _XkbCF_Geometry 3 +#define _XkbCF_PhysSymbols 4 +#define _XkbCF_Symbols 5 +#define _XkbCF_Types 6 +#define _XkbCF_CompatMap 7 + +#define _XkbCF_RulesFile 8 +#define _XkbCF_Model 9 +#define _XkbCF_Layout 10 +#define _XkbCF_Variant 11 +#define _XkbCF_Options 12 + +#define _XkbCF_InitialMods 13 +#define _XkbCF_InitialCtrls 14 + +#define _XkbCF_ClickVolume 15 +#define _XkbCF_BellVolume 16 +#define _XkbCF_BellPitch 17 +#define _XkbCF_BellDuration 18 +#define _XkbCF_RepeatDelay 19 +#define _XkbCF_RepeatInterval 20 +#define _XkbCF_SlowKeysDelay 21 +#define _XkbCF_DebounceDelay 22 +#define _XkbCF_MouseKeysDelay 23 +#define _XkbCF_MouseKeysInterval 24 +#define _XkbCF_MouseKeysTimeToMax 25 +#define _XkbCF_MouseKeysMaxSpeed 26 +#define _XkbCF_MouseKeysCurve 27 +#define _XkbCF_AccessXTimeout 28 +#define _XkbCF_AccessXTimeoutCtrlsOn 29 +#define _XkbCF_AccessXTimeoutCtrlsOff 30 +#define _XkbCF_AccessXTimeoutOptsOn 31 +#define _XkbCF_AccessXTimeoutOptsOff 32 + +#define _XkbCF_IgnoreLockMods 33 +#define _XkbCF_IgnoreGroupLock 34 +#define _XkbCF_InternalMods 35 + +#define _XkbCF_GroupsWrap 36 +#define _XkbCF_InitialFeedback 37 + +static Bool +AddCtrlByName(XkbConfigRtrnPtr rtrn,char *name,unsigned long *ctrls_rtrn) +{ + if ((_XkbStrCaseCmp(name,"repeat")==0)|| + (_XkbStrCaseCmp(name,"repeatkeys")==0)) + *ctrls_rtrn= XkbRepeatKeysMask; + else if (_XkbStrCaseCmp(name,"slowkeys")==0) + *ctrls_rtrn= XkbSlowKeysMask; + else if (_XkbStrCaseCmp(name,"bouncekeys")==0) + *ctrls_rtrn= XkbBounceKeysMask; + else if (_XkbStrCaseCmp(name,"stickykeys")==0) + *ctrls_rtrn= XkbStickyKeysMask; + else if (_XkbStrCaseCmp(name,"mousekeys")==0) + *ctrls_rtrn= XkbMouseKeysMask; + else if (_XkbStrCaseCmp(name,"mousekeysaccel")==0) + *ctrls_rtrn= XkbMouseKeysAccelMask; + else if (_XkbStrCaseCmp(name,"accessxkeys")==0) + *ctrls_rtrn= XkbAccessXKeysMask; + else if (_XkbStrCaseCmp(name,"accessxtimeout")==0) + *ctrls_rtrn= XkbAccessXTimeoutMask; + else if (_XkbStrCaseCmp(name,"accessxfeedback")==0) + *ctrls_rtrn= XkbAccessXFeedbackMask; + else if (_XkbStrCaseCmp(name,"audiblebell")==0) + *ctrls_rtrn= XkbAudibleBellMask; + else if (_XkbStrCaseCmp(name,"overlay1")==0) + *ctrls_rtrn= XkbOverlay1Mask; + else if (_XkbStrCaseCmp(name,"overlay2")==0) + *ctrls_rtrn= XkbOverlay2Mask; + else if (_XkbStrCaseCmp(name,"ignoregrouplock")==0) + *ctrls_rtrn= XkbIgnoreGroupLockMask; + else { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + return True; +} + +static Bool +AddAXTimeoutOptByName( XkbConfigRtrnPtr rtrn, + char * name, + unsigned short * opts_rtrn) +{ + if (_XkbStrCaseCmp(name,"slowkeyspress")==0) + *opts_rtrn= XkbAX_SKPressFBMask; + else if (_XkbStrCaseCmp(name,"slowkeysaccept")==0) + *opts_rtrn= XkbAX_SKAcceptFBMask; + else if (_XkbStrCaseCmp(name,"feature")==0) + *opts_rtrn= XkbAX_FeatureFBMask; + else if (_XkbStrCaseCmp(name,"slowwarn")==0) + *opts_rtrn= XkbAX_SlowWarnFBMask; + else if (_XkbStrCaseCmp(name,"indicator")==0) + *opts_rtrn= XkbAX_IndicatorFBMask; + else if (_XkbStrCaseCmp(name,"stickykeys")==0) + *opts_rtrn= XkbAX_StickyKeysFBMask; + else if (_XkbStrCaseCmp(name,"twokeys")==0) + *opts_rtrn= XkbAX_TwoKeysMask; + else if (_XkbStrCaseCmp(name,"latchtolock")==0) + *opts_rtrn= XkbAX_LatchToLockMask; + else if (_XkbStrCaseCmp(name,"slowkeysrelease")==0) + *opts_rtrn= XkbAX_SKReleaseFBMask; + else if (_XkbStrCaseCmp(name,"slowkeysreject")==0) + *opts_rtrn= XkbAX_SKRejectFBMask; + else if (_XkbStrCaseCmp(name,"bouncekeysreject")==0) + *opts_rtrn= XkbAX_BKRejectFBMask; + else if (_XkbStrCaseCmp(name,"dumbbell")==0) + *opts_rtrn= XkbAX_DumbBellFBMask; + else { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + return True; +} + +XkbConfigUnboundModPtr +XkbCFAddModByName( XkbConfigRtrnPtr rtrn, + int what, + char * name, + Bool merge, + XkbConfigUnboundModPtr last) +{ + if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) { + rtrn->sz_unbound_mods+= 5; + rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods, + rtrn->sz_unbound_mods, + XkbConfigUnboundModRec); + if (rtrn->unbound_mods==NULL) { + rtrn->error= XkbCF_BadAlloc; + return False; + } + } + if (last==NULL) { + last= &rtrn->unbound_mods[rtrn->num_unbound_mods++]; + last->what= what; + last->mods= 0; + last->vmods= 0; + last->merge= merge; + last->name= NULL; + } + if (_XkbStrCaseCmp(name,"shift")==0) + last->mods|= ShiftMask; + else if (_XkbStrCaseCmp(name,"lock")==0) + last->mods|= LockMask; + else if ((_XkbStrCaseCmp(name,"control")==0)|| + (_XkbStrCaseCmp(name,"ctrl")==0)) + last->mods|= ControlMask; + else if (_XkbStrCaseCmp(name,"mod1")==0) + last->mods|= Mod1Mask; + else if (_XkbStrCaseCmp(name,"mod2")==0) + last->mods|= Mod2Mask; + else if (_XkbStrCaseCmp(name,"mod3")==0) + last->mods|= Mod3Mask; + else if (_XkbStrCaseCmp(name,"mod4")==0) + last->mods|= Mod4Mask; + else if (_XkbStrCaseCmp(name,"mod5")==0) + last->mods|= Mod5Mask; + else { + if (last->name!=NULL) { + last= &rtrn->unbound_mods[rtrn->num_unbound_mods++]; + last->what= what; + last->mods= 0; + last->vmods= 0; + last->merge= merge; + last->name= NULL; + } + last->name= _XkbDupString(name); + } + return last; +} + +int +XkbCFBindMods(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb) +{ +register int n,v; +Atom name; +XkbConfigUnboundModPtr mod; +int missing; + + if (rtrn->num_unbound_mods<1) + return 0; + if ((xkb==NULL) || (xkb->names==NULL)) + return -1; + + missing= 0; + for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) { + if (mod->name!=NULL) { + name= XkbInternAtom(xkb->dpy,mod->name,True); + if (name==None) + continue; + for (v=0;v<XkbNumVirtualMods;v++) { + if (xkb->names->vmods[v]==name) { + mod->vmods= (1<<v); + _XkbFree(mod->name); + mod->name= NULL; + break; + } + } + if (mod->name!=NULL) + missing++; + } + } + return missing; +} + +Bool +XkbCFApplyMods(XkbConfigRtrnPtr rtrn,int what,XkbConfigModInfoPtr info) +{ +register int n; +XkbConfigUnboundModPtr mod; + + if (rtrn->num_unbound_mods<1) + return True; + + for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) { + if (mod->what!=what) + continue; + if (mod->merge==XkbCF_MergeRemove) { + info->mods_clear|= mod->mods; + info->vmods_clear|= mod->vmods; + } + else { + if (mod->merge==XkbCF_MergeSet) + info->replace= True; + info->mods|= mod->mods; + info->vmods|= mod->vmods; + } + if (mod->name==NULL) { + mod->what= _XkbCF_Illegal; + } + else { + mod->mods= 0; + mod->vmods= 0; + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +DefaultParser( FILE * file, + XkbConfigFieldsPtr fields, + XkbConfigFieldPtr field, + XkbDescPtr xkb, + XkbConfigRtrnPtr rtrn) +{ +int tok; +XkbCFScanResultRec val; +char ** str; +int merge; +unsigned long * ctrls, ctrls_mask; +unsigned short * opts, opts_mask; +int * pival, sign; +int onoff; +XkbConfigUnboundModPtr last; +unsigned what; + + tok= XkbCFScan(file,&val,rtrn); + str= NULL; + onoff= 0; + pival= NULL; + switch (field->field_id) { + case _XkbCF_RulesFile: if (!str) str= &rtrn->rules_file; + case _XkbCF_Model: if (!str) str= &rtrn->model; + case _XkbCF_Layout: if (!str) str= &rtrn->layout; + case _XkbCF_Variant: if (!str) str= &rtrn->variant; + case _XkbCF_Options: if (!str) str= &rtrn->options; + case _XkbCF_Keymap: if (!str) str= &rtrn->keymap; + case _XkbCF_Keycodes: if (!str) str= &rtrn->keycodes; + case _XkbCF_Geometry: if (!str) str= &rtrn->geometry; + case _XkbCF_PhysSymbols:if (!str) str= &rtrn->phys_symbols; + case _XkbCF_Symbols: if (!str) str= &rtrn->symbols; + case _XkbCF_Types: if (!str) str= &rtrn->types; + case _XkbCF_CompatMap: if (!str) str= &rtrn->compat; + if (tok!=XkbCF_Equals) { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_String)&&(tok!=XkbCF_Ident)) { + rtrn->error= XkbCF_ExpectedString; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedEOS; + return False; + } + if (*str!=NULL) + _XkbFree(*str); + *str= _XkbDupString(val.str); + break; + case _XkbCF_InitialMods: + case _XkbCF_IgnoreLockMods: + case _XkbCF_InternalMods: + what= XkbCF_InitialMods; + if (field->field_id==_XkbCF_InitialMods) + rtrn->defined|= (what=XkbCF_InitialMods); + else if (field->field_id==_XkbCF_InternalMods) + rtrn->defined|= (what=XkbCF_InternalMods); + else if (field->field_id==_XkbCF_IgnoreLockMods) + rtrn->defined|= (what=XkbCF_IgnoreLockMods); + if (tok==XkbCF_Equals) merge= XkbCF_MergeSet; + else if (tok==XkbCF_MinusEquals) merge= XkbCF_MergeRemove; + else if (tok==XkbCF_PlusEquals) merge= XkbCF_MergeAdd; + else { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedModifier; + return False; + } + last= NULL; + while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) { + rtrn->error= XkbCF_ExpectedModifier; + return False; + } + last=XkbCFAddModByName(rtrn,what,val.str,merge,last); + if (last==NULL) + return False; + if (merge==XkbCF_MergeSet) + merge= XkbCF_MergeAdd; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) { + if (tok!=XkbCF_Plus) { + rtrn->error= XkbCF_ExpectedOperator; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + } + } + break; + case _XkbCF_InitialCtrls: + rtrn->defined|= XkbCF_InitialCtrls; + ctrls= NULL; + if (tok==XkbCF_PlusEquals) + ctrls= &rtrn->initial_ctrls; + else if (tok==XkbCF_MinusEquals) + ctrls= &rtrn->initial_ctrls_clear; + else if (tok==XkbCF_Equals) { + ctrls= &rtrn->initial_ctrls; + rtrn->replace_initial_ctrls= True; + *ctrls= 0; + } + else { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) { + return False; + } + *ctrls |= ctrls_mask; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) { + if (tok!=XkbCF_Plus) { + rtrn->error= XkbCF_ExpectedOperator; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + } + } + break; + case _XkbCF_AccessXTimeoutCtrlsOn: + case _XkbCF_AccessXTimeoutCtrlsOff: + opts= NULL; + if (tok==XkbCF_MinusEquals) { + ctrls= &rtrn->axt_ctrls_ignore; + opts= &rtrn->axt_opts_ignore; + } + else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) { + if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) { + ctrls= &rtrn->axt_ctrls_off; + opts= &rtrn->axt_opts_off; + if (tok==XkbCF_Equals) + rtrn->replace_axt_ctrls_off= True; + } + else { + ctrls= &rtrn->axt_ctrls_on; + opts= &rtrn->axt_opts_on; + if (tok==XkbCF_Equals) + rtrn->replace_axt_ctrls_on= True; + } + *ctrls= 0; + } + else { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) { + if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) + return False; + *opts |= opts_mask; + if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) { + rtrn->defined|= XkbCF_AccessXTimeoutOptsOff; + if (rtrn->replace_axt_ctrls_off) + rtrn->replace_axt_opts_off= True; + } + else { + rtrn->defined|= XkbCF_AccessXTimeoutOptsOn; + if (rtrn->replace_axt_ctrls_on) + rtrn->replace_axt_opts_on= True; + } + } + else + *ctrls |= ctrls_mask; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) { + if (tok!=XkbCF_Plus) { + rtrn->error= XkbCF_ExpectedOperator; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + } + } + break; + case _XkbCF_InitialFeedback: + rtrn->defined|= XkbCF_InitialOpts; + opts= NULL; + if (tok==XkbCF_PlusEquals) + opts= &rtrn->initial_opts; + else if (tok==XkbCF_MinusEquals) + opts= &rtrn->initial_opts_clear; + else if (tok==XkbCF_Equals) { + opts= &rtrn->initial_opts; + rtrn->replace_initial_opts= True; + *opts= 0; + } + else { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedAXOption; + return False; + } + while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) { + rtrn->error= XkbCF_ExpectedAXOption; + return False; + } + if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) { + return False; + } + *opts |= opts_mask; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) { + if (tok!=XkbCF_Plus) { + rtrn->error= XkbCF_ExpectedOperator; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + } + } + break; + case _XkbCF_AccessXTimeoutOptsOff: + case _XkbCF_AccessXTimeoutOptsOn: + opts= NULL; + if (tok==XkbCF_MinusEquals) + opts= &rtrn->axt_opts_ignore; + else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) { + if (field->field_id==_XkbCF_AccessXTimeoutOptsOff) { + opts= &rtrn->axt_opts_off; + if (tok==XkbCF_Equals) + rtrn->replace_axt_opts_off= True; + } + else { + opts= &rtrn->axt_opts_on; + if (tok==XkbCF_Equals) + rtrn->replace_axt_opts_on= True; + } + *opts = 0; + } + else { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) { + rtrn->error= XkbCF_ExpectedControl; + return False; + } + if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) + return False; + *opts |= opts_mask; + + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) { + if (tok!=XkbCF_Plus) { + rtrn->error= XkbCF_ExpectedOperator; + return False; + } + tok= XkbCFScan(file,&val,rtrn); + } + } + break; + case _XkbCF_ClickVolume: + if (!pival) { + pival= &rtrn->click_volume; + onoff= 100; + } + case _XkbCF_BellVolume: + if (!pival) { + pival= &rtrn->bell_volume; + onoff= 100; + } + case _XkbCF_BellPitch: + if (!pival) + pival= &rtrn->bell_pitch; + case _XkbCF_BellDuration: + if (!pival) + pival= &rtrn->bell_duration; + case _XkbCF_RepeatDelay: + if (!pival) + pival= &rtrn->repeat_delay; + case _XkbCF_RepeatInterval: + if (!pival) + pival= &rtrn->repeat_interval; + case _XkbCF_SlowKeysDelay: + if (!pival) + pival= &rtrn->slow_keys_delay; + case _XkbCF_DebounceDelay: + if (!pival) + pival= &rtrn->debounce_delay; + case _XkbCF_MouseKeysDelay: + if (!pival) + pival= &rtrn->mk_delay; + case _XkbCF_MouseKeysInterval: + if (!pival) + pival= &rtrn->mk_interval; + case _XkbCF_MouseKeysTimeToMax: + if (!pival) + pival= &rtrn->mk_time_to_max; + case _XkbCF_MouseKeysMaxSpeed: + if (!pival) + pival= &rtrn->mk_max_speed; + case _XkbCF_MouseKeysCurve: + if (!pival) + pival= &rtrn->mk_curve; + case _XkbCF_AccessXTimeout: + if (!pival) + pival= &rtrn->ax_timeout; + if (tok!=XkbCF_Equals) { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) { + /* This can be a negative value */ + tok = XkbCFScan(file,&val,rtrn); + sign = -1; + } + else + sign = 1; + if (tok!=XkbCF_Integer) { + Bool ok= False; + if ((onoff)&&(tok==XkbCF_Ident)&&(val.str!=NULL)) { + if (_XkbStrCaseCmp(val.str,"on")) { + val.ival= onoff; + ok= True; + } + else if (_XkbStrCaseCmp(val.str,"off")) { + val.ival= 0; + ok= True; + } + } + if (!ok) { + rtrn->error= XkbCF_ExpectedInteger; + goto BAILOUT; + } + } + *pival= val.ival * sign; + if (field->field_id == _XkbCF_AccessXTimeout) + rtrn->defined|=XkbCF_AccessXTimeout; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedEOS; + return False; + } + break; + case _XkbCF_GroupsWrap: + if (tok!=XkbCF_Equals) { + rtrn->error= XkbCF_MissingEquals; + goto BAILOUT; + } + tok= XkbCFScan(file,&val,rtrn); + if (tok==XkbCF_Ident) { + if (_XkbStrCaseCmp(val.str,"wrap")==0) { + rtrn->groups_wrap= XkbSetGroupInfo(0,XkbWrapIntoRange,0); + } + else if (_XkbStrCaseCmp(val.str,"clamp")==0) { + rtrn->groups_wrap= XkbSetGroupInfo(0,XkbClampIntoRange,0); + } + else { + rtrn->error= XkbCF_ExpectedOORGroupBehavior; + return False; + } + } + else if ((tok==XkbCF_Integer)&&(XkbIsLegalGroup(val.ival-1))) { + rtrn->groups_wrap= XkbSetGroupInfo(0,XkbRedirectIntoRange, + val.ival-1); + } + else { + rtrn->error= XkbCF_ExpectedOORGroupBehavior; + return False; + } + rtrn->defined|= XkbCF_GroupsWrap; + tok= XkbCFScan(file,&val,rtrn); + if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) { + rtrn->error= XkbCF_ExpectedEOS; + return False; + } + break; + default: + rtrn->error= XkbCF_ExpectedInteger; + goto BAILOUT; + + } + return True; +BAILOUT: + return False; +} + +static Bool +DefaultCleanUp(XkbConfigRtrnPtr rtrn) +{ + if (rtrn->keymap) _XkbFree(rtrn->keymap); + if (rtrn->keycodes) _XkbFree(rtrn->keycodes); + if (rtrn->geometry) _XkbFree(rtrn->geometry); + if (rtrn->phys_symbols) _XkbFree(rtrn->phys_symbols); + if (rtrn->symbols) _XkbFree(rtrn->symbols); + if (rtrn->types) _XkbFree(rtrn->types); + if (rtrn->compat) _XkbFree(rtrn->compat); + rtrn->keycodes= rtrn->geometry= NULL; + rtrn->symbols= rtrn->phys_symbols= NULL; + rtrn->types= rtrn->compat= NULL; + if ((rtrn->unbound_mods!=NULL)&&(rtrn->num_unbound_mods>0)) { + register int i; + for (i=0;i<rtrn->num_unbound_mods;i++) { + if (rtrn->unbound_mods[i].name!=NULL) { + _XkbFree(rtrn->unbound_mods[i].name); + rtrn->unbound_mods[i].name= NULL; + } + } + _XkbFree(rtrn->unbound_mods); + rtrn->sz_unbound_mods= 0; + rtrn->num_unbound_mods= 0; + rtrn->unbound_mods= NULL; + } + return True; +} + +static Bool +DefaultApplyNames(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb) +{ +char *str; + + if (XkbAllocNames(xkb,XkbComponentNamesMask,0,0)!=Success) + return False; + if ((str=rtrn->keycodes)!=NULL) { + xkb->names->keycodes= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->keycodes= NULL; + } + if ((str=rtrn->geometry)!=NULL) { + xkb->names->geometry= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->geometry= NULL; + } + if ((str=rtrn->symbols)!=NULL) { + xkb->names->symbols= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->symbols= NULL; + } + if ((str=rtrn->phys_symbols)!=NULL) { + xkb->names->phys_symbols= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->phys_symbols= NULL; + } + if ((str=rtrn->types)!=NULL) { + xkb->names->types= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->types= NULL; + } + if ((str=rtrn->compat)!=NULL) { + xkb->names->compat= XkbInternAtom(xkb->dpy,str,False); + _XkbFree(str); + rtrn->compat= NULL; + } + return True; +} + +static Bool +DefaultApplyControls(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb) +{ +unsigned on,off; +XkbControlsPtr ctrls; +unsigned int mask; + + if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) + return False; + ctrls= xkb->ctrls; + if (rtrn->replace_initial_ctrls) + ctrls->enabled_ctrls= rtrn->initial_ctrls; + else ctrls->enabled_ctrls|= rtrn->initial_ctrls; + ctrls->enabled_ctrls&= ~rtrn->initial_ctrls_clear; + if (rtrn->internal_mods.replace) { + ctrls->internal.real_mods= rtrn->internal_mods.mods; + ctrls->internal.vmods= rtrn->internal_mods.vmods; + } + else { + ctrls->internal.real_mods&= ~rtrn->internal_mods.mods_clear; + ctrls->internal.vmods&= ~rtrn->internal_mods.vmods_clear; + ctrls->internal.real_mods|= rtrn->internal_mods.mods; + ctrls->internal.vmods|= rtrn->internal_mods.vmods; + } + mask= 0; + (void)XkbVirtualModsToReal(xkb,ctrls->internal.vmods,&mask); + ctrls->internal.mask= (ctrls->internal.real_mods|mask); + + if (rtrn->ignore_lock_mods.replace) { + ctrls->ignore_lock.real_mods= rtrn->ignore_lock_mods.mods; + ctrls->ignore_lock.vmods= rtrn->ignore_lock_mods.vmods; + } + else { + ctrls->ignore_lock.real_mods&= ~rtrn->ignore_lock_mods.mods_clear; + ctrls->ignore_lock.vmods&= ~rtrn->ignore_lock_mods.vmods_clear; + ctrls->ignore_lock.real_mods|= rtrn->ignore_lock_mods.mods; + ctrls->ignore_lock.vmods|= rtrn->ignore_lock_mods.vmods; + } + mask= 0; + (void)XkbVirtualModsToReal(xkb,ctrls->ignore_lock.vmods,&mask); + ctrls->ignore_lock.mask= (ctrls->ignore_lock.real_mods|mask); + + if (rtrn->repeat_delay>0) + ctrls->repeat_delay= rtrn->repeat_delay; + if (rtrn->repeat_interval>0) + ctrls->repeat_interval= rtrn->repeat_interval; + if (rtrn->slow_keys_delay>0) + ctrls->slow_keys_delay= rtrn->slow_keys_delay; + if (rtrn->debounce_delay>0) + ctrls->debounce_delay= rtrn->debounce_delay; + if (rtrn->mk_delay>0) + ctrls->mk_delay= rtrn->mk_delay; + if (rtrn->mk_interval>0) + ctrls->mk_interval= rtrn->mk_interval; + if (rtrn->mk_time_to_max>0) + ctrls->mk_time_to_max= rtrn->mk_time_to_max; + if (rtrn->mk_max_speed>0) + ctrls->mk_max_speed= rtrn->mk_max_speed; + if (rtrn->mk_curve>0) + ctrls->mk_curve= rtrn->mk_curve; + if (rtrn->defined&XkbCF_AccessXTimeout && rtrn->ax_timeout > 0) + ctrls->ax_timeout= rtrn->ax_timeout; + + /* any value set to both off and on is reset to ignore */ + if ((off=(rtrn->axt_ctrls_on&rtrn->axt_ctrls_off))!=0) + rtrn->axt_ctrls_ignore|= off; + + /* ignore takes priority over on and off */ + rtrn->axt_ctrls_on&= ~rtrn->axt_ctrls_ignore; + rtrn->axt_ctrls_off&= ~rtrn->axt_ctrls_ignore; + + if (!rtrn->replace_axt_ctrls_off) { + off= (ctrls->axt_ctrls_mask&(~ctrls->axt_ctrls_values)); + off&= ~rtrn->axt_ctrls_on; + off|= rtrn->axt_ctrls_off; + } + else off= rtrn->axt_ctrls_off; + if (!rtrn->replace_axt_ctrls_on) { + on= (ctrls->axt_ctrls_mask&ctrls->axt_ctrls_values); + on&= ~rtrn->axt_ctrls_off; + on|= rtrn->axt_ctrls_on; + } + else on= rtrn->axt_ctrls_on; + ctrls->axt_ctrls_mask= (on|off)&~rtrn->axt_ctrls_ignore; + ctrls->axt_ctrls_values= on&~rtrn->axt_ctrls_ignore; + + /* any value set to both off and on is reset to ignore */ + if ((off=(rtrn->axt_opts_on&rtrn->axt_opts_off))!=0) + rtrn->axt_opts_ignore|= off; + + /* ignore takes priority over on and off */ + rtrn->axt_opts_on&= ~rtrn->axt_opts_ignore; + rtrn->axt_opts_off&= ~rtrn->axt_opts_ignore; + + if (rtrn->replace_axt_opts_off) { + off= (ctrls->axt_opts_mask&(~ctrls->axt_opts_values)); + off&= ~rtrn->axt_opts_on; + off|= rtrn->axt_opts_off; + } + else off= rtrn->axt_opts_off; + if (!rtrn->replace_axt_opts_on) { + on= (ctrls->axt_opts_mask&ctrls->axt_opts_values); + on&= ~rtrn->axt_opts_off; + on|= rtrn->axt_opts_on; + } + else on= rtrn->axt_opts_on; + ctrls->axt_opts_mask= (unsigned short)((on|off)&~rtrn->axt_ctrls_ignore); + ctrls->axt_opts_values= (unsigned short)(on&~rtrn->axt_ctrls_ignore); + + if (rtrn->defined&XkbCF_GroupsWrap) { + int n; + n= XkbNumGroups(ctrls->groups_wrap); + rtrn->groups_wrap= XkbSetNumGroups(rtrn->groups_wrap,n); + ctrls->groups_wrap= rtrn->groups_wrap; + } + return True; +} + +/*ARGSUSED*/ +static Bool +DefaultFinish( XkbConfigFieldsPtr fields, + XkbDescPtr xkb, + XkbConfigRtrnPtr rtrn, + int what) +{ + if ((what==XkbCF_Destroy)||(what==XkbCF_CleanUp)) + return DefaultCleanUp(rtrn); + if (what==XkbCF_Check) { + if ((rtrn->symbols==NULL)&&(rtrn->phys_symbols!=NULL)) + rtrn->symbols= _XkbDupString(rtrn->phys_symbols); + } + if ((what==XkbCF_Apply)||(what==XkbCF_Check)) { + if (xkb && xkb->names && (rtrn->num_unbound_mods>0)) + XkbCFBindMods(rtrn,xkb); + XkbCFApplyMods(rtrn,XkbCF_InitialMods,&rtrn->initial_mods); + XkbCFApplyMods(rtrn,XkbCF_InternalMods,&rtrn->internal_mods); + XkbCFApplyMods(rtrn,XkbCF_IgnoreLockMods,&rtrn->ignore_lock_mods); + } + if (what==XkbCF_Apply) { + if (xkb!=NULL) { + DefaultApplyNames(rtrn,xkb); + DefaultApplyControls(rtrn,xkb); + XkbCFBindMods(rtrn,xkb); + } + } + return True; +} + +static XkbConfigFieldRec _XkbCFDfltFields[] = { + { "rules", _XkbCF_RulesFile }, + { "model", _XkbCF_Model }, + { "layout", _XkbCF_Layout }, + { "variant", _XkbCF_Variant }, + { "options", _XkbCF_Options }, + { "keymap", _XkbCF_Keymap }, + { "keycodes", _XkbCF_Keycodes }, + { "geometry", _XkbCF_Geometry }, + { "realsymbols",_XkbCF_PhysSymbols }, + { "actualsymbols",_XkbCF_PhysSymbols }, + { "symbols", _XkbCF_Symbols }, + { "symbolstouse",_XkbCF_Symbols }, + { "types", _XkbCF_Types }, + { "compat", _XkbCF_CompatMap }, + { "modifiers", _XkbCF_InitialMods }, + { "controls", _XkbCF_InitialCtrls }, + { "click", _XkbCF_ClickVolume }, + { "clickvolume",_XkbCF_ClickVolume }, + { "bell", _XkbCF_BellVolume }, + { "bellvolume", _XkbCF_BellVolume }, + { "bellpitch", _XkbCF_BellPitch }, + { "bellduration",_XkbCF_BellDuration }, + { "repeatdelay",_XkbCF_RepeatDelay }, + { "repeatinterval",_XkbCF_RepeatInterval }, + { "slowkeysdelay",_XkbCF_SlowKeysDelay }, + { "debouncedelay",_XkbCF_DebounceDelay }, + { "mousekeysdelay",_XkbCF_MouseKeysDelay }, + { "mousekeysinterval",_XkbCF_MouseKeysInterval }, + { "mousekeystimetomax",_XkbCF_MouseKeysTimeToMax }, + { "mousekeysmaxspeed",_XkbCF_MouseKeysMaxSpeed }, + { "mousekeyscurve",_XkbCF_MouseKeysCurve }, + { "accessxtimeout",_XkbCF_AccessXTimeout }, + { "axtimeout",_XkbCF_AccessXTimeout }, + { "accessxtimeoutctrlson",_XkbCF_AccessXTimeoutCtrlsOn }, + { "axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn }, + { "accessxtimeoutctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff }, + { "axtctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff }, + { "accessxtimeoutfeedbackon", _XkbCF_AccessXTimeoutOptsOn }, + { "axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn }, + { "accessxtimeoutfeedbackoff", _XkbCF_AccessXTimeoutOptsOff }, + { "axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff }, + { "ignorelockmods",_XkbCF_IgnoreLockMods }, + { "ignorelockmodifiers",_XkbCF_IgnoreLockMods }, + { "ignoregrouplock",_XkbCF_IgnoreGroupLock }, + { "internalmods",_XkbCF_InternalMods }, + { "internalmodifiers",_XkbCF_InternalMods }, + { "outofrangegroups",_XkbCF_GroupsWrap }, + { "groups", _XkbCF_GroupsWrap }, + { "feedback", _XkbCF_InitialFeedback }, +}; +#define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec)) + +static XkbConfigFieldsRec _XkbCFDflts = { + 0, /* cfg_id */ + _XkbCFNumDfltFields, /* num_fields */ + _XkbCFDfltFields, /* fields */ + DefaultParser, /* parser */ + DefaultFinish, /* finish */ + NULL, /* priv */ + NULL /* next */ +}; + +XkbConfigFieldsPtr XkbCFDflts= &_XkbCFDflts; + +/***====================================================================***/ + +XkbConfigFieldsPtr +XkbCFDup(XkbConfigFieldsPtr fields) +{ +XkbConfigFieldsPtr pNew; + + pNew= _XkbTypedAlloc(XkbConfigFieldsRec); + if (pNew!=NULL) { + memcpy(pNew,fields,sizeof(XkbConfigFieldsRec)); + if ((pNew->fields!=NULL)&&(pNew->num_fields>0)) { + pNew->fields= _XkbTypedCalloc(pNew->num_fields,XkbConfigFieldRec); + if (pNew->fields) { + memcpy(fields->fields,pNew->fields, + (pNew->num_fields*sizeof(XkbConfigFieldRec))); + } + else { + _XkbFree(pNew); + return NULL; + } + } + else { + pNew->num_fields= 0; + pNew->fields= NULL; + } + pNew->next= NULL; + } + return pNew; +} + +XkbConfigFieldsPtr +XkbCFFree(XkbConfigFieldsPtr fields,Bool all) +{ +XkbConfigFieldsPtr next; + + next= NULL; + while (fields!=NULL) { + next= fields->next; + if (fields!=XkbCFDflts) { + if (fields->fields) { + _XkbFree(fields->fields); + fields->fields= NULL; + fields->num_fields= 0; + } + _XkbFree(fields); + } + fields= (all?next:NULL); + } + return next; +} + +Bool +XkbCFApplyRtrnValues( XkbConfigRtrnPtr rtrn, + XkbConfigFieldsPtr fields, + XkbDescPtr xkb) +{ +Bool ok; + + if ((fields==NULL)||(rtrn==NULL)||(xkb==NULL)) + return False; + for (ok=True;fields!=NULL;fields=fields->next) { + if (fields->finish!=NULL) + ok= (*fields->finish)(fields,xkb,rtrn,XkbCF_Apply)&&ok; + } + return ok; +} + +XkbConfigRtrnPrivPtr +XkbCFAddPrivate( XkbConfigRtrnPtr rtrn, + XkbConfigFieldsPtr fields, + XPointer ptr) +{ +XkbConfigRtrnPrivPtr priv; + + if ((rtrn==NULL)||(fields==NULL)) + return NULL; + priv= _XkbTypedAlloc(XkbConfigRtrnPrivRec); + if (priv!=NULL) { + priv->cfg_id= fields->cfg_id; + priv->priv= ptr; + priv->next= rtrn->priv; + rtrn->priv= priv; + } + return priv; +} + +void +XkbCFFreeRtrn( XkbConfigRtrnPtr rtrn, + XkbConfigFieldsPtr fields, + XkbDescPtr xkb) +{ +XkbConfigRtrnPrivPtr tmp,next; + + if ((fields==NULL)||(rtrn==NULL)) + return; + while (fields!=NULL) { + if (fields->finish!=NULL) + (*fields->finish)(fields,xkb,rtrn,XkbCF_Destroy); + fields= fields->next; + } + for (tmp=rtrn->priv;tmp!=NULL;tmp=next) { + next= tmp->next; + bzero((char *)tmp,sizeof(XkbConfigRtrnPrivRec)); + _XkbFree(tmp); + } + bzero((char *)rtrn,sizeof(XkbConfigRtrnRec)); + return; +} + +Bool +XkbCFParse( FILE * file, + XkbConfigFieldsPtr fields, + XkbDescPtr xkb, + XkbConfigRtrnPtr rtrn) +{ +int tok; +XkbCFScanResultRec val; +XkbConfigFieldsPtr tmp; + + if ((file==NULL)||(fields==NULL)||(rtrn==NULL)) + return False; + for (tok=0,tmp=fields;tmp!=NULL;tmp=tmp->next,tok++) { + fields->cfg_id= tok; + } + bzero((char *)rtrn,sizeof(XkbConfigRtrnRec)); + rtrn->line= 1; + rtrn->click_volume= -1; + rtrn->bell_volume= -1; + while ((tok=XkbCFScan(file,&val,rtrn))!=XkbCF_EOF) { + if (tok==XkbCF_Ident) { + Bool done; + for (tmp=fields,done=False;(tmp!=NULL)&&(!done);tmp=tmp->next) { + register int i; + XkbConfigFieldPtr f; + + for (i=0,f=tmp->fields;(i<tmp->num_fields)&&(!done);i++,f++) { + if (_XkbStrCaseCmp(val.str,f->field)!=0) + continue; + if ((*tmp->parser)(file,tmp,f,xkb,rtrn)) + done= True; + else goto BAILOUT; + } + } + } + else if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)) { + rtrn->error= XkbCF_MissingIdent; + goto BAILOUT; + } + } + for (tmp=fields;tmp!=NULL;tmp=tmp->next) { + if ((tmp->finish)&&(!(*tmp->finish)(tmp,xkb,rtrn,XkbCF_Check))) + goto BAILOUT; + } + return True; +BAILOUT: + for (tmp=fields;tmp!=NULL;tmp=tmp->next) { + if (tmp->finish) + (*tmp->finish)(tmp,xkb,rtrn,XkbCF_CleanUp); + } + return False; +} + +/*ARGSUSED*/ +void +XkbCFReportError(FILE *file,char *name,int error,int line) +{ +char * msg; + + switch(error) { + case XkbCF_BadAlloc: + msg= "allocation failed\n"; break; + case XkbCF_UnterminatedString: + msg= "unterminated string on line %d"; break; + case XkbCF_MissingIdent: + msg= "expected identifier on line %d"; break; + case XkbCF_MissingEquals: + msg= "expected '=' on line %d"; break; + case XkbCF_ExpectedEOS: + msg= "expected ';' or newline on line %d"; break; + case XkbCF_ExpectedBoolean: + msg= "expected a boolean value on line %d"; break; + case XkbCF_ExpectedInteger: + msg= "expected a numeric value on line %d"; break; + case XkbCF_ExpectedString: + msg= "expected a string on line %d"; break; + case XkbCF_ExpectedModifier: + msg= "expected a modifier name on line %d"; break; + case XkbCF_ExpectedControl: + msg= "expected a control name on line %d"; break; + case XkbCF_ExpectedAXOption: + msg= "expected an AccessX option on line %d"; break; + case XkbCF_ExpectedOperator: + msg= "expected '+' or '-' on line %d"; break; + case XkbCF_ExpectedOORGroupBehavior: + msg= "expected wrap, clamp or group number on line %d"; break; + default: + msg= "unknown error on line %d"; break; + } +#ifndef XKB_IN_SERVER + fprintf(file,msg,line); + if (name) fprintf(file," of %s\n",name); + else fprintf(file,"\n"); +#else + ErrorF(msg,line); + if (name) ErrorF(" of %s\n",name); + else ErrorF("\n"); +#endif + return; +} diff --git a/libxkbfile/src/xkbdraw.c b/libxkbfile/src/xkbdraw.c new file mode 100644 index 000000000..c955f0321 --- /dev/null +++ b/libxkbfile/src/xkbdraw.c @@ -0,0 +1,135 @@ +/* $Xorg: xkbdraw.c,v 1.3 2000/08/17 19:46:43 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbdraw.c,v 1.3 2001/07/29 05:01:13 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include <X11/Xos.h> +#include <X11/Xfuncs.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> +#include "XKMformat.h" +#include "XKBfileInt.h" + +static void +_XkbAddDrawable(XkbDrawablePtr *pfirst,XkbDrawablePtr *plast,XkbDrawablePtr tmp) +{ +XkbDrawablePtr old; + + if (*pfirst==NULL) { + *pfirst= *plast= tmp; + } + else if (tmp->priority>=(*plast)->priority) { + (*plast)->next= tmp; + *plast= tmp; + } + else if (tmp->priority<(*pfirst)->priority) { + tmp->next= (*pfirst); + (*pfirst)= tmp; + } + else { + old= *pfirst; + while ((old->next)&&(old->next->priority<=tmp->priority)) { + old= old->next; + } + tmp->next= old->next; + old->next= tmp; + } + return; +} + +XkbDrawablePtr +XkbGetOrderedDrawables(XkbGeometryPtr geom,XkbSectionPtr section) +{ +XkbDrawablePtr first,last,tmp; +int i; + + first= last= NULL; + if (geom!=NULL) { + XkbSectionPtr section; + XkbDoodadPtr doodad; + for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { + tmp= _XkbTypedCalloc(1,XkbDrawableRec); + if (!tmp) { + XkbFreeOrderedDrawables(first); + return NULL; + } + tmp->type= XkbDW_Section; + tmp->priority= section->priority; + tmp->u.section= section; + tmp->next= NULL; + _XkbAddDrawable(&first,&last,tmp); + } + for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { + tmp= _XkbTypedCalloc(1,XkbDrawableRec); + if (!tmp) { + XkbFreeOrderedDrawables(first); + return NULL; + } + tmp->type= XkbDW_Doodad; + tmp->priority= doodad->any.priority; + tmp->u.doodad= doodad; + tmp->next= NULL; + _XkbAddDrawable(&first,&last,tmp); + } + } + if (section!=NULL) { + XkbDoodadPtr doodad; + for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { + tmp= _XkbTypedCalloc(1,XkbDrawableRec); + if (!tmp) { + XkbFreeOrderedDrawables(first); + return NULL; + } + tmp->type= XkbDW_Doodad; + tmp->priority= doodad->any.priority; + tmp->u.doodad= doodad; + tmp->next= NULL; + _XkbAddDrawable(&first,&last,tmp); + } + } + return first; +} + +void +XkbFreeOrderedDrawables(XkbDrawablePtr draw) +{ +XkbDrawablePtr tmp; + + for (;draw!=NULL;draw=tmp) { + tmp= draw->next; + _XkbFree(draw); + } + return; +} diff --git a/libxkbfile/src/xkberrs.c b/libxkbfile/src/xkberrs.c new file mode 100644 index 000000000..1b856bcaf --- /dev/null +++ b/libxkbfile/src/xkberrs.c @@ -0,0 +1,72 @@ +/* $Xorg: xkberrs.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkberrs.c,v 3.4 2001/07/29 05:01:13 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +char * _XkbErrMessages[] = { + "success", /* _XkbSuccess */ + "key names not defined", /* _XkbErrMissingNames */ + "key types not defined", /* _XkbErrMissingTypes */ + "required key types not present", /* _XkbErrMissingReqTypes */ + "symbols not defined", /* _XkbErrMissingSymbols */ + "virtual modifier bindings not defined",/* _XkbErrMissingVMods */ + "indicators not defined", /* _XkbErrMissingIndicators */ + "compatibility map not defined", /* _XkbErrMissingCompatMap */ + "symbol interpretations not defined", /* _XkbErrMissingSymInterps */ + "geometry not defined", /* _XkbErrMissingGeometry */ + "illegal doodad type", /* _XkbErrIllegalDoodad */ + "illegal TOC type", /* _XkbErrIllegalTOCType */ + "illegal contents", /* _XkbErrIllegalContents */ + "empty file", /* _XkbErrEmptyFile */ + "file not found", /* _XkbErrFileNotFound */ + "cannot open", /* _XkbErrFileCannotOpen */ + "bad value", /* _XkbErrBadValue */ + "bad match", /* _XkbErrBadMatch */ + "illegal name for type", /* _XkbErrBadTypeName */ + "illegal width for type", /* _XkbErrBadTypeWidth */ + "bad file type", /* _XkbErrBadFileType */ + "bad file version", /* _XkbErrBadFileVersion */ + "error in Xkm file", /* _XkbErrBadFileFormat */ + "allocation failed", /* _XkbErrBadAlloc */ + "bad length", /* _XkbErrBadLength */ + "X request failed", /* _XkbErrXReqFailure */ + "not implemented" /* _XkbErrBadImplementation */ +}; + +unsigned _XkbErrCode; +char * _XkbErrLocation= NULL; +unsigned _XkbErrData; + diff --git a/libxkbfile/src/xkbmisc.c b/libxkbfile/src/xkbmisc.c new file mode 100644 index 000000000..41f1f7f25 --- /dev/null +++ b/libxkbfile/src/xkbmisc.c @@ -0,0 +1,677 @@ +/* $Xorg: xkbmisc.c,v 1.4 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbmisc.c,v 1.7 2003/07/16 02:31:10 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include <X11/Xos.h> +#include <X11/Xfuncs.h> + +#ifndef XKB_IN_SERVER + +#include <X11/Xlib.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> +#include "XKMformat.h" +#include "XKBfileInt.h" + +#else + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/keysym.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "dix.h" +#include <X11/extensions/XKBstr.h> +#define XKBSRV_NEED_FILE_FUNCS 1 +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBgeom.h> +#include "xkb.h" + +#endif + +unsigned +_XkbKSCheckCase(KeySym ks) +{ +unsigned set,rtrn; + + set= (ks & (~0xff)) >> 8; + rtrn= 0; + switch (set) { + case 0: /* latin 1 */ + if (((ks>=XK_A)&&(ks<=XK_Z))|| + ((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_a)&&(ks<=XK_z))|| + ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) { + rtrn|= _XkbKSLower; + } + break; + case 1: /* latin 2 */ + if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))|| + ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))|| + ((ks>=XK_racute)&&(ks<=XK_tcedilla))) { + rtrn|= _XkbKSLower; + } + break; + case 2: /* latin 3 */ + if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))|| + ((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))|| + ((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) { + rtrn|= _XkbKSLower; + } + break; + case 3: /* latin 4 */ + if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))|| + (ks==XK_ENG)|| + ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| + (ks==XK_eng)|| + ((ks>=XK_amacron)&&(ks<=XK_umacron))) { + rtrn|= _XkbKSLower; + } + break; + case 18: /* latin 8 */ + if ((ks==XK_Babovedot)|| + ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))|| + ((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))|| + (ks==XK_Mabovedot)|| + (ks==XK_Pabovedot)|| + (ks==XK_Sabovedot)|| + (ks==XK_Wdiaeresis)|| + ((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) { + rtrn|= _XkbKSUpper; + } + if ((ks==XK_babovedot)|| + (ks==XK_dabovedot)|| + (ks==XK_fabovedot)|| + (ks==XK_mabovedot)|| + ((ks>=XK_wgrave)&&(ks<=XK_wacute))|| + (ks==XK_ygrave)|| + ((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) { + rtrn|= _XkbKSLower; + } + break; + case 19: /* latin 9 */ + if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) { + rtrn|= _XkbKSUpper; + } + if (ks==XK_oe) { + rtrn|= _XkbKSLower; + } + break; + } + return rtrn; +} + +/***===================================================================***/ + +Bool +XkbLookupGroupAndLevel( XkbDescPtr xkb, + int key, + int * mods_inout, + int * grp_inout, + int * lvl_rtrn) +{ +int nG,eG; + + if ((!xkb)||(!XkbKeycodeInRange(xkb,key))||(!grp_inout)) + return False; + + nG= XkbKeyNumGroups(xkb,key); + eG= *grp_inout; + + if ( nG==0 ) { + *grp_inout= 0; + if (lvl_rtrn!=NULL) + *lvl_rtrn= 0; + return False; + } + else if ( nG==1 ) { + eG= 0; + } + else if ( eG>=nG ) { + unsigned gI= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(gI)) { + default: + eG %= nG; + break; + case XkbClampIntoRange: + eG = nG-1; + break; + case XkbRedirectIntoRange: + eG = XkbOutOfRangeGroupNumber(gI); + if (eG>=nG) + eG= 0; + break; + } + } + *grp_inout= eG; + if (mods_inout!=NULL) { + XkbKeyTypePtr type; + int preserve; + + type = XkbKeyKeyType(xkb,key,eG); + if (lvl_rtrn!=NULL) + *lvl_rtrn= 0; + preserve= 0; + if (type->map) { /* find the shift level */ + register int i; + register XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;i<type->map_count;i++,entry++) { + if ((entry->active)&& + (((*mods_inout)&type->mods.mask)==entry->mods.mask)){ + if (lvl_rtrn!=NULL) + *lvl_rtrn= entry->level; + if (type->preserve) + preserve= type->preserve[i].mask; + break; + } + } + } + (*mods_inout)&= ~(type->mods.mask&(~preserve)); + } + return True; +} + +/***===================================================================***/ + +static Bool +XkbWriteSectionFromName(FILE *file,char *sectionName,char *name) +{ + fprintf(file," xkb_%-20s { include \"%s\" };\n",sectionName,name); + return True; +} + +#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%'))) +#define COMPLETE(n) ((n)&&(!NEED_DESC(n))) + +/* ARGSUSED */ +static void +_AddIncl( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + int index, + void * priv) +{ + if ((priv)&&(strcmp((char *)priv,"%")!=0)) + fprintf(file," include \"%s\"\n",(char *)priv); + return; +} + +Bool +XkbWriteXKBKeymapForNames( FILE * file, + XkbComponentNamesPtr names, + Display * dpy, + XkbDescPtr xkb, + unsigned want, + unsigned need) +{ +char * name,*tmp; +unsigned complete; +XkbNamesPtr old_names; +int multi_section; +unsigned wantNames,wantConfig,wantDflts; +XkbFileInfo finfo; + + bzero(&finfo,sizeof(XkbFileInfo)); + + complete= 0; + if ((name=names->keymap)==NULL) name= "default"; + if (COMPLETE(names->keycodes)) complete|= XkmKeyNamesMask; + if (COMPLETE(names->types)) complete|= XkmTypesMask; + if (COMPLETE(names->compat)) complete|= XkmCompatMapMask; + if (COMPLETE(names->symbols)) complete|= XkmSymbolsMask; + if (COMPLETE(names->geometry)) complete|= XkmGeometryMask; + want|= (complete|need); + if (want&XkmSymbolsMask) + want|= XkmKeyNamesMask|XkmTypesMask; + + if (want==0) + return False; + + if (xkb!=NULL) { + old_names= xkb->names; + finfo.type= 0; + finfo.defined= 0; + finfo.xkb= xkb; + if (!XkbDetermineFileType(&finfo,XkbXKBFile,NULL)) + return False; + } + else old_names= NULL; + + wantConfig= want&(~complete); + if (xkb!=NULL) { + if (wantConfig&XkmTypesMask) { + if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes)) + wantConfig&= ~XkmTypesMask; + } + if (wantConfig&XkmCompatMapMask) { + if ((!xkb->compat) || (xkb->compat->num_si<1)) + wantConfig&= ~XkmCompatMapMask; + } + if (wantConfig&XkmSymbolsMask) { + if ((!xkb->map) || (!xkb->map->key_sym_map)) + wantConfig&= ~XkmSymbolsMask; + } + if (wantConfig&XkmIndicatorsMask) { + if (!xkb->indicators) + wantConfig&= ~XkmIndicatorsMask; + } + if (wantConfig&XkmKeyNamesMask) { + if ((!xkb->names)||(!xkb->names->keys)) + wantConfig&= ~XkmKeyNamesMask; + } + if ((wantConfig&XkmGeometryMask)&&(!xkb->geom)) + wantConfig&= ~XkmGeometryMask; + } + else { + wantConfig= 0; + } + complete|= wantConfig; + + wantDflts= 0; + wantNames= want&(~complete); + if ((xkb!=NULL) && (old_names!=NULL)) { + if (wantNames&XkmTypesMask) { + if (old_names->types!=None) { + tmp= XkbAtomGetString(dpy,old_names->types); + names->types= tmp; + } + else { + wantDflts|= XkmTypesMask; + } + complete|= XkmTypesMask; + } + if (wantNames&XkmCompatMapMask) { + if (old_names->compat!=None) { + tmp= XkbAtomGetString(dpy,old_names->compat); + names->compat= tmp; + } + else wantDflts|= XkmCompatMapMask; + complete|= XkmCompatMapMask; + } + if (wantNames&XkmSymbolsMask) { + if (old_names->symbols==None) + return False; + tmp= XkbAtomGetString(dpy,old_names->symbols); + names->symbols= tmp; + complete|= XkmSymbolsMask; + } + if (wantNames&XkmKeyNamesMask) { + if (old_names->keycodes!=None) { + tmp= XkbAtomGetString(dpy,old_names->keycodes); + names->keycodes= tmp; + } + else wantDflts|= XkmKeyNamesMask; + complete|= XkmKeyNamesMask; + } + if (wantNames&XkmGeometryMask) { + if (old_names->geometry==None) + return False; + tmp= XkbAtomGetString(dpy,old_names->geometry); + names->geometry= tmp; + complete|= XkmGeometryMask; + wantNames&= ~XkmGeometryMask; + } + } + if (complete&XkmCompatMapMask) + complete|= XkmIndicatorsMask|XkmVirtualModsMask; + else if (complete&(XkmSymbolsMask|XkmTypesMask)) + complete|= XkmVirtualModsMask; + if (need & (~complete)) + return False; + if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete))) + return False; + + multi_section= 1; + if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&& + ((complete&(~XkmKeymapLegal))==0)) { + fprintf(file,"xkb_keymap \"%s\" {\n",name); + } + else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&& + ((complete&(~XkmSemanticsLegal))==0)) { + fprintf(file,"xkb_semantics \"%s\" {\n",name); + } + else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&& + ((complete&(~XkmLayoutLegal))==0)) { + fprintf(file,"xkb_layout \"%s\" {\n",name); + } + else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) { + multi_section= 0; + } + else { + return False; + } + + wantNames= complete&(~(wantConfig|wantDflts)); + name= names->keycodes; + if (wantConfig&XkmKeyNamesMask) + XkbWriteXKBKeycodes(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmKeyNamesMask) + fprintf(stderr,"Default symbols not implemented yet!\n"); + else if (wantNames&XkmKeyNamesMask) + XkbWriteSectionFromName(file,"keycodes",name); + + name= names->types; + if (wantConfig&XkmTypesMask) + XkbWriteXKBKeyTypes(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmTypesMask) + fprintf(stderr,"Default types not implemented yet!\n"); + else if (wantNames&XkmTypesMask) + XkbWriteSectionFromName(file,"types",name); + + name= names->compat; + if (wantConfig&XkmCompatMapMask) + XkbWriteXKBCompatMap(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmCompatMapMask) + fprintf(stderr,"Default interps not implemented yet!\n"); + else if (wantNames&XkmCompatMapMask) + XkbWriteSectionFromName(file,"compatibility",name); + + name= names->symbols; + if (wantConfig&XkmSymbolsMask) + XkbWriteXKBSymbols(file,&finfo,False,False,_AddIncl,name); + else if (wantNames&XkmSymbolsMask) + XkbWriteSectionFromName(file,"symbols",name); + + name= names->geometry; + if (wantConfig&XkmGeometryMask) + XkbWriteXKBGeometry(file,&finfo,False,False,_AddIncl,name); + else if (wantNames&XkmGeometryMask) + XkbWriteSectionFromName(file,"geometry",name); + + if (multi_section) + fprintf(file,"};\n"); + return True; +} + +/***====================================================================***/ + +/*ARGSUSED*/ +Status +XkbMergeFile(XkbDescPtr xkb,XkbFileInfo finfo) +{ + return BadImplementation; +} + +/***====================================================================***/ + +int +XkbFindKeycodeByName(XkbDescPtr xkb,char *name,Bool use_aliases) +{ +register int i; + + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) + return 0; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (strncmp(xkb->names->keys[i].name,name,XkbKeyNameLength)==0) + return i; + } + if (!use_aliases) + return 0; + if (xkb->geom && xkb->geom->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->geom->key_aliases; + for (i=0;i<xkb->geom->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) + return XkbFindKeycodeByName(xkb,a->real,False); + } + } + if (xkb->names && xkb->names->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->names->key_aliases; + for (i=0;i<xkb->names->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) + return XkbFindKeycodeByName(xkb,a->real,False); + } + } + return 0; +} + + +unsigned +XkbConvertGetByNameComponents(Bool toXkm,unsigned orig) +{ +unsigned rtrn; + + rtrn= 0; + if (toXkm) { + if (orig&XkbGBN_TypesMask) rtrn|= XkmTypesMask; + if (orig&XkbGBN_CompatMapMask) rtrn|= XkmCompatMapMask; + if (orig&XkbGBN_SymbolsMask) rtrn|= XkmSymbolsMask; + if (orig&XkbGBN_IndicatorMapMask) rtrn|= XkmIndicatorsMask; + if (orig&XkbGBN_KeyNamesMask) rtrn|= XkmKeyNamesMask; + if (orig&XkbGBN_GeometryMask) rtrn|= XkmGeometryMask; + } + else { + if (orig&XkmTypesMask) rtrn|= XkbGBN_TypesMask; + if (orig&XkmCompatMapMask) rtrn|= XkbGBN_CompatMapMask; + if (orig&XkmSymbolsMask) rtrn|= XkbGBN_SymbolsMask; + if (orig&XkmIndicatorsMask) rtrn|= XkbGBN_IndicatorMapMask; + if (orig&XkmKeyNamesMask) rtrn|= XkbGBN_KeyNamesMask; + if (orig&XkmGeometryMask) rtrn|= XkbGBN_GeometryMask; + if (orig!=0) rtrn|= XkbGBN_OtherNamesMask; + } + return rtrn; +} + +unsigned +XkbConvertXkbComponents(Bool toXkm,unsigned orig) +{ +unsigned rtrn; + + rtrn= 0; + if (toXkm) { + if (orig&XkbClientMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; + if (orig&XkbServerMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; + if (orig&XkbCompatMapMask) rtrn|= XkmCompatMapMask; + if (orig&XkbIndicatorMapMask) rtrn|= XkmIndicatorsMask; + if (orig&XkbNamesMask) rtrn|= XkmKeyNamesMask; + if (orig&XkbGeometryMask) rtrn|= XkmGeometryMask; + } + else { + if (orig!=0) rtrn|= XkbNamesMask; + if (orig&XkmTypesMask) rtrn|= XkbClientMapMask; + if (orig&XkmCompatMapMask) + rtrn|= XkbCompatMapMask|XkbIndicatorMapMask; + if (orig&XkmSymbolsMask) rtrn|=XkbClientMapMask|XkbServerMapMask; + if (orig&XkmIndicatorsMask) rtrn|= XkbIndicatorMapMask; + if (orig&XkmKeyNamesMask) + rtrn|= XkbNamesMask|XkbIndicatorMapMask; + if (orig&XkmGeometryMask) rtrn|= XkbGeometryMask; + } + return rtrn; +} + +Bool +XkbDetermineFileType(XkbFileInfoPtr finfo,int format,int *opts_missing) +{ +unsigned present; +XkbDescPtr xkb; + + if ((!finfo)||(!finfo->xkb)) + return False; + if (opts_missing) + *opts_missing= 0; + xkb= finfo->xkb; + present= 0; + if ((xkb->names)&&(xkb->names->keys)) present|= XkmKeyNamesMask; + if ((xkb->map)&&(xkb->map->types)) present|= XkmTypesMask; + if (xkb->compat) present|= XkmCompatMapMask; + if ((xkb->map)&&(xkb->map->num_syms>1)) present|= XkmSymbolsMask; + if (xkb->indicators) present|= XkmIndicatorsMask; + if (xkb->geom) present|= XkmGeometryMask; + if (!present) + return False; + else switch (present) { + case XkmKeyNamesMask: + finfo->type= XkmKeyNamesIndex; + finfo->defined= present; + return True; + case XkmTypesMask: + finfo->type= XkmTypesIndex; + finfo->defined= present; + return True; + case XkmCompatMapMask: + finfo->type= XkmCompatMapIndex; + finfo->defined= present; + return True; + case XkmSymbolsMask: + if (format!=XkbXKMFile) { + finfo->type= XkmSymbolsIndex; + finfo->defined= present; + return True; + } + break; + case XkmGeometryMask: + finfo->type= XkmGeometryIndex; + finfo->defined= present; + return True; + } + if ((present&(~XkmSemanticsLegal))==0) { + if ((XkmSemanticsRequired&present)==XkmSemanticsRequired) { + if (opts_missing) + *opts_missing= XkmSemanticsOptional&(~present); + finfo->type= XkmSemanticsFile; + finfo->defined= present; + return True; + } + } + else if ((present&(~XkmLayoutLegal))==0) { + if ((XkmLayoutRequired&present)==XkmLayoutRequired) { + if (opts_missing) + *opts_missing= XkmLayoutOptional&(~present); + finfo->type= XkmLayoutFile; + finfo->defined= present; + return True; + } + } + else if ((present&(~XkmKeymapLegal))==0) { + if ((XkmKeymapRequired&present)==XkmKeymapRequired) { + if (opts_missing) + *opts_missing= XkmKeymapOptional&(~present); + finfo->type= XkmKeymapFile; + finfo->defined= present; + return True; + } + } + return False; +} + +/* all latin-1 alphanumerics, plus parens, slash, minus, underscore and */ +/* wildcards */ + +static unsigned char componentSpecLegal[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83, + 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff +}; + +void +XkbEnsureSafeMapName(char *name) +{ + if (name==NULL) + return; + while (*name!='\0') { + if ((componentSpecLegal[(*name)/8]&(1<<((*name)%8)))==0) + *name= '_'; + name++; + } + return; +} + +/***====================================================================***/ + +#define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/')) + +Bool +XkbNameMatchesPattern(char *name,char *ptrn) +{ + while (ptrn[0]!='\0') { + if (name[0]=='\0') { + if (ptrn[0]=='*') { + ptrn++; + continue; + } + return False; + } + if (ptrn[0]=='?') { + if (UNMATCHABLE(name[0])) + return False; + } + else if (ptrn[0]=='*') { + if ((!UNMATCHABLE(name[0]))&&XkbNameMatchesPattern(name+1,ptrn)) + return True; + return XkbNameMatchesPattern(name,ptrn+1); + } + else if (ptrn[0]!=name[0]) + return False; + name++; + ptrn++; + } + /* if we get here, the pattern is exhausted (-:just like me:-) */ + return (name[0]=='\0'); +} + +#ifdef NEED_STRCASECMP +_X_HIDDEN int +_XkbStrCaseCmp(char *str1,char *str2) +{ + const u_char *us1 = (const u_char *)str1, *us2 = (const u_char *)str2; + + while (tolower(*us1) == tolower(*us2)) { + if (*us1++ == '\0') + return (0); + us2++; + } + + return (tolower(*us1) - tolower(*us2)); +} +#endif diff --git a/libxkbfile/src/xkbout.c b/libxkbfile/src/xkbout.c new file mode 100644 index 000000000..53457f1c1 --- /dev/null +++ b/libxkbfile/src/xkbout.c @@ -0,0 +1,1072 @@ +/* $Xorg: xkbout.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbout.c,v 3.9 2001/10/28 03:32:47 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xfuncs.h> + +#ifndef XKB_IN_SERVER + +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +#else + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/keysym.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "dix.h" +#include <X11/extensions/XKBstr.h> +#define XKBSRV_NEED_FILE_FUNCS 1 +#include <X11/extensions/XKBsrv.h> + +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBfile.h> + +#endif + +#define VMOD_HIDE_VALUE 0 +#define VMOD_SHOW_VALUE 1 +#define VMOD_COMMENT_VALUE 2 + +static Bool +WriteXKBVModDecl(FILE *file,Display *dpy,XkbDescPtr xkb,int showValue) +{ +register int i,nMods; +Atom * vmodNames; + + if (xkb==NULL) + return False; + if (xkb->names!=NULL) + vmodNames= xkb->names->vmods; + else vmodNames= NULL; + + for (i=nMods=0;i<XkbNumVirtualMods;i++) { + if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) { + if (nMods==0) fprintf(file," virtual_modifiers "); + else fprintf(file,","); + fprintf(file,"%s",XkbAtomText(dpy,vmodNames[i],XkbXKBFile)); + if ((showValue!=VMOD_HIDE_VALUE)&& + (xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) { + if (showValue==VMOD_COMMENT_VALUE) { + fprintf(file,"/* = %s */", + XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); + } + else { + fprintf(file,"= %s", + XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); + } + } + nMods++; + } + } + if (nMods>0) + fprintf(file,";\n\n"); + return True; +} + +/***====================================================================***/ + +static Bool +WriteXKBAction(FILE *file,XkbFileInfo *result,XkbAnyAction *action) +{ +XkbDescPtr xkb; +Display * dpy; + + xkb= result->xkb; + dpy= xkb->dpy; + fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)action,XkbXKBFile)); + return True; +} + +/***====================================================================***/ + +Bool +XkbWriteXKBKeycodes( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Atom kcName; +register unsigned i; +XkbDescPtr xkb; +Display * dpy; +char * alternate; + + xkb= result->xkb; + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0); + return False; + } + dpy= xkb->dpy; + kcName= xkb->names->keycodes; + if (kcName!=None) + fprintf(file,"xkb_keycodes \"%s\" {\n", + XkbAtomText(dpy,kcName,XkbXKBFile)); + else fprintf(file,"xkb_keycodes {\n"); + fprintf(file," minimum = %d;\n",xkb->min_key_code); + fprintf(file," maximum = %d;\n",xkb->max_key_code); + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (xkb->names->keys[i].name[0]!='\0') { + if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) + alternate= "alternate "; + else alternate= ""; + fprintf(file," %s%6s = %d;\n",alternate, + XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile), + i); + } + } + if (xkb->indicators!=NULL) { + for (i=0;i<XkbNumIndicators;i++) { + char *type; + if (xkb->indicators->phys_indicators&(1<<i)) + type= " "; + else type= " virtual "; + if (xkb->names->indicators[i]!=None) { + fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1, + XkbAtomText(dpy,xkb->names->indicators[i],XkbXKBFile)); + } + } + } + if (xkb->names->key_aliases!=NULL) { + XkbKeyAliasPtr pAl; + pAl= xkb->names->key_aliases; + for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) { + fprintf(file," alias %6s = %6s;\n", + XkbKeyNameText(pAl->alias,XkbXKBFile), + XkbKeyNameText(pAl->real,XkbXKBFile)); + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmKeyNamesIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +Bool +XkbWriteXKBKeyTypes( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,n; +XkbKeyTypePtr type; +XkbKTMapEntryPtr entry; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { + _XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0); + return False; + } + dpy= xkb->dpy; + if (xkb->map->num_types<XkbNumRequiredTypes) { + _XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0); + return 0; + } + if ((xkb->names==NULL)||(xkb->names->types==None)) + fprintf(file,"xkb_types {\n\n"); + else fprintf(file,"xkb_types \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->types,XkbXKBFile)); + WriteXKBVModDecl(file,dpy,xkb, + (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); + + type= xkb->map->types; + for (i=0;i<xkb->map->num_types;i++,type++) { + fprintf(file," type \"%s\" {\n", + XkbAtomText(dpy,type->name,XkbXKBFile)); + fprintf(file," modifiers= %s;\n", + XkbVModMaskText(dpy,xkb,type->mods.real_mods,type->mods.vmods, + XkbXKBFile)); + entry= type->map; + for (n=0;n<type->map_count;n++,entry++) { + char *str; + str=XkbVModMaskText(dpy,xkb,entry->mods.real_mods,entry->mods.vmods, + XkbXKBFile); + fprintf(file," map[%s]= Level%d;\n",str,entry->level+1); + if ((type->preserve)&&((type->preserve[n].real_mods)|| + (type->preserve[n].vmods))) { + fprintf(file," preserve[%s]= ",str); + fprintf(file,"%s;\n",XkbVModMaskText(dpy,xkb, + type->preserve[n].real_mods, + type->preserve[n].vmods, + XkbXKBFile)); + } + } + if (type->level_names!=NULL) { + Atom *name= type->level_names; + for (n=0;n<type->num_levels;n++,name++) { + if ((*name)==None) + continue; + fprintf(file," level_name[Level%d]= \"%s\";\n",n+1, + XkbAtomText(dpy,*name,XkbXKBFile)); + } + } + fprintf(file," };\n"); + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmTypesIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteXKBIndicatorMap( FILE * file, + XkbFileInfo * result, + Atom name, + XkbIndicatorMapPtr led, + XkbFileAddOnFunc addOn, + void * priv) +{ +XkbDescPtr xkb; +char *tmp; + + xkb= result->xkb; + tmp = XkbAtomGetString(xkb->dpy, name); + fprintf(file," indicator \"%s\" {\n",tmp); + _XkbFree(tmp); + if (led->flags&XkbIM_NoExplicit) + fprintf(file," !allowExplicit;\n"); + if (led->flags&XkbIM_LEDDrivesKB) + fprintf(file," indicatorDrivesKeyboard;\n"); + if (led->which_groups!=0) { + if (led->which_groups!=XkbIM_UseEffective) { + fprintf(file," whichGroupState= %s;\n", + XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile)); + } + fprintf(file," groups= 0x%02x;\n",led->groups); + } + if (led->which_mods!=0) { + if (led->which_mods!=XkbIM_UseEffective) { + fprintf(file," whichModState= %s;\n", + XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile)); + } + fprintf(file," modifiers= %s;\n", + XkbVModMaskText(xkb->dpy,xkb, + led->mods.real_mods,led->mods.vmods, + XkbXKBFile)); + } + if (led->ctrls!=0) { + fprintf(file," controls= %s;\n", + XkbControlsMaskText(led->ctrls,XkbXKBFile)); + } + if (addOn) + (*addOn)(file,result,False,True,XkmIndicatorsIndex,priv); + fprintf(file," };\n"); + return True; +} + +Bool +XkbWriteXKBCompatMap( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i; +XkbSymInterpretPtr interp; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { + _XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0); + return False; + } + dpy= xkb->dpy; + if ((xkb->names==NULL)||(xkb->names->compat==None)) + fprintf(file,"xkb_compatibility {\n\n"); + else fprintf(file,"xkb_compatibility \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->compat,XkbXKBFile)); + WriteXKBVModDecl(file,dpy,xkb, + (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); + + fprintf(file," interpret.useModMapMods= AnyLevel;\n"); + fprintf(file," interpret.repeat= False;\n"); + fprintf(file," interpret.locking= False;\n"); + interp= xkb->compat->sym_interpret; + for (i=0;i<xkb->compat->num_si;i++,interp++) { + fprintf(file," interpret %s+%s(%s) {\n", + ((interp->sym==NoSymbol)?"Any": + XkbKeysymText(interp->sym,XkbXKBFile)), + XkbSIMatchText(interp->match,XkbXKBFile), + XkbModMaskText(interp->mods,XkbXKBFile)); + if (interp->virtual_mod!=XkbNoModifier) { + fprintf(file," virtualModifier= %s;\n", + XkbVModIndexText(dpy,xkb,interp->virtual_mod,XkbXKBFile)); + } + if (interp->match&XkbSI_LevelOneOnly) + fprintf(file," useModMapMods=level1;\n"); + if (interp->flags&XkbSI_LockingKey) + fprintf(file," locking= True;\n"); + if (interp->flags&XkbSI_AutoRepeat) + fprintf(file," repeat= True;\n"); + fprintf(file," action= "); + WriteXKBAction(file,result,&interp->act); + fprintf(file,";\n"); + fprintf(file," };\n"); + } + for (i=0;i<XkbNumKbdGroups;i++) { + XkbModsPtr gc; + + gc= &xkb->compat->groups[i]; + if ((gc->real_mods==0)&&(gc->vmods==0)) + continue; + fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb->dpy,xkb, + gc->real_mods,gc->vmods, + XkbXKBFile)); + } + if (xkb->indicators) { + for (i=0;i<XkbNumIndicators;i++) { + XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; + if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| + (map->which_mods!=0)|| + (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| + (map->ctrls!=0)) { + WriteXKBIndicatorMap(file,result,xkb->names->indicators[i],map, + addOn,priv); + } + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmCompatMapIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +Bool +XkbWriteXKBSymbols( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,tmp; +XkbDescPtr xkb; +XkbClientMapPtr map; +XkbServerMapPtr srv; +Bool showActions; + + xkb= result->xkb; + + if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) { + _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); + return False; + } + if ((!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0); + return False; + } + + map= xkb->map; + srv= xkb->server; + dpy= xkb->dpy; + + if ((xkb->names==NULL)||(xkb->names->symbols==None)) + fprintf(file,"xkb_symbols {\n\n"); + else fprintf(file,"xkb_symbols \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->symbols,XkbXKBFile)); + for (tmp=i=0;i<XkbNumKbdGroups;i++) { + if (xkb->names->groups[i]!=None) { + fprintf(file," name[group%d]=\"%s\";\n",i+1, + XkbAtomText(dpy,xkb->names->groups[i],XkbXKBFile)); + tmp++; + } + } + if (tmp>0) + fprintf(file,"\n"); + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + Bool simple; + if ((int)XkbKeyNumSyms(xkb,i)<1) + continue; + if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) + continue; + simple= True; + fprintf(file," key %6s {", + XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile)); + if (srv->explicit) { + if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)|| + (showImplicit)) { + int typeNdx,g; + Bool multi; + char * comment=" "; + + if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0) + comment= "//"; + multi= False; + typeNdx= XkbKeyKeyTypeIndex(xkb,i,0); + for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) { + if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx) + multi= True; + } + if (multi) { + for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { + typeNdx= XkbKeyKeyTypeIndex(xkb,i,g); + if (srv->explicit[i]&(1<<g)) { + fprintf(file,"\n%s type[group%d]= \"%s\",", + comment,g+1, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + else if (showImplicit) { + fprintf(file,"\n// type[group%d]= \"%s\",",g+1, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + } + } + else { + fprintf(file,"\n%s type= \"%s\",",comment, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + simple= False; + } + if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&& + (xkb->ctrls!=NULL)) { + if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8))) + fprintf(file,"\n repeat= Yes,"); + else fprintf(file,"\n repeat= No,"); + simple= False; + } + if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&& + (xkb->server->vmodmap[i]!=0)) { + if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) { + fprintf(file,"\n virtualMods= %s,", + XkbVModMaskText(dpy,xkb,0, + xkb->server->vmodmap[i], + XkbXKBFile)); + } + else if (showImplicit) { + fprintf(file,"\n// virtualMods= %s,", + XkbVModMaskText(dpy,xkb,0, + xkb->server->vmodmap[i], + XkbXKBFile)); + } + } + } + switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) { + case XkbClampIntoRange: + fprintf(file,"\n groupsClamp,"); + break; + case XkbRedirectIntoRange: + fprintf(file,"\n groupsRedirect= Group%d,", + XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1); + break; + } + if (srv->behaviors!=NULL) { + unsigned type; + type= srv->behaviors[i].type&XkbKB_OpMask; + + if (type!=XkbKB_Default) { + simple= False; + fprintf(file,"\n %s,", + XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile)); + } + } + if ((srv->explicit==NULL) || showImplicit || + ((srv->explicit[i]&XkbExplicitInterpretMask)!=0)) + showActions= XkbKeyHasActions(xkb,i); + else showActions= False; + + if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions) + simple= False; + if (simple) { + KeySym *syms; + unsigned s; + + syms= XkbKeySymsPtr(xkb,i); + fprintf(file," [ "); + for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) { + if (s!=0) + fprintf(file,", "); + fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile)); + } + fprintf(file," ] };\n"); + } + else { + unsigned g,s; + KeySym *syms; + XkbAction *acts; + syms= XkbKeySymsPtr(xkb,i); + acts= XkbKeyActionsPtr(xkb,i); + for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { + if (g!=0) + fprintf(file,","); + fprintf(file,"\n symbols[Group%d]= [ ",g+1); + for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { + if (s!=0) + fprintf(file,", "); + fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile)); + } + fprintf(file," ]"); + syms+= XkbKeyGroupsWidth(xkb,i); + if (showActions) { + fprintf(file,",\n actions[Group%d]= [ ",g+1); + for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { + if (s!=0) + fprintf(file,", "); + WriteXKBAction(file,result,(XkbAnyAction *)&acts[s]); + } + fprintf(file," ]"); + acts+= XkbKeyGroupsWidth(xkb,i); + } + } + fprintf(file,"\n };\n"); + } + } + if (map && map->modmap) { + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (map->modmap[i]!=0) { + register int n,bit; + for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) { + if (map->modmap[i]&bit) { + char buf[5]; + memcpy(buf,xkb->names->keys[i].name,4); + buf[4]= '\0'; + fprintf(file," modifier_map %s { <%s> };\n", + XkbModIndexText(n,XkbXKBFile),buf); + } + } + } + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmSymbolsIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteXKBOutline( FILE * file, + XkbShapePtr shape, + XkbOutlinePtr outline, + int lastRadius, + int first, + int indent) +{ +register int i; +XkbPointPtr pt; +char * iStr; + + fprintf(file,"%s",iStr= XkbIndentText(first)); + if (first!=indent) + iStr= XkbIndentText(indent); + if (outline->corner_radius!=lastRadius) { + fprintf(file,"corner= %s,", + XkbGeomFPText(outline->corner_radius,XkbMessage)); + if (shape!=NULL) { + fprintf(file,"\n%s",iStr); + } + } + if (shape) { + if (outline==shape->approx) + fprintf(file,"approx= "); + else if (outline==shape->primary) + fprintf(file,"primary= "); + } + fprintf(file,"{"); + for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) { + if (i==0) fprintf(file," "); + else if ((i%4)==0) fprintf(file,",\n%s ",iStr); + else fprintf(file,", "); + fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile), + XkbGeomFPText(pt->y,XkbXKBFile)); + } + fprintf(file," }"); + return True; +} + +static Bool +WriteXKBDoodad( FILE * file, + Display * dpy, + unsigned indent, + XkbGeometryPtr geom, + XkbDoodadPtr doodad) +{ +register char * i_str; +XkbShapePtr shape; +XkbColorPtr color; + + i_str= XkbIndentText(indent); + fprintf(file,"%s%s \"%s\" {\n",i_str, + XkbDoodadTypeText(doodad->any.type,XkbMessage), + XkbAtomText(dpy,doodad->any.name,XkbMessage)); + fprintf(file,"%s top= %s;\n",i_str, + XkbGeomFPText(doodad->any.top,XkbXKBFile)); + fprintf(file,"%s left= %s;\n",i_str, + XkbGeomFPText(doodad->any.left,XkbXKBFile)); + fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority); + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + if (doodad->shape.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->shape.angle,XkbXKBFile)); + } + if (doodad->shape.color_ndx!=0) { + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbShapeDoodadColor(geom,&doodad->shape)->spec); + } + shape= XkbShapeDoodadShape(geom,&doodad->shape); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + case XkbTextDoodad: + if (doodad->text.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->text.angle,XkbXKBFile)); + } + if (doodad->text.width!=0) { + fprintf(file,"%s width= %s;\n",i_str, + XkbGeomFPText(doodad->text.width,XkbXKBFile)); + + } + if (doodad->text.height!=0) { + fprintf(file,"%s height= %s;\n",i_str, + XkbGeomFPText(doodad->text.height,XkbXKBFile)); + + } + if (doodad->text.color_ndx!=0) { + color= XkbTextDoodadColor(geom,&doodad->text); + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + } + fprintf(file,"%s XFont= \"%s\";\n",i_str, + XkbStringText(doodad->text.font,XkbXKBFile)); + fprintf(file,"%s text= \"%s\";\n",i_str, + XkbStringText(doodad->text.text,XkbXKBFile)); + break; + case XkbIndicatorDoodad: + shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); + color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator); + fprintf(file,"%s onColor= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator); + fprintf(file,"%s offColor= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + case XkbLogoDoodad: + fprintf(file,"%s logoName= \"%s\";\n",i_str, + XkbStringText(doodad->logo.logo_name,XkbXKBFile)); + if (doodad->shape.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->logo.angle,XkbXKBFile)); + } + if (doodad->shape.color_ndx!=0) { + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbLogoDoodadColor(geom,&doodad->logo)->spec); + } + shape= XkbLogoDoodadShape(geom,&doodad->logo); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + } + fprintf(file,"%s};\n",i_str); + return True; +} + +/*ARGSUSED*/ +static Bool +WriteXKBOverlay( FILE * file, + Display * dpy, + unsigned indent, + XkbGeometryPtr geom, + XkbOverlayPtr ol) +{ +register char * i_str; +int r,k,nOut; +XkbOverlayRowPtr row; +XkbOverlayKeyPtr key; + + i_str= XkbIndentText(indent); + if (ol->name!=None) { + fprintf(file,"%soverlay \"%s\" {\n",i_str, + XkbAtomText(dpy,ol->name,XkbMessage)); + } + else fprintf(file,"%soverlay {\n",i_str); + for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + char *over,*under; + over= XkbKeyNameText(key->over.name,XkbXKBFile); + under= XkbKeyNameText(key->under.name,XkbXKBFile); + if (nOut==0) + fprintf(file,"%s %6s=%6s",i_str,under,over); + else if ((nOut%4)==0) + fprintf(file,",\n%s %6s=%6s",i_str,under,over); + else fprintf(file,", %6s=%6s",under,over); + nOut++; + } + } + fprintf(file,"\n%s};\n",i_str); + return True; +} + +static Bool +WriteXKBSection( FILE * file, + Display * dpy, + XkbSectionPtr s, + XkbGeometryPtr geom) +{ +register int i; +XkbRowPtr row; +int dfltKeyColor = 0; + + fprintf(file," section \"%s\" {\n", + XkbAtomText(dpy,s->name,XkbXKBFile)); + if (s->rows&&(s->rows->num_keys>0)) { + dfltKeyColor= s->rows->keys[0].color_ndx; + fprintf(file," key.color= \"%s\";\n", + XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile)); + } + fprintf(file," priority= %d;\n",s->priority); + fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile)); + fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile)); + fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile)); + fprintf(file," height= %s;\n", + XkbGeomFPText(s->height,XkbXKBFile)); + if (s->angle!=0) { + fprintf(file," angle= %s;\n", + XkbGeomFPText(s->angle,XkbXKBFile)); + } + for (i=0,row=s->rows;row&&i<s->num_rows;i++,row++) { + fprintf(file," row {\n"); + fprintf(file," top= %s;\n", + XkbGeomFPText(row->top,XkbXKBFile)); + fprintf(file," left= %s;\n", + XkbGeomFPText(row->left,XkbXKBFile)); + if (row->vertical) + fprintf(file," vertical;\n"); + if (row->num_keys>0) { + register int k; + register XkbKeyPtr key; + int forceNL=0; + int nThisLine= 0; + fprintf(file," keys {\n"); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + XkbShapePtr shape; + if (key->color_ndx!=dfltKeyColor) + forceNL= 1; + if (k==0) { + fprintf(file," "); + nThisLine= 0; + } + else if (((nThisLine%2)==1)||(forceNL)) { + fprintf(file,",\n "); + forceNL= nThisLine= 0; + } + else { + fprintf(file,", "); + nThisLine++; + } + shape= XkbKeyShape(geom,key); + fprintf(file,"{ %6s, \"%s\", %3s", + XkbKeyNameText(key->name.name,XkbXKBFile), + XkbAtomText(dpy,shape->name,XkbXKBFile), + XkbGeomFPText(key->gap,XkbXKBFile)); + if (key->color_ndx!=dfltKeyColor) { + fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec); + forceNL= 1; + } + fprintf(file," }"); + } + fprintf(file,"\n };\n"); + } + fprintf(file," };\n"); + } + if (s->doodads!=NULL) { + XkbDoodadPtr doodad; + for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) { + WriteXKBDoodad(file,dpy,8,geom,doodad); + } + } + if (s->overlays!=NULL) { + XkbOverlayPtr ol; + for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) { + WriteXKBOverlay(file,dpy,8,geom,ol); + } + } + fprintf(file," }; // End of \"%s\" section\n\n", + XkbAtomText(dpy,s->name,XkbXKBFile)); + return True; +} + +Bool +XkbWriteXKBGeometry( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,n; +XkbDescPtr xkb; +XkbGeometryPtr geom; + + xkb= result->xkb; + if ((!xkb)||(!xkb->geom)) { + _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0); + return False; + } + dpy= xkb->dpy; + geom= xkb->geom; + if (geom->name==None) + fprintf(file,"xkb_geometry {\n\n"); + else fprintf(file,"xkb_geometry \"%s\" {\n\n", + XkbAtomText(dpy,geom->name,XkbXKBFile)); + fprintf(file," width= %s;\n", + XkbGeomFPText(geom->width_mm,XkbXKBFile)); + fprintf(file," height= %s;\n\n", + XkbGeomFPText(geom->height_mm,XkbXKBFile)); + + if (geom->key_aliases!=NULL) { + XkbKeyAliasPtr pAl; + pAl= geom->key_aliases; + for (i=0;i<geom->num_key_aliases;i++,pAl++) { + fprintf(file," alias %6s = %6s;\n", + XkbKeyNameText(pAl->alias,XkbXKBFile), + XkbKeyNameText(pAl->real,XkbXKBFile)); + } + fprintf(file,"\n"); + } + + if (geom->base_color!=NULL) + fprintf(file," baseColor= \"%s\";\n", + XkbStringText(geom->base_color->spec,XkbXKBFile)); + if (geom->label_color!=NULL) + fprintf(file," labelColor= \"%s\";\n", + XkbStringText(geom->label_color->spec,XkbXKBFile)); + if (geom->label_font!=NULL) + fprintf(file," xfont= \"%s\";\n", + XkbStringText(geom->label_font,XkbXKBFile)); + if ((geom->num_colors>0)&&(showImplicit)) { + XkbColorPtr color; + for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) { + fprintf(file,"// color[%d]= \"%s\"\n",i, + XkbStringText(color->spec,XkbXKBFile)); + } + fprintf(file,"\n"); + } + if (geom->num_properties>0) { + XkbPropertyPtr prop; + for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) { + fprintf(file," %s= \"%s\";\n",prop->name, + XkbStringText(prop->value,XkbXKBFile)); + } + fprintf(file,"\n"); + } + if (geom->num_shapes>0) { + XkbShapePtr shape; + XkbOutlinePtr outline; + int lastR; + for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { + lastR=0; + fprintf(file," shape \"%s\" {", + XkbAtomText(dpy,shape->name,XkbXKBFile)); + outline= shape->outlines; + if (shape->num_outlines>1) { + for (n=0;n<shape->num_outlines;n++,outline++) { + if (n==0) fprintf(file,"\n"); + else fprintf(file,",\n"); + WriteXKBOutline(file,shape,outline,lastR,8,8); + lastR= outline->corner_radius; + } + fprintf(file,"\n };\n"); + } + else { + WriteXKBOutline(file,NULL,outline,lastR,1,8); + fprintf(file," };\n"); + } + } + } + if (geom->num_sections>0) { + XkbSectionPtr section; + for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){ + WriteXKBSection(file,dpy,section,geom); + } + } + if (geom->num_doodads>0) { + XkbDoodadPtr doodad; + for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { + WriteXKBDoodad(file,dpy,4,geom,doodad); + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmGeometryIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBSemantics( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; + + fprintf(file,"xkb_semantics {\n"); + ok= XkbWriteXKBKeyTypes(file,result,False,False,addOn,priv); + ok= ok&&XkbWriteXKBCompatMap(file,result,False,False,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBLayout( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + fprintf(file,"xkb_layout {\n"); + ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); + if (xkb->geom) + ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBKeymap( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + fprintf(file,"xkb_keymap {\n"); + ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBCompatMap(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); + if (xkb->geom) + ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +Bool +XkbWriteXKBFile( FILE * out, + XkbFileInfo * result, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok = False; +Bool (*func)( + FILE * /* file */, + XkbFileInfo * /* result */, + Bool /* topLevel */, + Bool /* showImplicit */, + XkbFileAddOnFunc /* addOn */, + void * /* priv */ +) = NULL; + + switch (result->type) { + case XkmSemanticsFile: + func= XkbWriteXKBSemantics; + break; + case XkmLayoutFile: + func= XkbWriteXKBLayout; + break; + case XkmKeymapFile: + func= XkbWriteXKBKeymap; + break; + case XkmTypesIndex: + func= XkbWriteXKBKeyTypes; + break; + case XkmCompatMapIndex: + func= XkbWriteXKBCompatMap; + break; + case XkmSymbolsIndex: + func= XkbWriteXKBSymbols; + break; + case XkmKeyNamesIndex: + func= XkbWriteXKBKeycodes; + break; + case XkmGeometryFile: + case XkmGeometryIndex: + func= XkbWriteXKBGeometry; + break; + case XkmVirtualModsIndex: + case XkmIndicatorsIndex: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(result->type,XkbMessage),0); + return False; + } + if (out==NULL) { + _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXkbFile",0); + ok= False; + } + else if (func) { + ok= (*func)(out,result,True,showImplicit,addOn,priv); + } + return ok; +} diff --git a/libxkbfile/src/xkbtext.c b/libxkbfile/src/xkbtext.c new file mode 100644 index 000000000..577bdb5b6 --- /dev/null +++ b/libxkbfile/src/xkbtext.c @@ -0,0 +1,1442 @@ +/* $Xorg: xkbtext.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbtext.c,v 3.11 2002/12/21 18:49:02 paulo Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include <X11/Xos.h> + +#ifndef XKB_IN_SERVER + +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +#else + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "dix.h" +#include <X11/extensions/XKBstr.h> +#define XKBSRV_NEED_FILE_FUNCS 1 +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBgeom.h> + +#endif + +/***====================================================================***/ + +#define BUFFER_SIZE 512 + +static char textBuffer[BUFFER_SIZE]; +static int tbNext= 0; + +static char * +tbGetBuffer(unsigned size) +{ +char *rtrn; + + if (size>=BUFFER_SIZE) + return NULL; + if ((BUFFER_SIZE-tbNext)<=size) + tbNext= 0; + rtrn= &textBuffer[tbNext]; + tbNext+= size; + return rtrn; +} + +/***====================================================================***/ + +char * +XkbAtomText(Display *dpy,Atom atm,unsigned format) +{ +char *rtrn,*tmp; + + tmp= XkbAtomGetString(dpy,atm); + if (tmp!=NULL) { + int len; + len= strlen(tmp)+1; + if (len>BUFFER_SIZE) + len= BUFFER_SIZE-2; + rtrn= tbGetBuffer(len); + strncpy(rtrn,tmp,len); + rtrn[len]= '\0'; + _XkbFree(tmp); + } + else { + rtrn= tbGetBuffer(1); + rtrn[0]= '\0'; + } + if (format==XkbCFile) { + for (tmp=rtrn;*tmp!='\0';tmp++) { + if ((tmp==rtrn)&&(!isalpha(*tmp))) + *tmp= '_'; + else if (!isalnum(*tmp)) + *tmp= '_'; + } + } + return XkbStringText(rtrn,format); +} + +/***====================================================================***/ + +char * +XkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format) +{ +register int len; +register Atom *vmodNames; +char *rtrn,*tmp; + + if (xkb && xkb->names) + vmodNames= xkb->names->vmods; + else vmodNames= NULL; + + tmp= NULL; + if (ndx>=XkbNumVirtualMods) + tmp= strdup("illegal"); + else if (vmodNames&&(vmodNames[ndx]!=None)) + tmp= XkbAtomGetString(dpy,vmodNames[ndx]); + if (tmp==NULL) { + tmp= (char *)_XkbAlloc(20 * sizeof(char)); + snprintf(tmp,20,"%d",ndx); + } + + len= strlen(tmp)+1; + if (format==XkbCFile) + len+= 4; + if (len>=BUFFER_SIZE) + len= BUFFER_SIZE-1; + rtrn= tbGetBuffer(len); + if (format==XkbCFile) { + snprintf(rtrn, len, "vmod_%s", tmp); + } + else strncpy(rtrn,tmp,len); + _XkbFree(tmp); + return rtrn; +} + +char * +XkbVModMaskText( Display * dpy, + XkbDescPtr xkb, + unsigned modMask, + unsigned mask, + unsigned format) +{ +register int i,bit; +int len; +char *mm,*rtrn; +char *str,buf[BUFFER_SIZE]; + + if ((modMask==0)&&(mask==0)) { + rtrn= tbGetBuffer(5); + if (format==XkbCFile) + sprintf(rtrn,"0"); + else sprintf(rtrn,"none"); + return rtrn; + } + if (modMask!=0) + mm= XkbModMaskText(modMask,format); + else mm= NULL; + + str= buf; + buf[0]= '\0'; + if (mask) { + char *tmp; + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (mask&bit) { + tmp= XkbVModIndexText(dpy,xkb,i,format); + len= strlen(tmp)+1+(str==buf?0:1); + if (format==XkbCFile) + len+= 4; + if ((str-(buf+len))<=BUFFER_SIZE) { + if (str!=buf) { + if (format==XkbCFile) *str++= '|'; + else *str++= '+'; + len--; + } + } + if (format==XkbCFile) + sprintf(str,"%sMask",tmp); + else strcpy(str,tmp); + str= &str[len-1]; + } + } + str= buf; + } + else str= NULL; + if (mm) + len= strlen(mm); + else len= 0; + if (str) + len+= strlen(str)+(mm==NULL?0:1); + if (len>=BUFFER_SIZE) + len= BUFFER_SIZE-1; + rtrn= tbGetBuffer(len+1); + rtrn[0]= '\0'; + + if (mm!=NULL) { + i= strlen(mm); + if (i>len) + i= len; + strcpy(rtrn,mm); + } + else { + i=0; + } + if (str!=NULL) { + if (mm!=NULL) { + if (format==XkbCFile) strcat(rtrn,"|"); + else strcat(rtrn,"+"); + } + strncat(rtrn,str,len-i); + } + rtrn[len]= '\0'; + return rtrn; +} + +static char *modNames[XkbNumModifiers] = { + "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5" +}; + +char * +XkbModIndexText(unsigned ndx,unsigned format) +{ +char * rtrn; +char buf[100]; + + if (format==XkbCFile) { + if (ndx<XkbNumModifiers) + sprintf(buf,"%sMapIndex",modNames[ndx]); + else if (ndx==XkbNoModifier) + sprintf(buf,"XkbNoModifier"); + else sprintf(buf,"0x%02x",ndx); + } + else { + if (ndx<XkbNumModifiers) + strcpy(buf,modNames[ndx]); + else if (ndx==XkbNoModifier) + strcpy(buf,"none"); + else sprintf(buf,"ILLEGAL_%02x",ndx); + } + rtrn= tbGetBuffer(strlen(buf)+1); + strcpy(rtrn,buf); + return rtrn; +} + +char * +XkbModMaskText(unsigned mask,unsigned format) +{ +register int i,bit; +char buf[64],*rtrn; + + if ((mask&0xff)==0xff) { + if (format==XkbCFile) strcpy(buf,"0xff"); + else strcpy(buf,"all"); + } + else if ((mask&0xff)==0) { + if (format==XkbCFile) strcpy(buf,"0"); + else strcpy(buf,"none"); + } + else { + char *str= buf; + buf[0]= '\0'; + for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { + if (mask&bit) { + if (str!=buf) { + if (format==XkbCFile) *str++= '|'; + else *str++= '+'; + } + strcpy(str,modNames[i]); + str= &str[strlen(str)]; + if (format==XkbCFile) { + strcpy(str,"Mask"); + str+= 4; + } + } + } + } + rtrn= tbGetBuffer(strlen(buf)+1); + strcpy(rtrn,buf); + return rtrn; +} + +/***====================================================================***/ + +/*ARGSUSED*/ +char * +XkbConfigText(unsigned config,unsigned format) +{ +static char *buf; + + buf= tbGetBuffer(32); + switch (config) { + case XkmSemanticsFile: + strcpy(buf,"Semantics"); + break; + case XkmLayoutFile: + strcpy(buf,"Layout"); + break; + case XkmKeymapFile: + strcpy(buf,"Keymap"); + break; + case XkmGeometryFile: + case XkmGeometryIndex: + strcpy(buf,"Geometry"); + break; + case XkmTypesIndex: + strcpy(buf,"Types"); + break; + case XkmCompatMapIndex: + strcpy(buf,"CompatMap"); + break; + case XkmSymbolsIndex: + strcpy(buf,"Symbols"); + break; + case XkmIndicatorsIndex: + strcpy(buf,"Indicators"); + break; + case XkmKeyNamesIndex: + strcpy(buf,"KeyNames"); + break; + case XkmVirtualModsIndex: + strcpy(buf,"VirtualMods"); + break; + default: + sprintf(buf,"unknown(%d)",config); + break; + } + return buf; +} + +/***====================================================================***/ + +char * +XkbKeysymText(KeySym sym,unsigned format) +{ +static char buf[32],*rtrn; + +#ifndef XKB_IN_SERVER + if (sym==NoSymbol) + strcpy(rtrn=buf,"NoSymbol"); + else if ((rtrn=XKeysymToString(sym))==NULL) + sprintf(rtrn=buf, "0x%lx", (long)sym); + else if (format==XkbCFile) { + sprintf(buf,"XK_%s",rtrn); + rtrn= buf; + } + return rtrn; +#else /* def XKB_IN_SERVER */ + if (sym==NoSymbol) + strcpy(rtrn=buf,"NoSymbol"); + else sprintf(rtrn=buf, "0x%lx", (long)sym); + return rtrn; +#endif /* XKB_IN_SERVER */ +} + +char * +XkbKeyNameText(char *name,unsigned format) +{ +char *buf; + + if (format==XkbCFile) { + buf= tbGetBuffer(5); + memcpy(buf,name,4); + buf[4]= '\0'; + } + else { + int len; + buf= tbGetBuffer(7); + buf[0]= '<'; + memcpy(&buf[1],name,4); + buf[5]= '\0'; + len= strlen(buf); + buf[len++]= '>'; + buf[len]= '\0'; + } + return buf; +} + +/***====================================================================***/ + +static char *siMatchText[5] = { + "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly" +}; + +char * +XkbSIMatchText(unsigned type,unsigned format) +{ +static char buf[40]; +char *rtrn; + + switch (type&XkbSI_OpMask) { + case XkbSI_NoneOf: rtrn= siMatchText[0]; break; + case XkbSI_AnyOfOrNone: rtrn= siMatchText[1]; break; + case XkbSI_AnyOf: rtrn= siMatchText[2]; break; + case XkbSI_AllOf: rtrn= siMatchText[3]; break; + case XkbSI_Exactly: rtrn= siMatchText[4]; break; + default: sprintf(buf,"0x%x",type&XkbSI_OpMask); + return buf; + } + if (format==XkbCFile) { + if (type&XkbSI_LevelOneOnly) + sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn); + else sprintf(buf,"XkbSI_%s",rtrn); + rtrn= buf; + } + return rtrn; +} + +/***====================================================================***/ + +static char *imWhichNames[]= { + "base", + "latched", + "locked", + "effective", + "compat" +}; + +char * +XkbIMWhichStateMaskText(unsigned use_which,unsigned format) +{ +int len; +unsigned i,bit,tmp; +char * buf; + + if (use_which==0) { + buf= tbGetBuffer(2); + strcpy(buf,"0"); + return buf; + } + tmp= use_which&XkbIM_UseAnyMods; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + len+= strlen(imWhichNames[i])+1; + if (format==XkbCFile) + len+= 9; + } + } + buf= tbGetBuffer(len+1); + tmp= use_which&XkbIM_UseAnyMods; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + if (format==XkbCFile) { + if (len!=0) + buf[len++]= '|'; + sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]); + buf[len+9]= toupper(buf[len+9]); + } + else { + if (len!=0) + buf[len++]= '+'; + sprintf(&buf[len],"%s",imWhichNames[i]); + } + len+= strlen(&buf[len]); + } + } + return buf; +} + +char * +XkbAccessXDetailText(unsigned state,unsigned format) +{ +char *buf,*prefix; + + buf= tbGetBuffer(32); + if (format==XkbMessage) prefix= ""; + else prefix= "XkbAXN_"; + switch (state){ + case XkbAXN_SKPress: sprintf(buf,"%sSKPress",prefix); break; + case XkbAXN_SKAccept: sprintf(buf,"%sSKAccept",prefix); break; + case XkbAXN_SKRelease: sprintf(buf,"%sSKRelease",prefix); break; + case XkbAXN_SKReject: sprintf(buf,"%sSKReject",prefix); break; + case XkbAXN_BKAccept: sprintf(buf,"%sBKAccept",prefix); break; + case XkbAXN_BKReject: sprintf(buf,"%sBKReject",prefix); break; + case XkbAXN_AXKWarning: sprintf(buf,"%sAXKWarning",prefix); break; + default: sprintf(buf,"ILLEGAL"); break; + } + return buf; +} + +static char *nknNames[] = { + "keycodes", "geometry", "deviceID" +}; +#define NUM_NKN (sizeof(nknNames)/sizeof(char *)) + +char * +XkbNKNDetailMaskText(unsigned detail,unsigned format) +{ +char *buf,*prefix,*suffix; +register int i; +register unsigned bit; +int len,plen,slen; + + + if ((detail&XkbAllNewKeyboardEventsMask)==0) { + char *tmp = ""; + if (format==XkbCFile) tmp= "0"; + else if (format==XkbMessage) tmp= "none"; + buf= tbGetBuffer(strlen(tmp)+1); + strcpy(buf,tmp); + return buf; + } + else if ((detail&XkbAllNewKeyboardEventsMask)==XkbAllNewKeyboardEventsMask){ + char * tmp; + if (format==XkbCFile) tmp= "XkbAllNewKeyboardEventsMask"; + else tmp= "all"; + buf= tbGetBuffer(strlen(tmp)+1); + strcpy(buf,tmp); + return buf; + } + if (format==XkbMessage) { + prefix= ""; + suffix= ""; + slen= plen= 0; + } + else { + prefix= "XkbNKN_"; + plen= 7; + if (format==XkbCFile) + suffix= "Mask"; + else suffix= ""; + slen= strlen(suffix); + } + for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) { + if (detail&bit) { + if (len!=0) len+= 1; /* room for '+' or '|' */ + len+= plen+slen+strlen(nknNames[i]); + } + } + buf= tbGetBuffer(len+1); + buf[0]= '\0'; + for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) { + if (detail&bit) { + if (len!=0) { + if (format==XkbCFile) buf[len++]= '|'; + else buf[len++]= '+'; + } + if (plen) { + strcpy(&buf[len],prefix); + len+= plen; + } + strcpy(&buf[len],nknNames[i]); + len+= strlen(nknNames[i]); + if (slen) { + strcpy(&buf[len],suffix); + len+= slen; + } + } + } + buf[len++]= '\0'; + return buf; +} + +static char *ctrlNames[] = { + "repeatKeys", + "slowKeys", + "bounceKeys", + "stickyKeys", + "mouseKeys", + "mouseKeysAccel", + "accessXKeys", + "accessXTimeout", + "accessXFeedback", + "audibleBell", + "overlay1", + "overlay2", + "ignoreGroupLock" +}; + +char * +XkbControlsMaskText(unsigned ctrls,unsigned format) +{ +int len; +unsigned i,bit,tmp; +char * buf; + + if (ctrls==0) { + buf= tbGetBuffer(5); + if (format==XkbCFile) + strcpy(buf,"0"); + else strcpy(buf,"none"); + return buf; + } + tmp= ctrls&XkbAllBooleanCtrlsMask; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + len+= strlen(ctrlNames[i])+1; + if (format==XkbCFile) + len+= 7; + } + } + buf= tbGetBuffer(len+1); + tmp= ctrls&XkbAllBooleanCtrlsMask; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + if (format==XkbCFile) { + if (len!=0) + buf[len++]= '|'; + sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]); + buf[len+3]= toupper(buf[len+3]); + } + else { + if (len!=0) + buf[len++]= '+'; + sprintf(&buf[len],"%s",ctrlNames[i]); + } + len+= strlen(&buf[len]); + } + } + return buf; +} + +/***====================================================================***/ + +char * +XkbStringText(char *str,unsigned format) +{ +char * buf; +register char *in,*out; +int len; +Bool ok; + + if (str==NULL) { + buf= tbGetBuffer(2); + buf[0]='\0'; + return buf; + } + else if (format==XkbXKMFile) + return str; + for (ok= True,len=0,in=str;*in!='\0';in++,len++) { + if (!isprint(*in)) { + ok= False; + switch (*in) { + case '\n': case '\t': case '\v': + case '\b': case '\r': case '\f': + len++; + break; + default: + len+= 4; + break; + } + } + } + if (ok) + return str; + buf= tbGetBuffer(len+1); + for (in=str,out=buf;*in!='\0';in++) { + if (isprint(*in)) + *out++= *in; + else { + *out++= '\\'; + if (*in=='\n') *out++= 'n'; + else if (*in=='\t') *out++= 't'; + else if (*in=='\v') *out++= 'v'; + else if (*in=='\b') *out++= 'b'; + else if (*in=='\r') *out++= 'r'; + else if (*in=='\f') *out++= 'f'; + else if ((*in=='\033')&&(format==XkbXKMFile)) { + *out++= 'e'; + } + else { + *out++= '0'; + sprintf(out,"%o",*in); + while (*out!='\0') + out++; + } + } + } + *out++= '\0'; + return buf; +} + +/***====================================================================***/ + +char * +XkbGeomFPText(int val,unsigned format) +{ +int whole,frac; +char * buf; + + buf= tbGetBuffer(12); + if (format==XkbCFile) { + sprintf(buf,"%d",val); + } + else { + whole= val/XkbGeomPtsPerMM; + frac= val%XkbGeomPtsPerMM; + if (frac!=0) + sprintf(buf,"%d.%d",whole,frac); + else sprintf(buf,"%d",whole); + } + return buf; +} + +char * +XkbDoodadTypeText(unsigned type,unsigned format) +{ +char * buf; + if (format==XkbCFile) { + buf= tbGetBuffer(24); + if (type==XkbOutlineDoodad) strcpy(buf,"XkbOutlineDoodad"); + else if (type==XkbSolidDoodad) strcpy(buf,"XkbSolidDoodad"); + else if (type==XkbTextDoodad) strcpy(buf,"XkbTextDoodad"); + else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad"); + else if (type==XkbLogoDoodad) strcpy(buf,"XkbLogoDoodad"); + else sprintf(buf,"UnknownDoodad%d",type); + } + else { + buf= tbGetBuffer(12); + if (type==XkbOutlineDoodad) strcpy(buf,"outline"); + else if (type==XkbSolidDoodad) strcpy(buf,"solid"); + else if (type==XkbTextDoodad) strcpy(buf,"text"); + else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator"); + else if (type==XkbLogoDoodad) strcpy(buf,"logo"); + else sprintf(buf,"unknown%d",type); + } + return buf; +} + +static char *actionTypeNames[XkbSA_NumActions]= { + "NoAction", + "SetMods", "LatchMods", "LockMods", + "SetGroup", "LatchGroup", "LockGroup", + "MovePtr", + "PtrBtn", "LockPtrBtn", + "SetPtrDflt", + "ISOLock", + "Terminate", "SwitchScreen", + "SetControls", "LockControls", + "ActionMessage", + "RedirectKey", + "DeviceBtn", "LockDeviceBtn" +}; + +char * +XkbActionTypeText(unsigned type,unsigned format) +{ +static char buf[32]; +char *rtrn; + + if (type<=XkbSA_LastAction) { + rtrn= actionTypeNames[type]; + if (format==XkbCFile) { + sprintf(buf,"XkbSA_%s",rtrn); + return buf; + } + return rtrn; + } + sprintf(buf,"Private"); + return buf; +} + +/***====================================================================***/ + +static int +TryCopyStr(char *to,char *from,int *pLeft) +{ +register int len; + if (*pLeft>0) { + len= strlen(from); + if (len<((*pLeft)-3)) { + strcat(to,from); + *pLeft-= len; + return True; + } + } + *pLeft= -1; + return False; +} + +/*ARGSUSED*/ +static Bool +CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz) +{ + return True; +} + +static Bool +CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int* sz) +{ +XkbModAction * act; +unsigned tmp; + + act= &action->mods; + tmp= XkbModActionVMods(act); + TryCopyStr(buf,"modifiers=",sz); + if (act->flags&XkbSA_UseModMapMods) + TryCopyStr(buf,"modMapMods",sz); + else if (act->real_mods || tmp) { + TryCopyStr(buf, + XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile), + sz); + } + else TryCopyStr(buf,"none",sz); + if (act->type==XkbSA_LockMods) + return True; + if (act->flags&XkbSA_ClearLocks) + TryCopyStr(buf,",clearLocks",sz); + if (act->flags&XkbSA_LatchToLock) + TryCopyStr(buf,",latchToLock",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbGroupAction * act; +char tbuf[32]; + + act= &action->group; + TryCopyStr(buf,"group=",sz); + if (act->flags&XkbSA_GroupAbsolute) + sprintf(tbuf,"%d",XkbSAGroup(act)+1); + else if (XkbSAGroup(act)<0) + sprintf(tbuf,"%d",XkbSAGroup(act)); + else sprintf(tbuf,"+%d",XkbSAGroup(act)); + TryCopyStr(buf,tbuf,sz); + if (act->type==XkbSA_LockGroup) + return True; + if (act->flags&XkbSA_ClearLocks) + TryCopyStr(buf,",clearLocks",sz); + if (act->flags&XkbSA_LatchToLock) + TryCopyStr(buf,",latchToLock",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbPtrAction * act; +int x,y; +char tbuf[32]; + + act= &action->ptr; + x= XkbPtrActionX(act); + y= XkbPtrActionY(act); + if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0)) + sprintf(tbuf,"x=%d",x); + else sprintf(tbuf,"x=+%d",x); + TryCopyStr(buf,tbuf,sz); + + if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0)) + sprintf(tbuf,",y=%d",y); + else sprintf(tbuf,",y=+%d",y); + TryCopyStr(buf,tbuf,sz); + if (act->flags&XkbSA_NoAcceleration) + TryCopyStr(buf,",!accel",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbPtrBtnAction * act; +char tbuf[32]; + + act= &action->btn; + TryCopyStr(buf,"button=",sz); + if ((act->button>0)&&(act->button<6)) { + sprintf(tbuf,"%d",act->button); + TryCopyStr(buf,tbuf,sz); + } + else TryCopyStr(buf,"default",sz); + if (act->count>0) { + sprintf(tbuf,",count=%d",act->count); + TryCopyStr(buf,tbuf,sz); + } + if (action->type==XkbSA_LockPtrBtn) { + switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { + case XkbSA_LockNoLock: + sprintf(tbuf,",affect=unlock"); break; + case XkbSA_LockNoUnlock: + sprintf(tbuf,",affect=lock"); break; + case XkbSA_LockNoUnlock|XkbSA_LockNoLock: + sprintf(tbuf,",affect=neither"); break; + default: + sprintf(tbuf,",affect=both"); break; + } + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbPtrDfltAction * act; +char tbuf[32]; + + act= &action->dflt; + if (act->affect==XkbSA_AffectDfltBtn) { + TryCopyStr(buf,"affect=button,button=",sz); + if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0)) + sprintf(tbuf,"%d",XkbSAPtrDfltValue(act)); + else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act)); + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +static Bool +CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbISOAction * act; +char tbuf[64]; + + act= &action->iso; + if (act->flags&XkbSA_ISODfltIsGroup) { + TryCopyStr(tbuf,"group=",sz); + if (act->flags&XkbSA_GroupAbsolute) + sprintf(tbuf,"%d",XkbSAGroup(act)+1); + else if (XkbSAGroup(act)<0) + sprintf(tbuf,"%d",XkbSAGroup(act)); + else sprintf(tbuf,"+%d",XkbSAGroup(act)); + TryCopyStr(buf,tbuf,sz); + } + else { + unsigned tmp; + tmp= XkbModActionVMods(act); + TryCopyStr(buf,"modifiers=",sz); + if (act->flags&XkbSA_UseModMapMods) + TryCopyStr(buf,"modMapMods",sz); + else if (act->real_mods || tmp) { + if (act->real_mods) { + TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz); + if (tmp) + TryCopyStr(buf,"+",sz); + } + if (tmp) + TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz); + } + else TryCopyStr(buf,"none",sz); + } + TryCopyStr(buf,",affect=",sz); + if ((act->affect&XkbSA_ISOAffectMask)==0) + TryCopyStr(buf,"all",sz); + else { + int nOut= 0; + if ((act->affect&XkbSA_ISONoAffectMods)==0) { + TryCopyStr(buf,"mods",sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectGroup)==0) { + sprintf(tbuf,"%sgroups",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectPtr)==0) { + sprintf(tbuf,"%spointer",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectCtrls)==0) { + sprintf(tbuf,"%scontrols",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbSwitchScreenAction * act; +char tbuf[32]; + + act= &action->screen; + if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0)) + sprintf(tbuf,"screen=%d",XkbSAScreen(act)); + else sprintf(tbuf,"screen=+%d",XkbSAScreen(act)); + TryCopyStr(buf,tbuf,sz); + if (act->flags&XkbSA_SwitchApplication) + TryCopyStr(buf,",!same",sz); + else TryCopyStr(buf,",same",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action, + char *buf,int *sz) +{ +XkbCtrlsAction * act; +unsigned tmp; +char tbuf[32]; + + act= &action->ctrls; + tmp= XkbActionCtrls(act); + TryCopyStr(buf,"controls=",sz); + if (tmp==0) + TryCopyStr(buf,"none",sz); + else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask) + TryCopyStr(buf,"all",sz); + else { + int nOut= 0; + if (tmp&XkbRepeatKeysMask) { + sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbSlowKeysMask) { + sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbBounceKeysMask) { + sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbStickyKeysMask) { + sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbMouseKeysMask) { + sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbMouseKeysAccelMask) { + sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXKeysMask) { + sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXTimeoutMask) { + sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXFeedbackMask) { + sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAudibleBellMask) { + sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbOverlay1Mask) { + sprintf(tbuf,"%sOverlay1",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbOverlay2Mask) { + sprintf(tbuf,"%sOverlay2",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbIgnoreGroupLockMask) { + sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbMessageAction * act; +unsigned all; +char tbuf[32]; + + act= &action->msg; + all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease; + TryCopyStr(buf,"report=",sz); + if ((act->flags&all)==0) + TryCopyStr(buf,"none",sz); + else if ((act->flags&all)==all) + TryCopyStr(buf,"all",sz); + else if (act->flags&XkbSA_MessageOnPress) + TryCopyStr(buf,"KeyPress",sz); + else TryCopyStr(buf,"KeyRelease",sz); + sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz); + return True; +} + +static Bool +CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbRedirectKeyAction * act; +char tbuf[32],*tmp; +unsigned kc; +unsigned vmods,vmods_mask; + + act= &action->redirect; + kc= act->new_key; + vmods= XkbSARedirectVMods(act); + vmods_mask= XkbSARedirectVModsMask(act); + if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) && + (xkb->names->keys[kc].name[0]!='\0')) { + char *kn; + kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); + sprintf(tbuf,"key=%s",kn); + } + else sprintf(tbuf,"key=%d",kc); + TryCopyStr(buf,tbuf,sz); + if ((act->mods_mask==0)&&(vmods_mask==0)) + return True; + if ((act->mods_mask==XkbAllModifiersMask)&& + (vmods_mask==XkbAllVirtualModsMask)) { + tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile); + TryCopyStr(buf,",mods=",sz); + TryCopyStr(buf,tmp,sz); + } + else { + if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) { + tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods, + vmods_mask&vmods,XkbXKBFile); + TryCopyStr(buf,",mods= ",sz); + TryCopyStr(buf,tmp,sz); + } + if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) { + tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods), + vmods_mask&(~vmods),XkbXKBFile); + TryCopyStr(buf,",clearMods= ",sz); + TryCopyStr(buf,tmp,sz); + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbDeviceBtnAction * act; +char tbuf[32]; + + act= &action->devbtn; + sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz); + TryCopyStr(buf,",button=",sz); + sprintf(tbuf,"%d",act->button); + TryCopyStr(buf,tbuf,sz); + if (act->count>0) { + sprintf(tbuf,",count=%d",act->count); + TryCopyStr(buf,tbuf,sz); + } + if (action->type==XkbSA_LockDeviceBtn) { + switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { + case XkbSA_LockNoLock: + sprintf(tbuf,",affect=unlock"); break; + case XkbSA_LockNoUnlock: + sprintf(tbuf,",affect=lock"); break; + case XkbSA_LockNoUnlock|XkbSA_LockNoLock: + sprintf(tbuf,",affect=neither"); break; + default: + sprintf(tbuf,",affect=both"); break; + } + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbAnyAction * act; +char tbuf[32]; + + act= &action->any; + sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz); + return True; +} + +typedef Bool (*actionCopy)( + Display * /* dpy */, + XkbDescPtr /* xkb */, + XkbAction * /* action */, + char * /* buf */, + int* /* sz */ +); +static actionCopy copyActionArgs[XkbSA_NumActions] = { + CopyNoActionArgs /* NoAction */, + CopyModActionArgs /* SetMods */, + CopyModActionArgs /* LatchMods */, + CopyModActionArgs /* LockMods */, + CopyGroupActionArgs /* SetGroup */, + CopyGroupActionArgs /* LatchGroup */, + CopyGroupActionArgs /* LockGroup */, + CopyMovePtrArgs /* MovePtr */, + CopyPtrBtnArgs /* PtrBtn */, + CopyPtrBtnArgs /* LockPtrBtn */, + CopySetPtrDfltArgs /* SetPtrDflt */, + CopyISOLockArgs /* ISOLock */, + CopyNoActionArgs /* Terminate */, + CopySwitchScreenArgs /* SwitchScreen */, + CopySetLockControlsArgs /* SetControls */, + CopySetLockControlsArgs /* LockControls */, + CopyActionMessageArgs /* ActionMessage*/, + CopyRedirectKeyArgs /* RedirectKey */, + CopyDeviceBtnArgs /* DeviceBtn */, + CopyDeviceBtnArgs /* LockDeviceBtn*/ +}; + +#define ACTION_SZ 256 + +char * +XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format) +{ +char buf[ACTION_SZ],*tmp; +int sz; + + if (format==XkbCFile) { + sprintf(buf, + "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }", + XkbActionTypeText(action->type,XkbCFile), + action->any.data[0],action->any.data[1],action->any.data[2], + action->any.data[3],action->any.data[4],action->any.data[5], + action->any.data[6]); + } + else { + sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile)); + sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */ + if (action->type<(unsigned)XkbSA_NumActions) + (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz); + else CopyOtherArgs(dpy,xkb,action,buf,&sz); + TryCopyStr(buf,")",&sz); + } + tmp= tbGetBuffer(strlen(buf)+1); + if (tmp!=NULL) + strcpy(tmp,buf); + return tmp; +} + +char * +XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format) +{ +char buf[256],*tmp; + + if (format==XkbCFile) { + if (behavior->type==XkbKB_Default) + sprintf(buf,"{ 0, 0 }"); + else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data); + } + else { + unsigned type,permanent; + type= behavior->type&XkbKB_OpMask; + permanent=((behavior->type&XkbKB_Permanent)!=0); + + if (type==XkbKB_Lock) { + sprintf(buf,"lock= %s",(permanent?"Permanent":"True")); + } + else if (type==XkbKB_RadioGroup) { + int g; + char *tmp; + g= ((behavior->data)&(~XkbKB_RGAllowNone))+1; + if (XkbKB_RGAllowNone&behavior->data) { + sprintf(buf,"allowNone,"); + tmp= &buf[strlen(buf)]; + } + else tmp= buf; + if (permanent) + sprintf(tmp,"permanentRadioGroup= %d",g); + else sprintf(tmp,"radioGroup= %d",g); + } + else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) { + int ndx,kc; + char *kn; + + ndx= ((type==XkbKB_Overlay1)?1:2); + kc= behavior->data; + if ((xkb)&&(xkb->names)&&(xkb->names->keys)) + kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); + else { + static char tbuf[8]; + sprintf(tbuf,"%d",kc); + kn= tbuf; + } + if (permanent) + sprintf(buf,"permanentOverlay%d= %s",ndx,kn); + else sprintf(buf,"overlay%d= %s",ndx,kn); + } + } + tmp= tbGetBuffer(strlen(buf)+1); + if (tmp!=NULL) + strcpy(tmp,buf); + return tmp; +} + +/***====================================================================***/ + +char * +XkbIndentText(unsigned size) +{ +static char buf[32]; +register int i; + + if (size>31) + size= 31; + + for (i=0;i<size;i++) { + buf[i]= ' '; + } + buf[size]= '\0'; + return buf; +} + +#ifndef XKB_IN_SERVER + +/***====================================================================***/ + +#define PIXEL_MAX 65535 + +Bool +XkbLookupCanonicalRGBColor(char *def,XColor *color) +{ +int tmp; + + if (_XkbStrCaseEqual(def,"black")) { + color->red= color->green= color->blue= 0; + return True; + } + else if (_XkbStrCaseEqual(def,"white")) { + color->red= color->green= color->blue= PIXEL_MAX; + return True; + } + else if ((sscanf(def,"grey%d",&tmp)==1)|| + (sscanf(def,"gray%d",&tmp)==1)|| + (sscanf(def,"Grey%d",&tmp)==1)|| + (sscanf(def,"Gray%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->red= color->green= color->blue= tmp; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"red")*100))|| + (sscanf(def,"red%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->red= tmp; + color->green= color->blue= 0; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"green")*100))|| + (sscanf(def,"green%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->green= tmp; + color->red= color->blue= 0; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"blue")*100))|| + (sscanf(def,"blue%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->blue= tmp; + color->red= color->green= 0; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"magenta")*100))|| + (sscanf(def,"magenta%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->green= 0; + color->red= color->blue= tmp; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"cyan")*100))|| + (sscanf(def,"cyan%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->red= 0; + color->green= color->blue= tmp; + return True; + } + } + else if ((tmp=(_XkbStrCaseEqual(def,"yellow")*100))|| + (sscanf(def,"yellow%d",&tmp)==1)) { + if ((tmp>0)&&(tmp<=100)) { + tmp= (PIXEL_MAX*tmp)/100; + color->blue= 0; + color->red= color->green= tmp; + return True; + } + } + return False; +} + +#endif diff --git a/libxkbfile/src/xkmout.c b/libxkbfile/src/xkmout.c new file mode 100644 index 000000000..403e48810 --- /dev/null +++ b/libxkbfile/src/xkmout.c @@ -0,0 +1,1389 @@ +/* $Xorg: xkmout.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkmout.c,v 1.5 2001/07/25 15:04:58 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xfuncs.h> +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBgeom.h> + +#include "XKMformat.h" +#include "XKBfileInt.h" + +typedef struct _XkmInfo { + unsigned short bound_vmods; + unsigned short named_vmods; + unsigned char num_bound; + unsigned char group_compat; + unsigned short num_group_compat; + unsigned short num_leds; + int total_vmodmaps; +} XkmInfo; + +/***====================================================================***/ + +#define xkmPutCARD8(f,v) (putc(v,f),1) + +static int +xkmPutCARD16(FILE *file,unsigned val) +{ +CARD16 tmp= val; + + fwrite(&tmp,2,1,file); + return 2; +} + +static int +xkmPutCARD32(FILE *file,unsigned long val) +{ +CARD32 tmp= val; + + fwrite(&tmp,4,1,file); + return 4; +} + +static int +xkmPutPadding(FILE *file,unsigned pad) +{ +int i; + for (i=0;i<pad;i++) { + putc('\0',file); + } + return pad; +} + +static int +xkmPutCountedBytes(FILE *file,char *ptr,unsigned count) +{ +register int nOut; +register unsigned pad; + + if (count==0) + return xkmPutCARD32(file,(unsigned long)0); + + xkmPutCARD16(file,count); + nOut= fwrite(ptr,1,count,file); + if (nOut<0) + return 2; + nOut= count+2; + pad= XkbPaddedSize(nOut)-nOut; + if (pad) + xkmPutPadding(file,pad); + return nOut+pad; +} + +static unsigned +xkmSizeCountedString(char *str) +{ + if (str==NULL) + return 4; + return XkbPaddedSize(strlen(str)+2); +} + +static int +xkmPutCountedString(FILE *file,char *str) +{ + if (str==NULL) + return xkmPutCARD32(file,(unsigned long)0); + return xkmPutCountedBytes(file,str,strlen(str)); +} + +#define xkmSizeCountedAtomString(d,a) \ + xkmSizeCountedString(XkbAtomGetString((d),(a))) + +#define xkmPutCountedAtomString(d,f,a) \ + xkmPutCountedString((f),XkbAtomGetString((d),(a))) + +/***====================================================================***/ + +static unsigned +SizeXKMVirtualMods( XkbFileInfo * result, + XkmInfo * info, + xkmSectionInfo * toc, + int * offset_inout) +{ +Display * dpy; +XkbDescPtr xkb; +unsigned nBound,bound; +unsigned nNamed,named,szNames; +register unsigned i,bit; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->names)||(!xkb->server)) { + _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0); + return 0; + } + bound=named=0; + for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (xkb->server->vmods[i]!=XkbNoModifierMask) { + bound|= bit; + nBound++; + } + if (xkb->names->vmods[i]!=None) { + named|= bit; + szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]); + nNamed++; + } + } + info->num_bound= nBound; + info->bound_vmods= bound; + info->named_vmods= named; + if ((nBound==0)&&(nNamed==0)) + return 0; + toc->type= XkmVirtualModsIndex; + toc->format= MSBFirst; + toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo); + toc->offset= *offset_inout; + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info) +{ +register unsigned int i,bit; +XkbDescPtr xkb; +Display * dpy; +unsigned size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + size+= xkmPutCARD16(file,info->bound_vmods); + size+= xkmPutCARD16(file,info->named_vmods); + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (info->bound_vmods&bit) + size+= xkmPutCARD8(file,xkb->server->vmods[i]); + } + if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0) + size+= xkmPutPadding(file,i); + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (info->named_vmods&bit) { + register char *name; + name= XkbAtomGetString(dpy,xkb->names->vmods[i]); + size+= xkmPutCountedString(file,name); + } + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) +{ +XkbDescPtr xkb; +Atom kcName; +int size=0; +Display * dpy; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0); + return 0; + } + kcName= xkb->names->keycodes; + size+= 4; /* min and max keycode */ + size+= xkmSizeCountedAtomString(dpy,kcName); + size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec); + if (xkb->names->num_key_aliases>0) { + if (xkb->names->key_aliases!=NULL) + size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec); + else xkb->names->num_key_aliases= 0; + } + toc->type= XkmKeyNamesIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMKeycodes(FILE *file,XkbFileInfo *result) +{ +XkbDescPtr xkb; +Atom kcName; +char *start; +Display * dpy; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + kcName= xkb->names->keycodes; + start= xkb->names->keys[xkb->min_key_code].name; + + size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName)); + size+= xkmPutCARD8(file,xkb->min_key_code); + size+= xkmPutCARD8(file,xkb->max_key_code); + size+= xkmPutCARD8(file,xkb->names->num_key_aliases); + size+= xkmPutPadding(file,1); + tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file); + size+= tmp*sizeof(XkbKeyNameRec); + if (xkb->names->num_key_aliases>0) { + tmp= fwrite((char *)xkb->names->key_aliases, + sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases, + file); + size+= tmp*sizeof(XkbKeyAliasRec); + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) +{ +register unsigned i,n,size; +XkbKeyTypePtr type; +XkbDescPtr xkb; +Display * dpy; +char * name; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { + _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0); + return 0; + } + if (xkb->map->num_types<XkbNumRequiredTypes) { + _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0); + return 0; + } + if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); + else name= NULL; + size= xkmSizeCountedString(name); + size+= 4; /* room for # of key types + padding */ + for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) { + size+= SIZEOF(xkmKeyTypeDesc); + size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count; + size+= xkmSizeCountedAtomString(dpy,type->name); + if (type->preserve) + size+= SIZEOF(xkmModsDesc)*type->map_count; + if (type->level_names) { + Atom *names; + names= type->level_names; + for (n=0;n<(unsigned)type->num_levels;n++) { + size+= xkmSizeCountedAtomString(dpy,names[n]); + } + } + } + toc->type= XkmTypesIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMKeyTypes(FILE *file,XkbFileInfo *result) +{ +register unsigned i,n; +XkbDescPtr xkb; +XkbKeyTypePtr type; +xkmKeyTypeDesc wire; +XkbKTMapEntryPtr entry; +xkmKTMapEntryDesc wire_entry; +Atom * names; +Display * dpy; +unsigned tmp,size= 0; +char * name; + + xkb= result->xkb; + dpy= xkb->dpy; + if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); + else name= NULL; + size+= xkmPutCountedString(file,name); + size+= xkmPutCARD16(file,xkb->map->num_types); + size+= xkmPutPadding(file,2); + type= xkb->map->types; + for (i=0;i<xkb->map->num_types;i++,type++) { + wire.realMods= type->mods.real_mods; + wire.virtualMods= type->mods.vmods; + wire.numLevels= type->num_levels; + wire.nMapEntries= type->map_count; + wire.preserve= (type->preserve!=NULL); + if (type->level_names!=NULL) + wire.nLevelNames= type->num_levels; + else wire.nLevelNames= 0; + tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file); + size+= tmp*SIZEOF(xkmKeyTypeDesc); + for (n=0,entry= type->map;n<type->map_count;n++,entry++) { + wire_entry.level= entry->level; + wire_entry.realMods= entry->mods.real_mods; + wire_entry.virtualMods= entry->mods.vmods; + tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file); + size+= tmp*SIZEOF(xkmKTMapEntryDesc); + } + size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name)); + if (type->preserve) { + xkmModsDesc p_entry; + XkbModsPtr pre; + for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) { + p_entry.realMods= pre->real_mods; + p_entry.virtualMods= pre->vmods; + tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file); + size+= tmp*SIZEOF(xkmModsDesc); + } + } + if (type->level_names!=NULL) { + names= type->level_names; + for (n=0;n<wire.nLevelNames;n++) { + size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n])); + } + } + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMCompatMap( XkbFileInfo * result, + XkmInfo * info, + xkmSectionInfo * toc, + int * offset_inout) +{ +XkbDescPtr xkb; +char * name; +int size; +register int i; +unsigned groups,nGroups; +Display * dpy; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { + _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0); + return 0; + } + if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); + else name= NULL; + + for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) { + if ((xkb->compat->groups[i].real_mods!=0)|| + (xkb->compat->groups[i].vmods!=0)) { + groups|= (1<<i); + nGroups++; + } + } + info->group_compat= groups; + info->num_group_compat= nGroups; + size= 4; /* room for num_si and group_compat mask */ + size+= xkmSizeCountedString(name); + size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si); + size+= (SIZEOF(xkmModsDesc)*nGroups); + toc->type= XkmCompatMapIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info) +{ +register unsigned i; +char * name; +XkbDescPtr xkb; +XkbSymInterpretPtr interp; +xkmSymInterpretDesc wire; +Display * dpy; +unsigned tmp,size=0; + + xkb= result->xkb; + dpy= xkb->dpy; + if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); + else name= NULL; + size+= xkmPutCountedString(file,name); + size+= xkmPutCARD16(file,xkb->compat->num_si); + size+= xkmPutCARD8(file,info->group_compat); + size+= xkmPutPadding(file,1); + interp= xkb->compat->sym_interpret; + for (i=0;i<xkb->compat->num_si;i++,interp++) { + wire.sym= interp->sym; + wire.mods= interp->mods; + wire.match= interp->match; + wire.virtualMod= interp->virtual_mod; + wire.flags= interp->flags; + wire.actionType= interp->act.type; + wire.actionData[0]= interp->act.data[0]; + wire.actionData[1]= interp->act.data[1]; + wire.actionData[2]= interp->act.data[2]; + wire.actionData[3]= interp->act.data[3]; + wire.actionData[4]= interp->act.data[4]; + wire.actionData[5]= interp->act.data[5]; + wire.actionData[6]= interp->act.data[6]; + tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file); + size+= tmp*SIZEOF(xkmSymInterpretDesc); + } + if (info->group_compat) { + register unsigned bit; + xkmModsDesc modsWire; + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if (info->group_compat&bit) { + modsWire.realMods= xkb->compat->groups[i].real_mods; + modsWire.virtualMods= xkb->compat->groups[i].vmods; + fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file); + size+= SIZEOF(xkmModsDesc); + } + } + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMSymbols( XkbFileInfo * result, + XkmInfo * info, + xkmSectionInfo * toc, + int * offset_inout) +{ +Display * dpy; +XkbDescPtr xkb; +unsigned size; +register int i,nSyms; +char * name; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) { + _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0); + return 0; + } + if (xkb->names && (xkb->names->symbols!=None)) + name= XkbAtomGetString(dpy,xkb->names->symbols); + else name= NULL; + size= xkmSizeCountedString(name); + size+= 4; /* min and max keycode, group names mask */ + for (i=0;i<XkbNumKbdGroups;i++) { + if (xkb->names->groups[i]!=None) + size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]); + } + info->total_vmodmaps= 0; + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + nSyms= XkbKeyNumSyms(xkb,i); + size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4); + if (xkb->server) { + if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { + register int g; + for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { + if (xkb->server->explicit[i]&(1<<g)) { + XkbKeyTypePtr type; + char * name; + type= XkbKeyKeyType(xkb,i,g); + name= XkbAtomGetString(dpy,type->name); + if (name!=NULL) + size+= xkmSizeCountedString(name); + } + } + } + if (XkbKeyHasActions(xkb,i)) + size+= nSyms*SIZEOF(xkmActionDesc); + if (xkb->server->behaviors[i].type!=XkbKB_Default) + size+= SIZEOF(xkmBehaviorDesc); + if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0)) + info->total_vmodmaps++; + } + } + size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc); + toc->type= XkmSymbolsIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info) +{ +Display * dpy; +XkbDescPtr xkb; +register int i,n; +xkmKeySymMapDesc wireMap; +char * name; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + if (xkb->names && (xkb->names->symbols!=None)) + name= XkbAtomGetString(dpy,xkb->names->symbols); + else name= NULL; + size+= xkmPutCountedString(file,name); + for (tmp=i=0;i<XkbNumKbdGroups;i++) { + if (xkb->names->groups[i]!=None) + tmp|= (1<<i); + } + size+= xkmPutCARD8(file,xkb->min_key_code); + size+= xkmPutCARD8(file,xkb->max_key_code); + size+= xkmPutCARD8(file,tmp); + size+= xkmPutCARD8(file,info->total_vmodmaps); + for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) { + if ((tmp&n)==0) + continue; + size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]); + } + for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { + char *typeName[XkbNumKbdGroups]; + wireMap.width= XkbKeyGroupsWidth(xkb,i); + wireMap.num_groups= XkbKeyGroupInfo(xkb,i); + if (xkb->map && xkb->map->modmap) + wireMap.modifier_map= xkb->map->modmap[i]; + else wireMap.modifier_map= 0; + wireMap.flags= 0; + bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *)); + if (xkb->server) { + if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { + register int g; + for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { + if (xkb->server->explicit[i]&(1<<g)) { + XkbKeyTypePtr type; + type= XkbKeyKeyType(xkb,i,g); + typeName[g]= XkbAtomGetString(dpy,type->name); + if (typeName[g]!=NULL) + wireMap.flags|= (1<<g); + } + } + } + if (XkbKeyHasActions(xkb,i)) + wireMap.flags|= XkmKeyHasActions; + if (xkb->server->behaviors[i].type!=XkbKB_Default) + wireMap.flags|= XkmKeyHasBehavior; + if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&& + (xkb->ctrls!=NULL)) { + if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8))) + wireMap.flags|= XkmRepeatingKey; + else wireMap.flags|= XkmNonRepeatingKey; + } + } + tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file); + size+= tmp*SIZEOF(xkmKeySymMapDesc); + if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { + register int g; + for (g=0;g<XkbNumKbdGroups;g++) { + if (typeName[g]!=NULL) + size+= xkmPutCountedString(file,typeName[g]); + } + } + if (XkbNumGroups(wireMap.num_groups)>0) { + KeySym *sym; + sym= XkbKeySymsPtr(xkb,i); + for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) { + size+= xkmPutCARD32(file,(CARD32)*sym); + } + if (wireMap.flags&XkmKeyHasActions) { + XkbAction * act; + act= XkbKeyActionsPtr(xkb,i); + for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) { + tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file); + size+= tmp*SIZEOF(xkmActionDesc); + } + } + } + if (wireMap.flags&XkmKeyHasBehavior) { + xkmBehaviorDesc b; + b.type= xkb->server->behaviors[i].type; + b.data= xkb->server->behaviors[i].data; + tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file); + size+= tmp*SIZEOF(xkmBehaviorDesc); + } + } + if (info->total_vmodmaps>0) { + xkmVModMapDesc v; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (xkb->server->vmodmap[i]!=0) { + v.key= i; + v.vmods= xkb->server->vmodmap[i]; + tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file); + size+= tmp*SIZEOF(xkmVModMapDesc); + } + } + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc, + int *offset_inout) +{ +Display * dpy; +XkbDescPtr xkb; +unsigned size; +register unsigned i,nLEDs; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((xkb==NULL)||(xkb->indicators==NULL)) { +/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/ + return 0; + } + nLEDs=0; + size= 8; /* number of indicator maps/physical indicators */ + if (xkb->indicators!=NULL) { + for (i=0;i<XkbNumIndicators;i++) { + XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; + if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| + (map->which_mods!=0)|| + (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| + (map->ctrls!=0) || + (xkb->names && (xkb->names->indicators[i]!=None))) { + char *name; + if (xkb->names && xkb->names->indicators[i]!=None) { + name= XkbAtomGetString(dpy,xkb->names->indicators[i]); + } + else name= NULL; + size+= xkmSizeCountedString(name); + size+= SIZEOF(xkmIndicatorMapDesc); + nLEDs++; + } + } + } + info->num_leds= nLEDs; + toc->type= XkmIndicatorsIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info) +{ +Display * dpy; +XkbDescPtr xkb; +register unsigned i; +xkmIndicatorMapDesc wire; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + size+= xkmPutCARD8(file,info->num_leds); + size+= xkmPutPadding(file,3); + size+= xkmPutCARD32(file,xkb->indicators->phys_indicators); + if (xkb->indicators!=NULL) { + for (i=0;i<XkbNumIndicators;i++) { + XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; + if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| + (map->which_mods!=0)|| + (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| + (map->ctrls!=0) || + (xkb->names && (xkb->names->indicators[i]!=None))) { + char *name; + if (xkb->names && xkb->names->indicators[i]!=None) { + name= XkbAtomGetString(dpy,xkb->names->indicators[i]); + } + else name= NULL; + size+= xkmPutCountedString(file,name); + wire.indicator= i+1; + wire.flags= map->flags; + wire.which_mods= map->which_mods; + wire.real_mods= map->mods.real_mods; + wire.vmods= map->mods.vmods; + wire.which_groups= map->which_groups; + wire.groups= map->groups; + wire.ctrls= map->ctrls; + tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file); + size+= tmp*SIZEOF(xkmIndicatorMapDesc); + } + } + } + return size; +} + +/***====================================================================***/ + +static unsigned +SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad) +{ +unsigned size; + + size= SIZEOF(xkmAnyDoodadDesc); + size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name); + if (doodad->any.type==XkbTextDoodad) { + size+= xkmSizeCountedString(doodad->text.text); + size+= xkmSizeCountedString(doodad->text.font); + } + else if (doodad->any.type==XkbLogoDoodad) { + size+= xkmSizeCountedString(doodad->logo.logo_name); + } + return size; +} + +static unsigned +SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section) +{ +register int i; +unsigned size; + + size= SIZEOF(xkmSectionDesc); + size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name); + if (section->rows) { + XkbRowPtr row; + for (row=section->rows,i=0;i<section->num_rows;i++,row++) { + size+= SIZEOF(xkmRowDesc); + size+= row->num_keys*SIZEOF(xkmKeyDesc); + } + } + if (section->doodads) { + XkbDoodadPtr doodad; + for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) { + size+= SizeXKMGeomDoodad(result,doodad); + } + } + if (section->overlays) { + XkbOverlayPtr ol; + for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) { + register int r; + XkbOverlayRowPtr row; + size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name); + size+= SIZEOF(xkmOverlayDesc); + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + size+= SIZEOF(xkmOverlayRowDesc); + size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc); + } + } + } + return size; +} + +static unsigned +SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) +{ +register int i; +Display * dpy; +XkbDescPtr xkb; +XkbGeometryPtr geom; +unsigned size; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->geom)) + return 0; + geom= xkb->geom; + size= xkmSizeCountedAtomString(dpy,geom->name); + size+= SIZEOF(xkmGeometryDesc); + size+= xkmSizeCountedString(geom->label_font); + if (geom->properties) { + XkbPropertyPtr prop; + for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { + size+= xkmSizeCountedString(prop->name); + size+= xkmSizeCountedString(prop->value); + } + } + if (geom->colors) { + XkbColorPtr color; + for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { + size+= xkmSizeCountedString(color->spec); + } + } + if (geom->shapes) { + XkbShapePtr shape; + for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { + register int n; + register XkbOutlinePtr ol; + size+= xkmSizeCountedAtomString(dpy,shape->name); + size+= SIZEOF(xkmShapeDesc); + for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { + size+= SIZEOF(xkmOutlineDesc); + size+= ol->num_points*SIZEOF(xkmPointDesc); + } + } + } + if (geom->sections) { + XkbSectionPtr section; + for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { + size+= SizeXKMGeomSection(result,section); + } + } + if (geom->doodads) { + XkbDoodadPtr doodad; + for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { + size+= SizeXKMGeomDoodad(result,doodad); + } + } + if (geom->key_aliases) { + size+= geom->num_key_aliases*(XkbKeyNameLength*2); + } + toc->type= XkmGeometryIndex; + toc->format= MSBFirst; + toc->size= size+SIZEOF(xkmSectionInfo); + toc->offset= (*offset_inout); + (*offset_inout)+= toc->size; + return 1; +} + +static unsigned +WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad) +{ +Display * dpy; +XkbDescPtr xkb; +xkmDoodadDesc doodadWire; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + bzero((char *)&doodadWire,sizeof(doodadWire)); + doodadWire.any.type= doodad->any.type; + doodadWire.any.priority= doodad->any.priority; + doodadWire.any.top= doodad->any.top; + doodadWire.any.left= doodad->any.left; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodadWire.shape.angle= doodad->shape.angle; + doodadWire.shape.color_ndx= doodad->shape.color_ndx; + doodadWire.shape.shape_ndx= doodad->shape.shape_ndx; + break; + case XkbTextDoodad: + doodadWire.text.angle= doodad->text.angle; + doodadWire.text.width= doodad->text.width; + doodadWire.text.height= doodad->text.height; + doodadWire.text.color_ndx= doodad->text.color_ndx; + break; + case XkbIndicatorDoodad: + doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx; + doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx; + doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx; + break; + case XkbLogoDoodad: + doodadWire.logo.angle= doodad->logo.angle; + doodadWire.logo.color_ndx= doodad->logo.color_ndx; + doodadWire.logo.shape_ndx= doodad->logo.shape_ndx; + break; + default: + _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad", + doodad->any.type); + return 0; + } + size+= xkmPutCountedAtomString(dpy,file,doodad->any.name); + tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); + size+= tmp*SIZEOF(xkmDoodadDesc); + if (doodad->any.type==XkbTextDoodad) { + size+= xkmPutCountedString(file,doodad->text.text); + size+= xkmPutCountedString(file,doodad->text.font); + } + else if (doodad->any.type==XkbLogoDoodad) { + size+= xkmPutCountedString(file,doodad->logo.logo_name); + } + return size; +} + +static unsigned +WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol) +{ +register int r,k; +Display * dpy; +XkbDescPtr xkb; +XkbOverlayRowPtr row; +xkmOverlayDesc olWire; +xkmOverlayRowDesc rowWire; +xkmOverlayKeyDesc keyWire; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + bzero((char *)&olWire,sizeof(olWire)); + bzero((char *)&rowWire,sizeof(rowWire)); + bzero((char *)&keyWire,sizeof(keyWire)); + size+= xkmPutCountedAtomString(dpy,file,ol->name); + olWire.num_rows= ol->num_rows; + tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file); + size+= tmp*SIZEOF(xkmOverlayDesc); + for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + XkbOverlayKeyPtr key; + rowWire.row_under= row->row_under; + rowWire.num_keys= row->num_keys; + tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); + size+= tmp*SIZEOF(xkmOverlayRowDesc); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + memcpy(keyWire.over,key->over.name,XkbKeyNameLength); + memcpy(keyWire.under,key->under.name,XkbKeyNameLength); + tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); + size+= tmp*SIZEOF(xkmOverlayKeyDesc); + } + } + return size; +} + +static unsigned +WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section) +{ +register int i; +Display * dpy; +XkbDescPtr xkb; +xkmSectionDesc sectionWire; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + size+= xkmPutCountedAtomString(dpy,file,section->name); + sectionWire.top= section->top; + sectionWire.left= section->left; + sectionWire.width= section->width; + sectionWire.height= section->height; + sectionWire.angle= section->angle; + sectionWire.priority= section->priority; + sectionWire.num_rows= section->num_rows; + sectionWire.num_doodads= section->num_doodads; + sectionWire.num_overlays= section->num_overlays; + tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file); + size+= tmp*SIZEOF(xkmSectionDesc); + if (section->rows) { + register unsigned k; + XkbRowPtr row; + xkmRowDesc rowWire; + XkbKeyPtr key; + xkmKeyDesc keyWire; + for (i=0,row=section->rows;i<section->num_rows;i++,row++) { + rowWire.top= row->top; + rowWire.left= row->left; + rowWire.num_keys= row->num_keys; + rowWire.vertical= row->vertical; + tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file); + size+= tmp*SIZEOF(xkmRowDesc); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + memcpy(keyWire.name,key->name.name,XkbKeyNameLength); + keyWire.gap= key->gap; + keyWire.shape_ndx= key->shape_ndx; + keyWire.color_ndx= key->color_ndx; + tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file); + size+= tmp*SIZEOF(xkmKeyDesc); + } + } + } + if (section->doodads) { + XkbDoodadPtr doodad; + for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { + size+= WriteXKMGeomDoodad(file,result,doodad); + } + } + if (section->overlays) { + XkbOverlayPtr ol; + for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) { + size+= WriteXKMGeomOverlay(file,result,ol); + } + } + return size; +} + +static unsigned +WriteXKMGeometry(FILE *file,XkbFileInfo *result) +{ +register int i; +Display * dpy; +XkbDescPtr xkb; +XkbGeometryPtr geom; +xkmGeometryDesc wire; +unsigned tmp,size= 0; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->geom)) + return 0; + geom= xkb->geom; + wire.width_mm= geom->width_mm; + wire.height_mm= geom->height_mm; + wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color); + wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color); + wire.num_properties= geom->num_properties; + wire.num_colors= geom->num_colors; + wire.num_shapes= geom->num_shapes; + wire.num_sections= geom->num_sections; + wire.num_doodads= geom->num_doodads; + wire.num_key_aliases= geom->num_key_aliases; + size+= xkmPutCountedAtomString(dpy,file,geom->name); + tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file); + size+= tmp*SIZEOF(xkmGeometryDesc); + size+= xkmPutCountedString(file,geom->label_font); + if (geom->properties) { + XkbPropertyPtr prop; + for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { + size+= xkmPutCountedString(file,prop->name); + size+= xkmPutCountedString(file,prop->value); + } + } + if (geom->colors) { + XkbColorPtr color; + for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { + size+= xkmPutCountedString(file,color->spec); + } + } + if (geom->shapes) { + XkbShapePtr shape; + xkmShapeDesc shapeWire; + + for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { + register int n; + XkbOutlinePtr ol; + xkmOutlineDesc olWire; + bzero((char *)&shapeWire,sizeof(xkmShapeDesc)); + size+= xkmPutCountedAtomString(dpy,file,shape->name); + shapeWire.num_outlines= shape->num_outlines; + if (shape->primary!=NULL) + shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary); + else shapeWire.primary_ndx= XkbNoShape; + if (shape->approx!=NULL) + shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx); + else shapeWire.approx_ndx= XkbNoShape; + tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file); + size+= tmp*SIZEOF(xkmShapeDesc); + for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { + register int p; + XkbPointPtr pt; + xkmPointDesc ptWire; + olWire.num_points= ol->num_points; + olWire.corner_radius= ol->corner_radius; + tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file); + size+= tmp*SIZEOF(xkmOutlineDesc); + for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { + ptWire.x= pt->x; + ptWire.y= pt->y; + tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file); + size+= tmp*SIZEOF(xkmPointDesc); + } + } + } + } + if (geom->sections) { + XkbSectionPtr section; + for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { + size+= WriteXKMGeomSection(file,result,section); + } + } + if (geom->doodads) { + XkbDoodadPtr doodad; + for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { + size+= WriteXKMGeomDoodad(file,result,doodad); + } + } + if (geom->key_aliases) { + tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases, + file); + size+= tmp*(2*XkbKeyNameLength); + } + return size; +} + +/***====================================================================***/ + +/*ARGSUSED*/ +static int +GetXKMKeyNamesTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMTypesTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMCompatMapTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMSemanticsTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMLayoutTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMKeymapTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) + num_toc++; + if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +/*ARGSUSED*/ +static int +GetXKMGeometryTOC( XkbFileInfo * result, + XkmInfo * info, + int max_toc, + xkmSectionInfo *toc_rtrn) +{ +int num_toc; +int total_size; + + total_size= num_toc=0; + if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) + num_toc++; + return num_toc; +} + +static Bool +WriteXKMFile( FILE * file, + XkbFileInfo * result, + int num_toc, + xkmSectionInfo *toc, + XkmInfo * info) +{ +register int i; +unsigned tmp,size,total= 0; + + for (i=0;i<num_toc;i++) { + tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file); + total+= tmp*SIZEOF(xkmSectionInfo); + switch (toc[i].type) { + case XkmTypesIndex: + size= WriteXKMKeyTypes(file,result); + break; + case XkmCompatMapIndex: + size= WriteXKMCompatMap(file,result,info); + break; + case XkmSymbolsIndex: + size= WriteXKMSymbols(file,result,info); + break; + case XkmIndicatorsIndex: + size= WriteXKMIndicators(file,result,info); + break; + case XkmKeyNamesIndex: + size= WriteXKMKeycodes(file,result); + break; + case XkmGeometryIndex: + size= WriteXKMGeometry(file,result); + break; + case XkmVirtualModsIndex: + size= WriteXKMVirtualMods(file,result,info); + break; + default: + _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type); + return False; + } + size+= SIZEOF(xkmSectionInfo); + if (size!=toc[i].size) { + _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage), + size-toc[i].size); + return False; + } + } + return True; +} + + +#define MAX_TOC 16 + +Bool +XkbWriteXKMFile(FILE *out,XkbFileInfo *result) +{ +Bool ok; +XkbDescPtr xkb; +XkmInfo info; +int size_toc,i; +unsigned hdr,present; +xkmFileInfo fileInfo; +xkmSectionInfo toc[MAX_TOC]; +int (*getTOC)( + XkbFileInfo * /* result */, + XkmInfo * /* info */, + int /* max_to */, + xkmSectionInfo */* toc_rtrn */ +); + + switch (result->type) { + case XkmKeyNamesIndex: + getTOC= GetXKMKeyNamesTOC; + break; + case XkmTypesIndex: + getTOC= GetXKMTypesTOC; + break; + case XkmCompatMapIndex: + getTOC= GetXKMCompatMapTOC; + break; + case XkmSemanticsFile: + getTOC= GetXKMSemanticsTOC; + break; + case XkmLayoutFile: + getTOC= GetXKMLayoutTOC; + break; + case XkmKeymapFile: + getTOC= GetXKMKeymapTOC; + break; + case XkmGeometryFile: + case XkmGeometryIndex: + getTOC= GetXKMGeometryTOC; + break; + default: + _XkbLibError(_XkbErrIllegalContents, + XkbConfigText(result->type,XkbMessage),0); + return False; + } + xkb= result->xkb; + + bzero((char *)&info,sizeof(XkmInfo)); + size_toc= (*getTOC)(result,&info,MAX_TOC,toc); + if (size_toc<1) { + _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0); + return False; + } + if (out==NULL) { + _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0); + return False; + } + for (i=present=0;i<size_toc;i++) { + toc[i].offset+= 4+SIZEOF(xkmFileInfo); + toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo)); + if (toc[i].type<=XkmLastIndex) { + present|= (1<<toc[i].type); + } +#ifdef DEBUG + else { + fprintf(stderr,"Illegal section type %d\n",toc[i].type); + fprintf(stderr,"Ignored\n"); + } +#endif + } + hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); + xkmPutCARD32(out,(unsigned long)hdr); + fileInfo.type= result->type; + fileInfo.min_kc= xkb->min_key_code; + fileInfo.max_kc= xkb->max_key_code; + fileInfo.num_toc= size_toc; + fileInfo.present= present; + fileInfo.pad= 0; + fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out); + fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out); + ok= WriteXKMFile(out,result,size_toc,toc,&info); + return ok; +} diff --git a/libxkbfile/src/xkmread.c b/libxkbfile/src/xkmread.c new file mode 100644 index 000000000..f22941f67 --- /dev/null +++ b/libxkbfile/src/xkmread.c @@ -0,0 +1,1315 @@ +/* $Xorg: xkmread.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkmread.c,v 1.6 2002/02/13 22:09:42 herrb Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#elif defined(HAVE_CONFIG_H) +#include <config.h> +#endif + +#include <stdio.h> + +#include <X11/Xos.h> +#include <X11/Xfuncs.h> + +#ifndef XKB_IN_SERVER + +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> + +#include <X11/XKBlib.h> + +#include <X11/extensions/XKBgeom.h> +#include "XKMformat.h" +#include "XKBfileInt.h" + +#else + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/extensions/XKBstr.h> +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBgeom.h> + +Atom +XkbInternAtom(Display *dpy,char *str,Bool only_if_exists) +{ + if (str==NULL) + return None; + return MakeAtom(str,strlen(str),!only_if_exists); +} + +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +char * +_XkbDupString(char *str) +{ +char *new; + + if (str==NULL) + return NULL; + new= (char *)_XkbCalloc(strlen(str)+1,sizeof(char)); + if (new) + strcpy(new,str); + return new; +} + +/***====================================================================***/ + +static XPointer +XkmInsureSize(XPointer oldPtr,int oldCount,int *newCountRtrn,int elemSize) +{ +int newCount= *newCountRtrn; + + if (oldPtr==NULL) { + if (newCount==0) + return NULL; + oldPtr= (XPointer)_XkbCalloc(newCount,elemSize); + } + else if (oldCount<newCount) { + oldPtr= (XPointer)_XkbRealloc(oldPtr,newCount*elemSize); + if (oldPtr!=NULL) { + char *tmp= (char *)oldPtr; + bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize); + } + } + else if (newCount<oldCount) { + *newCountRtrn= oldCount; + } + return oldPtr; +} + +#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t)))) + +static CARD8 +XkmGetCARD8(FILE *file,int *pNRead) +{ +int tmp; + tmp= getc(file); + if (pNRead&&(tmp!=EOF)) + (*pNRead)+= 1; + return tmp; +} + +static CARD16 +XkmGetCARD16(FILE *file,int *pNRead) +{ +CARD16 val; + + if ((fread(&val,2,1,file)==1)&&(pNRead)) + (*pNRead)+= 2; + return val; +} + +static CARD32 +XkmGetCARD32(FILE *file,int *pNRead) +{ +CARD32 val; + + if ((fread(&val,4,1,file)==1)&&(pNRead)) + (*pNRead)+= 4; + return val; +} + +static int +XkmSkipPadding(FILE *file,unsigned pad) +{ +register int i,nRead=0; + + for (i=0;i<pad;i++) { + if (getc(file)!=EOF) + nRead++; + } + return nRead; +} + +static int +XkmGetCountedString(FILE *file,char *str,int max_len) +{ +int count,nRead=0; + + count= XkmGetCARD16(file,&nRead); + if (count>0) { + int tmp; + if (count>max_len) { + tmp= fread(str,1,max_len,file); + while (tmp<count) { + if ((getc(file))!=EOF) + tmp++; + else break; + } + } + else { + tmp= fread(str,1,count,file); + } + nRead+= tmp; + } + if (count>=max_len) str[max_len-1]= '\0'; + else str[count]= '\0'; + count= XkbPaddedSize(nRead)-nRead; + if (count>0) + nRead+= XkmSkipPadding(file,count); + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmVirtualMods(FILE *file,XkbFileInfo *result,XkbChangesPtr changes) +{ +register unsigned int i,bit; +unsigned int bound,named,tmp; +int nRead=0; +XkbDescPtr xkb; + + xkb= result->xkb; + if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); + return -1; + } + bound= XkmGetCARD16(file,&nRead); + named= XkmGetCARD16(file,&nRead); + for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if (bound&bit) { + xkb->server->vmods[i]= XkmGetCARD8(file,&nRead); + if (changes) + changes->map.vmods|= bit; + tmp++; + } + } + if ((i= XkbPaddedSize(tmp)-tmp)>0) + nRead+= XkmSkipPadding(file,i); + if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0); + return -1; + } + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + char name[100]; + if (named&bit) { + if (nRead+=XkmGetCountedString(file,name,100)) { + xkb->names->vmods[i]= XkbInternAtom(xkb->dpy,name,False); + if (changes) + changes->names.changed_vmods|= bit; + } + } + } + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmKeycodes(FILE *file,XkbFileInfo *result,XkbChangesPtr changes) +{ +register int i; +unsigned minKC,maxKC,nAl; +int nRead=0; +char name[100]; +XkbKeyNamePtr pN; +XkbDescPtr xkb; + + xkb= result->xkb; + name[0]= '\0'; + nRead+= XkmGetCountedString(file,name,100); + minKC= XkmGetCARD8(file,&nRead); + maxKC= XkmGetCARD8(file,&nRead); + if (xkb->min_key_code==0) { + xkb->min_key_code= minKC; + xkb->max_key_code= maxKC; + } + else { + if (minKC<xkb->min_key_code) + xkb->min_key_code= minKC; + if (maxKC>xkb->max_key_code) { + _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC); + return -1; + } + } + nAl= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,1); + +#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask) + if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); + return -1; + } + if (name[0]!='\0') { + xkb->names->keycodes= XkbInternAtom(xkb->dpy,name,False); + } + + for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) { + if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); + return -1; + } + nRead+= XkbKeyNameLength; + } + if (nAl>0) { + XkbKeyAliasPtr pAl; + for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) { + int tmp; + tmp= fread(pAl,1,2*XkbKeyNameLength,file); + if (tmp!=2*XkbKeyNameLength) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); + return -1; + } + nRead+= 2*XkbKeyNameLength; + } + if (changes) + changes->names.changed|= XkbKeyAliasesMask; + } + if (changes) + changes->names.changed|= XkbKeyNamesMask; + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmKeyTypes(FILE *file,XkbFileInfo *result,XkbChangesPtr changes) +{ +register unsigned i,n; +unsigned num_types; +int nRead=0; +int tmp; +XkbKeyTypePtr type; +xkmKeyTypeDesc wire; +XkbKTMapEntryPtr entry; +xkmKTMapEntryDesc wire_entry; +char buf[100]; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((tmp= XkmGetCountedString(file,buf,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); + return -1; + } + nRead+= tmp; + if (buf[0]!='\0') { + if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); + return -1; + } + xkb->names->types= XkbInternAtom(xkb->dpy,buf,False); + } + num_types= XkmGetCARD16(file,&nRead); + nRead+= XkmSkipPadding(file,2); + if (num_types<1) + return nRead; + if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0); + return nRead; + } + xkb->map->num_types= num_types; + if (num_types<XkbNumRequiredTypes) { + _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0); + return -1; + } + type= xkb->map->types; + for (i=0;i<num_types;i++,type++) { + if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); + return -1; + } + nRead+= SIZEOF(xkmKeyTypeDesc); + if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))|| + (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)|| + ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) { + _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i); + return -1; + } + tmp= wire.nMapEntries; + XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec); + if ((wire.nMapEntries>0)&&(type->map==NULL)) { + _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries); + return -1; + } + for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) { + if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0); + return -1; + } + nRead+= SIZEOF(xkmKTMapEntryDesc); + entry->active= (wire_entry.virtualMods==0); + entry->level= wire_entry.level; + entry->mods.mask= wire_entry.realMods; + entry->mods.real_mods= wire_entry.realMods; + entry->mods.vmods= wire_entry.virtualMods; + } + nRead+= XkmGetCountedString(file,buf,100); + if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))|| + ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))|| + ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))|| + ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) { + _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0); + return -1; + } + if (buf[0]!='\0') { + type->name= XkbInternAtom(xkb->dpy,buf,False); + } + else type->name= None; + + if (wire.preserve) { + xkmModsDesc p_entry; + XkbModsPtr pre; + XkmInsureTypedSize(type->preserve,type->map_count,&tmp, + XkbModsRec); + if (type->preserve==NULL) { + _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); + return -1; + } + for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) { + if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0); + return -1; + } + nRead+= SIZEOF(xkmModsDesc); + pre->mask= p_entry.realMods; + pre->real_mods= p_entry.realMods; + pre->vmods= p_entry.virtualMods; + } + } + if (wire.nLevelNames>0) { + int width= wire.numLevels; + if (wire.nLevelNames>(unsigned)width) { + _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0); + return -1; + } + XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom); + if (type->level_names!=NULL) { + for (n=0;n<wire.nLevelNames;n++) { + if ((tmp=XkmGetCountedString(file,buf,100))<1) + return -1; + nRead+= tmp; + if (strlen(buf)==0) + type->level_names[n]= None; + else type->level_names[n]= XkbInternAtom(xkb->dpy,buf,0); + } + } + } + type->mods.mask= wire.realMods; + type->mods.real_mods= wire.realMods; + type->mods.vmods= wire.virtualMods; + type->num_levels= wire.numLevels; + type->map_count= wire.nMapEntries; + } + if (changes) { + changes->map.changed|= XkbKeyTypesMask; + changes->map.first_type= 0; + changes->map.num_types= xkb->map->num_types; + } + return nRead; +} + +/***====================================================================***/ + +static int +ReadXkmCompatMap(FILE *file,XkbFileInfo *result,XkbChangesPtr changes) +{ +register int i; +unsigned num_si,groups; +char name[100]; +XkbSymInterpretPtr interp; +xkmSymInterpretDesc wire; +unsigned tmp; +int nRead=0; +XkbDescPtr xkb; +XkbCompatMapPtr compat; + + xkb= result->xkb; + if ((tmp= XkmGetCountedString(file,name,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0); + return -1; + } + nRead+= tmp; + if (name[0]!='\0') { + if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0); + return -1; + } + xkb->names->compat= XkbInternAtom(xkb->dpy,name,False); + } + num_si= XkmGetCARD16(file,&nRead); + groups= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,1); + if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success) + return -1; + compat= xkb->compat; + compat->num_si= num_si; + interp= compat->sym_interpret; + for (i=0;i<num_si;i++,interp++) { + tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file); + nRead+= tmp*SIZEOF(xkmSymInterpretDesc); + interp->sym= wire.sym; + interp->mods= wire.mods; + interp->match= wire.match; + interp->virtual_mod= wire.virtualMod; + interp->flags= wire.flags; + interp->act.type= wire.actionType; + interp->act.data[0]= wire.actionData[0]; + interp->act.data[1]= wire.actionData[1]; + interp->act.data[2]= wire.actionData[2]; + interp->act.data[3]= wire.actionData[3]; + interp->act.data[4]= wire.actionData[4]; + interp->act.data[5]= wire.actionData[5]; + interp->act.data[6]= wire.actionData[6]; + } + if ((num_si>0)&&(changes)) { + changes->compat.first_si= 0; + changes->compat.num_si= num_si; + } + if (groups) { + register unsigned bit; + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + xkmModsDesc md; + if (groups&bit) { + tmp= fread(&md,SIZEOF(xkmModsDesc),1,file); + nRead+= tmp*SIZEOF(xkmModsDesc); + xkb->compat->groups[i].real_mods= md.realMods; + xkb->compat->groups[i].vmods= md.virtualMods; + if (md.virtualMods != 0) { + unsigned mask; + if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask)) + xkb->compat->groups[i].mask= md.realMods|mask; + } + else xkb->compat->groups[i].mask= md.realMods; + } + } + if (changes) + changes->compat.changed_groups|= groups; + } + return nRead; +} + +static int +ReadXkmIndicators(FILE *file,XkbFileInfo *result,XkbChangesPtr changes) +{ +register unsigned nLEDs; +xkmIndicatorMapDesc wire; +char buf[100]; +unsigned tmp; +int nRead=0; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) { + _XkbLibError(_XkbErrBadAlloc,"indicator rec",0); + return -1; + } + if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"indicator names",0); + return -1; + } + nLEDs= XkmGetCARD8(file,&nRead); + nRead+= XkmSkipPadding(file,3); + xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead); + while (nLEDs-->0) { + Atom name; + XkbIndicatorMapPtr map; + + if ((tmp=XkmGetCountedString(file,buf,100))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); + return -1; + } + nRead+= tmp; + if (buf[0]!='\0') + name= XkbInternAtom(xkb->dpy,buf,False); + else name= None; + if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0); + return -1; + } + nRead+= tmp*SIZEOF(xkmIndicatorMapDesc); + if (xkb->names) { + xkb->names->indicators[wire.indicator-1]= name; + if (changes) + changes->names.changed_indicators|= (1<<(wire.indicator-1)); + } + map= &xkb->indicators->maps[wire.indicator-1]; + map->flags= wire.flags; + map->which_groups= wire.which_groups; + map->groups= wire.groups; + map->which_mods= wire.which_mods; + map->mods.mask= wire.real_mods; + map->mods.real_mods= wire.real_mods; + map->mods.vmods= wire.vmods; + map->ctrls= wire.ctrls; + } + return nRead; +} + +static XkbKeyTypePtr +FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms) +{ + if ((!xkb)||(!xkb->map)) + return NULL; + if (name!=None) { + register unsigned i; + for (i=0;i<xkb->map->num_types;i++) { + if (xkb->map->types[i].name==name) { +#ifdef DEBUG + if (xkb->map->types[i].num_levels!=width) + fprintf(stderr,"Group width mismatch between key and type\n"); +#endif + return &xkb->map->types[i]; + } + } + } + if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol))) + return &xkb->map->types[XkbOneLevelIndex]; + if (syms!=NULL) { + if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1])) + return &xkb->map->types[XkbAlphabeticIndex]; + else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1])) + return &xkb->map->types[XkbKeypadIndex]; + } + return &xkb->map->types[XkbTwoLevelIndex]; +} + +static int +ReadXkmSymbols(FILE *file,XkbFileInfo *result) +{ +register int i,g,s,totalVModMaps; +xkmKeySymMapDesc wireMap; +char buf[100]; +unsigned minKC,maxKC,groupNames,tmp; +int nRead=0; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((tmp=XkmGetCountedString(file,buf,100))<1) + return -1; + nRead+= tmp; + minKC= XkmGetCARD8(file,&nRead); + maxKC= XkmGetCARD8(file,&nRead); + groupNames= XkmGetCARD8(file,&nRead); + totalVModMaps= XkmGetCARD8(file,&nRead); + if (XkbAllocNames(xkb, + XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask, + 0,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"physical names",0); + return -1; + } + if ((buf[0]!='\0')&&(xkb->names)) { + Atom name; + name= XkbInternAtom(xkb->dpy,buf,0); + xkb->names->symbols= name; + xkb->names->phys_symbols= name; + } + for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) { + if (groupNames&g) { + if ((tmp=XkmGetCountedString(file,buf,100))<1) + return -1; + nRead+= tmp; + if ((buf[0]!='\0')&&(xkb->names)) { + Atom name; + name= XkbInternAtom(xkb->dpy,buf,0); + xkb->names->groups[i]= name; + } + else xkb->names->groups[i]= None; + } + } + if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"server map",0); + return -1; + } + if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"client map",0); + return -1; + } + if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"controls",0); + return -1; + } + if ((xkb->map==NULL)||(xkb->server==NULL)) + return -1; + if (xkb->min_key_code<8) xkb->min_key_code= minKC; + if (xkb->max_key_code<8) xkb->max_key_code= maxKC; + if ((minKC>=8)&&(minKC<xkb->min_key_code)) + xkb->min_key_code= minKC; + if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) { + _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC); + return -1; + } + for (i=minKC;i<=(int)maxKC;i++) { + Atom typeName[XkbNumKbdGroups]; + XkbKeyTypePtr type[XkbNumKbdGroups]; + if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) { + _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0); + return -1; + } + nRead+= tmp*SIZEOF(xkmKeySymMapDesc); + bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom)); + bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr)); + if (wireMap.flags&XkmKeyHasTypes) { + register int g; + for (g=0;g<XkbNumKbdGroups;g++) { + if ((wireMap.flags&(1<<g))&& + ((tmp=XkmGetCountedString(file,buf,100))>0)) { + typeName[g]= XkbInternAtom(xkb->dpy,buf,1); + nRead+= tmp; + } + type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL); + if (type[g]==NULL) { + _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0); + return -1; + } + if (typeName[g]==type[g]->name) + xkb->server->explicit[i]|= (1<<g); + } + } + if (wireMap.flags&XkmRepeatingKey) { + xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8)); + xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; + } + else if (wireMap.flags&XkmNonRepeatingKey) { + xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8)); + xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask; + } + xkb->map->modmap[i]= wireMap.modifier_map; + if (XkbNumGroups(wireMap.num_groups)>0) { + KeySym *sym; + int nSyms; + + if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups) + xkb->ctrls->num_groups= wireMap.num_groups; + nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width; + sym= XkbResizeKeySyms(xkb,i,nSyms); + if (!sym) + return -1; + for (s=0;s<nSyms;s++) { + *sym++= XkmGetCARD32(file,&nRead); + } + if (wireMap.flags&XkmKeyHasActions) { + XkbAction * act; + act= XkbResizeKeyActions(xkb,i,nSyms); + for (s=0;s<nSyms;s++,act++) { + tmp=fread(act,SIZEOF(xkmActionDesc),1,file); + nRead+= tmp*SIZEOF(xkmActionDesc); + } + xkb->server->explicit[i]|= XkbExplicitInterpretMask; + } + } + for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) { + if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) { + KeySym *tmpSyms; + tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g); + type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms); + } + xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]); + } + xkb->map->key_sym_map[i].group_info= wireMap.num_groups; + xkb->map->key_sym_map[i].width= wireMap.width; + if (wireMap.flags&XkmKeyHasBehavior) { + xkmBehaviorDesc b; + tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file); + nRead+= tmp*SIZEOF(xkmBehaviorDesc); + xkb->server->behaviors[i].type= b.type; + xkb->server->behaviors[i].data= b.data; + xkb->server->explicit[i]|= XkbExplicitBehaviorMask; + } + } + if (totalVModMaps>0) { + xkmVModMapDesc v; + for (i=0;i<totalVModMaps;i++) { + tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file); + nRead+= tmp*SIZEOF(xkmVModMapDesc); + if (tmp>0) + xkb->server->vmodmap[v.key]= v.vmods; + } + } + return nRead; +} + +static int +ReadXkmGeomDoodad( + FILE * file, + Display * dpy, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ +XkbDoodadPtr doodad; +xkmDoodadDesc doodadWire; +char buf[100]; +unsigned tmp; +int nRead=0; + + nRead+= XkmGetCountedString(file,buf,100); + tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); + nRead+= SIZEOF(xkmDoodadDesc)*tmp; + doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(dpy,buf,False)); + if (!doodad) + return nRead; + doodad->any.type= doodadWire.any.type; + doodad->any.priority= doodadWire.any.priority; + doodad->any.top= doodadWire.any.top; + doodad->any.left= doodadWire.any.left; + switch (doodadWire.any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodad->shape.angle= doodadWire.shape.angle; + doodad->shape.color_ndx= doodadWire.shape.color_ndx; + doodad->shape.shape_ndx= doodadWire.shape.shape_ndx; + break; + case XkbTextDoodad: + doodad->text.angle= doodadWire.text.angle; + doodad->text.width= doodadWire.text.width; + doodad->text.height= doodadWire.text.height; + doodad->text.color_ndx= doodadWire.text.color_ndx; + nRead+= XkmGetCountedString(file,buf,100); + doodad->text.text= _XkbDupString(buf); + nRead+= XkmGetCountedString(file,buf,100); + doodad->text.font= _XkbDupString(buf); + break; + case XkbIndicatorDoodad: + doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; + doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx; + doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx; + break; + case XkbLogoDoodad: + doodad->logo.angle= doodadWire.logo.angle; + doodad->logo.color_ndx= doodadWire.logo.color_ndx; + doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; + nRead+= XkmGetCountedString(file,buf,100); + doodad->logo.logo_name= _XkbDupString(buf); + break; + default: + /* report error? */ + return nRead; + } + return nRead; +} + +static int +ReadXkmGeomOverlay( FILE * file, + Display * dpy, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ +char buf[100]; +unsigned tmp; +int nRead=0; +XkbOverlayPtr ol; +XkbOverlayRowPtr row; +xkmOverlayDesc olWire; +xkmOverlayRowDesc rowWire; +register int r; + + nRead+= XkmGetCountedString(file,buf,100); + tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file); + nRead+= tmp*SIZEOF(xkmOverlayDesc); + ol= XkbAddGeomOverlay(section,XkbInternAtom(dpy,buf,False), + olWire.num_rows); + if (!ol) + return nRead; + for (r=0;r<olWire.num_rows;r++) { + int k; + xkmOverlayKeyDesc keyWire; + tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); + nRead+= tmp*SIZEOF(xkmOverlayRowDesc); + row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys); + if (!row) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0); + return nRead; + } + for (k=0;k<rowWire.num_keys;k++) { + tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); + nRead+= tmp*SIZEOF(xkmOverlayKeyDesc); + memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength); + memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength); + } + row->num_keys= rowWire.num_keys; + } + return nRead; +} + +static int +ReadXkmGeomSection( FILE * file, + Display * dpy, + XkbGeometryPtr geom) +{ +register int i; +XkbSectionPtr section; +xkmSectionDesc sectionWire; +unsigned tmp; +int nRead= 0; +char buf[100]; +Atom nameAtom; + + nRead+= XkmGetCountedString(file,buf,100); + nameAtom= XkbInternAtom(dpy,buf,False); + tmp= fread(§ionWire,SIZEOF(xkmSectionDesc),1,file); + nRead+= SIZEOF(xkmSectionDesc)*tmp; + section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows, + sectionWire.num_doodads, + sectionWire.num_overlays); + if (!section) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); + return nRead; + } + 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.num_rows>0) { + register int k; + XkbRowPtr row; + xkmRowDesc rowWire; + XkbKeyPtr key; + xkmKeyDesc keyWire; + + for (i=0;i<sectionWire.num_rows;i++) { + tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file); + nRead+= SIZEOF(xkmRowDesc)*tmp; + row= XkbAddGeomRow(section,rowWire.num_keys); + if (!row) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0); + return nRead; + } + row->top= rowWire.top; + row->left= rowWire.left; + row->vertical= rowWire.vertical; + for (k=0;k<rowWire.num_keys;k++) { + tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file); + nRead+= SIZEOF(xkmKeyDesc)*tmp; + key= XkbAddGeomKey(row); + if (!key) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0); + return nRead; + } + memcpy(key->name.name,keyWire.name,XkbKeyNameLength); + key->gap= keyWire.gap; + key->shape_ndx= keyWire.shape_ndx; + key->color_ndx= keyWire.color_ndx; + } + } + } + if (sectionWire.num_doodads>0) { + for (i=0;i<sectionWire.num_doodads;i++) { + tmp= ReadXkmGeomDoodad(file,dpy,geom,section); + nRead+= tmp; + if (tmp<1) + return nRead; + } + } + if (sectionWire.num_overlays>0) { + for (i=0;i<sectionWire.num_overlays;i++) { + tmp= ReadXkmGeomOverlay(file,dpy,geom,section); + nRead+= tmp; + if (tmp<1) + return nRead; + } + } + return nRead; +} + +static int +ReadXkmGeometry(FILE *file,XkbFileInfo *result) +{ +register int i; +char buf[100]; +unsigned tmp; +int nRead= 0; +xkmGeometryDesc wireGeom; +XkbGeometryPtr geom; +XkbGeometrySizesRec sizes; + + nRead+= XkmGetCountedString(file,buf,100); + tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file); + nRead+= tmp*SIZEOF(xkmGeometryDesc); + sizes.which= XkbGeomAllMask; + sizes.num_properties= wireGeom.num_properties; + sizes.num_colors= wireGeom.num_colors; + sizes.num_shapes= wireGeom.num_shapes; + sizes.num_sections= wireGeom.num_sections; + sizes.num_doodads= wireGeom.num_doodads; + sizes.num_key_aliases= wireGeom.num_key_aliases; + if (XkbAllocGeometry(result->xkb,&sizes)!=Success) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); + return nRead; + } + geom= result->xkb->geom; + geom->name= XkbInternAtom(result->xkb->dpy,buf,False); + geom->width_mm= wireGeom.width_mm; + geom->height_mm= wireGeom.height_mm; + nRead+= XkmGetCountedString(file,buf,100); + geom->label_font= _XkbDupString(buf); + if (wireGeom.num_properties>0) { + char val[1024]; + for (i=0;i<wireGeom.num_properties;i++) { + nRead+= XkmGetCountedString(file,buf,100); + nRead+= XkmGetCountedString(file,val,1024); + if (XkbAddGeomProperty(geom,buf,val)==NULL) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); + return nRead; + } + } + } + if (wireGeom.num_colors>0) { + for (i=0;i<wireGeom.num_colors;i++) { + nRead+= XkmGetCountedString(file,buf,100); + if (XkbAddGeomColor(geom,buf,i)==NULL) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); + return nRead; + } + } + } + geom->base_color= &geom->colors[wireGeom.base_color_ndx]; + geom->label_color= &geom->colors[wireGeom.label_color_ndx]; + if (wireGeom.num_shapes>0) { + XkbShapePtr shape; + xkmShapeDesc shapeWire; + Atom nameAtom; + for (i=0;i<wireGeom.num_shapes;i++) { + register int n; + XkbOutlinePtr ol; + xkmOutlineDesc olWire; + nRead+= XkmGetCountedString(file,buf,100); + nameAtom= XkbInternAtom(result->xkb->dpy,buf,False); + tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file); + nRead+= tmp*SIZEOF(xkmShapeDesc); + shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines); + if (!shape) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); + return nRead; + } + for (n=0;n<shapeWire.num_outlines;n++) { + register int p; + xkmPointDesc ptWire; + tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file); + nRead+= tmp*SIZEOF(xkmOutlineDesc); + ol= XkbAddGeomOutline(shape,olWire.num_points); + if (!ol) { + _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0); + return nRead; + } + ol->num_points= olWire.num_points; + ol->corner_radius= olWire.corner_radius; + for (p=0;p<olWire.num_points;p++) { + tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file); + nRead+= tmp*SIZEOF(xkmPointDesc); + ol->points[p].x= ptWire.x; + ol->points[p].y= ptWire.y; + if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x; + if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x; + if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y; + if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y; + } + } + if (shapeWire.primary_ndx!=XkbNoShape) + shape->primary= &shape->outlines[shapeWire.primary_ndx]; + if (shapeWire.approx_ndx!=XkbNoShape) + shape->approx= &shape->outlines[shapeWire.approx_ndx]; + } + } + if (wireGeom.num_sections>0) { + for (i=0;i<wireGeom.num_sections;i++) { + tmp= ReadXkmGeomSection(file,result->xkb->dpy,geom); + nRead+= tmp; + if (tmp==0) + return nRead; + } + } + if (wireGeom.num_doodads>0) { + for (i=0;i<wireGeom.num_doodads;i++) { + tmp= ReadXkmGeomDoodad(file,result->xkb->dpy,geom,NULL); + nRead+= tmp; + if (tmp==0) + return nRead; + } + } + if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) { + int sz= XkbKeyNameLength*2; + int num= wireGeom.num_key_aliases; + if (fread(geom->key_aliases,sz,num,file)!=num) { + _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0); + return -1; + } + nRead+= (num*sz); + geom->num_key_aliases= num; + } + return nRead; +} + +Bool +XkmProbe(FILE *file) +{ +unsigned hdr,tmp; +int nRead=0; + + hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); + tmp= XkmGetCARD32(file,&nRead); + if (tmp!=hdr) { + if ((tmp&(~0xff))==(hdr&(~0xff))) { + _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff); + } + return 0; + } + return 1; +} + +Bool +XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc) +{ +unsigned hdr,tmp; +int nRead=0; +unsigned i,size_toc; + + hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); + tmp= XkmGetCARD32(file,&nRead); + if (tmp!=hdr) { + if ((tmp&(~0xff))==(hdr&(~0xff))) { + _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff); + } + else { + _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp); + } + return 0; + } + fread(file_info,SIZEOF(xkmFileInfo),1,file); + size_toc= file_info->num_toc; + if (size_toc>max_toc) { +#ifdef DEBUG + fprintf(stderr,"Warning! Too many TOC entries; last %d ignored\n", + size_toc-max_toc); +#endif + size_toc= max_toc; + } + for (i=0;i<size_toc;i++) { + fread(&toc[i],SIZEOF(xkmSectionInfo),1,file); + } + return 1; +} + +xkmSectionInfo * +XkmFindTOCEntry(xkmFileInfo *finfo,xkmSectionInfo *toc,unsigned type) +{ +register int i; + + for (i=0;i<finfo->num_toc;i++) { + if (toc[i].type==type) + return &toc[i]; + } + return NULL; +} + +Bool +XkmReadFileSection( FILE * file, + xkmSectionInfo * toc, + XkbFileInfo * result, + unsigned * loaded_rtrn) +{ +xkmSectionInfo tmpTOC; +int nRead; + + if ((!result)||(!result->xkb)) { + _XkbLibError(_XkbErrBadMatch,"XkmReadFileSection",0); + return 0; + } + fseek(file,toc->offset,SEEK_SET); + fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); + nRead= SIZEOF(xkmSectionInfo); + if ((tmpTOC.type!=toc->type)||(tmpTOC.format!=toc->format)|| + (tmpTOC.size!=toc->size)||(tmpTOC.offset!=toc->offset)) { + _XkbLibError(_XkbErrIllegalContents,"XkmReadFileSection",0); + return 0; + } + switch (tmpTOC.type) { + case XkmVirtualModsIndex: + nRead+= ReadXkmVirtualMods(file,result,NULL); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmVirtualModsMask; + break; + case XkmTypesIndex: + nRead+= ReadXkmKeyTypes(file,result,NULL); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmTypesMask; + break; + case XkmCompatMapIndex: + nRead+= ReadXkmCompatMap(file,result,NULL); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmCompatMapMask; + break; + case XkmKeyNamesIndex: + nRead+= ReadXkmKeycodes(file,result,NULL); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmKeyNamesMask; + break; + case XkmSymbolsIndex: + nRead+= ReadXkmSymbols(file,result); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmSymbolsMask; + break; + case XkmIndicatorsIndex: + nRead+= ReadXkmIndicators(file,result,NULL); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmIndicatorsMask; + break; + case XkmGeometryIndex: + nRead+= ReadXkmGeometry(file,result); + if ((loaded_rtrn)&&(nRead>=0)) + *loaded_rtrn|= XkmGeometryMask; + break; + default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); + nRead= 0; + break; + } + if (nRead!=tmpTOC.size) { + _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), + nRead-tmpTOC.size); + return 0; + } + return (nRead>=0); +} + +char * +XkmReadFileSectionName(FILE *file,xkmSectionInfo *toc) +{ +xkmSectionInfo tmpTOC; +char name[100]; + + if ((!file)||(!toc)) + return 0; + switch (toc->type) { + case XkmVirtualModsIndex: + case XkmIndicatorsIndex: + break; + case XkmTypesIndex: + case XkmCompatMapIndex: + case XkmKeyNamesIndex: + case XkmSymbolsIndex: + case XkmGeometryIndex: + fseek(file,toc->offset,SEEK_SET); + fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); + if ((tmpTOC.type!=toc->type)||(tmpTOC.format!=toc->format)|| + (tmpTOC.size!=toc->size)||(tmpTOC.offset!=toc->offset)) { + _XkbLibError(_XkbErrIllegalContents,"XkmReadFileSectionName",0); + return 0; + } + if (XkmGetCountedString(file,name,100)>0) + return _XkbDupString(name); + break; + default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); + break; + } + return NULL; +} + +/***====================================================================***/ + +#define MAX_TOC 16 +unsigned +XkmReadFile(FILE *file,unsigned need,unsigned want,XkbFileInfo *result) +{ +register unsigned i; +xkmSectionInfo toc[MAX_TOC],tmpTOC; +xkmFileInfo fileInfo; +unsigned tmp,nRead=0; +unsigned which= need|want; + + if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc)) + return which; + if ((fileInfo.present&need)!=need) { + _XkbLibError(_XkbErrIllegalContents,"XkmReadFile", + need&(~fileInfo.present)); + return which; + } + result->type= fileInfo.type; + if (result->xkb==NULL) + result->xkb= XkbAllocKeyboard(); + for (i=0;i<fileInfo.num_toc;i++) { +#ifdef SEEK_SET + fseek(file,toc[i].offset,SEEK_SET); +#else + fseek(file,toc[i].offset,0); +#endif + tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file); + nRead= tmp*SIZEOF(xkmSectionInfo); + if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)|| + (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) { + return which; + } + if ((which&(1<<tmpTOC.type))==0) { + continue; + } + switch (tmpTOC.type) { + case XkmVirtualModsIndex: + tmp= ReadXkmVirtualMods(file,result,NULL); + break; + case XkmTypesIndex: + tmp= ReadXkmKeyTypes(file,result,NULL); + break; + case XkmCompatMapIndex: + tmp= ReadXkmCompatMap(file,result,NULL); + break; + case XkmKeyNamesIndex: + tmp= ReadXkmKeycodes(file,result,NULL); + break; + case XkmIndicatorsIndex: + tmp= ReadXkmIndicators(file,result,NULL); + break; + case XkmSymbolsIndex: + tmp= ReadXkmSymbols(file,result); + break; + case XkmGeometryIndex: + tmp= ReadXkmGeometry(file,result); + break; + default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); + tmp= 0; + break; + } + if (tmp>0) { + nRead+= tmp; + which&= ~(1<<toc[i].type); + result->defined|= (1<<toc[i].type); + } + if (nRead!=tmpTOC.size) { + _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), + nRead-tmpTOC.size); + } + } + return which; +} |