summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-05-12 16:01:29 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-05-12 16:01:29 +1000
commitb3b780ff995b19ddaad77b22dc14ab69978b5983 (patch)
tree961f7cc50e2cf2923c8b8b0cec8a3f47ca66001c
Import xkbset 0.5
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--COPYRIGHT26
-rw-r--r--Makefile58
-rw-r--r--README27
-rw-r--r--TODO1
-rw-r--r--VERSIONS2
-rw-r--r--config_getargs190
-rw-r--r--config_print151
-rw-r--r--create_getargs423
-rw-r--r--create_print217
-rw-r--r--create_usage367
-rw-r--r--main.c150
-rw-r--r--misc.c57
-rwxr-xr-xxkbset-gui267
-rw-r--r--xkbset.h44
-rw-r--r--xkbset.man167
15 files changed, 2147 insertions, 0 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..c92cb3e
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,26 @@
+Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Stephen Montgomery-Smith nor the names of his
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..05d1360
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,58 @@
+X11PREFIX=/usr/X11R6
+X11BASE=/usr/X11R6
+
+INSTALL_BIN=${DESTDIR}${X11PREFIX}/bin
+INSTALL_MAN1=${DESTDIR}${X11PREFIX}/man/man1
+
+INC_PATH=-I${X11BASE}/include
+LIB_PATH=-L${X11BASE}/lib
+LIBS=-lX11
+
+all: xkbset xkbset.1
+
+xkbset: getargs.o print.o usage.o main.o misc.o
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} getargs.o print.o usage.o main.o misc.o -o $@ ${LIBS}
+
+getargs.o: getargs.c xkbset.h
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} -c getargs.c
+
+print.o: print.c xkbset.h
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} -c print.c
+
+usage.o: usage.c xkbset.h
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} -c usage.c
+
+main.o: main.c xkbset.h
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} -c main.c
+
+misc.o: misc.c xkbset.h
+ ${CC} ${CFLAGS} ${INC_PATH} ${LIB_PATH} -c misc.c
+
+getargs.c: create_getargs config_getargs
+ perl create_getargs
+
+print.c: create_print config_print
+ perl create_print
+
+usage.c: create_usage config_usage
+ perl create_usage
+
+config_usage: config_getargs
+ rm -f config_usage
+ ln -s config_getargs config_usage
+
+xkbset.1: xkbset.man
+ cp xkbset.man xkbset.1
+
+INSTALL= install -c
+INSTALL_DATA= ${INSTALL}
+INSTALL_SCRIPT= ${INSTALL}
+INSTALL_PROGRAM=${INSTALL} -s
+
+install: all
+ ${INSTALL_PROGRAM} xkbset ${INSTALL_BIN}
+ ${INSTALL_SCRIPT} xkbset-gui ${INSTALL_BIN}
+ ${INSTALL_DATA} xkbset.1 ${INSTALL_MAN1}
+
+clean:
+ rm -f *.o getargs.c print.c usage.c *.core xkbset config_usage xkbset.1
diff --git a/README b/README
new file mode 100644
index 0000000..b742507
--- /dev/null
+++ b/README
@@ -0,0 +1,27 @@
+xkbset is a program rather like xset in that it allows you to set
+various features of the X window interface. It allows one to configure
+most of the options connected with the XKB extensions. They are described
+in Section 10 of XKBlib.ps.
+
+This includes customizing the following:
+ MouseKeys: using the numeric pad keys to move the mouse;
+ StickyKeys: where modifiers like control and shift will lock until the
+ next key press (good for one finger typing);
+ SlowKeys: The keys will not work unless they are pressed for a certain
+ amount of time;
+ BounceKeys: If a key is pressed more than once rapidly, only one key
+ press will be registered.
+
+I also include a gui program xkbset-gui which is a GUI program to play
+with the mousekeys acceleration parameters. It is written in Perl/Tk,
+so Perl/Tk will need to be installed on your machine.
+
+If you have any improvents or ideas, please send them to me.
+
+Also, if you use this program and like it, please tell me so. If I
+don't get much feedback, I will assume no one is interested, and
+I won't develop it further (in particular I won't finish the man page).
+
+Stephen Montgomery-Smith
+stephen@math.missouri.edu
+http://www.math.missouri.edu/~stephen
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..88ecdcb
--- /dev/null
+++ b/TODO
@@ -0,0 +1 @@
+Finish the man page
diff --git a/VERSIONS b/VERSIONS
new file mode 100644
index 0000000..fc72afa
--- /dev/null
+++ b/VERSIONS
@@ -0,0 +1,2 @@
+xkbset-0.0 The very first version.
+xkbset-0.5 A later version
diff --git a/config_getargs b/config_getargs
new file mode 100644
index 0000000..adf8f25
--- /dev/null
+++ b/config_getargs
@@ -0,0 +1,190 @@
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+#C To switch the bell on or off:
+bell | b:
+MASK_XkbAudibleBellMask enabled_ctrls XkbControlsEnabledMask;
+
+#C To switch one key to autorepeat or not:
+repeatkeys %d|r %d:
+BIT32 per_key_repeat XkbPerKeyRepeatMask;
+
+#C To send a hex mask for all keys to autorepeat or not
+perkeyrepeat %64x:
+CHAR_ARRAY32 per_key_repeat XkbPerKeyRepeatMask;
+
+#C To switch autorepeat on or off, and optionally set the delay before
+#C the first repeat and the interval between repeats (times in milliseconds):
+repeatkeys|r:
+MASK_XkbRepeatKeysMask enabled_ctrls XkbControlsEnabledMask {
+ rate %d:
+ USHORT repeat_delay XkbRepeatKeysMask {
+ %d:
+ USHORT repeat_interval XkbRepeatKeysMask;
+ }
+}
+
+#C To switch mousekeys on or off, and optionally set the default
+#C button (whatever that is):
+mousekeys | m:
+MASK_XkbMouseKeysMask enabled_ctrls XkbControlsEnabledMask {
+ %d:
+ UCHAR mk_dflt_btn XkbMouseKeysMask;
+}
+
+#C To switch mousekeys acceleration on or off, and optionally set
+#C the acceleration characteristics:
+mousekeysaccel | ma:
+MASK_XkbMouseKeysAccelMask enabled_ctrls XkbControlsEnabledMask {
+ %d %d %d %d %d:
+ USHORT mk_delay XkbMouseKeysAccelMask,
+ USHORT mk_interval XkbMouseKeysAccelMask,
+ USHORT mk_time_to_max XkbMouseKeysAccelMask,
+ USHORT mk_max_speed XkbMouseKeysAccelMask,
+ SHORT mk_curve XkbMouseKeysAccelMask;
+}
+
+#C To switch AccessX on (so pressing shift five times starts sticky keys
+#C and pressing the shift key down 8 seconds starts slow keys):
+accessx | a:
+MASK_XkbAccessXKeysMask enabled_ctrls XkbControlsEnabledMask;
+
+#C To switch sticky keys on or off, and optionally set or reset:
+#C () two keys pressed at the same time stops sticky keys;
+#C () a modifier pressed twice will be locked:
+sticky | st:
+MASK_XkbStickyKeysMask enabled_ctrls XkbControlsEnabledMask {
+ twokey:
+ MASK_XkbAX_TwoKeysMask ax_options XkbStickyKeysMask;
+ latchlock:
+ MASK_XkbAX_LatchToLockMask ax_options XkbStickyKeysMask;
+}
+
+#C To switch on slowkeys, and optionally set the slow key delay (in
+#C milliseconds):
+slowkeys | sl:
+MASK_XkbSlowKeysMask enabled_ctrls XkbControlsEnabledMask {
+ %d:
+ USHORT slow_keys_delay XkbSlowKeysMask;
+}
+
+#C To switch on bouncekeys, and optionally set the time (in milliseconds) for
+#C which if the key is pressed again in that time it will not work:
+bouncekeys | bo:
+MASK_XkbBounceKeysMask enabled_ctrls XkbControlsEnabledMask {
+ %d:
+ USHORT debounce_delay XkbBounceKeysMask;
+}
+
+#C To switch on audible feedback, and optionally set which features
+#C cause the feedback (note [-]feature means that switching
+#C one of the AccessX features on of off causes feedback):
+feedback | f:
+MASK_XkbAccessXFeedbackMask enabled_ctrls XkbControlsEnabledMask {
+ dumbbell:
+ MASK_XkbAX_DumbBellFBMask ax_options XkbAccessXFeedbackMask;
+ led:
+ MASK_XkbAX_IndicatorFBMask ax_options XkbAccessXFeedbackMask;
+ feature:
+ MASK_XkbAX_FeatureFBMask ax_options XkbAccessXFeedbackMask;
+ slowwarn:
+ MASK_XkbAX_SlowWarnFBMask ax_options XkbAccessXFeedbackMask;
+ slowpress:
+ MASK_XkbAX_SKPressFBMask ax_options XkbAccessXFeedbackMask;
+ slowaccept:
+ MASK_XkbAX_SKAcceptFBMask ax_options XkbAccessXFeedbackMask;
+ slowreject:
+ MASK_XkbAX_SKRejectFBMask ax_options XkbAccessXFeedbackMask;
+ slowrelease:
+ MASK_XkbAX_SKReleaseFBMask ax_options XkbAccessXFeedbackMask;
+ bouncereject:
+ MASK_XkbAX_BKRejectFBMask ax_options XkbAccessXFeedbackMask;
+ stickybeep:
+ MASK_XkbAX_StickyKeysFBMask ax_options XkbAccessXFeedbackMask;
+}
+
+#C To switch keyboard overlays 1 or 2 on or off:
+overlay1 | ov1:
+MASK_XkbOverlay1Mask enabled_ctrls XkbControlsEnabledMask;
+overlay2 | ov2:
+MASK_XkbOverlay2Mask enabled_ctrls XkbControlsEnabledMask;
+
+#C To select the group wrap type (now what is that)?
+groupswrap %e {
+ redirect = XkbRedirectIntoRange;
+ clamp = XkbClampIntoRange;
+ wrap = XkbWrapIntoRange }:
+HIGH_NIBBLE_ENUM groups_wrap XkbGroupsWrapMask {
+ %d:
+ LOW_NIBBLE groups_wrap XkbGroupsWrapMask;
+}
+
+#C What is this?
+ignoregrouplock:
+MASK_XkbIgnoreGroupLockMask enabled_ctrls XkbControlsEnabledMask;
+
+#C To cause some of the key modifiers (like shift, num-lock=mod2, etc)
+#C to not work:
+nullify: {
+shift:
+MASK_ShiftMask "internal.real_mods" XkbInternalModsMask;
+lock:
+MASK_LockMask "internal.real_mods" XkbInternalModsMask;
+control:
+MASK_ControlMask "internal.real_mods" XkbInternalModsMask;
+mod1:
+MASK_Mod1Mask "internal.real_mods" XkbInternalModsMask;
+mod2:
+MASK_Mod2Mask "internal.real_mods" XkbInternalModsMask;
+mod3:
+MASK_Mod3Mask "internal.real_mods" XkbInternalModsMask;
+mod4:
+MASK_Mod4Mask "internal.real_mods" XkbInternalModsMask;
+mod5:
+MASK_Mod5Mask "internal.real_mods" XkbInternalModsMask;
+}
+
+#C What is this?
+ignorelock: {
+shift:
+MASK_ShiftMask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+lock:
+MASK_LockMask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+control:
+MASK_ControlMask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+mod1:
+MASK_Mod1Mask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+mod2:
+MASK_Mod2Mask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+mod3:
+MASK_Mod3Mask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+mod4:
+MASK_Mod4Mask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+mod5:
+MASK_Mod5Mask "ignore_lock.real_mods" XkbIgnoreLockModsMask;
+}
+
diff --git a/config_print b/config_print
new file mode 100644
index 0000000..1138932
--- /dev/null
+++ b/config_print
@@ -0,0 +1,151 @@
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+-b
+MASK_XkbAudibleBellMask enabled_ctrls Audible Bell
+
+-r
+MASK_XkbRepeatKeysMask enabled_ctrls Repeat Keys
+rate
+USHORT repeat_delay Repeat Delay
+USHORT repeat_interval Repeat Interval
+perkeyrepeat
+CHAR_ARRAY_32 per_key_repeat Per Key Repeat
+
+-m
+MASK_XkbMouseKeysMask enabled_ctrls Mouse-Keys
+UCHAR mk_dflt_btn Mouse-Keys Default Button
+-ma
+MASK_XkbMouseKeysAccelMask enabled_ctrls Mouse-Keys Acceleration
+USHORT mk_delay Mouse-Keys Acceleration Delay
+USHORT mk_interval Mouse-Keys Acceleration Interval
+USHORT mk_time_to_max Mouse-Keys Acceleration Time to Max
+USHORT mk_max_speed Mouse-Keys Acceleration Max Speed
+SHORT mk_curve Mouse-Keys Acceleration Curve
+
+-a
+MASK_XkbAccessXKeysMask enabled_ctrls Accessibility Features (AccessX)
+
+-st
+MASK_XkbStickyKeysMask enabled_ctrls Sticky-Keys
+-twokey
+MASK_XkbAX_TwoKeysMask ax_options Two Keys Mask
+-latchlock
+MASK_XkbAX_LatchToLockMask ax_options Latch to Lock Mask
+
+-sl
+MASK_XkbSlowKeysMask enabled_ctrls Slow-Keys
+USHORT slow_keys_delay Slow Keys Delay
+
+-bo
+MASK_XkbBounceKeysMask enabled_ctrls Bounce-Keys
+USHORT debounce_delay Debounce Delay
+
+-f
+MASK_XkbAccessXFeedbackMask enabled_ctrls AccessX Feedback
+-dumbbell
+MASK_XkbAX_DumbBellFBMask ax_options Use Fixed Pitch Bell
+-led
+MASK_XkbAX_IndicatorFBMask ax_options Beep when LED changes
+-feature
+MASK_XkbAX_FeatureFBMask ax_options Beep on Controls on/off
+-slowwarn
+MASK_XkbAX_SlowWarnFBMask ax_options Beep if Slow/Bounce-Keys about to be turned off
+-slowpress
+MASK_XkbAX_SKPressFBMask ax_options Beep on Slow-Key Press
+-slowaccept
+MASK_XkbAX_SKAcceptFBMask ax_options Beep on Slow-Key Accept
+-slowreject
+MASK_XkbAX_SKRejectFBMask ax_options Beep on Slow-Key Reject
+-slowrelease
+MASK_XkbAX_SKReleaseFBMask ax_options Beep on Slow-Key Release
+-bouncereject
+MASK_XkbAX_BKRejectFBMask ax_options Beep on Bounce-Key Reject
+-stickybeep
+MASK_XkbAX_StickyKeysFBMask ax_options Beep on Sticky-Key Actions
+
+-ov1
+MASK_XkbOverlay1Mask enabled_ctrls Keyboard Overlay 1
+-ov2
+MASK_XkbOverlay2Mask enabled_ctrls Keyboard Overlay 2
+
++groupswrap
+HIGH_NIBBLE_ENUM groups_wrap Groups Wrap Type
+redirect=XkbRedirectIntoRange,clamp=XkbClampIntoRange,wrap=XkbWrapIntoRange
+LOW_NIBBLE_IF_HIGH_NIBBLE_ENUM groups_wrap Groups Wrap Value
+redirect=XkbRedirectIntoRange,clamp=XkbClampIntoRange,wrap=XkbWrapIntoRange
+
+#finish later
+
+-ignoregrouplock
+MASK_XkbIgnoreGroupLockMask enabled_ctrls Ignore Group Lock
+
+nullify
+-shift
+MASK_ShiftMask internal.real_mods Nullify Shift
+-lock
+MASK_LockMask internal.real_mods Nullify Caps-Lock
+-control
+MASK_ControlMask internal.real_mods Nullify Control
+-mod1
+MASK_Mod1Mask internal.real_mods Nullify Mod1
+-mod2
+MASK_Mod2Mask internal.real_mods Nullify Mod2
+-mod3
+MASK_Mod3Mask internal.real_mods Nullify Mod3
+-mod4
+MASK_Mod4Mask internal.real_mods Nullify Mod4
+-mod5
+MASK_Mod5Mask internal.real_mods Nullify Mod5
+
+ignorelock
+-shift
+MASK_ShiftMask ignore_lock.real_mods Ignore Lock of Shift
+-lock
+MASK_LockMask ignore_lock.real_mods Ignore Lock of Caps-Lock
+-control
+MASK_ControlMask ignore_lock.real_mods Ignore Lock of Control
+-mod1
+MASK_Mod1Mask ignore_lock.real_mods Ignore Lock of Mod1
+-mod2
+MASK_Mod2Mask ignore_lock.real_mods Ignore Lock of Mod2
+-mod3
+MASK_Mod3Mask ignore_lock.real_mods Ignore Lock of Mod3
+-mod4
+MASK_Mod4Mask ignore_lock.real_mods Ignore Lock of Mod4
+-mod5
+MASK_Mod5Mask ignore_lock.real_mods Ignore Lock of Mod5
+
+
+
+
+
+
+
+
+
+
diff --git a/create_getargs b/create_getargs
new file mode 100644
index 0000000..80d5353
--- /dev/null
+++ b/create_getargs
@@ -0,0 +1,423 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+sub setatom {
+ $atom = $atomlist[$atomcount];
+ $previousatom = $atomlist[$atomcount-1];
+ $nextatom = $atomlist[$atomcount+1];
+ $atom =~ s/^\d+: // if defined $atom;
+ $previousatom =~ s/^\d+: // if defined $previousatom;
+ $nextatom =~ s/^\d+: // if defined $nextatom;
+}
+
+sub getatom {
+ $atomcount++;
+ setatom;
+}
+
+sub pushatom {
+ $atomcount--;
+ setatom;
+}
+
+sub fetchatoms {
+ @atomlist = ();
+ open(CONFIG,"config_getargs");
+ while ($line = <CONFIG>) {
+ if ($line !~ /^\#/) {
+ while (1) {
+ next if ($line =~ s/^\s+//);
+ if ($line =~ s/^\"([^\"]*)\"//) {}
+ elsif ($line =~ s/^([a-zA-Z\_][a-zA-Z\_0-9]*)//) {}
+ elsif ($line =~ s/^(\%\d*[a-zA-Z])//) {}
+ elsif ($line =~ s/^(\S)//) {}
+ else { last }
+ push(@atomlist,$1);
+ }
+ }
+ }
+ close(CONFIG);
+ push(@atomlist,"end");
+ $atomcount = 0;
+ setatom;
+}
+
+sub enum_value {
+ my $enum = '';
+ getatom; $enum = $atom;
+ getatom; die if $atom ne '=';
+ getatom; $enum .= '=' . $atom;
+ getatom;
+ return $enum;
+}
+
+sub sub_title_item {
+ my $item;
+ if ($atom =~ /^[a-zA-Z0-9]/) {
+ $item = "strcmp(ARG,\"$atom\")==0"
+ }
+ elsif ($atom eq '%d') {
+ $item = "get_number(ARG,LOW,HIGH,&VAL)"
+ }
+ elsif ($atom eq '%64x') {
+ $item = "get_64_hex(ARG,char_array_32)"
+ }
+ elsif ($atom eq '%e') {
+ getatom;
+ die "'{' expected at beginning of enum list\n" if $atom ne '{';
+ $item = "ENUM(ARG," . enum_value;
+ while ($atom eq ';') {
+ $item .= "," . enum_value;
+ }
+ die "'}' expected at end of enum list - got $atom\n" if $atom ne '}';
+ $item .= ')';
+ }
+ getatom if defined($item);
+ return $item;
+}
+
+sub title_item {
+ my $title_item = sub_title_item;
+ my $next_item;
+ my $n = 1;
+ die "syntax error in title\n" if !defined($title_item);
+ $title_item =~ s/ARG/argv[i]/;
+ while(defined($next_item = sub_title_item)) {
+ $next_item =~ s/ARG/argv\[i+$n\]/;
+ $title_item = "$title_item && $next_item";
+ $n++;
+ }
+ return "(i+$n<=argc && $title_item && (inc=$n))";
+}
+
+sub substitute {
+ @t=();
+ foreach $t (split /\|\|/,$_[0]) {
+ $t =~ s/LOW/$_[1]/;
+ $t =~ s/HIGH/$_[2]/;
+ $t =~ s/VAL/val$_[3]/;
+ push(@t,$t);
+ }
+ return join '||',@t;
+}
+
+$n_max = 0;
+
+sub process_item {
+ my $title_item;
+ $title_item = title_item;
+ while ($atom eq '|') {
+ getatom;
+ $title_item .= " ||\n " . title_item;
+ }
+ die "expected ':'\n" if $atom ne ':';
+
+ my $execute = '';
+ my %maskhash = ();
+ my $n = 1;
+ while ($atom =~ /^(\:|\,)$/) {
+ getatom;
+ my $type = $atom;
+ last if $atom eq '{';
+ getatom;
+ my $field = $atom;
+ getatom;
+ my $mask = $atom;
+ getatom;
+ die "expected three fields\n" if !defined($atom);
+
+#$execute .= "printf(\"executing for $type $field $mask\\n\");\n";
+ $maskhash{$mask} = 1;
+
+ if ($type =~ /^MASK\_(.*)$/) {
+ $execute .= "if (argv[i][0] == '-') ctrls->$field &= ~$1;\n" .
+ "else ctrls->$field |= $1;\n";
+ }
+ elsif ($type eq 'USHORT') {
+ $title_item = substitute($title_item,0,65535,$n);
+ $execute .= "ctrls->$field = val$n;\n";
+ $n++;
+ }
+ elsif ($type eq 'SHORT') {
+ $title_item = substitute($title_item,-32767,32767,$n);
+ $execute .= "ctrls->$field = val$n;\n";
+ $n++;
+ }
+ elsif ($type eq 'UCHAR') {
+ $title_item = substitute($title_item,0,255,$n);
+ $execute .= "ctrls->$field = val$n;\n";
+ $n++;
+ }
+ elsif ($type eq 'LOW_NIBBLE') {
+ $title_item = substitute($title_item,0,255,$n);
+ $execute .= "ctrls->$field &= 0xF0;\n" .
+ "ctrls->$field |= 0x0F & val$n;\n";
+ $n++;
+ }
+ elsif ($type eq 'BIT32') {
+ $title_item = substitute($title_item,0,255,$n);
+ $execute .= "if (argv[i][0] == '-') ctrls->$field\[val$n>>3] &= ~(1<<(val$n&7));\n" .
+ "else ctrls->$field\[val$n>>3] |= (1<<(val$n&7));\n";
+ $n++;
+ }
+ elsif ($type eq 'CHAR_ARRAY32') {
+ $execute .= "memcpy(ctrls->$field,char_array_32,32);\n";
+ }
+ elsif ($type eq 'HIGH_NIBBLE_ENUM') {
+ $title_item =~ s/ENUM\(([^\)]*)\)/1/;
+ @enum_list = split ',',$1;
+ $arg = shift(@enum_list);
+ $first = 1;
+ foreach $enum (@enum_list) {
+ ($code,$value) = split '=',$enum;
+ $execute .= (!$first?"else ":"") .
+ "if (strcmp($arg,\"$code\")==0) {\n" .
+ " ctrls->$field &= 0x0F;\n" .
+ " ctrls->$field |= $value;\n" .
+ "}\n";
+ $first = 0;
+ }
+ $execute .= "else return 0;\n";
+ }
+ else {
+ die "Unknown type $type";
+ }
+
+ if ($type eq 'BIT32' || $type =~ /^MASK\_/) {
+ $temp = $title_item;
+ $temp =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"-$2\"\)/g;
+ $title_item .= " ||\n $temp";
+ }
+ }
+
+ $n_max = $n-1 if $n-1>$n_max;
+
+ foreach $i (@_) {
+ $maskhash{$i} = 0;
+ }
+ $masklist = join '|',grep $maskhash{$_}==1, keys %maskhash;
+ $execute .= "*mask |= $masklist;\n" if $masklist;
+
+ $execute .= "i += inc;\n";
+
+ my $inner;
+ my $inner_count = 0;
+ if ($atom eq '{') {
+ getatom;
+ $inner = process_item(keys %maskhash);
+ $inner_count++ if $inner;
+ while ($atom ne '}') {
+ $t = process_item(keys %maskhash);
+ if ($t) {
+ $inner .= "else " . $t;
+ $inner_count++;
+ }
+ }
+ }
+ else {
+ die "expected ';' or '{' got $atom" if $atom ne ';';
+ }
+ if ($inner_count==1) {
+ $execute .= $inner;
+ }
+ elsif ($inner_count>=2) {
+ $inner .= "else break;\n";
+ $inner =~ s/^/ /gm;
+ $execute .= "while (1) {\n$inner}\n";
+ }
+
+ getatom;
+ $execute =~ s/^/ /gm;
+#$t=$title_item;
+#$t =~ s/\n/\\n/sg;
+#$t =~ s/\"/\\\"/g;
+#$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)";
+ $execute = "if ($title_item) {\n$execute}\n";
+ return $execute;
+}
+
+
+sub process_expire {
+ my $title_item;
+ $title_item = title_item;
+ while ($atom eq '|') {
+ getatom;
+ $title_item .= " ||\n " . title_item;
+ }
+ die "expected ':'\n" if $atom ne ':';
+
+ my $type;
+
+ my $execute = '';
+ while ($atom =~ /^(\:|\,)$/) {
+ getatom;
+ $type = $atom;
+ last if $atom eq '{';
+ getatom;
+ my $field = $atom;
+ getatom;
+ my $mask = $atom;
+ getatom;
+ die "expected three fields\n" if !defined($atom);
+
+#$execute .= "printf(\"executing for $type $field $mask\\n\");\n";
+
+ if ($type =~ /^MASK\_(.*)$/) {
+ if ($field eq 'enabled_ctrls') {
+ ($axmask,$axvalues) = ('axt_ctrls_mask','axt_ctrls_values');
+ }
+ elsif ($field eq 'ax_options') {
+ ($axmask,$axvalues) = ('axt_opts_mask','axt_opts_values');
+ }
+ else {
+ ($axmask,$axvalues) = ('','');
+ }
+ if ($axmask) {
+ $execute .= "if (argv[i][0] == '-') {\n" .
+ " ctrls->$axmask |= $1;\n" .
+ " ctrls->$axvalues &= ~$1;\n" .
+ "}\n" .
+ "else if (argv[i][0] == '=') {\n" .
+ " ctrls->$axmask &= ~$1;\n" .
+ " ctrls->$axvalues &= ~$1;\n" .
+ "}\n" .
+ "else {\n" .
+ " ctrls->$axmask |= $1;\n" .
+ " ctrls->$axvalues |= $1;\n" .
+ "}\n";
+ $temp1 = $title_item;
+ $temp1 =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"-$2\"\)/g;
+ $temp2 = $title_item;
+ $temp2 =~ s/strcmp\(([^\,]+)\,\"([^\"]+)\"\)/strcmp\($1,\"\=$2\"\)/g;
+ $title_item .= " ||\n $temp1 ||\n $temp2";
+ }
+ }
+ }
+
+ $execute .= "i += inc;\n";
+
+ my $inner;
+ my $inner_count = 0;
+ if ($atom eq '{') {
+ getatom;
+ $inner = process_expire();
+ $inner_count++ if $inner;
+ while ($atom ne '}') {
+ $t = process_expire();
+ if ($t) {
+ $inner .= "else " . $t;
+ $inner_count++;
+ }
+ }
+ }
+ else {
+ die "expected ';' or '{'" if $atom ne ';';
+ }
+ if ($inner_count==1) {
+ $execute .= $inner;
+ }
+ elsif ($inner_count>=2) {
+ $inner .= "else break;\n";
+ $inner =~ s/^/ /gm;
+ $execute .= "while (1) {\n$inner}\n";
+ }
+
+ getatom;
+ $execute =~ s/^/ /gm;
+#$t=$title_item;
+#$t =~ s/\n/\\n/sg;
+#$t =~ s/\"/\\\"/g;
+#$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)";
+ $execute = "if ($title_item) {\n$execute}\n";
+ return $type =~ /^MASK\_/ ? $execute : "";
+}
+
+
+
+
+
+############ main
+
+fetchatoms;
+$output .= process_item;
+while ($atom ne 'end') {
+ $output .= "else " . process_item;
+}
+$output .= "else return 0;";
+$output =~ s/^/ /gm;
+$vallist = join(', ', map "val$_",(1..$n_max));
+
+fetchatoms;
+$output_expire = process_expire;
+while ($atom ne 'end') {
+ $t = process_expire;
+ $output_expire .= "else " . $t if $t;
+}
+$output_expire .= "else if ((i+1<=argc && get_number(argv[i],0,65535,&val1) && (inc=1))) {\n" .
+ " ctrls->ax_timeout = val1;\n" .
+ " i += inc;\n" .
+ "}\n" .
+ "else return 0;";
+$output_expire =~ s/^/ /gm;
+
+open(GETC,">getargs.c");
+open(COPY,"COPYRIGHT");
+$copy = join '',<COPY>;
+print GETC <<EOM
+/*
+$copy
+*/
+
+#include "xkbset.h"
+
+Bool get_arguments(int argc, char *argv[], XkbControlsPtr ctrls, unsigned int *mask)
+{
+ char char_array_32[32];
+ int inc, i = 1;
+ int $vallist;
+
+ *mask = 0;
+ while (i<argc) {
+$output
+ }
+ return 1;
+}
+
+Bool get_expire_arguments(int argc, char *argv[], XkbControlsPtr ctrls, unsigned int *mask)
+{
+ int inc, i = 2;
+ int val1;
+
+ *mask = XkbAccessXTimeoutMask;
+ while (i<argc) {
+$output_expire
+ }
+ return 1;
+}
+EOM
diff --git a/create_print b/create_print
new file mode 100644
index 0000000..b64401f
--- /dev/null
+++ b/create_print
@@ -0,0 +1,217 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+open(PRINTC,">print.c");
+
+open(CONFIG,"config_print");
+
+$output = '';
+$outputline = '';
+$last_needs_mask = '';
+$last_needs_enum = '';
+
+while ($line = <CONFIG>) {
+ next if $line =~ /^\#/ || $line =~ /^\s*$/;
+
+ if ($line =~ /^[A-Z]/) {
+ ($type,$field,@title) = split ' ',$line;
+ $title = join ' ',@title;
+
+ if ($type =~ /^MASK\_(.*)$/) {
+ $output .= "printf(\"$title = %s\\n\", (ctrls->$field & $1)?\"On\":\"Off\");\n";
+ die "mask error\n" if !$last_needs_mask;
+ $outputline .= "printf(\" %s\",\"$last_needs_mask\" + ((ctrls->$field & $1) != 0));\n";
+ $last_needs_mask = '';
+ }
+ elsif ($last_needs_mask) {
+ die "mask error\n";
+ }
+ elsif ($type =~/^(USHORT|SHORT|UCHAR)$/) {
+ $output .= "printf(\"$title = %d\\n\", ctrls->$field);\n";
+ $outputline .= "printf(\" %d\", ctrls->$field);\n";
+ }
+ elsif ($type eq 'CHAR_ARRAY_32') {
+ $output .= "printf(\"$title =\");\n" .
+ "for (i=0;i<32;i++) {\n" .
+ " if (i%8==0) printf(\"\\n \");\n" .
+ " printf(\"%x%x\",ctrls->$field\[i]>>4,ctrls->$field\[i]&15);\n" .
+ "}\n" .
+ "printf(\"\\n\");\n";
+ $outputline .= "printf(\" \");\n" .
+ "for (i=0;i<32;i++)\n" .
+ " printf(\"%x%x\",ctrls->$field\[i]>>4,ctrls->$field\[i]&15);\n";
+ }
+ elsif ($type eq 'HIGH_NIBBLE_ENUM') {
+ die "enum error\n" if !$last_needs_enum;
+ $output .= "printf(\"$title = \");\n";
+ $outputline .= "s = NULL;\n";
+ $line = <CONFIG>;
+ $line =~ s/\s//g;
+ $first = 1;
+ foreach $enum (split ',',$line) {
+ ($code,$value) = split '=',$enum;
+ $output .= (!$first?"else ":"") .
+ "if ((ctrls->$field & 0xF0) == $value) printf(\"$code\\n\");\n";
+ $outputline .= (!$first?"else ":"") .
+ "if ((ctrls->$field & 0xF0)== $value) s = \"$code\";\n";
+ $first = 0;
+ }
+ $output .= "else printf(\"undefined\\n\");\n";
+ $outputline .= "if (s!=NULL) printf(\" " . substr($last_needs_enum,1) . " %s\",s);\n";
+ $last_needs_enum = 0;
+ }
+ elsif ($type eq 'LOW_NIBBLE_IF_HIGH_NIBBLE_ENUM') {
+ $output .= "printf(\"$title = %d\\n\", ctrls->$field & 0x0F);\n";
+ $outputline .= "print_nibble = 0;\n";
+ $line = <CONFIG>;
+ $line =~ s/\s//g;
+ $first = 1;
+ foreach $enum (split ',',$line) {
+ ($code,$value) = split '=',$enum;
+ $outputline .= (!$first?"else ":"") .
+ "if ((ctrls->$field & 0xF0)== $value) print_nibble = 1;\n";
+ $first = 0;
+ }
+ $outputline .= "if (print_nibble) printf(\" %d\", ctrls->$field & 0x0F);\n";
+ $last_needs_enum = 0;
+ }
+ else {
+ die "syntax error";
+ }
+ }
+ else {
+ chomp($line);
+ if ($line =~ /^\-/) {
+ $last_needs_mask = $line;
+ }
+ elsif ($line =~ /^\+/) {
+ $last_needs_enum = $line;
+ }
+ else {
+ $outputline .= "printf(\" $line\");\n";
+ }
+ }
+}
+
+$output =~ s/^/ /gm;
+$outputline =~ s/^/ /gm;
+
+close CONFIG;
+
+open(COPY,"COPYRIGHT");
+$copy = join '',<COPY>;
+print PRINTC <<EOM;
+/*
+$copy
+*/
+
+#include "xkbset.h"
+
+void print_controls(XkbControlsPtr ctrls) {
+ int i;
+
+$output
+}
+
+void print_controls_in_line(XkbControlsPtr ctrls) {
+ int i;
+ char *s;
+ int print_nibble;
+
+ printf(\"xkbset\");
+$outputline
+ printf(\"\\n\");
+}
+EOM
+
+
+########
+
+open(CONFIG,"config_print");
+
+$output = '';
+$outputline = '';
+$last_needs_mask = '';
+
+while ($line = <CONFIG>) {
+ next if $line =~ /^\#/ || $line =~ /^\s*$/;
+
+ if ($line =~ /^[A-Z]/) {
+ ($type,$field,@title) = split ' ',$line;
+ $title = join ' ',@title;
+
+ if ($type =~ /^MASK\_(.*)$/) {
+ if ($field eq 'enabled_ctrls') {
+ ($axmask,$axvalues) = ('axt_ctrls_mask','axt_ctrls_values');
+ }
+ elsif ($field eq 'ax_options') {
+ ($axmask,$axvalues) = ('axt_opts_mask','axt_opts_values');
+ }
+ else {
+ ($axmask,$axvalues) = ('','');
+ }
+ if ($axmask) {
+ $output .= "printf(\"Upon Expiry $title will be: %s\\n\",\n" .
+ " (ctrls->$axmask & $1)?((ctrls->$axvalues & $1)?\"On\":\"Off\"):\"Unchanged\");\n";
+ $t = substr $last_needs_mask,1;
+ $outputline .= "printf(\" %s$t\",\n" .
+ " (ctrls->$axmask & $1)?((ctrls->$axvalues & $1)?\"\":\"-\"):\"=\");\n";
+ $last_needs_mask = '';
+ }
+ }
+ elsif ($last_needs_mask) {
+ die "mask error\n";
+ }
+ }
+ else {
+ chomp($line);
+ if ($line =~ /^\-/) {
+ $last_needs_mask = $line;
+ }
+ }
+}
+
+$output =~ s/^/ /gm;
+$outputline =~ s/^/ /gm;
+
+close CONFIG;
+
+print PRINTC <<EOM
+
+void print_expire_controls(XkbControlsPtr ctrls) {
+ printf(\"AccessX Timeout = %d\\n\",ctrls->ax_timeout);
+$output
+}
+
+void print_expire_controls_in_line(XkbControlsPtr ctrls) {
+ printf(\"xkbset exp %d\",ctrls->ax_timeout);
+$outputline
+ printf(\"\\n\");
+}
+EOM
diff --git a/create_usage b/create_usage
new file mode 100644
index 0000000..e8f4bd3
--- /dev/null
+++ b/create_usage
@@ -0,0 +1,367 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+sub setatom {
+ $atom = $atomlist[$atomcount];
+}
+
+sub getatom {
+ $atomcount++;
+ setatom;
+}
+
+sub pushatom {
+ $atomcount--;
+ setatom;
+}
+
+sub fetchatoms {
+ @atomlist = ();
+ open(CONFIG,"config_getargs");
+ while ($line = <CONFIG>) {
+ if ($line =~ /^\#/) {
+ push(@atomlist,$line);
+ } else {
+ while (1) {
+ next if ($line =~ s/^\s+//);
+ if ($line =~ s/^\"([^\"]*)\"//) {}
+ elsif ($line =~ s/^([a-zA-Z\_][a-zA-Z\_0-9]*)//) {}
+ elsif ($line =~ s/^(\%\d*[a-zA-Z])//) {}
+ elsif ($line =~ s/^(\S)//) {}
+ else { last }
+ push(@atomlist,$1);
+ }
+ }
+ }
+ close(CONFIG);
+ push(@atomlist,"end");
+ $atomcount = 0;
+ setatom;
+}
+
+sub enum_value {
+ my $enum = '';
+ getatom; $enum = $atom;
+ getatom; die if $atom ne '=';
+ getatom;
+ getatom;
+ return $enum;
+}
+
+sub sub_title_item {
+ my $item;
+ if ($atom =~ /^[a-zA-Z0-9]/) {
+ $item = $atom;
+ }
+ elsif ($atom eq '%d') {
+ $item = "<VAL>"
+ }
+ elsif ($atom eq '%64x') {
+ $item = "<VAL>"
+ }
+ elsif ($atom eq '%e') {
+ getatom;
+ die "'{' expected at beginning of enum list\n" if $atom ne '{';
+ $item = enum_value;
+ while ($atom eq ';') {
+ $item .= "|" . enum_value;
+ }
+ $item = "{$item}";
+ die "'}' expected at end of enum list - got $atom\n" if $atom ne '}';
+ }
+ getatom if defined($item);
+ return $item;
+}
+
+sub title_item {
+ my $title_item = sub_title_item;
+ my $next_item;
+ die "syntax error in title - atom is $atom" if !defined($title_item);
+ while(defined($next_item = sub_title_item)) {
+ $title_item = "$title_item $next_item";
+ }
+ return $title_item;
+}
+
+sub substitute {
+ @t=();
+ foreach $t (split /\|/,$_[0]) {
+ $t =~ s/VAL/$_[1]/;
+ push(@t,$t);
+ }
+ return join '|',@t;
+}
+
+sub process_item {
+ my $comment="";
+ while ($atom =~ /^\#/) {
+ $comment .= "#$1\n" if $atom =~ /^\#C\s*(.*)/;
+ getatom;
+ }
+ my $title_item;
+ $title_item = title_item;
+ while ($atom eq '|') {
+ getatom;
+ $title_item .= "|" . title_item;
+ }
+ die "expected ':'\n" if $atom ne ':';
+
+ my $minus = 0;
+ while ($atom =~ /^(\:|\,)$/) {
+ getatom;
+ my $type = $atom;
+ last if $atom eq '{';
+ getatom;
+ my $field = $atom;
+ getatom;
+ my $mask = $atom;
+ getatom;
+ die "expected three fields\n" if !defined($atom);
+
+#$execute .= "printf(\"executing for $type $field $mask\\n\");\n";
+
+ if ($type !~ /^MASK\_(.*)$/) {
+ $title_item = substitute($title_item,$field);
+ }
+ $minus = 1 if $type eq 'BIT32' || $type =~ /^MASK\_/;
+ }
+
+ $t = $title_item;
+ while ($t=~s/\{[^\}]*\}//) {}
+ $title_item = "{$title_item}" if $t =~/\|/;
+ $title_item = "[-]$title_item" if $minus;
+
+ my $inner;
+ my $inner_count = 0;
+ if ($atom eq '{') {
+ getatom;
+ $inner = process_item();
+ $inner_count++ if $inner;
+ while ($atom ne '}') {
+ $t = process_item();
+ if ($t) {
+ $inner .= "|" . $t;
+ $inner_count++;
+ }
+ }
+ }
+ else {
+ die "expected ';' or '{'\n" if $atom ne ';';
+ }
+ if ($inner_count==1) {
+ $execute = " [$inner]";
+ }
+ elsif ($inner_count>=2) {
+ $execute = " [$inner]...";
+ }
+ else {
+ $execute = "";
+ }
+ getatom;
+#$t=$title_item;
+#$t =~ s/\n/\\n/sg;
+#$t =~ s/\"/\\\"/g;
+#$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)";
+ $comment = "\n$comment\n" if $comment;
+ $execute = "$comment$title_item$execute";
+ return $execute;
+}
+
+
+sub process_expire {
+ while ($atom =~ /^\#/) {
+ getatom;
+ }
+ my $title_item;
+ $title_item = title_item;
+ while ($atom eq '|') {
+ getatom;
+ $title_item .= "|" . title_item;
+ }
+ die "expected ':'\n" if $atom ne ':';
+
+ my $minus = 0;
+ my $execute = '';
+ while ($atom =~ /^(\:|\,)$/) {
+ getatom;
+ my $type = $atom;
+ last if $atom eq '{';
+ getatom;
+ my $field = $atom;
+ getatom;
+ my $mask = $atom;
+ getatom;
+ die "expected three fields\n" if !defined($atom);
+
+#$execute .= "printf(\"executing for $type $field $mask\\n\");\n";
+
+ $minus = 1 if $type =~ /^MASK\_(.*)$/;
+ }
+
+ $t = $title_item;
+ while ($t=~s/\{[^\}]*\}//) {}
+ $title_item = "{$title_item}" if $t =~/\|/;
+ $title_item = "[-|=]$title_item" if $minus;
+
+ my $inner;
+ my $inner_count = 0;
+ if ($atom eq '{') {
+ getatom;
+ $inner = process_expire();
+ $inner_count++ if $inner;
+ while ($atom ne '}') {
+ $t = process_expire();
+ if ($t) {
+ $inner .= "|" . $t;
+ $inner_count++;
+ }
+ }
+ }
+ else {
+ die "expected ';' or '{'\n" if $atom ne ';';
+ }
+ if ($inner_count==1) {
+ $execute = " [$inner]";
+ }
+ elsif ($inner_count>=2) {
+ $execute = " [$inner]...";
+ }
+ else {
+ $execute = "";
+ }
+ getatom;
+#$t=$title_item;
+#$t =~ s/\n/\\n/sg;
+#$t =~ s/\"/\\\"/g;
+#$title_item = "(printf(\"checking $t i = %d (%s)\\n\",i,argv[i])||1) && ($title_item)";
+ $execute = "$title_item$execute";
+ return $minus ? $execute : "";
+}
+
+
+
+
+
+############ main
+
+fetchatoms;
+$output .= process_item;
+while ($atom ne 'end') {
+ $output .= "\n" . process_item;
+}
+
+fetchatoms;
+$output_expire = "<ax_timeout>\n" . process_expire;
+while ($atom ne 'end') {
+ $t = process_expire;
+ $output_expire .= "\n" . $t if $t;
+}
+my @output = ();
+foreach $line(split "\n",$output) {
+ if ($line =~ /\#(.*)/) {
+ push(@output,$1);
+ } else {
+ while (length($line) > 70) {
+ for($i=69;substr($line,$i,1) !~ /\|| /;$i--) {}
+ push(@output," " . substr($line,0,$i+1));
+ $line = " " . substr($line,$i+1);
+ }
+ push(@output," " . $line);
+ }
+}
+$output = join "\n",@output;
+@output = ();
+foreach $line(split "\n",$output_expire) {
+ while (length($line) > 70) {
+ for($i=69;substr($line,$i,1) !~ /\|| / ||
+ substr($line,$i-1,3) =~ /\-\|\=/;$i--) {}
+ push(@output," " . substr($line,0,$i+1));
+ $line = " " . substr($line,$i+1);
+ }
+ push(@output," " . $line);
+}
+$output_expire = join "\n",@output;
+
+$usage = <<EOM;
+Usage: To set or unset various options:
+
+ xkbset <options>
+
+where <options> may be all or any of (the '-' switches the feature off,
+otherwise it is switched on):
+$output
+
+
+
+To set the AccessX expire controls:
+
+ xkbset exp <options>
+
+where <options> may be all or any of (<ax_timeout> is the timeout (in
+seconds) after which no user activity on X will cause the expiry; '-'
+indicates the feature will be switched off, '=' incicates the feature
+will be left unchanged, otherwise it will be switched on):
+
+$output_expire
+
+To see the current values of the controls:
+
+ xkbset q
+
+To see the current values of what controls will expire:
+
+ xkbset q exp
+
+To have these values written as a command line:
+
+ xkbset w [exp]
+
+To print this help message
+
+ xkbset [h]
+
+EOM
+
+$usage =~ s/^(.*)$/ printf\(\"$1\\n\"\);/mg;
+
+open(GETC,">usage.c");
+open(COPY,"COPYRIGHT");
+$copy = join '',<COPY>;
+print GETC <<EOM
+/*
+$copy
+*/
+
+#include "xkbset.h"
+
+void print_usage()
+{
+$usage
+}
+EOM
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..548b533
--- /dev/null
+++ b/main.c
@@ -0,0 +1,150 @@
+/*
+Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Stephen Montgomery-Smith nor the names of his
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "xkbset.h"
+
+
+int main(int argc, char *argv[]) {
+ Display *display;
+ int event_rtrn, error_rtrn;
+ int major_in_out = XkbMajorVersion;
+ int minor_in_out = XkbMinorVersion;
+ int reason_rtrn;
+/*
+ XkbControlsRec junk;
+*/
+ XkbDescPtr xkb;
+ unsigned int mask = 0;
+ Bool query, write_line, expire, query_expire, write_line_expire;
+ Status status;
+
+ if (argc == 1) {
+ print_usage();
+ exit(0);
+ }
+ query = argc==2 && strcmp(argv[1],"q")==0;
+ write_line = argc==2 && strcmp(argv[1],"w")==0;
+ query_expire = argc==3 && strcmp(argv[1],"q")==0 && strcmp(argv[2],"exp")==0;
+ write_line_expire = argc==3 && strcmp(argv[1],"w")==0 && strcmp(argv[2],"exp")==0;;
+ expire = argc>=2 && strcmp(argv[1],"exp")==0;
+
+/*
+ if (query || write_line)
+ mask = XkbAllControlsMask;
+ The first time we call get_arguments is just to get mask
+ No we don't - XkbGetControls seems buggy with repect to getting
+ ax_options if the mask is selective
+ else if (query_expire || write_line_expire)
+ mask = XkbAccessXTimeoutMask;
+ else if (expire) {
+ if (!get_expire_arguments(argc,argv, &junk, &mask)) {
+ print_usage();
+ exit(1);
+ }
+ }
+ else if (!get_arguments(argc,argv, &junk, &mask)) {
+ print_usage();
+ exit(1);
+ }
+*/
+
+ display = XkbOpenDisplay(NULL,
+ &event_rtrn, &error_rtrn, &major_in_out,
+ &minor_in_out, &reason_rtrn);
+ if (reason_rtrn != XkbOD_Success) {
+ switch(reason_rtrn) {
+ case XkbOD_BadLibraryVersion:
+ case XkbOD_BadServerVersion:
+ case XkbOD_NonXkbServer:
+ fprintf(stderr,"Non-existent or incompatible XKB library version\n");
+ break;
+ case XkbOD_ConnectionRefused:
+ fprintf(stderr, "Unable to open display\n");
+ break;
+ default:
+ fprintf(stderr, "Unknown error in XkbOpenDisplay\n");
+ break;
+ }
+ exit(1);
+ }
+
+ xkb = XkbGetKeyboard(display,XkbControlsMask,XkbUseCoreKbd);
+ if (xkb == 0) {
+ fprintf(stderr, "XKB not supported for display %s\n", getenv("DISPLAY"));
+ exit(1);
+ }
+
+ status = XkbGetControls(display, XkbAccessXTimeoutMask|XkbAllControlsMask, xkb);
+ switch(status) {
+ case Success:
+ break;
+ case BadAlloc:
+ fprintf(stderr,"Allocation error in XkbGetControls\n");
+ exit(1);
+ case BadMatch:
+ fprintf(stderr,"Bad match in XkbGetControls\n");
+ exit(1);
+ case BadImplementation:
+ fprintf(stderr,"Bad implementation in XkbGetControls\n");
+ exit(1);
+ default:
+ fprintf(stderr,"Unknown error in XkbGetControls\n");
+ exit(1);
+ }
+
+ if (query) {
+ print_controls(xkb->ctrls);
+ }
+ else if (write_line) {
+ print_controls_in_line(xkb->ctrls);
+ }
+ else if (query_expire) {
+ print_expire_controls(xkb->ctrls);
+ }
+ else if (write_line_expire) {
+ print_expire_controls_in_line(xkb->ctrls);
+ }
+ else if (expire) {
+ if (!get_expire_arguments(argc,argv, xkb->ctrls, &mask)) {
+ print_usage();
+ exit(1);
+ }
+ XkbSetControls(display, mask, xkb);
+ }
+ else {
+ if (!get_arguments(argc,argv, xkb->ctrls, &mask)) {
+ print_usage();
+ exit(1);
+ }
+ XkbSetControls(display, mask, xkb);
+ }
+
+ XCloseDisplay(display);
+ exit(0);
+}
diff --git a/misc.c b/misc.c
new file mode 100644
index 0000000..1dcbb0f
--- /dev/null
+++ b/misc.c
@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Stephen Montgomery-Smith nor the names of his
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "xkbset.h"
+
+Bool get_number(char *arg, int low, int high, int *val) {
+ int i;
+
+ for (i=0;i<(int)strlen(arg);i++)
+ if ((arg[i]<'0' || arg[i]>'9') && (i!=0 || arg[0]!='-'))
+ return 0;
+ *val = atoi(arg);
+ if (*val<low || *val>high)
+ return 0;
+ return 1;
+}
+
+#define digit(c) ( ((c)>='0'&&(c)<='9')?(c)-'0': \
+ ((c)>='a'&&(c)<='f')?(c)-'a'+10: \
+ ((c)>='A'&&(c)<='F')?(c)-'A'+10: \
+ (success = 0) )
+Bool get_64_hex(char *arg, char array[32]) {
+ int i, success = 1;
+
+ for(i=0;i<64&&success;i++)
+ if (i%2==0)
+ array[i/2] = digit(arg[i])*16;
+ else
+ array[i/2] += digit(arg[i]);
+ return success;
+}
diff --git a/xkbset-gui b/xkbset-gui
new file mode 100755
index 0000000..24ee8c5
--- /dev/null
+++ b/xkbset-gui
@@ -0,0 +1,267 @@
+#!/usr/bin/perl -w
+
+# Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+use Tk;
+
+my $mousekeys = 0;
+my $mousekeysaccel = 1;
+my $mk_delay = 160;
+my $mk_interval = 40;
+my $mk_time_to_max = 30;
+my $mk_max_speed = 30;
+my $mk_curve = 500;
+
+my $mw = MainWindow->new;
+
+$mw->title("MouseKeys Acceleration Management");
+
+read_values(`xkbset w`);
+
+do_widgets();
+
+MainLoop;
+
+sub do_widgets {
+
+ $outer_frame_mk_delay = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mk_delay = $outer_frame_mk_delay->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+ $outer_frame_mk_interval = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mk_interval = $outer_frame_mk_interval->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+ $outer_frame_mk_time_to_max = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mk_time_to_max = $outer_frame_mk_time_to_max->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+ $outer_frame_mk_max_speed = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mk_max_speed = $outer_frame_mk_max_speed->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+ $outer_frame_mk_curve = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mk_curve = $outer_frame_mk_curve->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+
+ $outer_frame_mouse_buttons = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_mouse_buttons = $outer_frame_mouse_buttons->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+
+ $outer_frame_canvas = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_canvas = $outer_frame_canvas->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+ $frame_canvas->Label(-textvariable=>\$inform,-justify=>"left")
+ ->pack(-anchor=>"w");
+ $canvas =
+ $frame_canvas->Canvas(-height=>220,width=>500,-borderwidth=>0)
+ ->pack;
+
+ $outer_frame_set_buttons = $mw->Frame(-borderwidth=>5)->pack;
+ $frame_set_buttons = $outer_frame_set_buttons->Frame(-borderwidth=>2,-relief=>"groove")->pack;
+ $frame_set_buttons->Button(-text=>"Rescale scales",-command=>\&do_scale_widgets)
+ ->pack(-side=>"left",-expand=>1);
+ $frame_set_buttons->Button(-text=>"Restore values",
+ -command=>sub{read_values(`xkbset w`);do_scale_widgets()})
+ ->pack(-side=>"left",-expand=>1);
+ $frame_set_buttons->Button(-text=>"Apply Changes",-command=>\&apply_changes)
+ ->pack(-side=>"left",-expand=>1);
+ $frame_set_buttons->Button(-text=>"Save in .xsession",-command=>\&save_in_xsession)
+ ->pack(-side=>"left",-expand=>1);
+ $frame_set_buttons->Button(-text=>"Quit",
+ -command=>sub{exit})
+ ->pack(-side=>"left",-expand=>1);
+
+ do_scale_widgets();
+}
+
+sub do_scale_widgets {
+
+ $scale_mk_delay->destroy() if Tk::Exists($scale_mk_delay);
+ $scale_mk_delay =
+ $frame_mk_delay->Scale(-variable=>\$mk_delay,
+ -from=>1,-to=>10+3*$mk_delay,-resolution=>1,
+ -orient=>"horizontal",
+ -command=>\&draw_curve,
+ -borderwidth=>0,
+ -length=>500)->pack;
+ $label_mk_delay->destroy() if Tk::Exists($label_mk_delay);
+ $label_mk_delay =
+ $frame_mk_delay->Label(-text=>"Delay before acceleration starts (milliseconds)"
+ )->pack(-anchor=>"w");
+
+
+ $scale_mk_interval->destroy() if Tk::Exists($scale_mk_interval);
+ $scale_mk_interval =
+ $frame_mk_interval->Scale(-variable=>\$mk_interval,
+ -from=>1,-to=>10+3*$mk_interval,-resolution=>1,
+ -orient=>"horizontal",
+ -command=>\&draw_curve,
+ -borderwidth=>0,
+ -length=>500)->pack;
+ $label_mk_interval->destroy() if Tk::Exists($label_mk_interval);
+ $label_mk_interval =
+ $frame_mk_interval->Label(-text=>"Time between pointer movements (milliseconds)"
+ )->pack(-anchor=>"w");
+
+ $scale_mk_time_to_max->destroy() if Tk::Exists($scale_mk_time_to_max);
+ $scale_mk_time_to_max =
+ $frame_mk_time_to_max->Scale(-variable=>\$mk_time_to_max,
+ -from=>1,-to=>10+3*$mk_time_to_max,-resolution=>1,
+ -orient=>"horizontal",
+ -command=>\&draw_curve,
+ -borderwidth=>0,
+ -length=>500)->pack;
+ $label_mk_time_to_max->destroy() if Tk::Exists($label_mk_time_to_max);
+ $label_mk_time_to_max =
+ $frame_mk_time_to_max->Label(-text=>"Number of pointer movements before accleration completed"
+ )->pack(-anchor=>"w");
+
+ $scale_mk_max_speed->destroy() if Tk::Exists($scale_mk_max_speed);
+ $scale_mk_max_speed =
+ $frame_mk_max_speed->Scale(-variable=>\$mk_max_speed,
+ -from=>1,-to=>10+3*$mk_max_speed,-resolution=>1,
+ -orient=>"horizontal",
+ -command=>\&draw_curve,
+ -borderwidth=>0,
+ -length=>500)->pack;
+ $label_mk_max_speed->destroy() if Tk::Exists($label_mk_max_speed);
+ $label_mk_max_speed =
+ $frame_mk_max_speed->Label(-text=>"Speed (pixels per pointer movement) after acceleration completed"
+ )->pack(-anchor=>"w");
+
+ $mk_curve_to = $mk_curve*3<5000 ? 5000 : 3*$mk_curve;
+ $mk_curve_to = 32000 if $mk_curve_to > 32000;
+ $scale_mk_curve->destroy() if Tk::Exists($scale_mk_curve);
+ $scale_mk_curve =
+ $frame_mk_curve->Scale(-variable=>\$mk_curve,
+ -from=>-1000,-to=>$mk_curve_to,-resolution=>100,
+ -orient=>"horizontal",
+ -command=>\&draw_curve,
+ -borderwidth=>0,
+ -length=>500)->pack;
+ $label_mk_curve->destroy() if Tk::Exists($label_mk_curve);
+ $label_mk_curve =
+ $frame_mk_curve->Label(-text=>"Acceleration curve factor"
+ )->pack(-anchor=>"w");
+
+ $mousekeysinfo=$mousekeys?
+ "MouseKeys Enabled":
+ "MouseKeys Disabled";
+ $mouse_button->destroy() if Tk::Exists($mouse_button);
+ $mouse_button =
+ $frame_mouse_buttons->Button(-textvariable=>\$mousekeysinfo,
+ -command=>sub{$mousekeys^=1;
+ $mousekeysinfo=$mousekeys?
+ "MouseKeys Enabled":
+ "MouseKeys Disabled"})
+ ->pack(-side=>"left",-expand=>1);
+
+ $mousekeysaccelinfo=$mousekeysaccel?
+ "Acceleration Enabled":
+ "Acceleration Disabled";
+ $mouseaccel_button->destroy() if Tk::Exists($mouseaccel_button);
+ $mouseaccel_button =
+ $frame_mouse_buttons->Button(-textvariable=>\$mousekeysaccelinfo,
+ -command=>sub{$mousekeysaccel^=1;
+ $mousekeysaccelinfo=$mousekeysaccel?
+ "Acceleration Enabled":
+ "Acceleration Disabled"})
+ ->pack(-side=>"left",-expand=>1);
+
+
+}
+
+sub draw_curve {
+ my $alpha = 1 + $mk_curve/1000;
+ my @coords;
+ $canvas->delete("all");
+
+ $xscale = 500/($mk_delay+$mk_time_to_max*$mk_interval*1.5);
+
+ @coords = (0,10+210,$mk_delay*$xscale,10+210,
+ $mk_delay*$xscale,10+200*(1-1/$mk_max_speed));
+ if ($alpha == 0) {
+ push(@coords,$mk_delay*$xscale,10,500,10);
+ }
+ else {
+ if ($mk_time_to_max > 0) {
+# for ($n=0;$n<=$mk_time_to_max+0.05;$n+=0.1) {
+ for ($t=0;$t<=100;$t++) {
+ $n=$t*$mk_time_to_max/100;
+ $x=$mk_delay+$n*$mk_interval;
+ $y=(1+($mk_max_speed-1)*pow($n/$mk_time_to_max,$alpha))/$mk_max_speed;
+ push(@coords,$x*$xscale,10+200*(1-$y));
+ }
+ } else {
+# ??? push(@coords,
+ }
+ }
+ push(@coords,500,10);
+ $canvas->createLine(@coords);
+ $canvas->createText($mk_delay*$xscale,210,
+ -text=>$mk_delay . " ms",-anchor=>"w");
+ $canvas->createText(0,10+200*(1-1/$mk_max_speed),
+ -text=>int(1000/$mk_interval) . " pix/s",-anchor=>"sw")
+ if $mk_max_speed != 1;
+ $canvas->createText(0,10,
+ -text=>int(1000*$mk_max_speed/$mk_interval) . " pix/s",-anchor=>"w");
+ $canvas->createText(($mk_delay+$mk_time_to_max*$mk_interval)*$xscale,210,
+ -text=>($mk_delay+$mk_time_to_max*$mk_interval)." ms");
+ $inform = "Total time until full acceleration is " .
+ ($mk_delay+$mk_time_to_max*$mk_interval) . " milliseconds\n" .
+ "Initial speed is " . int(1000/$mk_interval) . " pixels per second\n" .
+ "Max speed is " . int(1000*$mk_max_speed/$mk_interval) . " pixels per second\n\n" .
+ "Velocity/Time graph";
+}
+
+sub pow {
+ return $_[0] == 0 ? 0 : exp($_[1]*log($_[0]));
+}
+
+sub read_values {
+ if ($_[0] =~ / (\-?)ma (\d+) (\d+) (\d+) (\d+) (\d+) /) {
+ $mousekeysaccel = $1 ne '-';
+ $mk_delay = $2;
+ $mk_interval = $3;
+ $mk_time_to_max = $4;
+ $mk_max_speed = $5;
+ $mk_curve = $6;
+ }
+ if ($_[0] =~ / (\-?)m /) {
+ $mousekeys = $1 ne '-';
+ }
+}
+
+sub apply_changes {
+ system "xkbset " . ($mousekeys?"":"-") . "m " . ($mousekeysaccel?"":"-") . "ma $mk_delay $mk_interval $mk_time_to_max $mk_max_speed $mk_curve";
+}
+
+sub save_in_xsession {
+ if (defined($ENV{"HOME"})) {
+ if (-e "$ENV{'HOME'}/.xsession") {
+ system "perl -i -ne \"print if !/^xkbset /\" $ENV{'HOME'}/.xsession";
+ }
+ system "xkbset w >> $ENV{'HOME'}/.xsession";
+ }
+# system "xkbset " . ($mousekeys?"":"-") . "m " . ($mousekeysaccel?"":"-") . "ma $mk_delay $mk_interval $mk_time_to_max $mk_max_speed $mk_curve";
+}
diff --git a/xkbset.h b/xkbset.h
new file mode 100644
index 0000000..ad50e64
--- /dev/null
+++ b/xkbset.h
@@ -0,0 +1,44 @@
+/*
+Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Stephen Montgomery-Smith nor the names of his
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <X11/Xlib.h>
+#include <X11/XKBlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+Bool get_arguments(int argc, char *argv[], XkbControlsPtr ctrls, unsigned int *mask);
+Bool get_expire_arguments(int argc, char *argv[], XkbControlsPtr ctrls, unsigned int *mask);
+Bool get_number(char *arg, int low, int high, int *val);
+Bool get_64_hex(char *arg, char array[32]);
+void print_controls(XkbControlsPtr ctrls);
+void print_controls_in_line(XkbControlsPtr ctrls);
+void print_expire_controls(XkbControlsPtr ctrls);
+void print_expire_controls_in_line(XkbControlsPtr ctrls);
+void print_usage();
diff --git a/xkbset.man b/xkbset.man
new file mode 100644
index 0000000..d1ee5b3
--- /dev/null
+++ b/xkbset.man
@@ -0,0 +1,167 @@
+.\" Copyright (c) 2000, 2002 Stephen Montgomery-Smith
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of Stephen Montgomery-Smith nor the names of his
+.\" contributors may be used to endorse or promote products derived from
+.\" this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE STEPHEN MONTGOMERY-SMITH AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STEPHEN MONTGOMERY-SMITH OR
+.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+.\" OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH XKBSET 1 "Release 6.4" "X Version 11"
+.SH NAME
+xkbset - user preference utility for XKB extensions for X
+.SH SYNOPSIS
+.B xkbset
+h | \fIoptions\fP | exp \fIexpire-options\fP | q [exp] | w [exp]
+
+where \fIoptions\fP are any or all of:
+
+[-]{bell | b}
+
+[-]{repeatkeys \fIper-key_repeat> | r <per_key_repeat\fP}
+
+perkeyrepeat \fIper-key_repeat\fP
+
+[-]{repeatkeys | r} [rate \fIrepeat-delay> [<repeat_interval\fP]]
+
+[-]{mousekeys | m} [\fImk-dflt_btn\fP]
+
+[-]{mousekeysaccel | ma} [\fImk-delay> <mk_interval> <mk_time_to_max\fP
+\fImk-max_speed> <mk_curve\fP]
+
+[-]{accessx | a}
+
+[-]{sticky | st} [[-]twokey | [-]latchlock]...
+
+[-]{slowkeys | sl} [\fIslow-keys_delay\fP]
+
+[-]{bouncekeys | bo} [\fIdebounce-delay\fP]
+
+[-]{feedback | f} [[-]dumbbell | [-]led | [-]feature | [-]slowwarn |
+[-]slowpress | [-]slowaccept | [-]slowreject | [-]slowrelease |
+[-]bouncereject | [-]stickybeep]...
+
+[-]{overlay1 | ov1}
+
+[-]{overlay2 | ov2}
+
+groupswrap {redirect | clamp | wrap} [\fIgroups-wrap\fP]
+
+[-]ignoregrouplock
+
+nullify [[-]shift | [-]lock | [-]control | [-]mod1 | [-]mod2 | [-]mod3 | [-]mod4 |
+[-]mod5]...
+
+ignorelock [[-]shift | [-]lock | [-]control | [-]mod1 | [-]mod2 | [-]mod3 |
+[-]mod4 | [-]mod5]...
+
+
+and where \fIexpire-options\fP are any or all of:
+
+\fIax-timeout\fP
+
+[-|=]{bell | b}
+
+[-|=]{repeatkeys | r}
+
+[-|=]{mousekeys | m}
+
+[-|=]{mousekeysaccel | ma}
+
+[-|=]{accessx | a}
+
+[-|=]{sticky | st} [[-|=]twokey | [-|=]latchlock]...
+
+[-|=]{slowkeys | sl}
+
+[-|=]{bouncekeys | bo}
+
+[-|=]{feedback | f} [[-|=]dumbbell | [-|=]led | [-|=]feature | [-|=]slowwarn |
+[-|=]slowpress | [-|=]slowaccept | [-|=]slowreject | [-|=]slowrelease |
+[-|=]bouncereject | [-|=]stickybeep]...
+
+[-|=]{overlay1 | ov1}
+
+[-|=]{overlay2 | ov2}
+
+[-|=]ignoregrouplock
+
+
+.SH DESCRIPTION
+This program can be used to set various options available in the XKB
+extensions. This includes such things as
+.B mousekeys
+where one can use the numeric pad keys to move the mouse;
+.B stickykeys
+where modifiers like control and shift will lock until the
+next key press (good for one finger typing);
+.B slowkeys
+where the keys will not work unless they are pressed for a certain
+amount of time; and
+.B bouncekeys
+in which if a key is pressed more than once rapidly, only one key
+press will be registered.
+.SH OPTIONS
+.\-------------------- b
+.PP
+.TP 8
+.B b
+The \fBb\fP option controls whether the bell is switched on or off.
+.\-------------------- h
+.PP
+.TP 8
+.B h
+The \fBh\fP option (or no options) will type a rather helpful usage
+message - definitely more informative than this unfinished man page.
+.\-------------------- perkeyrepeat
+.TP 8
+.B perkeyrepeat \fIhex-mask\fP
+With this option, \fIhex-mask\fP is a sequence of 64 hex digits,
+representing 32 bytes. These bytes represent which keys will autorepeat,
+and which will not. The 8n+kth key will autorepeat if the kth bit
+of the nth byte is set. See also the \fBr\fP or the \fBrepeatkey\fP
+option.
+.\-------------------- r
+.TP 8
+.B repeatkeys|r [\fIkey-code\fP | \fBrate\fP \fIdelay\fP [\fIinterval\fP] ]
+The \fBr\fP or \fBrepeatkey\fP option can be used to control the
+autorepeat feature. By itself, it can switch the autorepeat on
+or off. Followed by a single number, it can be used
+to switch autorepeat on or off for that particular keycode (see also the
+\fBperkeyrepeat\fP option). Followed by \fBrate\fP, it can be used
+to set the time in milliseconds after the key is pressed before autorepeat
+will start, and optionally the time in milliseconds between the key
+repeats.
+.SH BUGS
+In some earlier versions of X, some of the features do not work
+properly. For example,
+mousekeys acceleration. Also, the
+.B perkeyrepeat
+option (or
+.B repeatkey
+followed by a key code) did not work. These are due to bugs in the
+XKB extensions. These bugs are fixed in more recent versions of X.
+
+Also the man page is woefully incomplete.
+.SH "SEE ALSO"
+xset(1)
+.SH AUTHOR
+Stephen Montgomery-Smith, University of Missouri