]> git.lyx.org Git - lyx.git/commitdiff
Added custom xvkbd for avoiding typing into other windows.
authorTommaso Cucinotta <tommaso@lyx.org>
Wed, 2 Feb 2011 23:18:16 +0000 (23:18 +0000)
committerTommaso Cucinotta <tommaso@lyx.org>
Wed, 2 Feb 2011 23:18:16 +0000 (23:18 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37439 a592a061-630c-0410-9148-cb99ea01b6c8

43 files changed:
development/autotests/Makefile
development/autotests/README
development/autotests/keytest.py
development/autotests/run-tests.sh
development/autotests/single-test.sh
development/autotests/xvkbd/Imakefile [new file with mode: 0644]
development/autotests/xvkbd/README [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-belgian.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-common.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-common.h [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-danish.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-fitaly.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-french.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-french2.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-german.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-greek.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-hebrew.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-icelandic.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-italian.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-jisx6002.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-jisx6004.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-korean.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-latin1.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-norwegian.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-portuguese.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-russian.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-slovene.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-small.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-spanish.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-strip.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-swedish.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-swissgerman.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-turkish.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd-uk.ad [new file with mode: 0644]
development/autotests/xvkbd/XVkbd.ad [new file with mode: 0644]
development/autotests/xvkbd/findwidget.c [new file with mode: 0644]
development/autotests/xvkbd/iconify.xbm [new file with mode: 0644]
development/autotests/xvkbd/resources.h [new file with mode: 0644]
development/autotests/xvkbd/xvkbd.c [new file with mode: 0644]
development/autotests/xvkbd/xvkbd.man [new file with mode: 0644]
development/autotests/xvkbd/xvkbd.xbm [new file with mode: 0644]
development/autotests/xvkbd/xvkbd_icon.xbm [new file with mode: 0644]
development/autotests/xvkbd/xvkbd_iconmask.xbm [new file with mode: 0644]

index 9c7820bebbb234548da20ecf0074e2ce409eaa57..200b425884d833625548821c37081915ab063a04 100644 (file)
@@ -1,2 +1,10 @@
-all:
+
+all: build-xvkbd run-tests
+
+.PHONY:
+build-xvkbd:
+       cd xvkbd && xmkmf && make
+
+.PHONY:
+run-tests: xvkbd
        ./run-tests.sh
index 52a162dad25eee33c68928055bf03057c3f6a429..6f437cdc7ce7b4ff55fb5adc42a434ca113cf61c 100644 (file)
@@ -1,33 +1,52 @@
 Automated tests based on the "MonKey Testing" keytest program.
+======================================================================
+
+WARNING!!
+----------------------------------------------------------------------
+Running the tests in this folder may cause abrupt kill of existing
+LyX instances on your system. In order to avoid any possible data
+loss, quit any running instance of LyX in which you're carrying out
+real work. Also, although precautions have been taken in order to not
+allow the key presses to reach non-LyX windows, this may sometimes
+happen anyway. Please, close any running application that is not
+strictly needed.
+
 
 DEPENDENCIES
+----------------------------------------------------------------------
+The following programs are needed by the testing framework:
+- xvkbd: a modified copy of xvkbd is included in this folder, and should
+         be built before running the tests
+- wmctrl
+- pcregrep
 
-xvkbd, wmctrl, pcregrep
 
 USAGE
-
+----------------------------------------------------------------------
 In order to launch all the tests available in this folder, just run
 
-  ./run-tests.sh
+  make
 
 and do not interact with your computer while the tests are running.
 
 If you wish to launch one or more specific tests, then provide them
-as argument to the script, e.g.:
+as argument to the run-tests.sh script, e.g.:
 
   ./run-tests.sh <whatever>*-in.txt
 
 For failed tests you get a folder with the logs that help you identify
 the problem.
 
-SYNTAX
 
+SYNTAX
+----------------------------------------------------------------------
 Each test-case script should be named as xxx-in.txt. The syntax of the
 script is described in detail in the sample test-case script
 hello-world-in.txt.
 
-TODO
 
+TODO
+----------------------------------------------------------------------
 Speed-up the execution of the tests as much as possible (i.e., get rid
 of heuristic waits when present and replace them with exact check of
 the condition we're waiting for).
index 1f6710eba741b18c4b1c8f830022896a11da6fb7..67cc0be8130a7eb9cbd494ba26cbd7c6b74eaaec 100755 (executable)
@@ -200,7 +200,7 @@ def sendKeystring(keystr, LYX_PID):
         time.sleep(0.1)
     sys.stdout.flush()
     if (subprocess.call(
-            ["xvkbd", "-xsendevent", "-window", lyx_window_name, "-delay", DELAY, "-text", keystr],
+            [xvkbd_exe, "-no_root", "-xsendevent", "-window", lyx_window_name, "-delay", DELAY, "-text", keystr],
             stdout=FNULL,stderr=FNULL
             ) == 0):
         sys.stdout.write('*')
@@ -244,6 +244,10 @@ lyx_exe = os.environ.get('LYX_EXE')
 if lyx_exe is None:
     lyx_exe = "lyx"
 
+xvkbd_exe = os.environ.get('XVKBD_EXE')
+if xvkbd_exe is None:
+    xvkbd_exe = "xvkbd"
+
 file_new_command = os.environ.get('FILE_NEW_COMMAND')
 if file_new_command is None:
     file_new_command = "\Afn"
index 766f4c1a70ea2a62cf155495dd4d01aa18a3b34a..36ab6ecb789e27181b04bec9b134d13cf2ef6247 100755 (executable)
@@ -4,9 +4,16 @@
 # Tests are identified as having a file name of *-in.txt
 # For failed tests, the collected output is kept in the corresponding folder
 
+if [ ! -x xvkbd/xvkbd ]; then
+    echo "You need to build XVKBD first, try: cd xvkbd && xmkmf && make"
+    exit -1;
+fi
+
 export LYX_EXE=../../../src/lyx
+export XVKBD_EXE=../xvkbd/xvkbd
 export KEYTEST=../keytest.py
-export LYX_USERDIR=$(pwd)/home/.lyx
+LYX_HOME=out-home
+export LYX_USERDIR=$(pwd)/$LYX_HOME/.lyx
 
 if [ "$#" -eq 0 ]; then
     TESTS=$(ls *-in.txt | sed -e 's/hello-world-in.txt\|first-time-in.txt//');
@@ -16,9 +23,9 @@ fi
 
 echo
 
-if [ ! -d home ]; then
-    mkdir home
-    cd home
+if [ ! -d $LYX_HOME ]; then
+    mkdir $LYX_HOME
+    cd $LYX_HOME
     echo "Initializing testing environment . . ."
     if ! ../single-test.sh "../first-time-in.txt" > keytest-log.txt 2>&1; then
        echo "Some error occurred: check $(pwd)"
index e83d834df40c86b393da16406d39e695f328ad5c..27c56cff1dd91bbc7d53f58cae54fe89720fb8f1 100755 (executable)
@@ -22,5 +22,6 @@ if [ "$(pidof lyx)" != "" ]; then
 fi
 export MAX_LOOPS=1
 export LYX_EXE=${LYX_EXE:-../../src/lyx}
+export XVKBD_EXE=${XVKBD_EXE:-./xvkbd/xvkbd}
 
 $KEYTEST
diff --git a/development/autotests/xvkbd/Imakefile b/development/autotests/xvkbd/Imakefile
new file mode 100644 (file)
index 0000000..5c0806c
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef XCOMM
+#define XCOMM #
+#endif
+
+
+XCOMM Remove the next line if you want genuine Xaw instead of Xaw3d
+XCOMM #define XAW3D
+
+XCOMM Remove the next line if you don't want to enable XTEST support
+#define XTEST
+
+XCOMM Remove the next line if you want to disable internationalization
+#define I18N
+
+
+SRCS = xvkbd.c findwidget.c
+OBJS = xvkbd.o findwidget.o
+DEPLIBS = XawClientDepLibs
+SYS_LIBRARIES = XawClientLibs
+
+#ifdef XAW3D
+D_XAW3D = -DXAW3D
+XAWLIB = -lXaw3d
+#endif
+
+#ifdef XTEST
+D_XTEST = -DUSE_XTEST
+SYS_LIBRARIES = XawClientLibs -lXtst
+#endif
+
+#ifdef I18N
+D_I18N = -DUSE_I18N
+#endif
+
+DEFINES = $(D_XAW3D) $(D_XTEST) $(D_I18N)
+
+SpecialObjectRule(xvkbd.o, xvkbd.c resources.h XVkbd-common.h, )
+ComplexProgramTarget(xvkbd)
+
+InstallAppDefaults(XVkbd)
+InstallAppDefaults(XVkbd-belgian)
+InstallAppDefaults(XVkbd-common)
+InstallAppDefaults(XVkbd-danish)
+InstallAppDefaults(XVkbd-fitaly)
+InstallAppDefaults(XVkbd-french)
+InstallAppDefaults(XVkbd-french2)
+InstallAppDefaults(XVkbd-german)
+InstallAppDefaults(XVkbd-greek)
+InstallAppDefaults(XVkbd-hebrew)
+InstallAppDefaults(XVkbd-icelandic)
+InstallAppDefaults(XVkbd-italian)
+InstallAppDefaults(XVkbd-jisx6002)
+InstallAppDefaults(XVkbd-jisx6004)
+InstallAppDefaults(XVkbd-korean)
+InstallAppDefaults(XVkbd-latin1)
+InstallAppDefaults(XVkbd-norwegian)
+InstallAppDefaults(XVkbd-portuguese)
+InstallAppDefaults(XVkbd-russian)
+InstallAppDefaults(XVkbd-slovene)
+InstallAppDefaults(XVkbd-small)
+InstallAppDefaults(XVkbd-spanish)
+InstallAppDefaults(XVkbd-swedish)
+InstallAppDefaults(XVkbd-swissgerman)
+InstallAppDefaults(XVkbd-turkish)
+InstallAppDefaults(XVkbd-uk)
+InstallAppDefaults(XVkbd-strip)
+
+
+XCOMM  ============================
+XCOMM  These rules are only for me
+
+_distclean: clean
+       -rm Makefile
+
+XVkbd-common.h: XVkbd-common.ad
+       -which ad2c > /dev/null && ad2c XVkbd-common.ad > XVkbd-common.h
+
+HTML = $(HOME)/public_html/homepage3.nifty.com/xvkbd/index.html
+_readme:
+       -[ -f $(HTML) ] && html2man $(HTML) > xvkbd.man
+       ( echo ".pl 10000"; echo ".ll 75"; echo ".hy 0"; echo ".ad l" ) | \
+               cat - xvkbd.man | groff -Tascii -man | sed 's/.\b//g' | \
+               head -9000 | cat -s | tail -n +3 > README
+
+XCOMM  ============================
diff --git a/development/autotests/xvkbd/README b/development/autotests/xvkbd/README
new file mode 100644 (file)
index 0000000..a40630d
--- /dev/null
@@ -0,0 +1,1053 @@
+NAME
+       xvkbd - virtual keyboard for X window system
+
+DESCRIPTION
+       xvkbd is a virtual (graphical) keyboard program for X Window System
+       which provides facility to enter characters onto other clients (soft-
+       wares) by clicking on a keyboard displayed on the screen.  This may be
+       used for systems without a hardware keyboard such as kiosk terminals or
+       handheld devices.  This program also has facility to send characters
+       specified as the command line option to another client.
+
+       The standard keyboard layout is based on the traditional US layout, but
+       some other keyboard layout (see "Screen Shot") are also supported.  The
+       default window size may be too large for systems with small screen, but
+       it can be configured to use smaller space (220x90 pixels, for example).
+       For details, see also "Screen Shot" and "How to Customize xvkbd" below,
+       and resouce files in the distribution.
+
+       xvkbd version 2.1 and later support word completion, which may make it
+       easier to enter long words with xvkbd.
+
+       IMPORTANT NOTE: When invoking xvkbd from display managers such as XDM,
+       GDM, etc., always use xvkbd with -secure option or you will have seri-
+       ous security risk.
+
+Environment
+       xvkbd will work on X11R5 or X11R6.  It is tested on redhat Linux and
+       Solaris, and it will work also on most UNIX-like systems.
+
+       This program uses Xaw (use of Xaw3d is recommended) and no special
+       library is required.
+
+Operation
+    Input Keys
+       When xvkbd is started, the image of a keyboard will be displayed on the
+       screen.  Clicking any key on the xvkbd window will send the character
+       to the focused window as if the key had been actually typed with the
+       hardware keyboard.
+
+       If you want to input upper-case alphabets or other characters on the
+       upper position on the keyboard, you should click the key after select-
+       ing Shift by clicking it, or click the key with mouse button 3 (maybe
+       right button) or mouse button 4.  In the similar manner, if you want to
+       input Controled characters, you should click the key after clicking
+       Control, or click the key with mouse button 2 (maybe middle button).
+       Alt and Meta can be used in the similar manner with Control, but there
+       are no shortcuts with mouse buttons.
+
+    ``Quick Modifiers''
+       xvkbd 2.5 and later support another way to input characters with modi-
+       fiers such as Shift, Control, AltGr, etc., which may be useful espe-
+       cially for machines with touch panels such as PDAs - we would call it
+       "Quick Modifiers".
+
+       Quick Modifiers can be enabled/disabled by the ``Enable "Quick Modi-
+       fiers?'' entry on the property panel.  If Quick Modifiers is enabled,
+       it will be activated by pressing a key on the xvkbd window, move the
+       pointer outside of the key, and then release the mouse button or equiv-
+       alent.
+
+       The direction of the pointer motion will select the modifier:
+
+             up        - Shift
+             right     - AltGr
+             right-up  - Shift AltGr
+             left      - Control
+             left-up   - Shift Control
+             down      - Meta
+             left-down - Alt
+
+    Setting Input Focus
+       If you are using a window manager and clients where you can set input
+       focus by clicking mouse button on the window (and you don't have to
+       keep pointer in the window after that), you can simply set input focus
+       in the normal way and then click keys on the xvkbd window - the charac-
+       ter will be sent to the selected position.
+
+       If you are using a window manager or clients where you must keep the
+       pointer in the input field to input from the keyboard, or if the input
+       focus is switched to the xvkbd window when you clicked on the key on
+       the xvkbd window, you must make xvkbd to set input focus explicitly by
+       clicking the Focus button on the xvkbd window and then click on the
+       input field.  This input focus can be cleared by clicking Focus button
+       with mouse button 3, or simply clicking Focus button twice.
+
+    Word Completion
+       Choosing ``Word Completion...'' in the main menu will popup the Word
+       Completion panel.
+
+       When you entered characters by clicked keys on the xvkbd window as
+       usual while the Word Completion panel open, words started with the
+       characters will be listed in the panel, and you can enter the remaining
+       characters of the selected word by clicking one of the words in the
+       list.
+
+       The dictionary (list of words) file is /usr/share/dict/words by
+       default, but it can be changed by -dict option or xvkbd.dictFile
+       resouce, or on the Property panel.
+
+    Main Menu
+       Pressing the ``xvkbd'' logo on the main keyboard (placed near left-bot-
+       tom corner in the default configuration) will popup the main menu.
+
+       The menu contains following items:
+
+       About...
+           Show short description of this program.
+
+       Manual...
+           Launch manual page reader.
+
+       Keypad...
+           Open the Keypad panel.
+
+       Sun Function Keys...
+           Open the Sun Function Keys panel.
+
+       Dead Keys...
+           Open the Dead Keys panel which can be used to enter Latin charac-
+           ters with accent symbol in double stroke.
+
+       Word Completion...
+           Open the Word Completion panel.
+
+       Change Keyboard Layout...
+           Open a popup window to change the keyboard layout.  In the default
+           configuration, Default (US), Belgian, Danish, French, German, Ice-
+           landic, Italian, Japanese (JIS-X-6002), Japanese (JIS-X-6004),
+           Korean, Norwegian, Portuguese, Russian, Spanish, Swedish,
+           Swiss/German, United Kingdom and Latin-1 are available.
+
+       Edit Function Keys...
+           Open a popup window to edit string assigned to function keys.  See
+           also "Assigning Text to Function Keys".
+
+       Show Keypad?
+           Toggle show/hide of the keypad on the main window.
+
+       Show Function Keys?
+           Toggle show/hide of the function keys on the main window.
+
+       Property...
+           Popup the Property panel.
+
+       Connect to Remote Display...
+           Open a panel to specify the name of a remote display to be con-
+           nected, so that following key events will be sent to windows on the
+           remote display.
+
+       Revert to Local Display
+           Disconnect from the remote display so that following key events
+           will be sent to windows on the local display.
+
+    Property Panel
+       Enable "Quick Modifiers"?
+           Toggle enable/disable of the Quick Modifiers feature.
+
+       Lock Shift?
+           Toggle locking/momentary of Shift keys.
+
+       Lock AltGr?
+           Toggle locking/momentary of AltGr key.
+
+       Lock Control, Alt and Meta?
+           Toggle locking/momentary of Control, Alt and Meta keys.
+
+       Always on Top?
+           If this entry is set ON, xvkbd attempts to keep the xvkbd window
+           always on the top of the display (i.e. not to be hidden by other
+           windows).  This feature is experimental, and care should be taken
+           as this feature can cause problem in some situations.
+
+       Behave as Toolbar Window?
+           xvkbd attempts to be a toolbar window when it is used with some
+           kind of window managers such as Matchbox window manager.
+
+       Use XTEST Extension?
+           XTEST extension will be used if this entry is checked.  If this
+           entry is set inactive, the X server does not support XTEST exten-
+           sion.
+
+       Jump Pointer?
+           If this entry is set ON, xvkbd will temporary jump the pointer to
+           the focused window, if XTEST extension is to be used to simulate
+           keyboard events.
+
+       Key-Click Sound
+           Set on/off and duration of key-click sound.
+
+       Automatic Click
+           Set on/off of the automatic click feature and the delay before
+           automatic click is activated.  If this feature is set, xvkbd will
+           work as if left mouse button is clicked when mouse pointer is moved
+           on a button and stays long enough.  You may want to set Jump
+           Pointer? to OFF to avoid auto-repeating.
+
+       Completion Dictionary
+           Set the filename to be used for word completion.  This setting take
+           precedence over the `xvkbd.dictFile' resource and the -dict option.
+
+    Options
+       xvkbd accept following command line options, in addition to general
+       options such as `-display'.
+
+       -version
+           Display version information and exit.
+
+       -xsendevent
+           Make xvkbd to use XSendEvent() to simulate keyboard events, as it
+           was in xvkbd version 1.0.  xvkbd version 1.1 and later will try to
+           use XTEST extension instead in the default configuration.
+           If XTEST extension is not supported by the X server, xvkbd will
+           automatically switch to this mode.
+           Resource `xvkbd.xtest: false' has the same function.
+
+       -no-sync
+           Normally, xvkbd attempts to synchronize with the destinating client
+           step by step.  This can cause problem when the client (or the X
+           server) responded too slow.  In such situation, maybe this -no-sync
+           can solve the problem.
+           Resource `xvkbd.noSync: true' has the same function.
+
+       -no-jump-pointer
+           Make xvkbd not to jump the pointer when sending events.  In the
+           default, xvkbd will temporary jump the pointer to the focused win-
+           dow, if input focus is set explicitly via Focus button, and XTEST
+           extension is to be used to simulate keyboard events.
+           Resource `xvkbd.jumpPointer: false' has the same function.
+
+       -no-back-pointer
+           Make xvkbd not to jump the pointer back to the original position
+           after events has been sent.  Maybe this can be useful when using
+           xvkbd to move the pointer position.
+           Resource `xvkbd.jumpPointerBack: false' has the same function.
+
+       -modal
+           Make labels on keys in the xvkbd window to be set independently for
+           each of four shift states, not shifted, Shift, AltGr and Shift-
+           AltGr.  This is useful when you want to make the xvkbd window very
+           small.
+           See also "Customizing Keyboard Layout" and resouce files in the
+           distribution.
+           Resource `xvkbd.modalKeytop: true' has the same function.
+
+       -geometry  [widthxheight][+xoff+yoff]
+           Set window geometry (size and position).
+           You can use form like -geometry 400x130 to specify the window size,
+           -geometry +100+100 to specify the window position from left/top
+           edge of the screen, and -geometry 400x130+100+100 to specify both
+           the size and the position.  You can specify position from
+           right/bottom edge of the screen by using - instead of +, but please
+           note that you must take account of size of the window border.  (If
+           you specify `-geometry -0-0', the window will not fit in the
+           screen.)
+           This can be set by xvkbd.windowGeometry resource (note that it is
+           not xvkbd.geometry), too.
+
+       -no-repeat
+           Do not auto-repeat even if key is depressed long time.
+           If auto-repeat is enabled (this is the default), time before start
+           auto-repeat can be set as `xvkbd*Repeater.initialDelay: 600', and
+           period of repeat can be set as `xvkbd*Repeater.minimumDelay: 100'
+           (unit of there parameters are milli-seconds).
+           Resource `xvkbd.autoRepeat: false' has the same function.
+
+       -no-functionkey
+           Do not display function keys.
+           Resource `xvkbd.functionkey: false' has the same function.
+
+       -no-keypad
+           Do not display keypad.
+           Resource `xvkbd.keypad: false' has the same function.
+
+       -compact
+           Do not display function keys nor keypad.
+           Resource `xvkbd.compact: true' has the same function.
+
+       -keypad
+           Display only keypad.  This option will be ignored if `-no-keypad'
+           or `-compact' is specified.
+           Resource `xvkbd.keypadOnly: true' has the same function.
+
+       -text string
+           Send the string to the focused window (see also `-window' option).
+           If this option is specified, xvkbd will not open its window and
+           terminate soon after sending the string.
+           The string can contain:
+
+           - \r - Return
+
+           - \t - Tab
+
+           - \b - Backspace
+
+           - \e - Escape
+
+           - \d - Delete
+
+           - \S - Shift (modify the next character; please note that modify
+             with ``\S'' will be ignored in many cases.  For example,
+             ``a\Cb\ScD\CE'' will be interpreted as a, Control-b, c, Shift-D,
+             and Control-Shift-E.)
+
+           - \C - Control (modify the next character)
+
+           - \A - Alt (modify the next character)
+
+           - \M - Meta (modify the next character)
+
+           - \[keysym] - the keysym keysym (e.g., \[Left])
+
+           - \Ddigit - delay digit * 100 ms
+
+           - \xvalue - move mouse pointer (use "+" or "-" for relative motion)
+
+           - \yvalue - move mouse pointer (use "+" or "-" for relative motion)
+
+           - \mdigit - simulate click of the specified mouse button
+
+       -file filename
+           Send the contents of the specified file to the focused window (see
+           also `-window' option).  If ``-'' was specified as the filename,
+           string to be sent will be read from the standard input (stdin).
+           If this option is specified, xvkbd will not open its window and
+           terminate soon after sending the string.
+
+       -delay value
+           Put value ms of delay for evey characters when sending characters
+           with -text or -file.  Maybe this is useful when problem arises when
+           characters are entered too fast.
+
+       -window window
+           Specify the ID (hexadecimal value leaded with `0x', or decimal
+           value), the name (instance name or class name) of the window, or
+           the title of the window to set input focus.  It is possible to use
+           wildcard characters `*' and `?'  to match the window name or the
+           window title.
+           If this is not specified, xvkbd will use input focus under control
+           of the window manager, unless focus is specified explicitly via
+           Focus button.  Even if this option is specified, you can set input
+           focus to other windows using Focus button, or clear the input
+           focus.
+           If there are two or more windows which have the name specified with
+           this option, the window which was found first will be selected.
+
+       -widget widget-name
+           Specify the name of the widget to set the input focus.  To use this
+           feature, the client must support Editres protocol.  In general,
+           this option will be used with `-window' option.
+           If you want to set input focus to the widget foo.bar.zot, you can
+           write zot, bar.zot or foo.bar.zot as widget-name.  To avoid confu-
+           sion, the widget-name should match with a single widget of the
+           client.
+           For example,
+
+               xvkbd -window xarchie -widget searchText -text "\Ca\Ckabc\r"
+
+           will enter the string ``abc'' to the ``Search Term'' field of a
+           xarchie window.
+
+       -true-keypad
+           If this option is specified, xvkbd will attempt to use keysyms such
+           as XK_KP_1 instead of XK_1.
+           Resource `xvkbd.keypadKeysym: true' has the same function.
+
+       -dict filename
+           Specify the default dictionary (list of words) file to be used for
+           word completion.  The `Completion Dictionary' filename set on the
+           Property panel takes precedence over this.
+           Resource `xvkbd.dictFile: filename' has the same function.
+           See also ``Making your own completion dictionary''.
+
+       -minimizable
+           Make xvkbd window can be minimized (iconified) even if no window
+           manager is in use.  When this feature is enabled, small triangle
+           will be displayed at left ot the xvkbd main menu, and xvkbd window
+           will be minimized when the triangle is clicked.
+           Resource `xvkbd.minimizable: true' has the same function.
+
+       -secure
+           Disable invocation of external commands, including user assigned
+           command and the online manual reader.  Connection to another dis-
+           plays would also be disabled.  This option may be useful when xvkbd
+           is to be run with some kind of privileges.
+           Resource `xvkbd.secure: true' has the same function.
+
+       -nonexitable
+           Disable termination of the xvkbd program.  This option may be use-
+           ful when xvkbd is to be run automatically for systems with no key-
+           boards and users should not terminate the xvkbd.
+           Resource `xvkbd.nonexitable: true' has the same function.
+
+       -xdm
+           Same as -secure -nonexitable.  When xvkbd is to be run for login
+           screen, it would be suggested to use this option.
+
+       -modifiers modifiers
+           Normally, xvkbd will activate modifiers (control, shift, etc.)
+           only while sending characters.  If modifiers were specified with
+           this option, the specified modifiers will be activated while corre-
+           sponding key on the xvkbd window is in active.  For example, you
+           can specify -modifiers shift,control,meta,alt to apply this for
+           those four modifiers.  Maybe this can be useful when attempting to
+           decorate the mouse operations with the modifiers.  Please note that
+           the modifiers will also be applied when attempting to click on the
+           xvkbd window and which can prevent the correct operation in some
+           situations.
+           Resource `xvkbd.positiveModifiers: modifiers...' has the same func-
+           tion.
+
+       -debug
+           Make xvkbd to output debug information.  It also disable keyboard
+           width adjustment, to help adjusting key size when making keyboard
+           layout file.
+           <!--
+
+       -version
+           Output version information and exit.  -->
+
+Screen Shot
+       Default (US)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-normal.gif
+
+       Belgian
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-belgian.gif
+
+       Danish
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-danish.gif
+
+       French
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-french.gif
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-french2.gif
+
+       German
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-german.gif
+
+       Icelandic
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-icelandic.gif
+
+       Italian
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-italian.gif
+
+       Japanese (JIS-X-6002)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-jisx6002.gif
+
+       Japanese (JIS-X-6004)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-jisx6004.gif
+
+       Norwegian
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-norwegian.gif
+
+       Portuguese
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-portuguese.gif
+
+       Spanish
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-spanish.gif
+
+       Swedish
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-swedish.gif
+
+       Swiss/German
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-swissgerman.gif
+
+       United Kingdom
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-uk.gif
+
+       Latin-1
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-latin1.gif
+
+       Small Keyboard (maybe suitable for PDAs)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-small.gif
+
+       Hebrew
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-hebrew.gif
+
+       Greek
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-greek.gif
+
+       Turkish
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-turkish.gif
+
+       Slovene
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-slovene.gif
+
+       Korean
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-korean.gif
+
+       Russian (Cyrillic)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-russian.gif
+
+Download
+       Latest Official Release
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.2.tar.gz
+           - source of version 3.2 (2010-03-14)
+
+       previous release
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.1.tar.gz
+           - source of version 3.1 (2010-01-17)
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.0.tar.gz
+           - source of version 3.0 (2008-05-05)
+
+       xvkbd is distributed under the terms of the GNU General Public License.
+
+Install
+         o untar the source in a directory, and move to the directory
+
+         o If you wish to use genuine Xaw insead of Xaw3d, edit Imakefile and
+           remove (or comment-out) `#define XAW3D'.
+           When you are installing xvkbd (for example) in very old systems,
+           you may also want to remove `#define XTEST' and `#define I18N' to
+           disable XTEST and internationalization facility respectively.
+
+         o Run xmkmf; make install install.man
+
+Customization
+    How to Customize xvkbd
+       Some degree of customization of xvkbd is possible by setting resources.
+       Some resources are already described above, and resources to customiz-
+       ing keyboard layout are described below.
+
+       To set resources, you can:
+
+         o put them in your $HOME/.Xdefaults file, or
+
+         o load them via xrdb(1), or
+
+         o set the filename to the $XENVIRONMENT environment variable, or
+
+         o put them in application default directory as `XVkbd-suffix' and set
+           resource ``xvkbd.customization: -suffix'', or
+
+         o put them in application default directory as XVkbd.
+
+       Here, application default directory can be either of:
+
+         o directories specified with $XUSERFILESEACHPATH, $XAPPLRESDIR or
+           else $HOME environment variable
+
+         o system's application default directory specified with $XFILESEACH-
+           PATH environment variable, or else the directory specified when
+           compiling the X (e.g., /usr/lib/X11/app-defaults)
+
+       When the application default file is to be stored in the system's
+       application default directory, the file must contain ``#include "XVkbd-
+       common"'' near top of the file.
+
+       xvkbd is distributed with some application default files, and they will
+       be installed in the system's application default directory.
+
+    Making Window Small
+       Size (and position) of xvkbd window can be set by `xvkbd.windowGeome-
+       try' resource.  When making window small, you may need to choose the
+       smaller font, too.
+
+             xvkbd.windowGeometry: 220x90
+             xvkbd.compact: true
+             xvkbd*Font: 6x12
+
+       You may also want to set:
+
+             xvkbd.modalKeytop: true
+
+       to display only the labels for the current shift state, instead of try-
+       ing to always display all of them in the small keytop.
+
+       See also XVkbd-small.ad in the xvkbd distribution.
+
+    Removing Unwanted Keys
+       Keys on xvkbd window can be removed by setting its width to 1.
+
+       To remove Compose key and make Shift key larger, you can write:
+
+             xvkbd*Multi_key.width: 1
+             xvkbd*Shift_R.width: 75
+
+       To remove right Alt and Meta key, you can write:
+
+             xvkbd*Alt_R.width: 1
+             xvkbd*Meta_R.width: 1
+
+    Customizing Keyboard Layout
+       Layout of keys on the xvkbd window can be customized with following
+       resources:
+
+       xvkbd.NormalKeys
+           list of keys available when neighter of Shift and AltGr are
+           selected
+
+       xvkbd.ShiftKeys
+           list of keys available when Shift is selected
+
+       xvkbd.AltgrKeys
+           list of keys available when AltGr is selected
+
+       xvkbd.ShiftAltgrKeys
+           list of keys available when both AltGr and Shift are selected
+
+       xvkbd.KeyLabels
+           list of labels displayed on the keys
+
+       xvkbd.NormalKeyLabels
+           list of labels displayed on the keys
+             when neither of Shift and AltGr are selected.
+
+       xvkbd.ShiftKeyLabels
+           list of labels displayed on the keys
+             when Shift is selected
+
+       xvkbd.AltgrKeyLabels
+           list of labels displayed on the keys
+             when AltGr is selected
+
+       xvkbd.ShiftAltgrKeyLabels
+           list of labels displayed on the keys
+             when both AltGr and Shift are selected
+
+       Four resources to set labels on the keys (xvkbd.NormalKeyLabels,
+       xvkbd.ShiftKeyLabels, xvkbd.AltgrKeyLabels and xvkbd.ShiftAltgrKeyLa-
+       bels) will be used instead of xvkbd.KeyLabels when xvkbd.modalKeytop
+       resoruce is set true.
+
+       In all of those resources, each keys are separated by spaces, and rows
+       of keys are terminated with ` \n\' (note that `\n' must have space
+       before it).  Please refer XVkbd-german.ad and XVkbd-latin1.ad in the
+       xvkbd distribution for more about these resources.
+
+       XVkbd-german and XVkbd-latin1 will be installed in the system's appli-
+       cation default directory, and setting the resource ``xvkbd.customiza-
+       tion: -german'' will make xvkbd to use the German layout.  For another
+       method to activate those settings, please refer "How to Customize
+       xvkbd" above.
+
+    Assigning Text to Function Keys
+       Text can be assigned to each function keys (and, actually, to most
+       other keys).  If text is assigned to the function key, clicking on the
+       key will send the assigned text instead of the function key itself.
+       When pointer is on a key where text is assigned, the text will be dis-
+       played near the key.
+
+       The setting will be read from a text file which contains text for each
+       function keys as:
+
+             F1 text for F1
+             F2 text for F2
+             s:F1 text for Shift-F1
+             c:F1 text for Control-F1
+             m:F1 text for Meta-F1
+             a:F1 text for Alt-F1
+             ...
+
+       `s:', `c:', `m:' and `a:' before the keys name indicates four modifiers
+       (Shift, Control, Meta and Alt) respectively.
+
+       If the first character of the assigned string is `!', the string will
+       be used as command to be executed when the key is clicked.  To assign
+       string starting with `!' or `\', put `\' before the string.
+
+       The file is $HOME/.xvkbd in default, and it can be changed by setting
+       the filename with xvkbd.keyFile resource.
+
+       For F1 to F12 with or without Shift modifier, it is possible to edit
+       the assigned string on a panel popped up via "Edit Function Keys..." in
+       the main menu.
+
+Miscellaneous Informations
+    Notes
+         o On XFree86, resolution switch with Ctrl + Alt + Keypad-Plus and
+           Ctrl + Alt + Keypad-Minus may be simulated.  However, Ctrl + Alt +
+           Backspace will not be simulated.
+
+         o Shift is used to decide key to be sent and it will not used to set
+           modifier bit when sending the event.  You can use xev command to
+           check what is actually sent.
+
+         o If Alt or Meta is not defined as modifier, the key can't be used as
+           modifier.  You can use `xmodmap -pm' to check how modifiers are
+           defined.
+
+         o Num Lock (and maybe other modifiers) on the physical keyboard may
+           not work correctly when xvkbd is in use.
+
+    Additional Informations
+       FAQ - Possible Problems and Solutions
+           http://homepage3.nifty.com/tsato/xvkbd/faq.html
+
+       Making your own completion dictionary
+           http://homepage3.nifty.com/tsato/xvkbd/make-dic.html
+
+       Hints to use xvkbd -text
+           http://homepage3.nifty.com/tsato/xvkbd/xvkbd-text.html
+
+       Note about how to send key events
+           http://homepage3.nifty.com/tsato/xvkbd/events.html
+
+Change Log
+       Version 0.1 (2000-05-13)
+
+           -  The first release, not announced anywhere.
+
+       Version 0.2 (2000-09-15)
+
+           - Compose key is added.  In the environments where Compose key is
+             supported, some characters (mainly letters with accent symbol)
+             which can't be entered directly from keyboard can be entered
+             using dedicated key combinations.
+
+           - Make keyboard layout not to be disturbed when window size if
+             specified with -geometry option.
+
+           - Sample app-defaults file is added.
+
+       Version 0.3 (2000-10-05)
+
+           - -text option can now accept some modifiers (\S, \C, etc.) and any
+             keysyms (\[keysym]).
+
+           - In addition to the window ID, -window option can now accept win-
+             dow name.
+
+           - New -widget option to specify the widget to set the input focus.
+
+       Version 1.0 (2000-11-03)
+
+           - Keyboard layout can be now configured with resources.  See "Cus-
+             tomizing Keyboard Layout" above, and XVkbd-german.ad in the dis-
+             tribution.
+
+           - xvkbd can now send keys with Mode_switch (AltGr) modifier, which
+             enables those characters in the position to be entered.
+
+           - xvkbd now support AltGr key so that German (and some other) key-
+             board layout can be used.  See XVkbd-german.ad in the distribu-
+             tion.
+
+           - XVkbd-german and XVkbd-latin1 are included in the distribution,
+             which modifies keyboard layout and put some non-ASCII keys on the
+             xvkbd window.
+
+           - CapsLock key is supported now.
+
+       Version 1.1 (2000-12-23)
+
+           - xvkbd can now use XTEST extension to simulate keyboard events.
+             It can still use XSendEvent(), as it was in the older release.
+             (thanks, Bjoern)
+
+           - Labels on keys can now be set independently for each of four
+             shift states, not shifted, Shift, AltGr and Shift-AltGr.
+             (thanks, Jim)
+
+           - -kterm option and xvkbd.kterm resource are removed.
+
+       Version 1.2 (2001-02-18)
+
+           - Focus button is now placed in the main keyboard, too, so that it
+             will be available also in compact mode.  If you don't need it, it
+             can be removed by setting ``xvkbd*row5.Focus.width: 1''.
+
+           - Input focus set by Focus button can now be cleard by clicking
+             Focus button twice.  Clicking Focus button with mouse button 3
+             will still clear the input focus, too.
+
+           - Text can now be assigned to function keys (and, actually, to most
+             other keys).
+
+           - It is now possible to assign keys modified with Shift, Control,
+             Alt and Meta on the main keyboard, by putting `s:', `c:', `a:'
+             and `m:' before those keysym name when customizing the keyboard
+             layout.
+
+           - xvkbd now ignores SIGINT and SIGQUIT so that it will not termi-
+             nated accidently.
+
+       Version 1.3 (2001-03-19)
+
+           - New app-defaults file for Swiss-German layout, XVkbd-swissger-
+             man.ad.  (contributed from Marcel Portner)
+
+           - xvkbd now catches MappingNotify event and reload the new mapping.
+             This allows users to use xmodmap while xvkbd is running.
+
+           - NumLock key is supported now.  (I'd removed Print, ScrLk and
+             Pause from keypad - somebody need them?)
+
+       Version 1.4 (2001-04-22)
+
+           - Auto-repeat didn't work when focus was set explicitly via Focus
+             button.  It is now fixed.
+
+           - When required keysym was not defined in the keymap table, xvkbd
+             will now add it on-the-fly.  This means that we don't have to add
+             them via xmodmap.
+
+           - Keypad panel can now be popped up from the main keyboard as a
+             separate window.
+
+           - Sun function keys is now supported.  It can be popped up from the
+             main keyboard as a separate window.
+
+           - Manual page is now available.
+
+       Version 1.5 (2001-10-08)
+
+           - Key events can now be sent to windows on a remote display (i.e.
+             windows on other X servers) - use "Connect to Remote Display..."
+             in the main menu to connect to remote display.
+
+           - Shift, Control, Alt and Meta can now be locked - use "Lock
+             Shift?" and "Lock Control, Alt and Meta?"  in the main menu.
+             Those initial settings can be set by xvkbd.shiftLock and
+             xvkbd.modifiersLock resource.
+
+           - If the first keysym for a key is an alphabet and the second
+             keysym is NoSymbol, it is now interpreted as if the first keysym
+             is lowercase alphabet and the second keysym is uppercase alpha-
+             bet.  Keymap may be defined in this way in some systems including
+             Solaris, and older xvkbd may not work correctly in such situa-
+             tion.
+
+       Version 1.6 (2001-11-10)
+
+           - New `-file' option to send characters in the specified file.
+             (thanks, Gregory)
+
+           - New entry `Use XTEST Extension?' is added to the main menu,
+             mainly to indicate the availability of the XTEST extension.
+
+           - xvkbd would crash when the window explicitly focused via Focus
+             button becomes was destroyed.  This problem is now fixed.
+
+       Version 2.0 (2001-12-09)
+
+           - Keyboard layout (default, German, French, etc.) can now be
+             changed after xvkbd is invoked.
+
+           - Show/hide of the keypad and funcion keys on the main window can
+             now be toggled from the main menu.
+
+           - New app-defaults file for French layout, XVkbd-french.ad.  (con-
+             tributed from Jean-Pierre Demailly)
+
+       Version 2.1 (2002-01-27)
+
+           - When height of the xvkbd window is smaller than
+             XVkbd.modalThreshold, xvkbd will now automatically switch the
+             keytop as if -modal option was specified.
+
+           - \[keysym] in -text option would send wrong keys - this problem is
+             now fixed.
+
+           - Target distclean in the Imakefile is renamed to avoid the possi-
+             ble confusion on some systems.
+
+           - Word completion is now supported.
+
+       Version 2.2 (2002-03-17)
+
+           - String assigned to function keys can now be edited on a panel
+             popped up via "Edit Function Keys..." in the main menu.
+
+           - When ``-'' was specified as the filename parameter for -file
+             option, xvkbd will now read its standard input (stdin) to get the
+             string to be sent.
+
+           - In the previous release, less-portable setenv() function was used
+             instead of putenv() function, may cause compilation error on some
+             systems including Solaris.
+
+       Version 2.3 (2002-04-05)
+
+           - New "Dead Keys" panel added.  Which can be used to enter Latin
+             characters with accent symbol in double stroke.
+
+           - More localized keyboard layout: Belgian, Danish, French, German,
+             Icelandic, Italian, Japanese (JIS-X-6004), Norwegian, Portuguese,
+             Spanish, Swedish, Swiss/German, United Kingdom and Latin-1.
+
+           - -keypad option would crash previous version of xvkbd - this prob-
+             lem is now fixed.
+
+       Version 2.4 (2002-10-02)
+
+           - Command can now be assigned to function keys so that clicking on
+             the function key will execute the command instead of sending the
+             string to clients.
+
+           - Assigned string for F1 to F12 with Shift modifier can now be
+             edited on a panel popped up via "Edit Function Keys..." in the
+             main menu.
+
+       Version 2.5 (2002-10-12)
+
+           - Quick Modifier feature added - now, it is possible to enter char-
+             acters with modifiers by pressing a key and then move the
+             pointer.  (suggested by Niklas Rokaeus)
+
+           - ``Lock AltGr?'' entry is added in the main menu.
+
+           - Status of ``Lock Shift?'', ``Lock AltGr'', ``Lock Control, Alt
+             and Meta?'' will be recorded in $HOME/.xvkbd file and it will be
+             read when xvkbd is invoked next time.
+
+       Version 2.5a (2003-06-25)
+
+           - ``Fitaly'' layout is now supported - may be useful for PDAs.
+
+       Version 2.6 (2004-05-04)
+
+           - Code to adding keysyms which were not found in the keymap table
+             is revised.  xvkbd now avoid to add keysyms in the shifted posi-
+             tion of keys which already have a keysym defined in the non-
+             shifted position, and entries in the keymap table which is modi-
+             fied keys will be redefined rather than redefining the entire
+             keymap table.  This change is to avoid possible problem (AltGr
+             key could be effectively disabled) which may caused in some sys-
+             tems where XGetKeyboardMapping() can produce incorrect map when
+             keys have more then two keysyms.
+
+           - If Mode_switch is not defined in the modifier table but
+             ISO_Level3_Shift is defined, xvkbd now attempt to add Mode_switch
+             as the same modifier with ISO_Level3_Shift.
+
+           - Korean layout is now supported.  Although Hangul characters will
+             be displayed on the keys, xvkbd will simply generate alphabet
+             characters when those keys are clicked.  It is intented to be
+             used with "ami" or similar Hangul input program.
+
+           - URL of the xvkbd main page is now changes to http://home-
+             page3.nifty.com/tsato/xvkbd/.
+
+       Version 2.7 (2005-05-05)
+
+           - Yet another Japanese keyboard layout, JIS X 6002, is now sup-
+             ported.
+
+           - It is now possible to minimize (iconify) the main window even if
+             no window manager is in use.  This feature can be activated by
+             -minimizable option or xvkbd.minimizable resource.
+
+           - Experimental code to keep the xvkbd window always on the top of
+             the display.  This feature can be activated by -always-on-top
+             option, xvkbd.alwaysOnTop resource or the "Always on Top?" entry
+             in the main menu.  Care should be taken as this feature can cause
+             problem in some situations.
+
+           - -text option now support combinations of modifiers and a special
+             key.  For example, -text '\C\A\d' can be used for Control-Alt-
+             Delete key combination.
+
+           - New options: -secure option (xvkbd.secure resource) which dis-
+             ables invocation of external commands, -nonexitable option
+             (xvkbd.nonexitable resource) which inhibits termination of the
+             program, and -xdm option which is equivalent to -secure -nonex-
+             itable and maybe useful when run xvkbd from a display manager.
+
+       Version 2.7a (2005-05-07)
+
+           - Fixed a problem that xvkbd could cause segmentation fault on
+             startup.
+
+       Version 2.8 (2006-09-10)
+
+           - ISO_Level3_Shift is now to be prefered over Mode_switch so that
+             AltGr can be used on relatively new systems where we must use
+             ISO_Level3_Shift instead of Mode_switch.
+
+           - Reference to the target bitmap is changed from
+             /usr/X11R6/include/X11/bitmaps/target to
+             /usr/include/X11/bitmaps/target.
+
+           - New options: -no-back-pointer, -no-sync, -modifiers.
+
+       Version 2.9 (2008-03-30)
+
+           - Russian (Cyrillic) keyboard layout supported. (thanks, Victor)
+
+           - New -delay option.
+
+           - \D special sequence in -text can be used to put a delay in spe-
+             cific position.
+
+           - -text can now simulate mouse operation via \x, \y and \m special
+             sequences.
+
+       Version 3.0 (2008-05-05)
+
+           - New Property panel.
+
+           - New automatic click feature.
+
+           - Key-click sounds when key is pressed.
+
+       Version 3.1 (2010-01-17)
+
+           - Changed the default setting for automatic click to OFF, which was
+             set ON in the previous release in error and caused confusion.
+
+           - The keypad is now customizable, too (see XVkbd-strip.ad for the
+             example).
+
+           - Up to 25x25 keys can now be supported both for the main keyboard
+             and the keypad.
+
+           - Able to open the keypad panel when startup, by setting
+             `xvkbd.keypad: false' and `xvkbd.keypadOnly: true'.
+
+           - Fixed errors in some keyboard layout files (Korean, Slovene, UK).
+
+           - A new sample layout file XVkbd-strip.ad.
+
+       Version 3.2 (2010-03-14)
+
+           - New option `Behave as Toolbar Window?' on the Property panel,
+               which may make xvkbd works better with some kind of window man-
+             agers
+               such as Matchbox window manager. (Thanks, Patrick)
+
+           - `Always on Top' will work rather better with window managers
+               which support extended window manager hint _NET_WM_STATE_ABOVE.
+
+           - -window option can now find window which have title match with
+               the specified string.
+
+           - -window option now accept wildcard characters
+               `*' and `?'.
+
+           - Word completion dictionary file to be used with `Word Comple-
+             tion...'
+               can now be specified on the Property panel.
+
+           - Only the words which have two or more characters will be appeared
+               in the word completion list.
+
+           - New -version option to display version information.
+
+Author
+       xvkbd was written by Tom Sato, and it is distributed under the terms of
+       the GNU General Public License Version 2 or any later version.
+
+       Please send any feedback (such as bug reports, requests or comments) to
+       Tom Sato <VEF00200@nifty.ne.jp>.
+
+       The latest version of this software and more information about it may
+       be available at http://homepage3.nifty.com/tsato/xvkbd/.  Release of
+       the new version will be announced on the Freshmeat (http://fresh-
+       meat.net), and you can probably receive the announce via e-mail if you
+       wish.
+
+       Tommaso Cucinotta <firstname.lastname@gmail.com> contributed the
+       -no_root and -instance command-line options.
+
+
+                                  2010-03-14                          xvkbd(1)
diff --git a/development/autotests/xvkbd/XVkbd-belgian.ad b/development/autotests/xvkbd/XVkbd-belgian.ad
new file mode 100644 (file)
index 0000000..f2e1543
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-belgian.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Belgian layout, roughly taken from
+! xkeycaps's "102 key, wide Delete, tall Enter / XFree86; Belgian"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Belgian)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape & é " ' ( § è ! ç à ) - ² µ \n\
+  Tab a z e r t y u i o p ^ $ Delete \n\
+  Control_L q s d f g h j k l m ù Return \n\
+  Shift_L < w x c v b n , ; : = Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ° _ ³ £ \n\
+  Tab A Z E R T Y U I O P ¨ * Delete \n\
+  Control_L Q S D F G H J K L M % Return \n\
+  Shift_L > W X C V B N ? . / + Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape | @ # ' ( ^ è ! { } ) - ² ` \n\
+  Tab a z e r t y u i o p [ ] Delete \n\
+  Control_L q s d f g h j k l m ' Return \n\
+  Shift_L \\ w x c v b n , ; : ~ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1\n&_| 2\né_@ 3\n"_# 4\n' 5\n( 6\n§_^ 7\nè 8\n! 9\nç_{ 0\nà_} °\n) _\n- ³\n² £\nµ_` \n\
+  Tab A Z E R T Y U I O P ¨\n^_[ *\n$_] Del \n\
+  Control Q S D F G H J K L M %\nù_' Return \n\
+  Shift >\n<_\\ W X C V B N ?\n, .\n; /\n: +\n=_~ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc & é " ' ( § è ! ç à ) - ² µ \n\
+  Tab a z e r t y u i o p ^ $ Del \n\
+  Ctrl q s d f g h j k l m ù Return \n\
+  Shift < w x c v b n , ; : = Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ° _ ³ £ \n\
+  Tab A Z E R T Y U I O P ¨ * Del \n\
+  Ctrl Q S D F G H J K L M % Return \n\
+  Shift > W X C V B N ? . / + Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc | @ # ' ( ^ è ! { } ) - ² ` \n\
+  Tab a z e r t y u i o p [ ] Del \n\
+  Ctrl q s d f g h j k l m ' Return \n\
+  Shift \\ w x c v b n , ; : ~ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-common.ad b/development/autotests/xvkbd/XVkbd-common.ad
new file mode 100644 (file)
index 0000000..a3cb5d7
--- /dev/null
@@ -0,0 +1,349 @@
+!! XVkbd-common  - default setting for xvkbd-2.2
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-17
+!
+! These settings are hardcoded in xvkbd.c as fallback resouces, too,
+! and this file is not required in general.
+! This is intended to be included in another app-defaults files
+! (XVkbd-german, for example), as:
+!
+!     #include "XVkbd-common"
+!
+! because fallback resouces may be ignored when such app-defaults file
+! (application class resource file) is loaded.
+
+XVkbd.title: xvkbd - Virtual Keyboard
+XVkbd.iconName: xvkbd
+XVkbd*input: false
+XVkbd*props_panel.input: true
+XVkbd*display_panel.input: true
+XVkbd.mappedWhenManaged: false
+XVkbd.translations: #override \
+       <Message>WM_PROTOCOLS: DeleteWindowProc()\n\
+        <Configure>: WindowResized()\n\
+        <MappingNotify>: ReadKeymap()\n\
+        <Visible>: VisibilityChanged()
+XVkbd.Form.translations: <BtnDown>:
+XVkbd.Form.?.translations: <BtnDown>:
+XVkbd*Command.translations: #override \n\
+        <EnterWindow>: ShowBalloon() highlight() \n\
+        <LeaveWindow>: CloseBalloon() unhighlight() \n\
+       <BtnDown>: ButtonDownAction() set()\n\
+       <BtnUp>: notify() unset() ButtonUpAction()
+XVkbd*Repeater.translations: #override \n\
+        <EnterWindow>: ShowBalloon() highlight() \n\
+        <LeaveWindow>: CloseBalloon() unhighlight() \n\
+       <BtnDown>: ButtonDownAction() set() start() \n\
+       <BtnUp>: stop() unset() ButtonUpAction()
+XVkbd*MenuButton.translations: #override \n\
+        <EnterWindow>: ShowBalloon() highlight() \n\
+        <LeaveWindow>: CloseBalloon() unhighlight()
+XVkbd.TransientShell.translations: #override \n\
+       <Message>WM_PROTOCOLS: ClosePopupPanel()
+XVkbd*Text*translations: #override \
+       <Key>Return: \n\
+       <Key>Linefeed: \n\
+       Ctrl<Key>m: \n\
+       Ctrl<Key>j:
+XVkbd*Repeater.initialDelay: 600
+XVkbd*Repeater.minimumDelay: 100
+XVkbd*Repeater.decay: 500
+
+XVkbd*Font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*generalFont: -*-lucidatypewriter-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*letterFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*specialFont: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*keypadFont: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-1
+XVkbd*banner.font: -*-lucida-bold-i-*-*-14-*-*-*-*-*-iso8859-1
+XVkbd*display_panel*label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+
+XVkbd*beNiceToColormap: false
+XVkbd*topShadowContrast: 40
+XVkbd*bottomShadowContrast: 80
+XVkbd*shadowWidth: 2
+XVkbd*Label.shadowWidth: 0
+XVkbd*MainMenu.shadowWidth: 0
+XVkbd*MainMenu.topShadowContrast: 0
+XVkbd*MainMenu.bottomShadowContrast: 0
+XVkbd*Background: gray85
+XVkbd*Text*background: white
+XVkbd*specialBackground: gray75
+XVkbd*focusBackground: bisque2
+XVkbd*remoteFocusBackground: lightcyan1
+XVkbd*Foreground: black
+XVkbd*highlightBackground: gray90
+XVkbd*highlightForeground: forestgreen
+XVkbd*highlightThickness: 1
+XVkbd*Form.resizable: true
+XVkbd*defaultDistance: 0
+XVkbd*Form.borderWidth: 0
+XVkbd*Label.borderWidth: 0
+XVkbd*Command.internalWidth: 2
+XVkbd*Repeater.internalWidth: 2
+XVkbd*Command.resize: false
+XVkbd*Repeater.resize: false
+XVkbd*Command.justify: center
+XVkbd*Repeater.justify: center
+
+XVkbd*row1.vertDistance: 5
+XVkbd*F5.horizDistance: 5
+XVkbd*F9.horizDistance: 5
+XVkbd*BackSpace.horizDistance: 5
+
+XVkbd*Command.height: 30
+XVkbd*Repeater.height: 30
+XVkbd*banner.height: 30
+XVkbd*row0.Repeater.height: 25
+XVkbd*Command.width: 30
+XVkbd*Repeater.width: 30
+XVkbd*space.width: 80
+XVkbd*Tab.width: 45
+XVkbd*Control_L.width: 60
+XVkbd*Shift_L.width: 75
+XVkbd*Shift_R.width: 40
+XVkbd*Multi_key.width: 35
+XVkbd*Caps_Lock.width: 35
+XVkbd*Alt_L.width: 38
+XVkbd*Alt_R.width: 38
+XVkbd*Meta_L.width: 38
+XVkbd*Meta_R.width: 38
+XVkbd*BackSpace.width: 75
+XVkbd*Delete.width: 45
+XVkbd*Return.width: 60
+XVkbd*row5.Focus.width: 35
+xvkbd*Mode_switch.width: 45
+
+XVkbd*keypad.vertDistance: 5
+XVkbd*keypad.horizDistance: 10
+XVkbd*keypad*Command.width: 35
+XVkbd*keypad*Repeater.width: 35
+XVkbd*keypad*Command.justify: left
+XVkbd*keypad*Repeater.justify: left
+XVkbd*keypad*pad3,3.height: 60
+XVkbd*keypad*pad4,0.width: 70
+
+XVkbd.balloonBackground: LightYellow1
+XVkbd.launchBalloonBackground: LightCyan1
+XVkbd*balloon_panel.Label.width: 150
+XVkbd*balloon_panel.Label.resize: false
+XVkbd*balloon_panel.Label.justify: left
+
+XVkbd*banner.width: 150
+XVkbd*banner.justify: right
+XVkbd*MainMenu.width: 0
+XVkbd*MainMenu.label: xvkbd
+XVkbd*MainMenu.justify: left
+XVkbd*MainMenu.internalWidth: 2
+XVkbd*MainMenu.highlightThickness: 0
+
+XVkbd*menu.about.label: About...
+XVkbd*menu.man.label: Manual...
+XVkbd*menu.keypad.label: Keypad...
+XVkbd*menu.sun_fkey.label: Sun Function Keys...
+XVkbd*menu.deadkey.label: Dead Keys...
+XVkbd*menu.completion.label: Word Completion...
+XVkbd*menu.select_layout.label: Change Keyboard Layout...
+XVkbd*menu.edit_fkey.label: Edit Function Keys...
+XVkbd*menu.show_keypad.label: Show Keypad?
+XVkbd*menu.show_functionkey.label: Show Function Keys?
+XVkbd*menu.props.label: Property...
+XVkbd*menu.open_display.label: Connect to Remote Display...
+XVkbd*menu.close_display.label: Revert to Local Display
+XVkbd*menu.quit.label: Quit
+XVkbd*menu.SmeBSB.rightMargin: 30
+
+XVkbd*props_panel.title: xvkbd - proprety
+XVkbd*props_panel*defaultDistance: 10
+XVkbd*props_panel*vertDistance: 5
+XVkbd*props_panel*always_on_top.label: Always on Top?
+XVkbd*props_panel*wm_toolbar.label: Behave as Toolbar Window?
+XVkbd*props_panel*shift_lock.label: Lock Shift?
+XVkbd*props_panel*altgr_lock.label: Lock AltGr?
+XVkbd*props_panel*modifiers_lock.label: Lock Control, Alt and Meta?
+XVkbd*props_panel*quick_modifiers.label: Enable "Quick Modifiers"?
+XVkbd*props_panel*use_xtest.label: Use XTEST Extension?
+XVkbd*props_panel*jump_pointer.label: Jump Pointer?
+XVkbd*props_panel*dict_entry_label.label: Completion Dictionary: 
+XVkbd*props_panel*dict_default_button.label: Default
+XVkbd*props_panel*click.label: Key-Click Sound:
+XVkbd*props_panel*autoclick.label: Automatic Click:
+XVkbd*props_panel*Command.internalWidth: 4
+XVkbd*props_panel*Command.width: 0
+XVkbd*props_panel*Command.height: 0
+XVkbd*props_panel*dismiss.label: Dismiss
+XVkbd*props_panel*dismiss.vertDistance: 10
+XVkbd*props_panel*Toggle.width: 200
+XVkbd*props_panel*Toggle.justify: left
+XVkbd*props_panel*dict_entry.width: 220
+XVkbd*props_panel*left: chainLeft
+XVkbd*props_panel*right: chainLeft
+XVkbd*props_panel*top: chainTop
+XVkbd*props_panel*bottom: chainTop
+XVkbd*props_panel*dict_entry.left: chainLeft
+XVkbd*props_panel*dict_entry.right: chainRight
+XVkbd*props_panel*dict_default_button.left: chainRight
+XVkbd*props_panel*dict_default_button.right: chainRight
+
+XVkbd.about_panel.title: xvkbd - about this program
+XVkbd.keypad_panel.title: xvkbd - keypad
+XVkbd.sun_fkey_panel.title: xvkbd - Sun
+XVkbd.display_panel.title: xvkbd - Remote Display
+
+XVkbd.sun_fkey_panel*Repeater.width: 35
+XVkbd.sun_fkey_panel*Help.width: 70
+XVkbd.sun_fkey_panel*justify: left
+
+XVkbd.display_panel*label.label: Remote Display:
+XVkbd.display_panel*ok.label: Connect
+XVkbd.display_panel*Text.width: 150
+XVkbd.display_panel*defaultDistance: 3
+XVkbd.display_panel*Command.width: 0
+XVkbd.display_panel*Command.height: 0
+XVkbd.display_panel*Command.internalWidth: 4
+XVkbd.display_panel*Label.width: 0
+XVkbd.display_panel*Label.resizable: true
+
+XVkbd*layout_panel.title: xvkbd - layout
+
+XVkbd*layout_panel*Command.width: 150
+XVkbd*layout_panel*Command.height: 0
+XVkbd*layout_panel*vSpace: 2
+XVkbd*layout_panel.box.width: 320
+XVkbd*layout_panel.box.orientation: vertical
+
+XVkbd*completion_panel.title: xvkbd - word completion
+XVkbd*completion_panel*Label.justify: left
+XVkbd*completion_panel*entry.width: 200
+XVkbd*completion_panel*view.allowVert: true
+XVkbd*completion_panel*view.useRight: true
+XVkbd*completion_panel*view.forceBars: true
+XVkbd*completion_panel*view.list.width: 400
+XVkbd*completion_panel*view.list.height: 150
+
+XVkbd*completion_panel*label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*completion_panel*list.font: -*-lucida-medium-r-*-*-14-*-*-*-*-*-iso8859-1
+XVkbd*completion_panel*label.label: Completion:
+XVkbd*completion_panel*bottom: chainTop
+XVkbd*completion_panel*label.right: chainLeft
+XVkbd*completion_panel*entry.left: chainLeft
+XVkbd*completion_panel*view.top: chainTop
+XVkbd*completion_panel*view.bottom: chainBottom
+XVkbd*completion_panel*view.right: chainRight
+
+XVkbd*edit_fkey_panel.title: xvkbd - edit function keys
+XVkbd*edit_fkey_panel.input: true
+XVkbd*edit_fkey_panel*defaultDistance: 4
+XVkbd*edit_fkey_panel*form2*vertDistance: 6
+XVkbd*edit_fkey_panel*width: 0
+XVkbd*edit_fkey_panel*height: 0
+XVkbd*edit_fkey_panel*internalWidth: 4
+XVkbd*edit_fkey_panel*MenuButton.shadowWidth: 2
+XVkbd*edit_fkey_panel*form2.borderWidth: 1
+XVkbd*edit_fkey_panel*form2.?.left: chainLeft
+XVkbd*edit_fkey_panel*form2.?.right: chainLeft
+XVkbd*edit_fkey_panel*form2.fkey_value.right: chainRight
+XVkbd*edit_fkey_panel*Command.left: chainLeft
+XVkbd*edit_fkey_panel*Command.right: chainLeft
+XVkbd*edit_fkey_panel*fkey_menu.fromHoriz: fkey_label
+XVkbd*edit_fkey_panel*fkey_value_menu.fromVert: fkey_label
+XVkbd*edit_fkey_panel*fkey_value.fromVert: fkey_label
+XVkbd*edit_fkey_panel*fkey_value_sep.fromVert: fkey_label
+XVkbd*edit_fkey_panel*fkey_value_sep.fromHoriz: fkey_value_menu
+XVkbd*edit_fkey_panel*fkey_value.fromHoriz: fkey_value_sep
+XVkbd*edit_fkey_panel*fkey_value.width: 200
+XVkbd*edit_fkey_panel*fkey_value.height: 22
+XVkbd*edit_fkey_panel*save_button.fromVert: form2
+XVkbd*edit_fkey_panel*close_button.fromVert: form2
+XVkbd*edit_fkey_panel*close_button.fromHoriz: save_button
+
+XVkbd*edit_fkey_panel*justify: left
+XVkbd*edit_fkey_panel*fkey_menu.label: Shift-F999
+XVkbd*edit_fkey_panel*fkey_label.label: Function Key:
+XVkbd*edit_fkey_panel*fkey_value_menu.label: Assigned Command
+XVkbd*edit_fkey_panel*fkey_value_menu*string.label: Assigned String
+XVkbd*edit_fkey_panel*fkey_value_menu*command.label: Assigned Command
+XVkbd*edit_fkey_panel*fkey_value_sep.label: :
+XVkbd*edit_fkey_panel*fkey_value_sep.horizDistance: 0
+XVkbd*edit_fkey_panel*save_button.label: Save
+XVkbd*edit_fkey_panel*close_button.label: Close
+
+XVkbd*edit_fkey_panel*Label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+XVkbd*edit_fkey_panel*fkey_value_menu.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1
+
+!! Dead Keys
+!
+XVkbd.deadkeys: dead_diaeresis,dead_acute,dead_grave,\
+  dead_circumflex,dead_macron,dead_abovering,dead_doubleacute,\
+  dead_tilde,dead_abovedot
+
+XVkbd*deadkey_panel.title: xvkbd - dead keys
+XVkbd*deadkey_panel*font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-1
+XVkbd*deadkey_panel*Repeater.width: 30
+XVkbd*deadkey_panel*Repeater.height: 36
+XVkbd*deadkey_panel*dead_diaeresis.label: \250
+XVkbd*deadkey_panel*dead_acute.label: \264
+XVkbd*deadkey_panel*dead_grave.label: `
+XVkbd*deadkey_panel*dead_circumflex.label: ^
+XVkbd*deadkey_panel*dead_macron.label: \257
+XVkbd*deadkey_panel*dead_abovering.label: \260
+XVkbd*deadkey_panel*dead_doubleacute.label: \264\264
+XVkbd*deadkey_panel*dead_tilde.label: ~
+XVkbd*deadkey_panel*dead_abovedot.label: \267
+
+!! keyboard layouts
+!
+XVkbd.customizations: default,belgian,danish,fitaly,\
+  french,french2,german,greek,hebrew,icelandic,italian,\
+  jisx6002/ja_JP.eucJP,jisx6004/ja_JP.eucJP,korean/ko_KR.eucKR,\
+  norwegian,portuguese,russian/ru_RU.KOI8-R,slovene,spanish,\
+  swedish,swissgerman,turkish,uk,latin1,small,strip
+
+XVkbd*layout_panel*default.label: Default
+XVkbd*layout_panel*belgian.label: Belgian
+XVkbd*layout_panel*danish.label: Danish
+XVkbd*layout_panel*fitaly.label: Fitaly
+XVkbd*layout_panel*french.label: French
+XVkbd*layout_panel*french2.label: French (2)
+XVkbd*layout_panel*german.label: German
+XVkbd*layout_panel*greek.label: Greek
+XVkbd*layout_panel*hebrew.label: Hebrew
+XVkbd*layout_panel*icelandic.label: Icelandic
+XVkbd*layout_panel*italian.label: Italian
+XVkbd*layout_panel*jisx6002.label: Japanese
+XVkbd*layout_panel*jisx6004.label: Japanese (JIS X 6004)
+XVkbd*layout_panel*korean.label: Korean
+XVkbd*layout_panel*norwegian.label: Norwegian
+XVkbd*layout_panel*portuguese.label: Portuguese
+XVkbd*layout_panel*russian.label: Russian
+XVkbd*layout_panel*slovene.label: Slovene
+XVkbd*layout_panel*spanish.label: Spanish
+XVkbd*layout_panel*swedish.label: Swedish
+XVkbd*layout_panel*swissgerman.label: Swiss/German
+XVkbd*layout_panel*turkish.label: Turkish
+XVkbd*layout_panel*uk.label: United Kingdom
+XVkbd*layout_panel*latin1.label: Latin-1
+XVkbd*layout_panel*small.label: Small Keyboard
+XVkbd*layout_panel*strip.label: Key Strip
+
+XVkbd*Iconify.width: 20
+XVkbd*Iconify.shadowWidth: 0
+XVkbd*Iconify.resizable: false
+XVkbd*iconified_window*hSpace: 0
+XVkbd*iconified_window*vSpace: 0
+XVkbd*iconified_window*shadowWidth: 0
+
+!! uncomment the following lines when genuine Xaw is used instead of Xaw3d
+!
+! XVkbd*keypad*pad3,3.height: 62
+! XVkbd*keypad*pad4,0.width: 72
+
+!! Sample settings to make window small - see also XVkbd-small.ad
+!
+!xvkbd.windowGeometry: 300x100
+!xvkbd.modalKeytop: true
+!xvkbd.compact: true
+
+!! You should set the label font if you want to make the window small.
+!
+!xvkbd*Font: -misc-fixed-medium-r-semicondensed--13-*-iso8859-1
diff --git a/development/autotests/xvkbd/XVkbd-common.h b/development/autotests/xvkbd/XVkbd-common.h
new file mode 100644 (file)
index 0000000..0fc2b01
--- /dev/null
@@ -0,0 +1,291 @@
+"XVkbd.title: xvkbd - Virtual Keyboard",
+"XVkbd.iconName: xvkbd",
+"XVkbd*input: false",
+"XVkbd*props_panel.input: true",
+"XVkbd*display_panel.input: true",
+"XVkbd.mappedWhenManaged: false",
+"XVkbd.translations: #override \
+       <Message>WM_PROTOCOLS: DeleteWindowProc()\\n\
+        <Configure>: WindowResized()\\n\
+        <MappingNotify>: ReadKeymap()\\n\
+        <Visible>: VisibilityChanged()",
+"XVkbd.Form.translations: <BtnDown>:",
+"XVkbd.Form.?.translations: <BtnDown>:",
+"XVkbd*Command.translations: #override \\n\
+        <EnterWindow>: ShowBalloon() highlight() \\n\
+        <LeaveWindow>: CloseBalloon() unhighlight() \\n\
+       <BtnDown>: ButtonDownAction() set()\\n\
+       <BtnUp>: notify() unset() ButtonUpAction()",
+"XVkbd*Repeater.translations: #override \\n\
+        <EnterWindow>: ShowBalloon() highlight() \\n\
+        <LeaveWindow>: CloseBalloon() unhighlight() \\n\
+       <BtnDown>: ButtonDownAction() set() start() \\n\
+       <BtnUp>: stop() unset() ButtonUpAction()",
+"XVkbd*MenuButton.translations: #override \\n\
+        <EnterWindow>: ShowBalloon() highlight() \\n\
+        <LeaveWindow>: CloseBalloon() unhighlight()",
+"XVkbd.TransientShell.translations: #override \\n\
+       <Message>WM_PROTOCOLS: ClosePopupPanel()",
+"XVkbd*Text*translations: #override \
+       <Key>Return: \\n\
+       <Key>Linefeed: \\n\
+       Ctrl<Key>m: \\n\
+       Ctrl<Key>j:",
+"XVkbd*Repeater.initialDelay: 600",
+"XVkbd*Repeater.minimumDelay: 100",
+"XVkbd*Repeater.decay: 500",
+"XVkbd*Font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*generalFont: -*-lucidatypewriter-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*letterFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*specialFont: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*keypadFont: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-1",
+"XVkbd*banner.font: -*-lucida-bold-i-*-*-14-*-*-*-*-*-iso8859-1",
+"XVkbd*display_panel*label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*beNiceToColormap: false",
+"XVkbd*topShadowContrast: 40",
+"XVkbd*bottomShadowContrast: 80",
+"XVkbd*shadowWidth: 2",
+"XVkbd*Label.shadowWidth: 0",
+"XVkbd*MainMenu.shadowWidth: 0",
+"XVkbd*MainMenu.topShadowContrast: 0",
+"XVkbd*MainMenu.bottomShadowContrast: 0",
+"XVkbd*Background: gray85",
+"XVkbd*Text*background: white",
+"XVkbd*specialBackground: gray75",
+"XVkbd*focusBackground: bisque2",
+"XVkbd*remoteFocusBackground: lightcyan1",
+"XVkbd*Foreground: black",
+"XVkbd*highlightBackground: gray90",
+"XVkbd*highlightForeground: forestgreen",
+"XVkbd*highlightThickness: 1",
+"XVkbd*Form.resizable: true",
+"XVkbd*defaultDistance: 0",
+"XVkbd*Form.borderWidth: 0",
+"XVkbd*Label.borderWidth: 0",
+"XVkbd*Command.internalWidth: 2",
+"XVkbd*Repeater.internalWidth: 2",
+"XVkbd*Command.resize: false",
+"XVkbd*Repeater.resize: false",
+"XVkbd*Command.justify: center",
+"XVkbd*Repeater.justify: center",
+"XVkbd*row1.vertDistance: 5",
+"XVkbd*F5.horizDistance: 5",
+"XVkbd*F9.horizDistance: 5",
+"XVkbd*BackSpace.horizDistance: 5",
+"XVkbd*Command.height: 30",
+"XVkbd*Repeater.height: 30",
+"XVkbd*banner.height: 30",
+"XVkbd*row0.Repeater.height: 25",
+"XVkbd*Command.width: 30",
+"XVkbd*Repeater.width: 30",
+"XVkbd*space.width: 80",
+"XVkbd*Tab.width: 45",
+"XVkbd*Control_L.width: 60",
+"XVkbd*Shift_L.width: 75",
+"XVkbd*Shift_R.width: 40",
+"XVkbd*Multi_key.width: 35",
+"XVkbd*Caps_Lock.width: 35",
+"XVkbd*Alt_L.width: 38",
+"XVkbd*Alt_R.width: 38",
+"XVkbd*Meta_L.width: 38",
+"XVkbd*Meta_R.width: 38",
+"XVkbd*BackSpace.width: 75",
+"XVkbd*Delete.width: 45",
+"XVkbd*Return.width: 60",
+"XVkbd*row5.Focus.width: 35",
+"xvkbd*Mode_switch.width: 45",
+"XVkbd*keypad.vertDistance: 5",
+"XVkbd*keypad.horizDistance: 10",
+"XVkbd*keypad*Command.width: 35",
+"XVkbd*keypad*Repeater.width: 35",
+"XVkbd*keypad*Command.justify: left",
+"XVkbd*keypad*Repeater.justify: left",
+"XVkbd*keypad*pad3,3.height: 60",
+"XVkbd*keypad*pad4,0.width: 70",
+"XVkbd.balloonBackground: LightYellow1",
+"XVkbd.launchBalloonBackground: LightCyan1",
+"XVkbd*balloon_panel.Label.width: 150",
+"XVkbd*balloon_panel.Label.resize: false",
+"XVkbd*balloon_panel.Label.justify: left",
+"XVkbd*banner.width: 150",
+"XVkbd*banner.justify: right",
+"XVkbd*MainMenu.width: 0",
+"XVkbd*MainMenu.label: xvkbd",
+"XVkbd*MainMenu.justify: left",
+"XVkbd*MainMenu.internalWidth: 2",
+"XVkbd*MainMenu.highlightThickness: 0",
+"XVkbd*menu.about.label: About...",
+"XVkbd*menu.man.label: Manual...",
+"XVkbd*menu.keypad.label: Keypad...",
+"XVkbd*menu.sun_fkey.label: Sun Function Keys...",
+"XVkbd*menu.deadkey.label: Dead Keys...",
+"XVkbd*menu.completion.label: Word Completion...",
+"XVkbd*menu.select_layout.label: Change Keyboard Layout...",
+"XVkbd*menu.edit_fkey.label: Edit Function Keys...",
+"XVkbd*menu.show_keypad.label: Show Keypad?",
+"XVkbd*menu.show_functionkey.label: Show Function Keys?",
+"XVkbd*menu.props.label: Property...",
+"XVkbd*menu.open_display.label: Connect to Remote Display...",
+"XVkbd*menu.close_display.label: Revert to Local Display",
+"XVkbd*menu.quit.label: Quit",
+"XVkbd*menu.SmeBSB.rightMargin: 30",
+"XVkbd*props_panel.title: xvkbd - proprety",
+"XVkbd*props_panel*defaultDistance: 10",
+"XVkbd*props_panel*vertDistance: 5",
+"XVkbd*props_panel*always_on_top.label: Always on Top?",
+"XVkbd*props_panel*wm_toolbar.label: Behave as Toolbar Window?",
+"XVkbd*props_panel*shift_lock.label: Lock Shift?",
+"XVkbd*props_panel*altgr_lock.label: Lock AltGr?",
+"XVkbd*props_panel*modifiers_lock.label: Lock Control, Alt and Meta?",
+"XVkbd*props_panel*quick_modifiers.label: Enable \"Quick Modifiers\"?",
+"XVkbd*props_panel*use_xtest.label: Use XTEST Extension?",
+"XVkbd*props_panel*jump_pointer.label: Jump Pointer?",
+"XVkbd*props_panel*dict_entry_label.label: Completion Dictionary: ",
+"XVkbd*props_panel*dict_default_button.label: Default",
+"XVkbd*props_panel*click.label: Key-Click Sound:",
+"XVkbd*props_panel*autoclick.label: Automatic Click:",
+"XVkbd*props_panel*Command.internalWidth: 4",
+"XVkbd*props_panel*Command.width: 0",
+"XVkbd*props_panel*Command.height: 0",
+"XVkbd*props_panel*dismiss.label: Dismiss",
+"XVkbd*props_panel*dismiss.vertDistance: 10",
+"XVkbd*props_panel*Toggle.width: 200",
+"XVkbd*props_panel*Toggle.justify: left",
+"XVkbd*props_panel*dict_entry.width: 220",
+"XVkbd*props_panel*left: chainLeft",
+"XVkbd*props_panel*right: chainLeft",
+"XVkbd*props_panel*top: chainTop",
+"XVkbd*props_panel*bottom: chainTop",
+"XVkbd*props_panel*dict_entry.left: chainLeft",
+"XVkbd*props_panel*dict_entry.right: chainRight",
+"XVkbd*props_panel*dict_default_button.left: chainRight",
+"XVkbd*props_panel*dict_default_button.right: chainRight",
+"XVkbd.about_panel.title: xvkbd - about this program",
+"XVkbd.keypad_panel.title: xvkbd - keypad",
+"XVkbd.sun_fkey_panel.title: xvkbd - Sun",
+"XVkbd.display_panel.title: xvkbd - Remote Display",
+"XVkbd.sun_fkey_panel*Repeater.width: 35",
+"XVkbd.sun_fkey_panel*Help.width: 70",
+"XVkbd.sun_fkey_panel*justify: left",
+"XVkbd.display_panel*label.label: Remote Display:",
+"XVkbd.display_panel*ok.label: Connect",
+"XVkbd.display_panel*Text.width: 150",
+"XVkbd.display_panel*defaultDistance: 3",
+"XVkbd.display_panel*Command.width: 0",
+"XVkbd.display_panel*Command.height: 0",
+"XVkbd.display_panel*Command.internalWidth: 4",
+"XVkbd.display_panel*Label.width: 0",
+"XVkbd.display_panel*Label.resizable: true",
+"XVkbd*layout_panel.title: xvkbd - layout",
+"XVkbd*layout_panel*Command.width: 150",
+"XVkbd*layout_panel*Command.height: 0",
+"XVkbd*layout_panel*vSpace: 2",
+"XVkbd*layout_panel.box.width: 320",
+"XVkbd*layout_panel.box.orientation: vertical",
+"XVkbd*completion_panel.title: xvkbd - word completion",
+"XVkbd*completion_panel*Label.justify: left",
+"XVkbd*completion_panel*entry.width: 200",
+"XVkbd*completion_panel*view.allowVert: true",
+"XVkbd*completion_panel*view.useRight: true",
+"XVkbd*completion_panel*view.forceBars: true",
+"XVkbd*completion_panel*view.list.width: 400",
+"XVkbd*completion_panel*view.list.height: 150",
+"XVkbd*completion_panel*label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*completion_panel*list.font: -*-lucida-medium-r-*-*-14-*-*-*-*-*-iso8859-1",
+"XVkbd*completion_panel*label.label: Completion:",
+"XVkbd*completion_panel*bottom: chainTop",
+"XVkbd*completion_panel*label.right: chainLeft",
+"XVkbd*completion_panel*entry.left: chainLeft",
+"XVkbd*completion_panel*view.top: chainTop",
+"XVkbd*completion_panel*view.bottom: chainBottom",
+"XVkbd*completion_panel*view.right: chainRight",
+"XVkbd*edit_fkey_panel.title: xvkbd - edit function keys",
+"XVkbd*edit_fkey_panel.input: true",
+"XVkbd*edit_fkey_panel*defaultDistance: 4",
+"XVkbd*edit_fkey_panel*form2*vertDistance: 6",
+"XVkbd*edit_fkey_panel*width: 0",
+"XVkbd*edit_fkey_panel*height: 0",
+"XVkbd*edit_fkey_panel*internalWidth: 4",
+"XVkbd*edit_fkey_panel*MenuButton.shadowWidth: 2",
+"XVkbd*edit_fkey_panel*form2.borderWidth: 1",
+"XVkbd*edit_fkey_panel*form2.?.left: chainLeft",
+"XVkbd*edit_fkey_panel*form2.?.right: chainLeft",
+"XVkbd*edit_fkey_panel*form2.fkey_value.right: chainRight",
+"XVkbd*edit_fkey_panel*Command.left: chainLeft",
+"XVkbd*edit_fkey_panel*Command.right: chainLeft",
+"XVkbd*edit_fkey_panel*fkey_menu.fromHoriz: fkey_label",
+"XVkbd*edit_fkey_panel*fkey_value_menu.fromVert: fkey_label",
+"XVkbd*edit_fkey_panel*fkey_value.fromVert: fkey_label",
+"XVkbd*edit_fkey_panel*fkey_value_sep.fromVert: fkey_label",
+"XVkbd*edit_fkey_panel*fkey_value_sep.fromHoriz: fkey_value_menu",
+"XVkbd*edit_fkey_panel*fkey_value.fromHoriz: fkey_value_sep",
+"XVkbd*edit_fkey_panel*fkey_value.width: 200",
+"XVkbd*edit_fkey_panel*fkey_value.height: 22",
+"XVkbd*edit_fkey_panel*save_button.fromVert: form2",
+"XVkbd*edit_fkey_panel*close_button.fromVert: form2",
+"XVkbd*edit_fkey_panel*close_button.fromHoriz: save_button",
+"XVkbd*edit_fkey_panel*justify: left",
+"XVkbd*edit_fkey_panel*fkey_menu.label: Shift-F999",
+"XVkbd*edit_fkey_panel*fkey_label.label: Function Key:",
+"XVkbd*edit_fkey_panel*fkey_value_menu.label: Assigned Command",
+"XVkbd*edit_fkey_panel*fkey_value_menu*string.label: Assigned String",
+"XVkbd*edit_fkey_panel*fkey_value_menu*command.label: Assigned Command",
+"XVkbd*edit_fkey_panel*fkey_value_sep.label: :",
+"XVkbd*edit_fkey_panel*fkey_value_sep.horizDistance: 0",
+"XVkbd*edit_fkey_panel*save_button.label: Save",
+"XVkbd*edit_fkey_panel*close_button.label: Close",
+"XVkbd*edit_fkey_panel*Label.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd*edit_fkey_panel*fkey_value_menu.font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
+"XVkbd.deadkeys: dead_diaeresis,dead_acute,dead_grave,\
+  dead_circumflex,dead_macron,dead_abovering,dead_doubleacute,\
+  dead_tilde,dead_abovedot",
+"XVkbd*deadkey_panel.title: xvkbd - dead keys",
+"XVkbd*deadkey_panel*font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-1",
+"XVkbd*deadkey_panel*Repeater.width: 30",
+"XVkbd*deadkey_panel*Repeater.height: 36",
+"XVkbd*deadkey_panel*dead_diaeresis.label: \\250",
+"XVkbd*deadkey_panel*dead_acute.label: \\264",
+"XVkbd*deadkey_panel*dead_grave.label: `",
+"XVkbd*deadkey_panel*dead_circumflex.label: ^",
+"XVkbd*deadkey_panel*dead_macron.label: \\257",
+"XVkbd*deadkey_panel*dead_abovering.label: \\260",
+"XVkbd*deadkey_panel*dead_doubleacute.label: \\264\\264",
+"XVkbd*deadkey_panel*dead_tilde.label: ~",
+"XVkbd*deadkey_panel*dead_abovedot.label: \\267",
+"XVkbd.customizations: default,belgian,danish,fitaly,\
+  french,french2,german,greek,hebrew,icelandic,italian,\
+  jisx6002/ja_JP.eucJP,jisx6004/ja_JP.eucJP,korean/ko_KR.eucKR,\
+  norwegian,portuguese,russian/ru_RU.KOI8-R,slovene,spanish,\
+  swedish,swissgerman,turkish,uk,latin1,small,strip",
+"XVkbd*layout_panel*default.label: Default",
+"XVkbd*layout_panel*belgian.label: Belgian",
+"XVkbd*layout_panel*danish.label: Danish",
+"XVkbd*layout_panel*fitaly.label: Fitaly",
+"XVkbd*layout_panel*french.label: French",
+"XVkbd*layout_panel*french2.label: French (2)",
+"XVkbd*layout_panel*german.label: German",
+"XVkbd*layout_panel*greek.label: Greek",
+"XVkbd*layout_panel*hebrew.label: Hebrew",
+"XVkbd*layout_panel*icelandic.label: Icelandic",
+"XVkbd*layout_panel*italian.label: Italian",
+"XVkbd*layout_panel*jisx6002.label: Japanese",
+"XVkbd*layout_panel*jisx6004.label: Japanese (JIS X 6004)",
+"XVkbd*layout_panel*korean.label: Korean",
+"XVkbd*layout_panel*norwegian.label: Norwegian",
+"XVkbd*layout_panel*portuguese.label: Portuguese",
+"XVkbd*layout_panel*russian.label: Russian",
+"XVkbd*layout_panel*slovene.label: Slovene",
+"XVkbd*layout_panel*spanish.label: Spanish",
+"XVkbd*layout_panel*swedish.label: Swedish",
+"XVkbd*layout_panel*swissgerman.label: Swiss/German",
+"XVkbd*layout_panel*turkish.label: Turkish",
+"XVkbd*layout_panel*uk.label: United Kingdom",
+"XVkbd*layout_panel*latin1.label: Latin-1",
+"XVkbd*layout_panel*small.label: Small Keyboard",
+"XVkbd*layout_panel*strip.label: Key Strip",
+"XVkbd*Iconify.width: 20",
+"XVkbd*Iconify.shadowWidth: 0",
+"XVkbd*Iconify.resizable: false",
+"XVkbd*iconified_window*hSpace: 0",
+"XVkbd*iconified_window*vSpace: 0",
+"XVkbd*iconified_window*shadowWidth: 0",
diff --git a/development/autotests/xvkbd/XVkbd-danish.ad b/development/autotests/xvkbd/XVkbd-danish.ad
new file mode 100644 (file)
index 0000000..f7e8c77
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-danish.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Danish layout, roughly taken from
+! xkeycaps's "PC 105 key, wide Delete, tall Enter / XFree86; Danish"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Danish)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 + ´ ½ ' \n\
+  Tab q w e r t y u i o p å ¨ Delete \n\
+  Control_L a s d f g h j k l æ ø Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # ¤ % & / ( ) = ? ` § * \n\
+  Tab Q W E R T Y U I O P Å ^ Delete \n\
+  Control_L A S D F G H J K L Æ Ø Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 @ £ $ 5 6 { [ ] } + | ½ ' \n\
+  Tab q w e r t y u i o p å ~ Delete \n\
+  Control_L a s d f g h j k l æ ø Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc !\n1 "\n2_@ #\n3_£ ¤\n4_$ %\n5 &\n6 /\n7_{ (\n8_[ )\n9_] =\n0_} ?\n+ `\n´_| §\n½ *\n' \n\
+  Tab Q W E R T Y U I O P Å ^\n¨_~ Del \n\
+  Control A S D F G H J K L Æ Ø Return \n\
+  Shift >\n< Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 + ´ ½ ' \n\
+  Tab q w e r t y u i o p å ¨ Del \n\
+  Ctrl a s d f g h j k l æ ø Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # ¤ % & / ( ) = ? ` § * \n\
+  Tab Q W E R T Y U I O P Å ^ Del \n\
+  Ctrl A S D F G H J K L Æ Ø Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 @ £ $ 5 6 { [ ] } + | ½ ' \n\
+  Tab q w e r t y u i o p å ~ Del \n\
+  Ctrl a s d f g h j k l æ ø Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-fitaly.ad b/development/autotests/xvkbd/XVkbd-fitaly.ad
new file mode 100644 (file)
index 0000000..c8f341f
--- /dev/null
@@ -0,0 +1,72 @@
+!! XVkbd-fitaly.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! with contribution from Marshall Rose
+!!
+!! Last update: 2003-06-23
+
+#include "XVkbd-common"
+
+xvkbd.title: xvkbd - Virtual Keyboard ("Fitaly" Style)
+
+xvkbd.inheritGeoemetry: false
+xvkbd.compact: true
+xvkbd.form*Repeater.shadowWidth: 1
+xvkbd.form*Command.shadowWidth: 1
+xvkbd.form*Repeater.height: 20
+xvkbd.form*Command.height: 20
+xvkbd.form*Repeater.width: 20
+xvkbd.form*row0*Repeater.width: 28
+xvkbd.Form*F5.horizDistance: 0
+xvkbd.Form*F9.horizDistance: 0
+xvkbd.form*Command.width: 60
+xvkbd.form*Escape.width: 60
+xvkbd.form*Tab.width: 60
+xvkbd.form*row1.BackSpace.horizDistance: 0
+xvkbd.form*BackSpace.width: 60
+xvkbd.form*Delete.width: 60
+xvkbd.form*Return.width: 60
+xvkbd.form*space.width: 60
+xvkbd.form*Alt_L.width: 30
+xvkbd.form*MainMenu.width: 30
+xvkbd.form*MainMenu.height: 20
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 BackSpace \n\
+  Escape \\ z v c h w k ; 1 2 BackSpace \n\
+  Shift_L ' f i t a l y , 3 4 Shift_R \n\
+  Tab space n e space 5 6 Return \n\
+  Caps_Lock ` g d o r s b . 7 8 [ = ] \n\
+  Control_L / q j u m p x - 9 0 Alt_L MainMenu
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 BackSpace \n\
+  Escape | Z V C H W K : ! @ Delete \n\
+  Shift_L " F I T A L Y < # $ Shift_R \n\
+  Tab space N E space % ^ Return \n\
+  Caps_Lock ~ G D O R S B > & * { + } \n\
+  Control_L ? Q J U M P X _ ( ) Alt_L MainMenu
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 back \n\
+  Esc \\ Z V C H W K ; 1 2 BS \n\
+  Shift ' F I T A L Y , 3 4 Shift \n\
+  Tab space N E space 5 6 Return \n\
+  Caps ` G D O R S B . 7 8 [ = ] \n\
+  Ctrl / Q J U M P X - 9 0 Alt MainMenu
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 back  \n\
+  Esc \\ z v c h w k ; 1 2 BS \n\
+  Shift ' f i t a l y , 3 4 Shift \n\
+  Tab space n e space 5 6 Return \n\
+  Caps ` g d o r s b . 7 8 [ = ] \n\
+  Ctrl / q j u m p x - 9 0 Alt MainMenu
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 back \n\
+  Esc | Z V C H W K : ! @ Del \n\
+  Shift " F I T A L Y < # $ Shift \n\
+  Tab space N E space % ^ Return \n\
+  Caps ~ G D O R S B > & * { + } \n\
+  Ctrl ? Q J U M P X _ ( ) Alt MainMenu
diff --git a/development/autotests/xvkbd/XVkbd-french.ad b/development/autotests/xvkbd/XVkbd-french.ad
new file mode 100644 (file)
index 0000000..84dd596
--- /dev/null
@@ -0,0 +1,76 @@
+!! XVkbd-french.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to French layout, roughly taken from
+! xkeycaps's "PC 102 key, wide Delete, tall Enter / XFree86; French"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (French)
+
+xvkbd*Shift_L.width: 45
+!xvkbd*Shift_R.width: 60
+!xvkbd*Return.width: 50
+!xvkbd*Delete.width: 40
+!xvkbd*Escape.width: 40
+xvkbd*space.width: 110
+!xvkbd*row2.BackSpace.width: 65
+!xvkbd*row2.BackSpace.horizDistance: 0
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape & é " ' ( - è _ ç à ) = ² * \n\
+  Tab a z e r t y u i o p ^ $ Delete \n\
+  Control_L q s d f g h j k l m ù Return \n\
+  Shift_L < w x c v b n , ; : ! Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ° + ³ µ \n\
+  Tab A Z E R T Y U I O P ¨ £ Delete \n\
+  Control_L Q S D F G H J K L M % Return \n\
+  Shift_L > W X C V B N ? . / § Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape & ~ # { [ | ` \\ ^ @ ] } ² * \n\
+  Tab a z e r t y u i o p ^ ¤ Delete \n\
+  Control_L q s d f g h j k l m ù Return \n\
+  Shift_L < w x c v b n , ; : ! Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1\n& 2\né_~ 3\n"_# 4\n'_{ 5\n(_[ 6\n-_| 7\nè_` 8\n__\\ 9\nç_^ 0\nà_@ °\n)_] +\n=_} ³\n² µ\n* \n\
+  Tab A Z E R T Y U I O P ¨\n^ £\n$_¤ Delete \n\
+  Control Q S D F G H J K L M %\nù Return \n\
+  Shift >\n< W X C V B N ?\n, .\n; /\n: §\n! Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc & é " ' ( - è _ ç à ) = ² * \n\
+  Tab a z e r t y u i o p ^ $ Del \n\
+  Ctrl q s d f g h j k l m ù Return \n\
+  Shift < w x c v b n , ; : ! Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ° + ³ µ \n\
+  Tab A Z E R T Y U I O P ¨ £ Del \n\
+  Ctrl Q S D F G H J K L M % Return \n\
+  Shift > W X C V B N ? . / § Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc & ~ # { [ | ` \\ ^ @ ] } ² * \n\
+  Tab a z e r t y u i o p ^ ¤ Del \n\
+  Ctrl q s d f g h j k l m ù Return \n\
+  Shift < w x c v b n , ; : ! Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-french2.ad b/development/autotests/xvkbd/XVkbd-french2.ad
new file mode 100644 (file)
index 0000000..dd35d8b
--- /dev/null
@@ -0,0 +1,93 @@
+!! XVkbd-french.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! This app-defaults file is contributed from Jean-Pierre Demailly
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard support most Latin-1 characters
+!
+xvkbd.title: xvkbd - Virtual Keyboard (French)
+
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape & ~ \" ' ( - ` _ ^ @ ) = \\ < \n\
+  Tab a z e r t y u i o p ^ $ Delete \n\
+  Control_L q s d f g h j k l m ù Return \n\
+  Shift_L w x c v b n , ; : ! Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ° + ¿ > \n\
+  Tab A Z E R T Y U I O P ¨ £ Delete \n\
+  Control_L Q S D F G H J K L M % Return \n\
+  Shift_L W X C V B N ? . / § Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ½ ¤ # { [ | ¥ ¸ ¢ ´ ] } ¦ µ \n\
+  Tab à á â ã ä å æ ç è é ê ë Delete \n\
+  Control_L ì í î ï ð ñ ò ó ô õ ö Return \n\
+  Shift ø ù ú û ü ý þ ÿ · ¡ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ¹ ² ³ ¾ ª ® © ¬ ­ º ¶ ± × ÷ \n\
+  Tab À Á Â Ã Ä Å Æ Ç È É Ê Ë Delete \n\
+  Control_L Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Return \n\
+  Shift Ø Ù Ú Û Ü Ý Þ ß « » Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc   1_¹\n&_½ 2_²\n~_¤ 3_³\n"_# 4_¾\n'_{ 5_ª\n(_[ \
+    6_®\n-_| 7_©\n`_¥ 8_¬\n__¸ 9_­\n^_¢ 0_º\n@_´ °_¶\n)_] \
+    +_±\n=_} ¿_×\n\\_¦ >_÷\n<_µ \n\
+  Tab A_à Z_á E_â R_ã T_ä Y_å U_æ I_ç O_è P_é \
+    ¨_¯\n^_ê £_Ë\n$_ë   Del \n\
+  Control   Q_ì S_í D_î F_ï G_ð H_ñ J_ò K_ó L_ô \
+    M_õ %_Ö\nù_ö   Return \n\
+  Shift W_ø X_ù C_ú V_û B_ü N_ý ?_Þ\n,_þ \
+    ._ß\n;_ÿ /_«\n:_· §_»\n!_¡   Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Escape & ~ \" ' ( - ` _ ^ @ ) = \\ < \n\
+  Tab a z e r t y u i o p ^ $ Del \n\
+  Ctrl q s d f g h j k l m ù Return \n\
+  Shift w x c v b n , ; : ! Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ° + ¿ > \n\
+  Tab A Z E R T Y U I O P ¨ £ Del \n\
+  Ctrl Q S D F G H J K L M % Return \n\
+  Shift W X C V B N ? . / § Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Escape ½ ¤ # { [ | ¥ ¸ ¢ ´ ] } ¦ µ \n\
+  Tab à á â ã ä å æ ç è é ê ë Del \n\
+  Ctrl ì í î ï ð ñ ò ó ô õ ö Return \n\
+  Shift ø ù ú û ü ý þ ÿ · ¡ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Escape ¹ ² ³ ¾ ª ® © ¬ ­ º ¶ ± × ÷ \n\
+  Tab À Á Â Ã Ä Å Æ Ç È É Ê Ë Del \n\
+  Ctrl Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Return \n\
+  Shift Ø Ù Ú Û Ü Ý Þ ß « » Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-german.ad b/development/autotests/xvkbd/XVkbd-german.ad
new file mode 100644 (file)
index 0000000..2895002
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-german.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to German layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (German)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ? ` ^ # \n\
+  Tab q w e r t z u i o p \374 + Delete \n\
+  Control_L a s d f g h j k l \366 \344 Return \n\
+  Shift_L < y x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " \247 $ % & / ( ) = \337 ' \260 | \n\
+  Tab Q W E R T Z U I O P \334 * Delete \n\
+  Control_L A S D F G H J K L \326 \304 Return \n\
+  Shift_L > Y X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape \271 \262 \263 \243 \254 \251 { [ ] } \\ ' ^ # \n\
+  Tab @ w e r t z u i o p \374 ~ Delete \n\
+  Control_L a s d f g h j k l \366 \344 Return \n\
+  Shift_L | y x c v b n \265 , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1_\271 "\n2_\262 \247\n3_\263 $\n4_\243 %\n5_\254 &\n6_\251 \
+    /\n7_{ (\n8_[ )\n9_] =\n0_} \337\n\?_\\ '\n` \260\n^ |\n# \n\
+  Tab Q_@ W E R T Z U I O P \334 *\n+_~ Del \n\
+  Control A S D F G H J K L \326 \304 Return \n\
+  Shift >\n<_| Y X C V B N M_\265 ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ? ` ^ # \n\
+  Tab q w e r t z u i o p \374 + Del \n\
+  Ctrl a s d f g h j k l \366 \344 Return \n\
+  Shift < y x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " \247 $ % & / ( ) = \337 ' \260 | \n\
+  Tab Q W E R T Z U I O P \334 * Del \n\
+  Ctrl A S D F G H J K L \326 \304 Return \n\
+  Shift > Y X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc \271 \262 \263 \243 \254 \251 { [ ] } \\ ' ^ # \n\
+  Tab @ w e r t z u i o p \374 ~ Del \n\
+  Ctrl a s d f g h j k l \366 \344 Return \n\
+  Shift | y x c v b n \265 , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-greek.ad b/development/autotests/xvkbd/XVkbd-greek.ad
new file mode 100644 (file)
index 0000000..e5972d0
--- /dev/null
@@ -0,0 +1,131 @@
+!! XVkbd-greek.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-17
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard support Greek characters
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Greek)
+
+XVkbd*generalFont: -*-lucidatypewriter-bold-r-*-*-12-*-*-*-*-*-iso8859-7
+XVkbd*letterFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-7
+
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Control_L A S D F G H J K L : " Return \n\
+  Shift_L Z X C V B N M < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab Greek_theta Greek_omega Greek_epsilon Greek_rho Greek_tau Greek_psi \
+    Greek_upsilon Greek_iota Greek_omicron Greek_pi [ ] Delete \n\
+  Control_L Greek_alpha Greek_sigma Greek_delta Greek_phi Greek_gamma Greek_eta \
+    space Greek_kappa Greek_lambda ; ' Return \n\
+  Shift_L Greek_zeta Greek_xi Greek_chi space Greek_beta Greek_nu Greek_mu \
+    , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab Greek_THETA Greek_OMEGA Greek_EPSILON Greek_RHO Greek_TAU Greek_PSI \
+    Greek_UPSILON Greek_IOTA Greek_OMICRON Greek_PI { } Delete \n\
+  Control_L Greek_ALPHA Greek_SIGMA Greek_DELTA Greek_PHI Greek_GAMMA Greek_ETA \
+    SPACE Greek_KAPPA Greek_LAMBDA : " Return \n\
+  Shift_L Greek_ZETA Greek_XI Greek_CHI SPACE Greek_BETA Greek_NU Greek_MU \
+    < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1 @\n2 #\n3 $\n4 %\n5 ^\n6 &\n7 *\n8 (\n9 )\n0 _\n- +\n= |\n\\ ~\n` \n\
+  Tab Q_\310 W_\331 E_\305 R_\321 T_\324 Y_\330 U_\325 I_\311 O_\317 P_\320 \
+    {\n[ }\n] Del \n\
+  Control A_\301 S_\323 D_\304 F_\326 G_\303 H_\307 J K_\312 L_\313 :\n; "\n' Return \n\
+  Shift Z_\306 X_\316 C_\327 V B_\302 N_\315 M_\314 <\n, >\n. ?\n/ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1 @\n2 #\n3 $\n4 %\n5 ^\n6 &\n7 *\n8 (\n9 )\n0 _\n- +\n= |\n\\ ~\n` \n\
+  Tab Q_\350 W_\371 E_\345 R_\361 T_\364 Y_\370 U_\365 I_\351 O_\357 P_\360 \
+    {\n[ }\n] Del \n\
+  Control A_\341 S_\363 D_\344 F_\366 G_\343 H_\347 J K_\352 L_\353 :\n; "\n' Return \n\
+  Shift Z_\346 X_\356 C_\367 V B_\342 N_\355 M_\354 <\n, >\n. ?\n/ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : " Return \n\
+  Shift Z X C V B N M < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab \350 \371 \345 \361 \364 \370 \365 \351 \357 \360 [ ] Del \n\
+  Ctrl \341 \363 \344 \366 \343 \347 space \352 \353 ; ' Return \n\
+  Shift \346 \356 \367 space \342 \355 \354 , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab \310 \331 \305 \321 \324 \330 \325 \311 \317 \320 { } Del \n\
+  Ctrl \301 \323 \304 \326 \303 \307 space \312 \313 : " Return \n\
+  Shift \306 \316 \327 space \302 \315 \314 < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+! A Greek_ALPHA          \301 \341
+! B Greek_BETA           \302 \342
+! C Greek_CHI            \327 \367
+! D Greek_DELTA          \304 \344
+! E Greek_EPSILON        \305 \345
+! F Greek_PHI            \326 \366
+! G Greek_GAMMA          \303 \343
+! H Greek_ETA            \307 \347
+! I Greek_IOTA           \311 \351
+! J
+! K Greek_KAPPA          \312 \352
+! L Greek_LAMBDA         \313 \353
+! M Greek_MU             \314 \354
+! N Greek_NU             \315 \355
+! O Greek_OMICRON        \317 \357
+! P Greek_PI             \320 \360
+! Q Greek_THETA          \310 \350
+! R Greek_RHO            \321 \361
+! S Greek_SIGMA          \323 \363
+! T Greek_TAU            \324 \364
+! U Greek_UPSILON        \325 \365
+! V
+! W Greek_OMEGA          \331 \371
+! X Greek_XI             \316 \356
+! Y Greek_PSI            \330 \370
+! Z Greek_ZETA           \306 \346
diff --git a/development/autotests/xvkbd/XVkbd-hebrew.ad b/development/autotests/xvkbd/XVkbd-hebrew.ad
new file mode 100644 (file)
index 0000000..78874a4
--- /dev/null
@@ -0,0 +1,75 @@
+!! XVkbd-hebrew.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-16
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard support Hebrew characters
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Hebrew)
+
+xvkbd*generalFont: -*-*-*-r-*-*-13-*-*-*-*-*-iso8859-8
+xvkbd*letterFont: -*-*-*-r-*-*-13-*-*-*-*-*-iso8859-8
+
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Control_L A S D F G H J K L : \" Return \n\
+  Shift_L Z X C V B N M < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab hebrew_aleph hebrew_bet hebrew_gimel hebrew_dalet hebrew_he hebrew_waw \
+    hebrew_zain hebrew_chet hebrew_tet hebrew_yod hebrew_finalkaph hebrew_kaph Delete \n\
+  Control_L hebrew_lamed hebrew_finalmem hebrew_mem hebrew_finalnun hebrew_nun hebrew_samech hebrew_ayin hebrew_finalpe hebrew_pe ; ' Return \n\
+  Shift_L hebrew_finalzade hebrew_zade hebrew_qoph hebrew_resh hebrew_shin hebrew_taw \
+    M , . Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1 @\n2 #\n3 $\n4 %\n5 ^\n6 &\n7 *\n8 (\n9 )\n0 _\n- +\n= |\n\\ ~\n` \n\
+  Tab Q_\340 W_\341 E_\342 R_\343 T_\344 Y_\345 U_\346 I_\347 O_\350 P_\351 \
+    {\n[_\352 }\n]_\353   Del \n\
+  Control   A_\354 S_\355 D_\356 F_\357 G_\360 H_\361 J_\362 K_\363 L_\364 :\n; \"\n' Return \n\
+  Shift Z_\365 X_\366 C_\367 V_\370 B_\371 N_\372 M <\n, >\n. ?\n/ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : \" Return \n\
+  Shift Z X C V B N M < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab \340 \341 \342 \343 \344 \345 \346 \347 \350 \351 \352 \353 Del \n\
+  Ctrl \354 \355 \356 \357 \360 \361 \362 \363 \364 ; ' Return \n\
+  Shift \365 \366 \367 \370 \371 \372 M , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-icelandic.ad b/development/autotests/xvkbd/XVkbd-icelandic.ad
new file mode 100644 (file)
index 0000000..beca597
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-icelandic.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Icelandic layout, roughly taken from
+! xkeycaps's "PC 105 key, wide Delete, tall Enter / XFree86; Icelandic"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Icelandic)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ö - ° + \n\
+  Tab q w e r t y u i o p ð ' Delete \n\
+  Control_L a s d f g h j k l æ ' Return \n\
+  Shift_L < z x c v b n m , . þ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & / ( ) = Ö _ ¨ * \n\
+  Tab Q W E R T Y U I O P Ð ? Delete \n\
+  Control_L A S D F G H J K L Æ ' Return \n\
+  Shift_L > Z X C V B N M ; : Þ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 { [ ] } \\ - ° ` \n\
+  Tab q w e r t y u i o p ð ~ Delete \n\
+  Control_L a s d f g h j k l æ ^ Return \n\
+  Shift_L | z x c v b n m , . þ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc !\n1 "\n2 #\n3 $\n4 %\n5 &\n6 /\n7_{ (\n8_[ )\n9_] =\n0_} Ö_\\ _\n- ¨\n° *\n+_` \n\
+  Tab Q W E R T Y U I O P Ð ?\n'_~ Del \n\
+  Control A S D F G H J K L Æ '_^ Return \n\
+  Shift >\n<_| Z X C V B N M ;\n, :\n. Þ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ö - ° + \n\
+  Tab q w e r t y u i o p ð ' Del \n\
+  Ctrl a s d f g h j k l æ ' Return \n\
+  Shift < z x c v b n m , . þ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & / ( ) = Ö _ ¨ * \n\
+  Tab Q W E R T Y U I O P Ð ? Del \n\
+  Ctrl A S D F G H J K L Æ ' Return \n\
+  Shift > Z X C V B N M ; : Þ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 { [ ] } \\ - ° ` \n\
+  Tab q w e r t y u i o p ð ~ Del \n\
+  Ctrl a s d f g h j k l æ ^ Return \n\
+  Shift | z x c v b n m , . þ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-italian.ad b/development/autotests/xvkbd/XVkbd-italian.ad
new file mode 100644 (file)
index 0000000..a7b5661
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-italian.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Italian layout, roughly taken from
+! xkeycaps's "PC 102 key, wide Delete, tall Enter / XFree86; Italian"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Italian)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ' ì \\ ú \n\
+  Tab q w e r t y u i o p è + Delete \n\
+  Control_L a s d f g h j k l ò à Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " £ $ % & / ( ) = ? ^ | § \n\
+  Tab Q W E R T Y U I O P é * Delete \n\
+  Control_L A S D F G H J K L ç ° Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ' ì \\ ú \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l @ # Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc !\n1 "\n2 £\n3 $\n4 %\n5 &\n6 /\n7 (\n8 )\n9 =\n0 ?\n' ^\nì |\n\\ §\nú \n\
+  Tab Q W E R T Y U I O P é\nè_[ *\n+_] Del \n\
+  Control A S D F G H J K L ç\nò_@ °\nà_# Return \n\
+  Shift >\n< Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ' ì \\ ú \n\
+  Tab q w e r t y u i o p è + Del \n\
+  Ctrl a s d f g h j k l ò à Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " £ $ % & / ( ) = ? ^ | § \n\
+  Tab Q W E R T Y U I O P é * Del \n\
+  Ctrl A S D F G H J K L ç ° Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ' ì \\ ú \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l @ # Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-jisx6002.ad b/development/autotests/xvkbd/XVkbd-jisx6002.ad
new file mode 100644 (file)
index 0000000..3fd85fd
--- /dev/null
@@ -0,0 +1,95 @@
+!! XVkbd-jisx6004.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2005-01-23
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Japanese (JIS X 6002) layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Japanese)
+
+xvkbd*Shift_L.width: 75
+xvkbd*Shift_R.width: 60
+xvkbd*Delete.width: 60
+xvkbd*Return.width: 45
+xvkbd*Henkan_Mode.width: 60
+xvkbd*Caps_Lock.width: 40
+xvkbd*Alt_L.width: 40
+xvkbd*Meta_L.width: 40
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 140
+xvkbd*row1.Focus.width: 45
+
+xvkbd*row1*international: true
+xvkbd*row2*international: true
+xvkbd*row3*international: true
+xvkbd*row4*international: true
+xvkbd*row5*international: true
+xvkbd*specialFontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-*,*--14-*
+xvkbd*fontSet: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-*,*--14-*
+xvkbd.modalKeytop: true
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab q w e r t y u i o p @ [ Delete \n\
+  Control_L a s d f g h j k l ; : ] Return \n\
+  Shift_L z x c v b n m , . / \\ Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab Q W E R T Y U I O P ` { Delete \n\
+  Control_L A S D F G H J K L + * } Return \n\
+  Shift_L Z X C V B N M < > ? _ Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape kana_NU kana_FU kana_A kana_U kana_E kana_O kana_YA kana_YU kana_YO kana_WA kana_HO kana_HE - Focus \n\
+  Tab kana_TA kana_TE kana_I kana_SU kana_KA kana_N kana_NA kana_NI kana_RA kana_SE voicedsound semivoicedsound Delete \n\
+  Control_L kana_CHI kana_TO kana_SHI kana_HA kana_KI kana_KU kana_MA kana_NO kana_RI kana_RE kana_KE kana_MU Return \n\
+  Shift_L kana_TSU kana_SA kana_SO kana_HI kana_KO kana_MI kana_MO kana_NE kana_RU kana_ME kana_RO Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " kana_a kana_u kana_e kana_o kana_ya kana_yu kana_yo kana_WO = ~ | Focus \n\
+  Tab Q W kana_i R T Y U I O P ` kana_openingbracket Delete \n\
+  Control_L A S D F G H J K L + * kana_closingbracket Return \n\
+  Shift_L kana_tsu X C V B N M kana_comma kana_fullstop kana_conjunctive | Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab q w e r t y u i o p @ [ Delete \n\
+  Control a s d f g h j k l ; : ] Return \n\
+  Shift z x c v b n m , . / \\ Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab Q W E R T Y U I O P ` { Delete \n\
+  Control A S D F G H J K L + * } Return \n\
+  Shift Z X C V B N M < > ? _ Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ¤Ì ¤Õ ¤¢ ¤¦ ¤¨ ¤ª ¤ä ¤æ ¤è ¤ï ¤Û ¤Ø ¡¼ Focus \n\
+  Tab ¤¿ ¤Æ ¤¤ ¤¹ ¤« ¤ó ¤Ê ¤Ë ¤é ¤» ¡« ¡¬ Delete \n\
+  Control ¤Á ¤È ¤· ¤Ï ¤­ ¤¯ ¤Þ ¤Î ¤ê ¤ì ¤± ¤à Return \n\
+  Shift ¤Ä ¤µ ¤½ ¤Ò ¤³ ¤ß ¤â ¤Í ¤ë ¤á ¤í Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc space space ¤¡ ¤¥ ¤§ ¤© ¤ã ¤å ¤ç ¤ò space space space Focus \n\
+  Tab space space ¤£ space space space space space space space space ¡Ö Delete \n\
+  Control space space space space space space space space space space space ¡× Return \n\
+  Shift ¤Ã space space space space space space ¡¢ ¡£ ¡¦ space Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
diff --git a/development/autotests/xvkbd/XVkbd-jisx6004.ad b/development/autotests/xvkbd/XVkbd-jisx6004.ad
new file mode 100644 (file)
index 0000000..ca3023b
--- /dev/null
@@ -0,0 +1,95 @@
+!! XVkbd-jisx6004.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Japanese (JIS X 6004) layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Japanese)
+
+xvkbd*Shift_L.width: 75
+xvkbd*Shift_R.width: 90
+xvkbd*Delete.width: 60
+xvkbd*Return.width: 45
+xvkbd*Henkan_Mode.width: 60
+xvkbd*Caps_Lock.width: 40
+xvkbd*Alt_L.width: 40
+xvkbd*Meta_L.width: 40
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 140
+xvkbd*row1.Focus.width: 45
+
+xvkbd*row1*international: true
+xvkbd*row2*international: true
+xvkbd*row3*international: true
+xvkbd*row4*international: true
+xvkbd*row5*international: true
+xvkbd*specialFontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-*,*--14-*
+xvkbd*fontSet: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-*,*--14-*
+xvkbd.modalKeytop: true
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab q w e r t y u i o p @ [ Delete \n\
+  Control_L a s d f g h j k l ; : ] Return \n\
+  Shift_L z x c v b n m , . / Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab Q W E R T Y U I O P ` { Delete \n\
+  Control_L A S D F G H J K L + * } Return \n\
+  Shift_L Z X C V B N M < > ? Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab kana_SO kana_KE kana_SE kana_TE kana_yo kana_TSU kana_N kana_NO kana_WO kana_RI kana_CHI space Delete \n\
+  Control_L kana_HA kana_KA kana_SHI kana_TO kana_TA kana_KU kana_U kana_I voicedsound kana_KI kana_NA space Return \n\
+  Shift_L kana_SU kana_KO kana_NI kana_SA kana_A kana_tsu kana_RU kana_comma kana_fullstop kana_RE Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab kana_a semivoicedsound kana_HO kana_FU kana_ME kana_HI kana_E kana_MI kana_YA kana_NU kana_openingbracket space Delete \n\
+  Control_L kana_i kana_HE kana_RA kana_yu kana_YO kana_MA kana_O kana_MO kana_WA kana_YU kana_closingbracket space Return \n\
+  Shift_L kana_u kana_e kana_o kana_NE kana_ya kana_MU kana_RO kana_conjunctive - space Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab q w e r t y u i o p @ [ Delete \n\
+  Control a s d f g h j k l ; : ] Return \n\
+  Shift z x c v b n m , . / Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab Q W E R T Y U I O P ` { Delete \n\
+  Control A S D F G H J K L + * } Return \n\
+  Shift Z X C V B N M < > ? Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - ^ \\ Focus \n\
+  Tab ¤½ ¤± ¤» ¤Æ ¤ç ¤Ä ¤ó ¤Î ¤ò ¤ê ¤Á space Delete \n\
+  Control ¤Ï ¤« ¤· ¤È ¤¿ ¤¯ ¤¦ ¤¤ ¡« ¤­ ¤Ê space Return \n\
+  Shift ¤¹ ¤³ ¤Ë ¤µ ¤¢ ¤Ã ¤ë ¡¢ ¡£ ¤ì Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & ' ( ) _ = ~ | Focus \n\
+  Tab ¤¡ ¡¬ ¤Û ¤Õ ¤á ¤Ò ¤¨ ¤ß ¤ä ¤Ì ¡Ö space Delete \n\
+  Control ¤£ ¤Ø ¤é ¤å ¤è ¤Þ ¤ª ¤â ¤ï ¤æ ¡× space Return \n\
+  Shift ¤¥ ¤§ ¤© ¤Í ¤ã ¤à ¤í ¡¦ ¡¼ space Shift \n\
+  MainMenu Caps Alt Meta space ¤«¤Ê left right up down
diff --git a/development/autotests/xvkbd/XVkbd-korean.ad b/development/autotests/xvkbd/XVkbd-korean.ad
new file mode 100644 (file)
index 0000000..0370727
--- /dev/null
@@ -0,0 +1,78 @@
+!! XVkbd-korean.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! with contribution from Young-Ho
+!!
+!! Last update: 2004-05-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Korean layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Korean)
+
+xvkbd*Shift_L.width: 75
+xvkbd*Shift_R.width: 80
+xvkbd*Control_L.width: 40
+xvkbd*Caps_Lock.width: 60
+xvkbd*Alt_L.width: 40
+xvkbd*Meta_L.width: 40
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 100
+xvkbd*Delete.width: 50
+xvkbd*Return.width: 65
+xvkbd*row0.F1.horizDistance: 6
+xvkbd*row1.BackSpace.horizDistance: 0
+xvkbd*row1.BackSpace.width: 40
+xvkbd*row5.Focus.international: false
+
+xvkbd*row1*international: true
+xvkbd*row2*international: true
+xvkbd*row3*international: true
+xvkbd*row4*international: true
+xvkbd*row5*international: true
+xvkbd*specialFontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-*,\
+  -*-*-medium-r-*-*-12-*-*-*-*-*-ksc5601.1987-0,*--12-*
+xvkbd*fontSet: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-*,\
+  -*-*-medium-r-*-*-12-*-*-*-*-*-ksc5601.1987-0,*--12-*
+xvkbd.modalKeytop: false
+
+xvkbd.NormalKeys: \
+  Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 \n\
+  ` 1 2 3 4 5 6 7 8 9 0 - = \\ BackSpace \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Caps_Lock a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Shift_R \n\
+  MainMenu Control_L Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 \n\
+  ~ ! @ # $ % ^ & * ( ) _ + | BackSpace \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Caps_Lock A S D F G H J K L : " Return \n\
+  Shift_L Z X C V B N M < > ? Shift_R \n\
+  MainMenu Control_L Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 \n\
+  ` 1 2 3 4 5 6 7 8 9 0 - = \\ BackSpace \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Caps_Lock a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Shift_R \n\
+  MainMenu Control_L Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftAltgrKeys: \
+  Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 \n\
+  ` 1 2 3 4 5 6 7 8 9 0 - = \\ BackSpace \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Caps_Lock a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Shift_R \n\
+  MainMenu Control_L Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 \n\
+  ~\n` !\n1 @\n2 #\n3 $\n4 %\n5 ^\n6 &\n7 *\n8 (\n9 )\n0 _\n- +\n= |\n\\ back \n\
+  Tab Q\n¤²¤³ W\n¤¸¤¹ E\n¤§¤¨ R\n¤¡¤¢ T\n¤µ¤¶ Y\n¤Ë U\n¤Å I\n¤Á O\n¤À¤Â P\n¤Ä¤Æ {\n[ }\n] Delete \n\
+  Caps A\n¤± S\n¤¤ D\n¤· F\n¤© G\n¤¾ H\n¤Ç J\n¤Ã K\n¤¿ L\n¤Ó :\n; "\n' Return \n\
+  Shift Z\n¤» X\n¤¼ C\n¤º V\n¤½ B\n¤Ð N\n¤Ì M\n¤Ñ <\n, >\n. ?\n/ Shift \n\
+  MainMenu Ctrl Alt Meta space ÇÑ/¿µ left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-latin1.ad b/development/autotests/xvkbd/XVkbd-latin1.ad
new file mode 100644 (file)
index 0000000..0bf3128
--- /dev/null
@@ -0,0 +1,90 @@
+!! XVkbd-latin1.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard support most Latin-1 characters
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Latin-1)
+
+xvkbd*Mode_switch.width: 50
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l ; ' Return \n\
+  Shift_L z x c v b n m , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Control_L A S D F G H J K L : \" Return \n\
+  Shift_L Z X C V B N M < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape \271 \262 \263 \243 \245 \247 \251 \272 \255 \254 \261 \267 \327 \367 \n\
+  Tab \340 \341 \342 \343 \344 \345 \346 \347 \350 \351 \352 \353 Delete \n\
+  Control_L \354 \355 \356 \357 \360 \361 \362 \363 \364 \365 \366 Return \n\
+  Shift \370 \371 \372 \373 \374 \375 \376 \377 \337 \241 Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape \274 \275 \276 \242 \244 \266 \256 \252 \250 \257 \260 \264 \270 \265 \n\
+  Tab \300 \301 \302 \303 \304 \305 \306 \307 \310 \311 \312 \313 Delete \n\
+  Control_L \314 \315 \316 \317 \320 \321 \322 \323 \324 \325 \326 Return \n\
+  Shift \330 \331 \332 \333 \334 \335 \336 \253 \273 \277 Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc   !_\274\n1_\271 @_\275\n2_\262 #_\276\n3_\263 $_\242\n4_\243 %_\244\n5_\245 \
+    ^_\266\n6_\247 &_\256\n7_\251 *_\252\n8_\272 (_\250\n9_\255 )_\257\n0_\254 __\260\n-_\261 \
+    +_\264\n=_\267 |_\270\n\\_\327 ~_\265\n`_\367 \n\
+  Tab   Q_\340 W_\341 E_\342 R_\343 T_\344 Y_\345 U_\346 I_\347 O_\350 P_\351 \
+    {\n[_\352 }\n]_\353   Del \n\
+  Control   A_\354 S_\355 D_\356 F_\357 G_\360 H_\361 J_\362 K_\363 L_\364 \
+    :\n;_\365 \"\n'_\366   Return \n\
+  Shift Z_\370 X_\371 C_\372 V_\373 B_\374 N_\375 M_\376 \
+    <_\253\n,_\377 >_\273\n._\337 ?_\277\n/_\241   Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : \" Return \n\
+  Shift Z X C V B N M < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc \271 \262 \263 \243 \245 \247 \251 \272 \255 \254 \261 \267 \327 \367 \n\
+  Tab \340 \341 \342 \343 \344 \345 \346 \347 \350 \351 \352 \353 Del \n\
+  Ctrl \354 \355 \356 \357 \360 \361 \362 \363 \364 \365 \366 Return \n\
+  Shift \370 \371 \372 \373 \374 \375 \376 \377 \337 \241 Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc \274 \275 \276 \242 \244 \266 \256 \252 \250 \257 \260 \264 \270 \265 \n\
+  Tab \300 \301 \302 \303 \304 \305 \306 \307 \310 \311 \312 \313 Del \n\
+  Ctrl \314 \315 \316 \317 \320 \321 \322 \323 \324 \325 \326 Return \n\
+  Shift \330 \331 \332 \333 \334 \335 \336 \253 \273 \277 Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-norwegian.ad b/development/autotests/xvkbd/XVkbd-norwegian.ad
new file mode 100644 (file)
index 0000000..be11404
--- /dev/null
@@ -0,0 +1,71 @@
+!! XVkbd-norwegian.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Norwegian layout, roughly taken from
+! xkeycaps's "PC 102 key, wide Delete, tall Enter / XFree86; Norwegian"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Norwegian)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 + \\ | ' \n\
+  Tab q w e r t y u i o p á ¨ Delete \n\
+  Control_L a s d f g h j k l ø æ Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # ¤ % & / ( ) = ? ` § * \n\
+  Tab Q W E R T Y U I O P Á ^ Delete \n\
+  Control_L A S D F G H J K L Ø Æ Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 @ £ $ 5 6 { [ ] } + ' ¦ ' \n\
+  Tab q w e r t y u i o p á ~ Delete \n\
+  Control_L a s d f g h j k l ø dead_diaeresis ' Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1 "\n2_@ #\n3_£ ¤\n4_$ %\n5 &\n6 /\n7_{ (\n8_[ )\n9_] =\n0_} ?\n+ `\n\\_' §\n|_¦ *\n' \n\
+  Tab Q W E R T Y U I O P Á ^\n¨_~ Del \n\
+  Control A S D F G H J K L Ø Æ Return \n\
+  Shift >\n< Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 + \\ | ' \n\
+  Tab q w e r t y u i o p á ¨ Del \n\
+  Ctrl a s d f g h j k l ø æ Return \n\
+  Shift < z x c v b n m , . - Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! " # ¤ % & / ( ) = ? ` § * \n\
+  Tab Q W E R T Y U I O P Á ^ Del \n\
+  Ctrl A S D F G H J K L Ø Æ Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 @ £ $ 5 6 { [ ] } + ' ¦ ' \n\
+  Tab q w e r t y u i o p á ~ Del \n\
+  Ctrl a s d f g h j k l ø æ Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
diff --git a/development/autotests/xvkbd/XVkbd-portuguese.ad b/development/autotests/xvkbd/XVkbd-portuguese.ad
new file mode 100644 (file)
index 0000000..4794629
--- /dev/null
@@ -0,0 +1,70 @@
+!! XVkbd-portuguese.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Portuguese layout, roughly taken from
+! xkeycaps's "PC 102 key, wide Delete, tall Enter / XFree86; Portuguse"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Portuguese)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ' « \\ ~ \n\
+  Tab q w e r t y u i o p + ' Delete \n\
+  Control_L a s d f g h j k l ç º Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & / ( ) = ? » | ^ \n\
+  Tab Q W E R T Y U I O P * ` Delete \n\
+  Control_L A S D F G H J K L Ç ª Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 @ £ § 5 6 { [ ] } ' « \\ ~ \n\
+  Tab q w e r t y u i o p ¨ ' Delete \n\
+  Control_L a s d f g h j k l ç º Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc !\n1 "\n2_@ #\n3_£ $\n4_§ %\n5 &\n6 /\n7_{ (\n8_[ )\n9_] =\n0_} ?\n' »\n« |\n\\ ^\n~ \n\
+  Tab Q W E R T Y U I O P *\n+_¨ `\n' Del \n\
+  Control A S D F G H J K L Ç ª\nº Return \n\
+  Shift >\n< Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ' « \\ ~ \n\
+  Tab q w e r t y u i o p + ' Del \n\
+  Ctrl a s d f g h j k l ç º Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & / ( ) = ? » | ^ \n\
+  Tab Q W E R T Y U I O P * ` Del \n\
+  Ctrl A S D F G H J K L Ç ª Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 @ £ § 5 6 { [ ] } ' « \\ ~ \n\
+  Tab q w e r t y u i o p ¨ ' Del \n\
+  Ctrl a s d f g h j k l ç º Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-russian.ad b/development/autotests/xvkbd/XVkbd-russian.ad
new file mode 100644 (file)
index 0000000..ad247e0
--- /dev/null
@@ -0,0 +1,108 @@
+!! XVkbd-russian.ad  - Russian (win-keyboard like) layout for xvkbd
+!! by Victor Wagner <vitus@wagner.pp.ru)
+!! based on sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Requires xvkbd to be started in ru_RU.KOI8-R (or ru_UA.KOI8-R) locale
+!! to show key labels correctly. You may recode this file to any other
+!! 8-bit cyrillic encoding and change font resources appropriately. But
+!! as of xvkbd ver  2.6 it doesn't show labels correctly if resourses
+!! are in utf-8
+!!
+!! Last update: 2006-07-27
+
+#include "XVkbd-common"
+
+xvkbd.title: xvkbd - Virtual Keyboard (Russian)
+
+xvkbd*generalFont: -*-fixed-medium-r-normal-*-13-*-*-*-*-*-koi8-r
+xvkbd*letterFont: -*-fixed-medium-r-normal-*-13-*-*-*-*-*-koi8-r
+
+xvkbd*space.width: 80
+
+xvkbd.modalKeytop: true
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = ` # \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l ; ' Return \n\
+  Shift_L \\ z x c v b n m , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! @ # $ % ^ & = ( ) _ + ~ # \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Control_L A S D F G H J K L : " Return \n\
+  Shift_L | Z X C V B N M < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Mode_switch Left Right Up Down Focus
+
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = ` # \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift \\ z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space Meta Rus left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = ` # \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift \\ z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space Meta Rus left right up down Focus
+
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & = ( ) _ + ~ # \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : " Return \n\
+  Shift | Z X C V B N M < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space Meta Rus left right up down Focus
+
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = Cyrillic_io # \n\
+  Tab Cyrillic_shorti Cyrillic_tse Cyrillic_u Cyrillic_ka Cyrillic_ie\
+  Cyrillic_en Cyrillic_ghe Cyrillic_sha Cyrillic_shcha Cyrillic_ze\
+  Cyrillic_ha Cyrillic_hardsign Delete \n\
+  Control_L Cyrillic_ef Cyrillic_yeru Cyrillic_ve Cyrillic_a Cyrillic_pe\
+  Cyrillic_er Cyrillic_o Cyrillic_el Cyrillic_de Cyrillic_zhe Cyrillic_e\
+  Return \n\
+  Shift_L \\ Cyrillic_ya Cyrillic_che Cyrillic_es Cyrillic_em Cyrillic_i\
+  Cyrillic_te Cyrillic_softsign Cyrillic_be Cyrillic_yu . Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftAltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # ; % : ? * ( ) _ + Cyrillic_IO # \n\
+  Tab Cyrillic_SHORTI Cyrillic_TSE Cyrillic_U Cyrillic_KA Cyrillic_IE\
+  Cyrillic_EN Cyrillic_GHE Cyrillic_SHA Cyrillic_SHCHA Cyrillic_ZE\
+  Cyrillic_HA Cyrillic_HARDSIGN Delete \n\
+  Control_L Cyrillic_EF Cyrillic_YERU Cyrillic_VE Cyrillic_A Cyrillic_PE\
+  Cyrillic_ER Cyrillic_O Cyrillic_EL Cyrillic_DE Cyrillic_ZHE Cyrillic_E\
+  Return \n\
+  Shift_L \\ Cyrillic_YA Cyrillic_CHE Cyrillic_ES Cyrillic_EM Cyrillic_I\
+  Cyrillic_TE Cyrillic_SOFTSIGN Cyrillic_BE Cyrillic_YU , Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = £ # \n\
+  Tab Ê Ã Õ Ë Å Î Ç Û Ý Ú È ß Delete \n\
+  Control Æ Ù × Á Ð Ò Ï Ì Ä Ö Ü Return \n\
+  Shift \\ Ñ Þ Ó Í É Ô Ø Â À . Comp Shift \n\
+  Menu Caps Alt Meta space Meta Eng left right up down Focus
+
+xvkbd.ShiftAltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! " # ; % : ? * ( ) _ + ³ ~ \n\
+  Tab ê ã õ ë å î ç û ý ú è ÿ Del \n\
+  Ctrl æ ù ÷ á ð ò ï ì ä ö ü Return \n\
+  Shift / ñ þ ó í é ô ø â à , Comp Shift \n\
+  Menu Caps Alt Meta space Meta Eng left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-slovene.ad b/development/autotests/xvkbd/XVkbd-slovene.ad
new file mode 100644 (file)
index 0000000..ae17514
--- /dev/null
@@ -0,0 +1,90 @@
+!! XVkbd-slovene.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-16
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Norwegian layout, roughly taken from
+! xkeycaps's "PC 105 key, wide Delete, tall Enter / XFree86; Slovene"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Slovene)
+
+xvkbd*generalFont: -*-lucidatypewriter-bold-r-*-*-12-*-*-*-*-*-iso8859-2
+xvkbd*letterFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-2
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ' + cedilla zcaron \n\
+  Tab q w e r t z u i o p scaron dstroke Delete \n\
+  Control_L a s d f g h j k l ccaron cacute Return \n\
+  Shift_L < y x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " # $ % & / ( ) = ? * diaeresis Zcaron \n\
+  Tab Q W E R T Z U I O P Scaron Dstroke Delete \n\
+  Control_L A S D F G H J K L Ccaron Cacute Return \n\
+  Shift_L > Y X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ~ 2 ^ 4 5 6 7 8 9 0 ' + cedilla currency \n\
+  Tab \\ | e r t z u i o p division multiply Delete \n\
+  Control_L a s d f g h j lstroke Lstroke ccaron ssharp Return \n\
+  Shift_L < y x c @ { } section , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1_~ "\n2 #\n3_^ $\n4 %\n5 &\n6 /\n7 (\n8 )\n9 =\n0 \
+         ?\n' *\n+ \250\n\270 \256_\244 \n\
+  Tab Q_\\ W_| E R T Z U I O P \251_\367 \320_\327 Del \n\
+  Control A S D F G H J K_\263 L_\243 \310 \306_\337 Return \n\
+  Shift >\n< Y X C V_@ B_{ N_} M_\247 ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ' + , \276 \n\
+  Tab q w e r t z u i o p \271 \360 Del \n\
+  Ctrl a s d f g h j k l \350 \346 Return \n\
+  Shift < y x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! " # $ % & / ( ) = ? * \250 \256 \n\
+  Tab Q W E R T Z U I O P \251 \320 Del \n\
+  Ctrl A S D F G H J K L \310 \306 Return \n\
+  Shift > Y X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ~ 2 ^ 4 5 6 7 8 9 0 ' + , \244 \n\
+  Tab \\ | e r t z u i o p \367 \327 Del \n\
+  Ctrl a s d f g h j \263 \243 \350 \337 Return \n\
+  Shift < y x c @ { } \247 , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+
+XVkbd.deadkeys: dead_diaeresis,dead_acute,dead_grave,\
+  dead_circumflex,dead_macron,dead_abovering,dead_doubleacute,\
+  dead_caron,dead_breve,\
+  dead_tilde,dead_abovedot,\
+  dead_ogonek,dead_cedilla
+
+XVkbd*deadkey_panel*dead_caron.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_breve.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_ogonek.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_cedilla.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_caron.label: \267
+XVkbd*deadkey_panel*dead_breve.label: \242
+XVkbd*deadkey_panel*dead_ogonek.label: \262
+XVkbd*deadkey_panel*dead_cedilla.label: \270
diff --git a/development/autotests/xvkbd/XVkbd-small.ad b/development/autotests/xvkbd/XVkbd-small.ad
new file mode 100644 (file)
index 0000000..ff69517
--- /dev/null
@@ -0,0 +1,66 @@
+!! XVkbd-small.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+!! Size of the window can be set with xvkbd.windowGeometry resource
+!! or -geometry (or -windowgeometry) option.
+!! Please note that you must take account of size of the window border
+!! when you want set window position from right/bottom of the screen.
+!
+xvkbd.inheritGeoemetry: false
+xvkbd.windowGeometry: 220x85-5-25
+xvkbd.keypad_panel.geometry: 100x100
+xvkbd.sun_fkey_panel.geometry: 70x120
+
+!! You should set the label font if you want to make the window small.
+!
+xvkbd.compact: true
+xvkbd*Font: 6x12
+xvkbd*Command.ShadowWidth: 1
+xvkbd*Repeater.ShadowWidth: 1
+
+!! Remove some keys and make some keys larger.
+!
+xvkbd*Alt_R.width: 1
+xvkbd*Meta_R.width: 1
+xvkbd*Multi_key.width: 1
+xvkbd*Caps_Lock.width: 45
+xvkbd*Shift_R.width: 75
+
+!! If you want to make the window very small but need Compose key,
+!! you may want to remove right Shift key and make Compose key larger.
+!
+!xvkbd*Shift_R.width: 1
+!xvkbd*Multi_key.width: 75
+
+!! Uncomment the following line if you want to remove "Focus" button
+!
+!xvkbd*Focus.width: 1
+
+!! Replace labels on some keys.  ("Control" to "Ctrl", for example)
+!
+xvkbd.modalKeytop: true
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = \\ ` \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Ret \n\
+  Shift z x c v b n m , . / Compose Shift \n\
+  MainMenu Caps Alt Meta space Meta Alt left right up down Fc
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! @ # $ % ^ & * ( ) _ + | ~ \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : \" Ret \n\
+  Shift Z X C V B N M < > ? Compose Shift \n\
+  MainMenu Caps Alt Meta space Meta Alt left right up down Fc
+
+!! Use "target" icon in the place of label on the Focus button
+!
+xvkbd*Focus.internalWidth: 0
+xvkbd*Focus.bitmap: /usr/include/X11/bitmaps/target
diff --git a/development/autotests/xvkbd/XVkbd-spanish.ad b/development/autotests/xvkbd/XVkbd-spanish.ad
new file mode 100644 (file)
index 0000000..17099f2
--- /dev/null
@@ -0,0 +1,76 @@
+!! XVkbd-uk.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to UK layout, roughly taken from
+! xkeycaps's "PC 102 key, wide Delete, tall Enter / XFree86; Spanish"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Spanish)
+
+xvkbd*Shift_L.width: 45
+xvkbd*Shift_R.width: 60
+xvkbd*Return.width: 50
+xvkbd*Delete.width: 40
+xvkbd*Escape.width: 40
+xvkbd*space.width: 120
+xvkbd*row2.BackSpace.width: 65
+xvkbd*row2.BackSpace.horizDistance: 0
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  º 1 2 3 4 5 6 7 8 9 0 ' ¿ Delete Escape \n\
+  Tab q w e r t y u i o p ` + BackSpace \n\
+  Control_L a s d f g h j k l ñ ' ç Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  ª ! " · $ % & / ( ) = ? ¡ Delete Escape \n\
+  Tab Q W E R T Y U I O P ^ * BackSpace \n\
+  Control_L A S D F G H J K L Ñ ~ Ç Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  \\ | @ # 4 5 ¬ 7 8 9 0 ' ¿ Delete Escape \n\
+  Tab q w e r t y u i o p [ ] BackSpace \n\
+  Control_L a s d f g h j k l ñ { } Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps\nLock Alt Meta space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  ª\nº_\\ !\n1_| "\n2_@ ·\n3_# $\n4 %\n5 &\n6_¬ /\n7 (\n8 )\n9 =\n0 ?\n' ¡\n¿ Del Esc \n\
+  Tab Q W E R T Y U I O P ^\n`_[ *\n+_] back \n\
+  Control A S D F G H J K L Ñ ~\n'_{ Ç_} Return \n\
+  Shift >\n< Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  º 1 2 3 4 5 6 7 8 9 0 ' ¿ Del Esc \n\
+  Tab q w e r t y u i o p ` + back \n\
+  Ctrl a s d f g h j k l ñ ' ç Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  ª ! " · $ % & / ( ) = ? ¡ Del Esc \n\
+  Tab Q W E R T Y U I O P ^ * back \n\
+  Ctrl A S D F G H J K L Ñ ~ Ç Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  \\ | @ # 4 5 ¬ 7 8 9 0 ' ¿ Del Esc \n\
+  Tab q w e r t y u i o p [ ] back \n\
+  Ctrl a s d f g h j k l ñ { } Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-strip.ad b/development/autotests/xvkbd/XVkbd-strip.ad
new file mode 100644 (file)
index 0000000..b37602c
--- /dev/null
@@ -0,0 +1,232 @@
+!! XVkbd-strip.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2010-01-16
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard support most Latin-1 characters
+!
+xvkbd.title: xvkbd - Virtual Keyboard
+
+xvkbd.inheritGeoemetry: false
+xvkbd.modalKeytop: true
+xvkbd.keypad: false
+xvkbd.keypadOnly: true
+xvkbd.geometry: +0-0
+xvkbd.keypad_panel.geometry: -0-0
+xvkbd*keypad.vertDistance: 0
+xvkbd*keypad.horizDistance: 0
+
+xvkbd*banner.width: 1
+xvkbd*banner.height: 1
+xvkbd.form*Command.width: 27
+xvkbd.form*Command.height: 22
+xvkbd.form*Repeater.width: 27
+xvkbd.form*Repeater.height: 22
+xvkbd.form*Return.width: 54
+xvkbd.form*MainMenu.width: 27
+xvkbd.form*Control_L.width: 18
+xvkbd.form*Shift_L.width: 18
+xvkbd.form*Mode_switch.width: 18
+xvkbd.keypad_panel*Repeater.width: 27
+xvkbd.keypad_panel*Repeater.height: 22
+xvkbd*Command.horizDistance: 0
+xvkbd*Repeater.horizDistance: 0
+xvkbd*Command.justify: center
+xvkbd*Repeater.justify: center
+xvkbd*Command.justify: center
+xvkbd*Repeater.justify: center
+xvkbd*vertDistance: 0
+
+xvkbd*Focus.bitmap: /usr/include/X11/bitmaps/target
+
+xvkbd.NormalKeys: \
+  a       n     \n\
+  b       o     \n\
+  c       p     \n\
+  d       q     \n\
+  e       r     \n\
+  f       s     \n\
+  g       t     \n\
+  h       u     \n\
+  i       v     \n\
+  j       w     \n\
+  k       x     \n\
+  l       y     \n\
+  m       z     \n\
+  space   BackSpace \n\
+  Return            \n\
+  Control_L Shift_L Mode_switch \n\
+  Focus   MainMenu
+
+xvkbd.ShiftKeys: \
+  A       N     \n\
+  B       O     \n\
+  C       P     \n\
+  D       Q     \n\
+  E       R     \n\
+  F       S     \n\
+  G       T     \n\
+  H       U     \n\
+  I       V     \n\
+  J       W     \n\
+  K       X     \n\
+  L       Y     \n\
+  M       Z     \n\
+  space   BackSpace \n\
+  Return            \n\
+  Control_L Shift_L Mode_switch \n\
+  Focus   MainMenu
+
+xvkbd.NormalKeyLabels: \
+  a       n     \n\
+  b       o     \n\
+  c       p     \n\
+  d       q     \n\
+  e       r     \n\
+  f       s     \n\
+  g       t     \n\
+  h       u     \n\
+  i       v     \n\
+  j       w     \n\
+  k       x     \n\
+  l       y     \n\
+  m       z     \n\
+  space   BS    \n\
+  Return        \n\
+  Ct   Sh   Ag  \n\
+  Focus   MainMenu
+
+xvkbd.ShiftKeyLabels: \
+  A       N     \n\
+  B       O     \n\
+  C       P     \n\
+  D       Q     \n\
+  E       R     \n\
+  F       S     \n\
+  G       T     \n\
+  H       U     \n\
+  I       V     \n\
+  J       W     \n\
+  K       X     \n\
+  L       Y     \n\
+  M       Z     \n\
+  space   BS    \n\
+  Return        \n\
+  Ctrl    Shift  AltGr \n\
+  Focus   MainMenu
+
+xvkbd.AltgrKeys: \
+  ,       .     \n\
+  ;       :     \n\
+  !       ?     \n\
+  (       )     \n\
+  {       }     \n\
+  [       ]     \n\
+  <       >     \n\
+  #       $     \n\
+  %       ^     \n\
+  &       @     \n\
+  _       ~     \n\
+  |       =     \n\
+  '       "     \n\
+  \\  BackSpace \n\
+  Return        \n\
+  Control_L Shift_L Mode_switch \n\
+  Focus   MainMenu
+
+xvkbd.AltgrKeyLabels: \
+  ,       .     \n\
+  ;       :     \n\
+  !       ?     \n\
+  (       )     \n\
+  {       }     \n\
+  [       ]     \n\
+  <       >     \n\
+  #       $     \n\
+  %       ^     \n\
+  &       @     \n\
+  _       ~     \n\
+  |       =     \n\
+  '       "     \n\
+  \\      BS    \n\
+  Return        \n\
+  Ct   Sh   Ag  \n\
+  Focus   MainMenu
+
+xvkbd.ShiftAltgrKeys: \
+  Escape  Tab   \n\
+  +       -     \n\
+  *       /     \n\
+  0       5     \n\
+  1       6     \n\
+  2       7     \n\
+  3       8     \n\
+  4       9     \n\
+  .       ,     \n\
+  Left    Right \n\
+  Up      Down  \n\
+  F1      F4    \n\
+  F2      F5    \n\
+  space   BackSpace \n\
+  Return            \n\
+  Control_L Shift_L Mode_switch \n\
+  Focus   MainMenu
+
+xvkbd.ShiftAltgrKeyLabels: \
+  Esc     Tab   \n\
+  +       -     \n\
+  *       /     \n\
+  0       5     \n\
+  1       6     \n\
+  2       7     \n\
+  3       8     \n\
+  4       9     \n\
+  .       ,     \n\
+  left    right \n\
+  up      down  \n\
+  F1      F4    \n\
+  F2      F5    \n\
+  space   BS    \n\
+  Return        \n\
+  Ct   Sh   Ag  \n\
+  Focus   MainMenu
+
+xvkbd.KeypadLabels: \
+  Esc         Tab   \n\
+  +           -     \n\
+  *           /     \n\
+  0           F1    \n\
+  1           F2    \n\
+  2           F3    \n\
+  3           F4    \n\
+  4           F5    \n\
+  5           F6    \n\
+  6           F7    \n\
+  7           F8    \n\
+  8           F9    \n\
+  9           F10   \n\
+  .           Ent   \n\
+  left        right \n\
+  up          down  \n\
+  Del         Ins
+
+xvkbd.NormalKeypad: \
+  Escape      Tab         \n\
+  KP_Add      KP_Subtract \n\
+  KP_Multiply KP_Divide   \n\
+  KP_0        F1     \n\
+  KP_1        F2     \n\
+  KP_2        F3     \n\
+  KP_3        F4     \n\
+  KP_4        F5     \n\
+  KP_5        F6     \n\
+  KP_6        F7     \n\
+  KP_7        F8     \n\
+  KP_8        F9     \n\
+  KP_9        F10    \n\
+  .           Enter  \n\
+  Left        Right  \n\
+  Up          Down   \n\
+  Delete      Insert
diff --git a/development/autotests/xvkbd/XVkbd-swedish.ad b/development/autotests/xvkbd/XVkbd-swedish.ad
new file mode 100644 (file)
index 0000000..becf60b
--- /dev/null
@@ -0,0 +1,79 @@
+!! XVkbd-swedish.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! with contribution from Hakan Lennestal
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Swedish layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Swedish)
+
+xvkbd*Shift_L.width: 45
+xvkbd*Shift_R.width: 60
+xvkbd*Return.width: 50
+xvkbd*Delete.width: 40
+xvkbd*Escape.width: 40
+xvkbd*space.width: 120
+xvkbd*row2.BackSpace.width: 65
+xvkbd*row2.BackSpace.horizDistance: 0
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  § 1 2 3 4 5 6 7 8 9 0 + ´ Delete Escape \n\
+  Tab q w e r t y u i o p å ¨ BackSpace \n\
+  Control_L a s d f g h j k l ö ä ' Return \n\
+  Shift_L < z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  ½ ! " # ¤ % & / ( ) = ? ` Delete Escape \n\
+  Tab Q W E R T Y U I O P Å ^ BackSpace \n\
+  Control_L A S D F G H J K L Ö Ä * Return \n\
+  Shift_L > Z X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  § 1 @ £ $ 5 6 { [ ] } \\ ´ Delete Escape \n\
+  Tab q w e r t y u i o p å ~ BackSpace \n\
+  Control_L a s d f g h j k l ö ä ' Return \n\
+  Shift_L | z x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  ½\n§ !\n1 "\n2_@ #\n3_£ ¤\n4_$ %\n5 &\n6 \
+      /\n7_{ (\n8_[ )\n9_] =\n0_} ?\n+_\\ `\n´ Del Esc \n\
+  Tab Q W E R T Y U I O P Å ^\n¨_~ back \n\
+  Control A S D F G H J K L Ö Ä *\n' Return \n\
+  Shift >\n<_| Z X C V B N M ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  § 1 2 3 4 5 6 7 8 9 0 + ´ Del Esc \n\
+  Tab q w e r t y u i o p å ¨ back \n\
+  Ctrl a s d f g h j k l ö ä ' Return \n\
+  Shift < z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  ½ ! " # ¤ % & / ( ) = ? ` Del Esc \n\
+  Tab Q W E R T Y U I O P Å ^ back \n\
+  Ctrl A S D F G H J K L Ö Ä * Return \n\
+  Shift > Z X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  § 1 @ £ $ 5 6 { [ ] } \\ ´ Del Esc \n\
+  Tab q w e r t y u i o p å ~ back \n\
+  Ctrl a s d f g h j k l ö ä ' Return \n\
+  Shift | z x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
diff --git a/development/autotests/xvkbd/XVkbd-swissgerman.ad b/development/autotests/xvkbd/XVkbd-swissgerman.ad
new file mode 100644 (file)
index 0000000..bcae3cc
--- /dev/null
@@ -0,0 +1,72 @@
+!! XVkbd-swissgerman.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! This app-defaults file is contributed from Marcel Portner
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to SwissGerman layout
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Swiss/German)
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 ' ^ \247 $ \n\
+  Tab q w e r t z u i o p \374 \250 Delete \n\
+  Control_L a s d f g h j k l \366 \344 Return \n\
+  Shift_L < y x c v b n m , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape + " * \347 % & / ( ) = ? ` \260 \243 \n\
+  Tab Q W E R T Z U I O P \350 ! Delete \n\
+  Control_L A S D F G H J K L \351 \340 Return \n\
+  Shift_L > Y X C V B N M ; : _ Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape | @ # \274 \275 \254 \246 \242 9 0 \264 ~ + + \n\
+  Tab q w e r t z u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l { } Return \n\
+  Shift_L \\ y x c v b n \265 , . - Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc +\n1_| "\n2_@ *\n3_# \347\n4_\274 %\n5_\275 &\n6_\254 \
+    /\n7_\246 (\n8_\242 )\n9 =\n0 ?\n'_\264 `\n^_~ \260\n\247 \243\n$ \n\
+  Tab Q W E R T Z U I O P \350\n\374_[ !\n\250_] Del \n\
+  Control A S D F G H J K L \351\n\366_{ \340\n\344_} Return \n\
+  Shift >\n<_\\ Y X C V B N M_\265 ;\n, :\n. _\n- Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 ' ^ \247 $ \n\
+  Tab q w e r t z u i o p \374 \250 Del \n\
+  Ctrl a s d f g h j k l \366 \344 Return \n\
+  Shift < y x c v b n m , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc + " * \347 % & / ( ) = ? ` \260 \243 \n\
+  Tab Q W E R T Z U I O P \350 ! Del \n\
+  Ctrl A S D F G H J K L \351 \340 Return \n\
+  Shift > Y X C V B N M ; : _ Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc | @ # \274 \275 \254 \246 \242 9 0 \264 ~ + + \n\
+  Tab q w e r t z u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l { } Return \n\
+  Shift \\ y x c v b n \265 , . - Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd-turkish.ad b/development/autotests/xvkbd/XVkbd-turkish.ad
new file mode 100644 (file)
index 0000000..7891db8
--- /dev/null
@@ -0,0 +1,90 @@
+!! XVkbd-turkish.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-16
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to Turkish layout, roughly taken from
+! xkeycaps's "PC 105 key, wide Delete, tall Enter / XFree86; Turkish"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (Turkish)
+
+xvkbd*generalFont: -*-lucidatypewriter-bold-r-*-*-12-*-*-*-*-*-iso8859-9
+xvkbd*letterFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-9
+
+xvkbd*Shift_L.width: 45
+xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 * - eacute , \n\
+  Tab q w e r t y u i o p gbreve udiaeresis Delete \n\
+  Control_L a s d f g h j k l scedilla idotless Return \n\
+  Shift_L < z x c v b n m odiaeresis ccedilla . Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! ' ^ + % & / ( ) = ? _ " ; \n\
+  Tab Q W E R T Y U I O P Gbreve Udiaeresis Delete \n\
+  Control_L A S D F G H J K L Scedilla Iabovedot Return \n\
+  Shift_L > Z X C V B N M Odiaeresis Ccedilla : Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.AltgrKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 # $ 5 6 { [ ] } \\ - eacute ` \n\
+  Tab @ w e r t y u i o p gbreve ~ Delete \n\
+  Control_L a s d f g h j k l scedilla idotless Return \n\
+  Shift_L | z x c v b n m odiaeresis ccedilla . Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Mode_switch Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc !\n1 '\n2 ^\n3_# +\n4_$ %\n5 &\n6 /\n7_{ (\n8_[ )\n9_] =\n0_} \
+       ?\n*_\\ _\n- "\n\351 ;\n,_` \n\
+  Tab Q W E R T Y U I O P \320 \334_~ Del \n\
+  Control A S D F G H J K L \336 \335 Return \n\
+  Shift >\n<_| Z X C V B N M \326 \307 :\n. Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space AltGr left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 * - \351 , \n\
+  Tab q w e r t y u i o p \360 \374 Del \n\
+  Ctrl a s d f g h j k l \376 \375 Return \n\
+  Shift < z x c v b n m \366 \347 . Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc ! ' ^ + % & / ( ) = ? _ " ; \n\
+  Tab Q W E R T Y U I O P \320 \334 Del \n\
+  Ctrl A S D F G H J K L \336 \335 Return \n\
+  Shift > Z X C V B N M \326 \307 : Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+xvkbd.AltgrKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Esc 1 2 # $ 5 6 { [ ] } \\ - \351 ` \n\
+  Tab @ w e r t y u i o p \360 ~ Del \n\
+  Ctrl a s d f g h j k l \376 \375 Return \n\
+  Shift | z x c v b n m \366 \347 . Comp Shift \n\
+  MainMenu Caps Alt Meta space AltGr left right up down Focus
+
+
+XVkbd.deadkeys: dead_diaeresis,dead_acute,dead_grave,\
+  dead_circumflex,dead_macron,dead_abovering,dead_doubleacute,\
+  dead_caron,dead_breve,\
+  dead_tilde,dead_abovedot,\
+  dead_ogonek,dead_cedilla
+
+XVkbd*deadkey_panel*dead_caron.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_breve.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_ogonek.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_cedilla.font: -*-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-2
+XVkbd*deadkey_panel*dead_caron.label: \267
+XVkbd*deadkey_panel*dead_breve.label: \242
+XVkbd*deadkey_panel*dead_ogonek.label: \262
+XVkbd*deadkey_panel*dead_cedilla.label: \270
diff --git a/development/autotests/xvkbd/XVkbd-uk.ad b/development/autotests/xvkbd/XVkbd-uk.ad
new file mode 100644 (file)
index 0000000..390f091
--- /dev/null
@@ -0,0 +1,54 @@
+!! XVkbd-uk.ad  - sample app-defaults file for xvkbd
+!! by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/
+!!
+!! Last update: 2002-04-04
+
+#include "XVkbd-common"
+
+! Make the virtual keyboard to UK layout, roughly taken from
+! xkeycaps's "102 key, wide Delete, tall Enter / XFree86; United Kingdom"
+!
+xvkbd.title: xvkbd - Virtual Keyboard (United Kingdom)
+
+xvkbd*Shift_L.width: 45
+!xvkbd*space.width: 110
+
+xvkbd.NormalKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape 1 2 3 4 5 6 7 8 9 0 - = ` # \n\
+  Tab q w e r t y u i o p [ ] Delete \n\
+  Control_L a s d f g h j k l ; ' Return \n\
+  Shift_L \\ z x c v b n m , . / Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Alt_R Left Right Up Down Focus
+
+xvkbd.ShiftKeys: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+  Escape ! " £ $ % ^ & * ( ) _ + ¬ ~ \n\
+  Tab Q W E R T Y U I O P { } Delete \n\
+  Control_L A S D F G H J K L : @ Return \n\
+  Shift_L | Z X C V B N M < > ? Multi_key Shift_R \n\
+  MainMenu Caps_Lock Alt_L Meta_L space Meta_R Alt_R Left Right Up Down Focus
+
+xvkbd.KeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc !\n1 "\n2 £\n3 $\n4 %\n5 ^\n6 &\n7 *\n8 (\n9 )\n0 _\n- +\n= ¬\n` ~\n# \n\
+  Tab Q W E R T Y U I O P {\n[ }\n] Del \n\
+  Control A S D F G H J K L :\n; @\n' Return \n\
+  Shift |\n\\ Z X C V B N M <\n, >\n. ?\n/ Com\npose Shift \n\
+  MainMenu Caps\nLock Alt Meta space Meta Alt left right up down Focus
+
+xvkbd.NormalKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc 1 2 3 4 5 6 7 8 9 0 - = ` # \n\
+  Tab q w e r t y u i o p [ ] Del \n\
+  Ctrl a s d f g h j k l ; ' Return \n\
+  Shift \\ z x c v b n m , . / Comp Shift \n\
+  MainMenu Caps Alt Meta space Meta Alt left right up down Focus
+
+xvkbd.ShiftKeyLabels: \
+  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Backspace \n\
+  Esc ! " £ $ % ^ & * ( ) _ + ¬ ~ \n\
+  Tab Q W E R T Y U I O P { } Del \n\
+  Ctrl A S D F G H J K L : @ Return \n\
+  Shift | Z X C V B N M < > ? Comp Shift \n\
+  MainMenu Caps Alt Meta space Meta Alt left right up down Focus
diff --git a/development/autotests/xvkbd/XVkbd.ad b/development/autotests/xvkbd/XVkbd.ad
new file mode 100644 (file)
index 0000000..5391916
--- /dev/null
@@ -0,0 +1 @@
+#include "XVkbd-common"
diff --git a/development/autotests/xvkbd/findwidget.c b/development/autotests/xvkbd/findwidget.c
new file mode 100644 (file)
index 0000000..3d6c163
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * xvkbd - Virtual Keyboard for X Window System
+ *
+ * Copyright (C) 2000 by Tom Sato <VEF00200@nifty.ne.jp>
+ * http://homepage3.nifty.com/tsato/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This code is derived from editres in X11R6 distribution.
+ */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xmu/EditresP.h>
+
+#include "resources.h"
+
+#define EDITRES_PROTOCOL_VERSION 5  /* Editres Protocol version 1.1 */
+#define EditresLocalSendWidgetTree 0  /* op code defined in Editres Protocol */
+
+#define CLIENT_TIME_OUT 2000  /* 2sec */
+
+static void RequestSendWidgetTree(Widget w);  /* forward */
+static void LoseSelection(Widget w, Atom *sel);  /* forward */
+
+static Atom atom_comm = None;
+static Atom atom_command = None;
+static Atom atom_resource_editor = None;
+static Atom atom_editres_protocol = None;
+static Atom atom_client_value = None;
+
+static ResIdent client_ident = 1;
+
+static Window client_window = None;
+static ProtocolStream client_stream;
+static int effective_protocol_version;
+
+static Boolean waiting_response;
+
+/*
+ * List of widgets will be stored in widget_list[], and number
+ * of widgets will be stored in num_widget_list.
+ */
+static int num_widget_list = 0;
+
+static struct WidgetList {
+  Window window;
+  unsigned long id;
+  unsigned long parent;
+  char *name;
+  char *class;
+  char *path;
+} *widget_list = NULL;
+
+
+/*
+ * This function will be called when the client requests the
+ * value of the selection.
+ */
+static Boolean ConvertCommand(Widget w,
+                      Atom *selection, Atom *target, Atom *type_ret,
+                      XtPointer *value_ret, unsigned long *length_ret,
+                      int *format_ret)
+{
+  if ((*selection != atom_comm) || (*target != atom_command))
+    return(FALSE);
+
+  *type_ret = atom_editres_protocol;
+  *value_ret = (XtPointer)client_stream.real_top;
+  *length_ret = client_stream.size + HEADER_SIZE;
+  *format_ret = EDITRES_FORMAT;
+
+  return(TRUE);
+}
+
+/*
+ * Read response to the Editres LocalSendWidgetTree request
+ * and make list of the widgets.
+ * If appres.list is TRUE, list of all widgets will be printed
+ * to the stdout.
+ */
+static void GetClientValue(Widget w, XtPointer data,
+                           Atom *selection, Atom *type, XtPointer value,
+                           unsigned long *length, int *format)
+{
+  ProtocolStream stream;
+  unsigned char ident, version, error_code;
+  unsigned short num_entries;
+  WidgetInfo widgets;
+  char *name, *class, *err_msg;
+  unsigned long window;
+  int i, j;
+
+  if (*length == 0) return;
+
+  stream.current = stream.top = (unsigned char *)value;
+  stream.size = HEADER_SIZE;
+
+  if (*length < HEADER_SIZE) {
+    fprintf(stderr, "%s: incorrectly formatted message from client\n",
+            PROGRAM_NAME);
+    return;
+  }
+
+  _XEditResGet8(&stream, &ident);
+  if (client_ident != ident) {
+    fprintf(stderr, "%s: wincorrect ident from client\n", PROGRAM_NAME);
+    if (!XtOwnSelection(w, *selection, CurrentTime,
+                        ConvertCommand, LoseSelection, NULL))
+    fprintf(stderr, "%s: XtOwnSelection() failed\n", PROGRAM_NAME);
+    return;
+  }
+
+  _XEditResGet8(&stream, &error_code);
+  _XEditResGet32(&stream, &stream.size);
+  stream.top = stream.current;  /* reset stream to top of value */
+
+  switch ((int) error_code) {
+  case PartialSuccess:
+    if (widget_list != NULL) {
+      for (i = 0; i < num_widget_list; i++) {
+        XtFree(widget_list[i].name);
+        XtFree(widget_list[i].class);
+        XtFree(widget_list[i].path);
+      }
+      XtFree((void *)widget_list);
+      widget_list = NULL;
+    }
+
+    if (_XEditResGet16(&stream, &num_entries)) {
+      widget_list = (struct WidgetList *)XtMalloc(sizeof(struct WidgetList)
+                                                  * num_entries);
+      num_widget_list = num_entries;
+      for (i = 0; i < num_entries; i++) {
+        if (!(_XEditResGetWidgetInfo(&stream, &widgets) &&
+              _XEditResGetString8(&stream, &name) &&
+              _XEditResGetString8(&stream, &class) &&
+              _XEditResGet32(&stream, &window))) {
+          num_widget_list = i;
+          break;
+        }
+        widget_list[i].window = window;
+        widget_list[i].id = widgets.ids[widgets.num_widgets - 1];
+        if (widgets.num_widgets < 2) widget_list[i].parent = 0;
+        else widget_list[i].parent = widgets.ids[widgets.num_widgets - 2];
+        widget_list[i].name = XtNewString(name);
+        widget_list[i].class = XtNewString(class);
+
+        widget_list[i].path = NULL;
+        if (widget_list[i].parent != 0) {
+          for (j = 0; j < i; j++) {
+            if (widget_list[j].id == widget_list[i].parent) {
+              widget_list[i].path = XtMalloc(strlen(widget_list[j].path)
+                                             + strlen(widget_list[i].name) + 2);
+              sprintf(widget_list[i].path, "%s.%s",
+                      widget_list[j].path, widget_list[i].name);
+              break;
+            }
+          }
+        }
+        if (widget_list[i].path == NULL) {
+          widget_list[i].path = XtMalloc(strlen(widget_list[i].name) + 2);
+          sprintf(widget_list[i].path, "%s%s",
+                  (widget_list[i].parent != 0) ? "*" : "",
+                  widget_list[i].name);
+        }
+        if (appres.list_widgets) {
+          fprintf(stdout, "0x%08lx 0x%08lx (%s) %s\n",
+                  (long)widget_list[i].window, (long)widget_list[i].id,
+                  widget_list[i].class, widget_list[i].path);
+        }
+      }
+    }
+    break;
+  case ProtocolMismatch:
+    if (!_XEditResGet8(&stream, &version)) {
+      fprintf(stderr, "%s: unable to unpack protocol request\n", PROGRAM_NAME);
+    } else if (version == effective_protocol_version) {
+      fprintf(stderr, "%s: internal error - ProtocolMismatch\n", PROGRAM_NAME);
+    } else {
+      fprintf(stderr, "%s: protocol version mismatch (requested=%d, supported=%d)\n",
+              PROGRAM_NAME, (int)effective_protocol_version, (int)version);
+      effective_protocol_version = version;
+      RequestSendWidgetTree(w);
+    }
+    break;
+  case Failure:
+    if (!_XEditResGetString8(&stream, &err_msg)) {
+      fprintf(stderr, "%s: unable to unpack protocol request\n", PROGRAM_NAME);
+    } else {
+      fprintf(stderr, "%s: %s\n", PROGRAM_NAME, err_msg);
+    }
+    break;
+  default:
+    fprintf(stderr, "%s: unknown error code %d\n", PROGRAM_NAME, (int)error_code);
+    break;
+  }
+  waiting_response = FALSE;
+}
+
+/*
+ * This will be called when selection "EditresComm", and will
+ * call GetClientValue() via XtGetSelectionValue().
+ *
+ * The selection is owned by this program when send the request
+ * to the client, and will be lost when the client responded to
+ * the request.
+ */
+static void LoseSelection(Widget w, Atom *sel)
+{
+  XtGetSelectionValue(w, *sel, atom_client_value, GetClientValue,
+                      NULL, XtLastTimestampProcessed(XtDisplay(w)));
+}
+
+/*
+ * Send the Editres LocalSendWidgetTree request to the client.
+ */
+static void RequestSendWidgetTree(Widget w)
+{
+  XClientMessageEvent client_event;
+
+  client_ident = client_ident + 1;
+
+  _XEditResResetStream(&client_stream);
+  client_stream.current = client_stream.real_top;
+  client_stream.alloc = client_stream.size + (2 * HEADER_SIZE);
+
+  _XEditResPut8(&client_stream, client_ident);
+  _XEditResPut8(&client_stream, (unsigned char)EditresLocalSendWidgetTree);
+  _XEditResPut32(&client_stream, client_stream.size);
+
+  if (!XtOwnSelection(w, atom_comm, CurrentTime,
+                      ConvertCommand, LoseSelection, NULL))
+    fprintf(stderr, "%s: XtOwnSelection() failed\n", PROGRAM_NAME);
+
+  client_event.window = client_window;
+  client_event.type = ClientMessage;
+  client_event.message_type = atom_resource_editor;
+  client_event.format = EDITRES_SEND_EVENT_FORMAT;
+  client_event.data.l[0] = XtLastTimestampProcessed(XtDisplay(w));
+  client_event.data.l[1] = atom_comm;
+  client_event.data.l[2] = (long)client_ident;
+  client_event.data.l[3] = effective_protocol_version;
+
+  XSendEvent(XtDisplay(w), client_event.window, FALSE, (long)0,
+             (XEvent *)&client_event);
+}
+
+/*
+ * Clients which doesn't support Editres protocol will not respond
+ * to the LocalSendWidgetTree request - we must detect it as timeout.
+ */
+static void ClientTimeOut(XtPointer client_data, XtIntervalId *id)
+{
+  fprintf(stderr, "%s: client 0x%lx didn't responded to Editres Protocol request\n",
+          PROGRAM_NAME, (long)client_window);
+  waiting_response = FALSE;
+}
+
+/*
+ * Find a widget which name matches the specified pattern, and
+ * return the window-id of the widget.  If there are two or more
+ * matched widgets, one of them will be returned.
+ *
+ * If name of the widget to be matched is "foo.bar.zot", the pattern
+ * (argument "name") can be "zot", "bar.zot" or "foo.bar.zot".
+ * The pattern can leaded with "*" such as "*zot", but "*" can't be
+ * used between the words (i.e., "foo*zot" is not allowed).
+ */
+Window FindWidget(Widget w, Window client, const char *name)
+{
+  XEvent event;
+  XtAppContext app_con;
+  XtIntervalId timer_id;
+  const char *pattern;
+  int pattern_len, inx, i;
+
+  if (waiting_response) {
+    fprintf(stderr, "%s: list widget requested recursively (ignored)\n",
+            PROGRAM_NAME);
+    return None;
+  }
+
+  if (appres.debug)
+    fprintf(stderr, "%s: list widget tree for window 0x%lx\n",
+            PROGRAM_NAME, (long)client);
+
+  if (atom_comm == None) {
+    Display *dpy = XtDisplay(w);
+    atom_comm = XInternAtom(dpy, EDITRES_COMM_ATOM, False);
+    atom_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
+    atom_resource_editor = XInternAtom(dpy, EDITRES_NAME, False);
+    atom_editres_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM, False);
+    atom_client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
+  }
+
+  client_window = client;
+  effective_protocol_version = EDITRES_PROTOCOL_VERSION;
+  app_con = XtWidgetToApplicationContext(w);
+
+  timer_id = XtAppAddTimeOut(app_con, CLIENT_TIME_OUT, ClientTimeOut, NULL);
+  waiting_response = TRUE;
+  RequestSendWidgetTree(w);
+  while (waiting_response) {
+    XtAppNextEvent(app_con, &event);
+    XtDispatchEvent(&event);
+  }
+  XtRemoveTimeOut(timer_id);
+
+  if (widget_list != NULL && strlen(name) != 0) {
+    pattern = name;
+    if (pattern[0] == '*') pattern = pattern + 1;
+    if (strchr(pattern, '*') != NULL)
+      fprintf(stderr, "%s: pattern should not include \"*\": %s\n",
+              PROGRAM_NAME, name);
+    pattern_len = strlen(pattern);
+    for (i = 0; i < num_widget_list; i++) {
+      if (appres.debug)
+       fprintf(stderr, "FindWidget: %s\n", widget_list[i].path);
+      inx = strlen(widget_list[i].path) - pattern_len;
+      if (0 <= inx) {
+        if (1 <= inx && widget_list[i].path[inx - 1] != '.'
+            && widget_list[i].path[inx - 1] != '*') continue;
+        if (strcmp(&widget_list[i].path[inx], pattern) == 0) break;
+      }
+    }
+    if (i < num_widget_list) {
+      if (appres.debug)
+        fprintf(stderr, "%s: matched widget: %s (id=0x%lx, window=0x%lx)\n",
+                PROGRAM_NAME, widget_list[i].path,
+                (long)widget_list[i].id, (long)widget_list[i].window);
+      return widget_list[i].window;
+    }
+  }
+  if (appres.debug && widget_list == NULL)
+    fprintf(stderr, "FindWidget: couldn't get widget list\n");
+  if (strlen(name) != 0) {
+    fprintf(stderr, "%s: no widget matched to pattern \"%s\"\n",
+            PROGRAM_NAME, name);
+  }
+
+  return None;
+}
diff --git a/development/autotests/xvkbd/iconify.xbm b/development/autotests/xvkbd/iconify.xbm
new file mode 100644 (file)
index 0000000..2590872
--- /dev/null
@@ -0,0 +1,5 @@
+#define iconify_width 8
+#define iconify_height 13
+static unsigned char iconify_bits[] = {
+   0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x7c, 0x78, 0x70, 0x60, 0x40,
+   0x00};
diff --git a/development/autotests/xvkbd/resources.h b/development/autotests/xvkbd/resources.h
new file mode 100644 (file)
index 0000000..efbc869
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * xvkbd - Virtual Keyboard for X Window System
+ *
+ * Copyright (C) 2000 by Tom Sato <VEF00200@nifty.ne.jp>
+ * http://homepage3.nifty.com/tsato/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ */
+
+#ifndef PROGRAM_NAME
+# define PROGRAM_NAME "xvkbd"
+#endif
+
+struct appres_struct {
+  String description;
+  String show_manual_command;
+
+  String geometry;
+  Boolean inherit_geometry;
+  Boolean version;
+  Boolean debug;
+  Boolean xtest;
+  Boolean no_sync;
+  Boolean always_on_top;
+  Boolean wm_toolbar;
+  Boolean jump_pointer;
+  Boolean jump_pointer_always;
+  Boolean jump_pointer_back;
+  Boolean quick_modifiers;
+  Boolean altgr_lock;
+  Boolean shift_lock;
+  Boolean modifiers_lock;
+  Boolean num_lock_state;
+  Boolean auto_repeat;
+  Boolean modal_keytop;
+  Boolean minimizable;
+  Boolean secure;
+  Boolean no_root;
+  Boolean nonexitable;
+  int modal_threshold;
+  Boolean keypad;
+  Boolean function_key;
+  Boolean compact;
+  Boolean keypad_only;
+  Boolean keypad_keysym;
+  Boolean auto_add_keysym;
+  Boolean list_widgets;
+  String positive_modifiers;
+  String text;
+  String file;
+  String window;
+  String instance;
+  String widget;
+  XFontStruct *general_font;
+  XFontStruct *letter_font;
+  XFontStruct *special_font;
+  XFontStruct *keypad_font;
+#ifdef USE_I18N
+  XFontSet special_fontset;
+#endif
+  Pixel general_background;
+  Pixel special_background;
+  Pixel special_foreground;
+  Pixel highlight_background;
+  Pixel highlight_foreground;
+  Pixel focus_background;
+  Pixel remote_focus_background;
+  Pixel balloon_background;
+  Pixel launch_balloon_background;
+
+  String keys_normal;
+  String keys_shift;
+  String keys_altgr;
+  String keys_shift_altgr;
+  String key_labels;
+  String normal_key_labels;
+  String shift_key_labels;
+  String altgr_key_labels;
+  String shift_altgr_key_labels;
+
+  String keypad_normal;
+  String keypad_shift;
+  String keypad_labels;
+
+  String deadkeys;
+  int altgr_keycode;
+
+  String key_file;
+  String dict_file;
+  String customizations;
+  int editable_function_keys;
+
+  float max_width_ratio;
+  float max_height_ratio;
+  int text_delay;
+  int key_click_pitch;
+  int key_click_duration;
+  int autoclick_delay;
+} appres;
+
+
+/* FindWidget() is defined in findwidget.c */
+extern Window FindWidget(Widget w, Window client, const char *name);
diff --git a/development/autotests/xvkbd/xvkbd.c b/development/autotests/xvkbd/xvkbd.c
new file mode 100644 (file)
index 0000000..b27a091
--- /dev/null
@@ -0,0 +1,3689 @@
+/*
+ * xvkbd - Virtual Keyboard for X Window System
+ * (Version 3.2, 2010-03-14)
+ *
+ * Copyright (C) 2000-2010 by Tom Sato <VEF00200@nifty.ne.jp>
+ * http://homepage3.nifty.com/tsato/xvkbd/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+#include <fnmatch.h>
+#include <limits.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+#include <X11/Xproto.h>  /* to get request code */
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Repeater.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/SmeLine.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Viewport.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xmu/WinUtil.h>
+#include <X11/Xatom.h>
+
+#ifdef USE_I18N
+# include <X11/Xlocale.h>
+#endif
+
+#ifdef USE_XTEST
+# include <X11/extensions/XTest.h>
+#endif
+
+#include "resources.h"
+#define PROGRAM_NAME_WITH_VERSION "xvkbd (v3.2)"
+
+/*
+ * Default keyboard layout is hardcoded here.
+ * Layout of the main keyboard can be redefined by resources.
+ */
+#define NUM_KEY_ROWS    25
+#define NUM_KEY_COLS    25
+
+static char *keys_normal[NUM_KEY_ROWS][NUM_KEY_COLS] = {
+  { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "BackSpace" },
+  { "Escape", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\\", "`" },
+  { "Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "Delete" },
+  { "Control_L", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Return" },
+  { "Shift_L", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Multi_key", "Shift_R" },
+  { "MainMenu", "Caps_Lock", "Alt_L", "Meta_L", "space", "Meta_R", "Alt_R",
+    "Left", "Right", "Up", "Down", "Focus" },
+};
+static char *keys_shift[NUM_KEY_ROWS][NUM_KEY_COLS] = {
+  { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "BackSpace" },
+  { "Escape", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "|", "~" },
+  { "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "{", "}", "Delete" },
+  { "Control_L", "A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "\"", "Return" },
+  { "Shift_L", "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?", "Multi_key", "Shift_R" },
+  { "MainMenu", "Caps_Lock", "Alt_L", "Meta_L", "space", "Meta_R", "Alt_R",
+    "Left", "Right", "Up", "Down", "Focus" },
+};
+static char *keys_altgr[NUM_KEY_ROWS][NUM_KEY_COLS] = { { NULL } };
+static char *keys_shift_altgr[NUM_KEY_ROWS][NUM_KEY_COLS] = { { NULL } };
+
+static char *key_labels[NUM_KEY_ROWS][NUM_KEY_COLS] = {
+  { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backspace" },
+  { "Esc", "!\n1", "@\n2", "#\n3", "$\n4", "%\n5", "^\n6",
+    "&\n7", "*\n8", "(\n9", ")\n0", "_\n-", "+\n=", "|\n\\", "~\n`" },
+  { "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "{\n[", "}\n]", "Del" },
+  { "Control", "A", "S", "D", "F", "G", "H", "J", "K", "L", ":\n;", "\"\n'", "Return" },
+  { "Shift", "Z", "X", "C", "V", "B", "N", "M", "<\n,", ">\n.", "?\n/", "Com\npose", "Shift" },
+  { "MainMenu", "Caps\nLock", "Alt", "Meta", "", "Meta", "Alt",
+    "left", "right", "up", "down", "Focus" },
+};
+static char *normal_key_labels[NUM_KEY_ROWS][NUM_KEY_COLS] = {
+  { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backspace" },
+  { "Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\\", "`" },
+  { "Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "Del" },
+  { "Ctrl", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Return" },
+  { "Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Comp", "Shift" },
+  { "MainMenu", "Caps", "Alt", "Meta", "", "Meta", "Alt",
+    "left", "right", "up", "down", "Focus" },
+};
+static char *shift_key_labels[NUM_KEY_ROWS][NUM_KEY_COLS] = {
+  { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backspace" },
+  { "Esc", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "|", "~" },
+  { "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "{", "}", "Del" },
+  { "Ctrl", "A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "\"", "Return" },
+  { "Shift", "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?", "Comp", "Shift" },
+  { "MainMenu", "Caps", "Alt", "Meta", "", "Meta", "Alt",
+    "left", "right", "up", "down", "Focus" },
+};
+static char *altgr_key_labels[NUM_KEY_ROWS][NUM_KEY_COLS] = { { NULL } };
+static char *shift_altgr_key_labels[NUM_KEY_ROWS][NUM_KEY_COLS] = { { NULL } };
+
+
+#define NUM_KEYPAD_ROWS  NUM_KEY_ROWS
+#define NUM_KEYPAD_COLS  NUM_KEY_COLS
+
+static char *keypad[NUM_KEYPAD_ROWS][NUM_KEYPAD_COLS] = {
+  { "Num_Lock",  "KP_Divide",   "KP_Multiply", "Focus"       },
+  { "Home",      "Up",          "Page_Up",     "KP_Add"      },
+  { "Left",      "5",           "Right",       "KP_Subtract" },
+  { "End",       "Down",        "Page_Down",   "KP_Enter"    },
+  { "Insert",                   "Delete"                     },
+};
+static char *keypad_shift[NUM_KEYPAD_ROWS][NUM_KEYPAD_COLS] = {
+  { "Num_Lock",  "KP_Divide",   "KP_Multiply", "Focus"       },
+  { "KP_7",      "KP_8",        "KP_9",        "KP_Add"      },
+  { "KP_4",      "KP_5",        "KP_6",        "KP_Subtract" },
+  { "KP_1",      "KP_2",        "KP_3",        "KP_Enter"    },
+  { "KP_0",                     "."                          },
+};
+static char *keypad_label[NUM_KEYPAD_ROWS][NUM_KEYPAD_COLS] = {
+  { "Num\nLock", "/",           "*",           "Focus"       },
+  { "7\nHome",   "8\nUp  ",     "9\nPgUp",     "+"           },
+  { "4\nLeft",   "5\n    ",     "6\nRight",    "-"           },
+  { "1\nEnd ",   "2\nDown",     "3\nPgDn",     "Enter"       },
+  { "0\nIns ",                  ".\nDel "                    },
+};
+
+#define NUM_SUN_FKEY_ROWS 6
+#define NUM_SUN_FKEY_COLS 3
+
+static char *sun_fkey[NUM_SUN_FKEY_ROWS][NUM_SUN_FKEY_COLS] = {
+  { "L1", "L2"  },
+  { "L3", "L4"  },
+  { "L5", "L6"  },
+  { "L7", "L8"  },
+  { "L9", "L10" },
+  { "Help"      },
+};
+static char *sun_fkey_label[NUM_SUN_FKEY_ROWS][NUM_SUN_FKEY_COLS] = {
+  { "Stop \nL1", "Again\nL2"  },
+  { "Props\nL3", "Undo \nL4"  },
+  { "Front\nL5", "Copy \nL6"  },
+  { "Open \nL7", "Paste\nL8"  },
+  { "Find \nL9", "Cut  \nL10" },
+  { "Help"                    },
+};
+
+/*
+ * Image for arrow keys
+ */
+#define up_width 7
+#define up_height 13
+static unsigned char up_bits[] = {
+   0x08, 0x1c, 0x1c, 0x3e, 0x2a, 0x49, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+   0x08};
+
+#define down_width 7
+#define down_height 13
+static unsigned char down_bits[] = {
+   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x49, 0x2a, 0x3e, 0x1c, 0x1c,
+   0x08};
+
+#define left_width 13
+#define left_height 13
+static unsigned char left_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0e, 0x00,
+   0xff, 0x1f, 0x0e, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00};
+
+#define right_width 13
+#define right_height 13
+static unsigned char right_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x0e,
+   0xff, 0x1f, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00};
+
+#define check_width 16
+#define check_height 16
+static unsigned char check_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1e, 0x08, 0x0f,
+  0x8c, 0x07, 0xde, 0x03, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0xf0, 0x00,
+  0x70, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define back_width 18
+#define back_height 13
+static unsigned char back_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+   0x78, 0x00, 0x00, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0xfe, 0xff, 0x03,
+   0x78, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00};
+
+/*
+ * Resources and options
+ */
+#define Offset(entry) XtOffset(struct appres_struct *, entry)
+static XtResource application_resources[] = {
+  { "description", "Description", XtRString, sizeof(char *),
+    Offset(description), XtRImmediate,
+    PROGRAM_NAME_WITH_VERSION " - virtual keyboard for X window system\n\n"
+    "Copyright (C) 2000-2010 by Tom Sato <VEF00200@nifty.ne.jp>\n"
+    "http://homepage3.nifty.com/tsato/xvkbd/\n\n"
+    "This program is free software with ABSOLUTELY NO WARRANTY,\n"
+    "distributed under the terms of the GNU General Public License.\n" },
+  { "showManualCommand", "ShowManualCommand", XtRString, sizeof(char *),
+    Offset(show_manual_command), XtRImmediate, "xterm -e man xvkbd &" },
+
+  { "windowGeometry", "Geometry", XtRString, sizeof(char *),
+    Offset(geometry), XtRImmediate, "" },
+  { "inheritGeoemetry", "Inherit", XtRBoolean, sizeof(Boolean),
+     Offset(inherit_geometry), XtRImmediate, (XtPointer)TRUE },
+  { "debug", "Debug", XtRBoolean, sizeof(Boolean),
+     Offset(debug), XtRImmediate, (XtPointer)FALSE },
+  { "version", "Version", XtRBoolean, sizeof(Boolean),
+     Offset(version), XtRImmediate, (XtPointer)FALSE },
+#ifdef USE_XTEST
+  { "xtest", "XTest", XtRBoolean, sizeof(Boolean),
+     Offset(xtest), XtRImmediate, (XtPointer)TRUE },
+#else
+  { "xtest", "XTest", XtRBoolean, sizeof(Boolean),
+     Offset(xtest), XtRImmediate, (XtPointer)FALSE },
+#endif
+  { "noSync", "NoSync", XtRBoolean, sizeof(Boolean),
+     Offset(no_sync), XtRImmediate, (XtPointer)FALSE },
+  { "alwaysOnTop", "AlwaysOnTop", XtRBoolean, sizeof(Boolean),
+     Offset(always_on_top), XtRImmediate, (XtPointer)FALSE },
+  { "wmToolbar", "WmToolbar", XtRBoolean, sizeof(Boolean),
+     Offset(wm_toolbar), XtRImmediate, (XtPointer)FALSE },
+  { "jumpPointer", "JumpPointer", XtRBoolean, sizeof(Boolean),
+     Offset(jump_pointer), XtRImmediate, (XtPointer)TRUE },
+  { "jumpPointerAlways", "JumpPointer", XtRBoolean, sizeof(Boolean),
+     Offset(jump_pointer_always), XtRImmediate, (XtPointer)TRUE },
+  { "jumpPointerBack", "JumpPointer", XtRBoolean, sizeof(Boolean),
+     Offset(jump_pointer_back), XtRImmediate, (XtPointer)TRUE },
+  { "quickModifiers", "QuickModifiers", XtRBoolean, sizeof(Boolean),
+     Offset(quick_modifiers), XtRImmediate, (XtPointer)TRUE },
+  { "altgrLock", "ModifiersLock", XtRBoolean, sizeof(Boolean),
+     Offset(altgr_lock), XtRImmediate, (XtPointer)FALSE },
+  { "shiftLock", "ModifiersLock", XtRBoolean, sizeof(Boolean),
+     Offset(shift_lock), XtRImmediate, (XtPointer)FALSE },
+  { "modifiersLock", "ModifiersLock", XtRBoolean, sizeof(Boolean),
+     Offset(modifiers_lock), XtRImmediate, (XtPointer)FALSE },
+  { "numLockState", "NumLockState", XtRBoolean, sizeof(Boolean),
+     Offset(num_lock_state), XtRImmediate, (XtPointer)TRUE },
+  { "autoRepeat", "AutoRepeat", XtRBoolean, sizeof(Boolean),
+     Offset(auto_repeat), XtRImmediate, (XtPointer)TRUE },
+  { "modalKeytop", "ModalKeytop", XtRBoolean, sizeof(Boolean),
+     Offset(modal_keytop), XtRImmediate, (XtPointer)FALSE },
+  { "minimizable", "Minimizable", XtRBoolean, sizeof(Boolean),
+     Offset(minimizable), XtRImmediate, (XtPointer)FALSE },
+  { "secure", "Secure", XtRBoolean, sizeof(Boolean),
+     Offset(secure), XtRImmediate, (XtPointer)FALSE },
+  { "no_root", "NoRoot", XtRBoolean, sizeof(Boolean),
+     Offset(no_root), XtRImmediate, (XtPointer)FALSE },
+  { "nonexitable", "Secure", XtRBoolean, sizeof(Boolean),
+     Offset(nonexitable), XtRImmediate, (XtPointer)FALSE },
+  { "modalKeytop", "ModalKeytop", XtRBoolean, sizeof(Boolean),
+     Offset(modal_keytop), XtRImmediate, (XtPointer)FALSE },
+  { "modalThreshold", "ModalThreshold", XtRInt, sizeof(int),
+     Offset(modal_threshold), XtRImmediate, (XtPointer)150 },
+  { "keypad", "Keypad", XtRBoolean, sizeof(Boolean),
+     Offset(keypad), XtRImmediate, (XtPointer)TRUE },
+  { "functionkey", "FunctionKey", XtRBoolean, sizeof(Boolean),
+     Offset(function_key), XtRImmediate, (XtPointer)TRUE },
+  { "compact", "Compact", XtRBoolean, sizeof(Boolean),
+     Offset(compact), XtRImmediate, (XtPointer)FALSE },
+  { "keypadOnly", "KeypadOnly", XtRBoolean, sizeof(Boolean),
+     Offset(keypad_only), XtRImmediate, (XtPointer)FALSE },
+  { "keypadKeysym", "KeypadKeysym", XtRBoolean, sizeof(Boolean),
+     Offset(keypad_keysym), XtRImmediate, (XtPointer)FALSE },
+  { "autoAddKeysym", "AutoAddKeysym", XtRBoolean, sizeof(Boolean),
+     Offset(auto_add_keysym), XtRImmediate, (XtPointer)TRUE },
+  { "listWidgets", "Debug", XtRBoolean, sizeof(Boolean),
+     Offset(list_widgets), XtRImmediate, (XtPointer)FALSE },
+  { "positiveModifiers", "PositiveModifiers", XtRString, sizeof(char *),
+    Offset(positive_modifiers), XtRImmediate, "" },
+  { "text", "Text", XtRString, sizeof(char *),
+    Offset(text), XtRImmediate, "" },
+  { "file", "File", XtRString, sizeof(char *),
+    Offset(file), XtRImmediate, "" },
+  { "window", "Window", XtRString, sizeof(char *),
+    Offset(window), XtRImmediate, "" },
+  { "instance", "Instance", XtRString, sizeof(char *),
+    Offset(instance), XtRImmediate, "" },
+  { "widget", "Widget", XtRString, sizeof(char *),
+    Offset(widget), XtRImmediate, "" },
+  { "generalFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+      Offset(general_font), XtRString, XtDefaultFont},
+  { "letterFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+      Offset(letter_font), XtRString, XtDefaultFont},
+  { "specialFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+      Offset(special_font), XtRString, XtDefaultFont},
+  { "keypadFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+      Offset(keypad_font), XtRString, XtDefaultFont},
+  { "generalBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(general_background), XtRString, "gray" },
+  { "specialBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(special_background), XtRString, "gray" },
+  { "specialForeground", XtCForeground, XtRPixel, sizeof(Pixel),
+     Offset(special_foreground), XtRString, "black" },
+#ifdef USE_I18N
+  { "specialFontSet", XtCFontSet, XtRFontSet, sizeof(XFontSet),
+      Offset(special_fontset), XtRString, XtDefaultFontSet},
+#endif
+  { "highlightBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(highlight_background), XtRString, "gray" },
+  { "highlightForeground", XtCForeground, XtRPixel, sizeof(Pixel),
+     Offset(highlight_foreground), XtRString, "forestgreen" },
+  { "focusBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(focus_background), XtRString, "gray" },
+  { "remoteFocusBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(remote_focus_background), XtRString, "cyan" },
+  { "balloonBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(balloon_background), XtRString, "LightYellow1" },
+  { "launchBalloonBackground", XtCBackground, XtRPixel, sizeof(Pixel),
+     Offset(launch_balloon_background), XtRString, "SkyBlue1" },
+
+  { "normalkeys", "NormalKeys", XtRString, sizeof(char *),
+    Offset(keys_normal), XtRImmediate, "" },
+  { "shiftkeys", "ShiftKeys", XtRString, sizeof(char *),
+    Offset(keys_shift), XtRImmediate, "" },
+  { "altgrkeys", "AltgrKeys", XtRString, sizeof(char *),
+    Offset(keys_altgr), XtRImmediate, "" },
+  { "shiftaltgrkeys", "ShiftAltgrKeys", XtRString, sizeof(char *),
+    Offset(keys_shift_altgr), XtRImmediate, "" },
+  { "keylabels", "KeyLabels", XtRString, sizeof(char *),
+    Offset(key_labels), XtRImmediate, "" },
+  { "normalkeylabels", "NormalKeyLabels", XtRString, sizeof(char *),
+    Offset(normal_key_labels), XtRImmediate, "" },
+  { "shiftkeylabels", "ShiftKeyLabels", XtRString, sizeof(char *),
+    Offset(shift_key_labels), XtRImmediate, "" },
+  { "altgrkeylabels", "AltgrKeyLabels", XtRString, sizeof(char *),
+    Offset(altgr_key_labels), XtRImmediate, "" },
+  { "shiftaltgrkeylabels", "ShiftAltgrKeyLabels", XtRString, sizeof(char *),
+    Offset(shift_altgr_key_labels), XtRImmediate, "" },
+
+  { "normalkeypad", "NormalKeypad", XtRString, sizeof(char *),
+    Offset(keypad_normal), XtRImmediate, "" },
+  { "shiftkeypad", "ShiftKeypad", XtRString, sizeof(char *),
+    Offset(keypad_shift), XtRImmediate, "" },
+  { "keypad_labels", "KeypadLabels", XtRString, sizeof(char *),
+    Offset(keypad_labels), XtRImmediate, "" },
+
+  { "deadkeys", "DeadKeys", XtRString, sizeof(char *),
+    Offset(deadkeys), XtRImmediate, "" },
+  { "altgrKeycode", "AltgrKeycode", XtRInt, sizeof(int),
+    Offset(altgr_keycode), XtRImmediate, (XtPointer)0 },
+
+  { "keyFile", "KeyFile", XtRString, sizeof(char *),
+    Offset(key_file), XtRImmediate, ".xvkbd" },
+  { "dictFile", "DictFile", XtRString, sizeof(char *),
+    Offset(dict_file), XtRImmediate, "/usr/share/dict/words" },
+  { "customizations", "Customizations", XtRString, sizeof(char *),
+    Offset(customizations), XtRImmediate, "default" },
+  { "editableFunctionKeys", "EditableFunctionKeys", XtRInt, sizeof(int),
+     Offset(editable_function_keys), XtRImmediate, (XtPointer)12 },
+
+  { "maxWidthRatio", "MaxRatio", XtRFloat, sizeof(float),
+     Offset(max_width_ratio), XtRString, "0.9" },
+  { "maxHeightRatio", "MaxRatio", XtRFloat, sizeof(float),
+     Offset(max_height_ratio), XtRString, "0.5" },
+  { "textDelay", "TextDelay", XtRInt, sizeof(int),
+     Offset(text_delay), XtRImmediate, (XtPointer)0 },
+
+  { "keyClickPitch", "KeyClickPitch", XtRInt, sizeof(int),
+     Offset(key_click_pitch), XtRImmediate, (XtPointer)1000 },
+  { "keyClickDuration", "KeyClickDuration", XtRInt, sizeof(int),
+     Offset(key_click_duration), XtRImmediate, (XtPointer)1 },
+  { "autoClickDelay", "AutoClickDelay", XtRInt, sizeof(int),
+     Offset(autoclick_delay), XtRImmediate, (XtPointer)0 },
+};
+#undef Offset
+
+static XrmOptionDescRec options[] = {
+  { "-geometry", ".windowGeometry", XrmoptionSepArg, NULL },
+  { "-windowgeometry", ".windowGeometry", XrmoptionSepArg, NULL },
+  { "-debug", ".debug", XrmoptionNoArg, "True" },
+#ifdef USE_XTEST
+  { "-xtest", ".xtest", XrmoptionNoArg, "True" },
+  { "-xsendevent", ".xtest", XrmoptionNoArg, "False" },
+  { "-no-jump-pointer", ".jumpPointer", XrmoptionNoArg, "False" },
+  { "-no-back-pointer", ".jumpPointerBack", XrmoptionNoArg, "False" },
+#endif
+  { "-no-sync", ".noSync", XrmoptionNoArg, "True" },
+  { "-always-on-top", ".alwaysOnTop", XrmoptionNoArg, "True" },  /* EXPERIMENTAL */
+  { "-quick", ".quickModifiers", XrmoptionNoArg, "True" },
+  { "-modifiers", ".positiveModifiers", XrmoptionSepArg, NULL },
+  { "-text", ".text", XrmoptionSepArg, NULL },
+  { "-file", ".file", XrmoptionSepArg, NULL },
+  { "-delay", ".textDelay", XrmoptionSepArg, NULL },
+  { "-window", ".window", XrmoptionSepArg, NULL },
+  { "-instance", ".instance", XrmoptionSepArg, NULL },
+  { "-widget", ".widget", XrmoptionSepArg, NULL },
+  { "-altgr-lock", ".altgrLock", XrmoptionNoArg, "True" },
+  { "-no-altgr-lock", ".altgrLock", XrmoptionNoArg, "False" },
+  { "-no-repeat", ".autoRepeat", XrmoptionNoArg, "False" },
+  { "-norepeat", ".autoRepeat", XrmoptionNoArg, "False" },
+  { "-no-keypad", ".keypad", XrmoptionNoArg, "False" },
+  { "-nokeypad", ".keypad", XrmoptionNoArg, "False" },
+  { "-no-functionkey", ".functionkey", XrmoptionNoArg, "False" },
+  { "-nofunctionkey", ".functionkey", XrmoptionNoArg, "False" },
+  { "-highlight", ".highlightForeground", XrmoptionSepArg, NULL },
+  { "-compact", ".compact", XrmoptionNoArg, "True" },
+  { "-keypad", ".keypadOnly", XrmoptionNoArg, "True" },
+  { "-true-keypad", ".keypadKeysym", XrmoptionNoArg, "True" },
+  { "-truekeypad", ".keypadKeysym", XrmoptionNoArg, "True" },
+  { "-no-add-keysym", ".autoAddKeysym", XrmoptionNoArg, "False" },
+  { "-altgr-keycode", ".altgrKeycode", XrmoptionSepArg, NULL },
+  { "-list", ".listWidgets", XrmoptionNoArg, "True" },
+  { "-modal", ".modalKeytop", XrmoptionNoArg, "True" },
+  { "-minimizable", ".minimizable", XrmoptionNoArg, "True" },
+  { "-secure", ".secure", XrmoptionNoArg, "True" },
+  { "-no_root", ".no_root", XrmoptionNoArg, "True" },
+  { "-nonexitable", ".nonexitable", XrmoptionNoArg, "True" },
+  { "-xdm", ".Secure", XrmoptionNoArg, "True" },
+  { "-dict", ".dictFile", XrmoptionSepArg, NULL },
+  { "-keyfile", ".keyFile", XrmoptionSepArg, NULL },
+  { "-customizations", ".customizations", XrmoptionSepArg, NULL },
+  { "-version", ".version", XrmoptionNoArg, "True" },
+  { "-help", ".version", XrmoptionNoArg, "True" },
+};
+
+/*
+ * Global variables
+ */
+static char dict_filename[PATH_MAX] = "";
+
+static int argc1;
+static char **argv1;
+
+static XtAppContext app_con;
+static Widget toplevel;
+static Widget key_widgets[NUM_KEY_ROWS][NUM_KEY_COLS];
+static Widget main_menu = None;
+
+static Dimension toplevel_height = 1000;
+
+static Display *dpy;
+static Atom wm_delete_window = None;
+
+static KeySym *keysym_table = NULL;
+static int min_keycode, max_keycode;
+static int keysym_per_keycode;
+static Boolean error_detected;
+
+static int alt_mask = 0;
+static int meta_mask = 0;
+static int altgr_mask = 0;
+static KeySym altgr_keysym = NoSymbol;
+
+static int shift_state = 0;
+static int mouse_shift = 0;
+
+static Display *target_dpy = NULL;
+
+static Window toplevel_parent = None;
+static Window focused_window = None;
+static Window focused_subwindow = None;
+
+static Pixmap xvkbd_pixmap = None;
+
+static int AddKeysym(KeySym keysym, Boolean top);  /* forward */
+static void SendString(const unsigned char *str);
+static void MakeKeyboard(Boolean remake);
+static void MakeKeypad(Widget form, Widget from_vert, Widget from_horiz);
+static void MakeSunFunctionKey(Widget form, Widget from_vert, Widget from_horiz);
+static void MakeDeadkeyPanel(Widget form);
+static void RefreshMainMenu(void);
+static void PopupFunctionKeyEditor(void);
+static void DeleteWindowProc(Widget w, XEvent *event, String *pars, Cardinal *n_pars);
+
+/*
+ * Search for window which has specified instance name (WM_NAME)
+ * or class name (WM_CLASS).
+ */
+static Window FindWindow(Window top, char *name)
+{
+  Window w;
+  Window *children, dummy;
+  unsigned int nchildren;
+  int i;
+  XClassHint hint;
+  char *win_name;
+
+  w = None;
+
+  if (appres.debug) fprintf(stderr, "FindWindow: id=0x%lX", (long)top);
+
+  if (XGetClassHint(target_dpy, top, &hint)) {
+    if (hint.res_name) {
+      if (appres.debug) fprintf(stderr, " instance=\"%s\"", hint.res_name);
+      if ((strlen(name) > 0 && fnmatch(name, hint.res_name, 0) == 0)
+         || (strlen(appres.instance) > 0 && fnmatch(appres.instance, hint.res_name, 0) == 0)) w = top;
+      XFree(hint.res_name);
+    }
+    if (strlen(name) > 0 && hint.res_class) {
+      if (appres.debug) fprintf(stderr, " class=\"%s\"", hint.res_class);
+      if (strlen(name) > 0 && fnmatch(name, hint.res_class, 0) == 0) w = top;
+      XFree(hint.res_class);
+    }
+  }
+  if (XFetchName(target_dpy, top, &win_name)) { /* window title */
+    if (appres.debug) fprintf(stderr, " title=\"%s\"", win_name);
+    if (strlen(name) > 0 && fnmatch(name, win_name, 0) == 0) w = top;
+    XFree(win_name);
+  }
+
+  if (appres.debug) fprintf(stderr, "%s\n", (w == None) ? "" : " [matched]");
+
+  if (w == None &&
+      XQueryTree(target_dpy, top, &dummy, &dummy, &children, &nchildren)) {
+    for (i = 0; i < nchildren; i++) {
+      w = FindWindow(children[i], name);
+      if (w != None) break;
+    }
+    if (children) XFree((char *)children);
+  }
+
+  return(w);
+}
+
+/*
+ * This will be called to get window to set input focus,
+ * when user pressed the "Focus" button.
+ */
+static void GetFocusedWindow(void)
+{
+  Cursor cursor;
+  XEvent event;
+  Window target_root, child;
+  int junk_i;
+  unsigned junk_u;
+  Window junk_w;
+  int scrn;
+  int cur_x, cur_y, last_x, last_y;
+  double x_ratio, y_ratio;
+
+  XFlush(target_dpy);
+  target_root = RootWindow(target_dpy, DefaultScreen(target_dpy));
+
+  cursor = XCreateFontCursor(dpy, (target_dpy == dpy) ? XC_crosshair : XC_dot);
+  if (XGrabPointer(dpy, RootWindow(dpy, DefaultScreen(dpy)), False, ButtonPressMask,
+                   GrabModeSync, GrabModeAsync, None,
+                   cursor, CurrentTime) == 0) {
+    if (appres.debug)
+      fprintf(stderr, "Grab pointer - waiting for button press\n");
+    last_x = -1;
+    last_y = -1;
+    x_ratio = ((double)WidthOfScreen(DefaultScreenOfDisplay(target_dpy))
+              / WidthOfScreen(XtScreen(toplevel)));
+    y_ratio = ((double)HeightOfScreen(DefaultScreenOfDisplay(target_dpy))
+              / HeightOfScreen(XtScreen(toplevel)));
+    do {
+      XAllowEvents(dpy, SyncPointer, CurrentTime);
+      if (target_dpy == dpy) {
+       XNextEvent(dpy, &event);
+      } else {
+       XCheckTypedEvent(dpy, ButtonPress, &event);
+       if (XQueryPointer(dpy, RootWindow(dpy, DefaultScreen(dpy)), &junk_w, &junk_w,
+                         &cur_x, &cur_y, &junk_i, &junk_i, &junk_u)) {
+         cur_x = cur_x * x_ratio;
+         cur_y = cur_y * y_ratio;
+       }
+       if (cur_x != last_x || cur_y != last_y) {
+         if (appres.debug) fprintf(stderr, "Moving pointer to (%d, %d) on %s\n",
+                                   cur_x, cur_y, XDisplayString(target_dpy));
+         XWarpPointer(target_dpy, None, target_root, 0, 0, 0, 0, cur_x, cur_y);
+         XFlush(target_dpy);
+         last_x = cur_x;
+         last_y = cur_y;
+         XQueryPointer(target_dpy, target_root, &junk_w, &child,
+                       &cur_x, &cur_y, &junk_i, &junk_i, &junk_u);
+         usleep(10000);
+       } else {
+         usleep(100000);
+       }
+      }
+    } while (event.type != ButtonPress);
+    XUngrabPointer(dpy, CurrentTime);
+
+    focused_window = None;
+    if (target_dpy == dpy) focused_window = event.xbutton.subwindow;
+    if (focused_window == None) {
+      XFlush(target_dpy);
+      for (scrn = 0; scrn < ScreenCount(target_dpy); scrn++) {
+       if (XQueryPointer(target_dpy, RootWindow(target_dpy, scrn), &junk_w, &child,
+                         &junk_i, &junk_i, &junk_i, &junk_i, &junk_u)) {
+         if (appres.debug)
+           fprintf(stderr, "Window on the other display/screen (screen #%d of %s) focused\n",
+                   scrn, XDisplayString(target_dpy));
+         target_root = RootWindow(target_dpy, scrn);
+         focused_window = child;
+         break;
+       }
+      }
+    }
+    if (focused_window == None) focused_window = target_root;
+    else focused_window = XmuClientWindow(target_dpy, focused_window);
+    if (appres.debug) fprintf(stderr, "Selected window is: 0x%lX on %s\n",
+                             focused_window, XDisplayString(target_dpy));
+
+    if (target_dpy == dpy && XtWindow(toplevel) == focused_window) {
+      focused_window = None;
+      focused_subwindow = focused_window;
+      return;
+    }
+
+    focused_subwindow = focused_window;
+    do {  /* search the child window */
+      XQueryPointer(target_dpy, focused_subwindow, &junk_w, &child,
+                    &junk_i, &junk_i, &junk_i, &junk_i, &junk_u);
+      if (child != None) {
+        focused_subwindow = child;
+        if (appres.debug) fprintf(stderr, "  going down: 0x%lX\n", focused_subwindow);
+      }
+    } while (child != None);
+    if (appres.list_widgets || strlen(appres.widget) != 0) {
+      child = FindWidget(toplevel, focused_window, appres.widget);
+      if (child != None) focused_subwindow = child;
+    }
+  } else {
+    fprintf(stderr, "%s: cannot grab pointer\n", PROGRAM_NAME);
+  }
+}
+
+/*
+ * Read keyboard mapping and modifier mapping.
+ * Keyboard mapping is used to know what keys are in shifted position.
+ * Modifier mapping is required because we should know Alt and Meta
+ * key are used as which modifier.
+ */
+static void Highlight(char *name, Boolean state);
+
+static void ReadKeymap(void)
+{
+  int i;
+  int keycode, inx, pos;
+  KeySym keysym;
+  XModifierKeymap *modifiers;
+  Widget w;
+  int last_altgr_mask;
+
+  XDisplayKeycodes(target_dpy, &min_keycode, &max_keycode);
+  if (keysym_table != NULL) XFree(keysym_table);
+  keysym_table = XGetKeyboardMapping(target_dpy,
+                             min_keycode, max_keycode - min_keycode + 1,
+                             &keysym_per_keycode);
+  for (keycode = min_keycode; keycode <= max_keycode; keycode++) {
+    /* if the first keysym is alphabet and the second keysym is NoSymbol,
+       it is equivalent to pair of lowercase and uppercase alphabet */
+    inx = (keycode - min_keycode) * keysym_per_keycode;
+    if (keysym_table[inx + 1] == NoSymbol
+       && ((XK_A <= keysym_table[inx] && keysym_table[inx] <= XK_Z)
+           || (XK_a <= keysym_table[inx] && keysym_table[inx] <= XK_z))) {
+      if (XK_A <= keysym_table[inx] && keysym_table[inx] <= XK_Z)
+       keysym_table[inx] = keysym_table[inx] - XK_A + XK_a;
+      keysym_table[inx + 1] = keysym_table[inx] - XK_a + XK_A;
+    }
+  }
+
+  last_altgr_mask = altgr_mask;
+  alt_mask = 0;
+  meta_mask = 0;
+  altgr_mask = 0;
+  altgr_keysym = NoSymbol;
+  modifiers = XGetModifierMapping(target_dpy);
+  for (i = 0; i < 8; i++) {
+    for (pos = 0; pos < modifiers->max_keypermod; pos++) {
+      keycode = modifiers->modifiermap[i * modifiers->max_keypermod + pos];
+      if (keycode < min_keycode || max_keycode < keycode) continue;
+
+      keysym = keysym_table[(keycode - min_keycode) * keysym_per_keycode];
+      if (keysym == XK_Alt_L || keysym == XK_Alt_R) {
+       alt_mask = 1 << i;
+      } else if (keysym == XK_Meta_L || keysym == XK_Meta_R) {
+       meta_mask = 1 << i;
+      } else if (keysym == XK_Mode_switch) {
+       if (appres.debug)
+         fprintf(stderr, "%s: found Mode_switch at %dth modifier\n", PROGRAM_NAME, i);
+       if (altgr_keysym == XK_ISO_Level3_Shift) {
+         if (appres.debug)
+           fprintf(stderr, "%s: both ISO_Level3_Shift and Mode_switch found - ISO_Level3_Shift prefered\n", PROGRAM_NAME);
+       } else {
+         altgr_mask = 0x0101 << i;
+         /* I don't know why, but 0x2000 was required for mod3 on my Linux box */
+         altgr_keysym = keysym;
+       }
+      } else if (keysym == XK_ISO_Level3_Shift) {
+       /* if no Mode_switch, try to use ISO_Level3_Shift instead */
+       /* however, it may not work as intended - I don't know why */
+       if (appres.debug)
+         fprintf(stderr, "%s: found ISO_Level3_Shift at %dth modifier\n", PROGRAM_NAME, i);
+       if (altgr_keysym == XK_Mode_switch) {
+         if (appres.debug)
+           fprintf(stderr, "%s: both ISO_Level3_Shift and Mode_switch found - ISO_Level3_Shift prefered\n", PROGRAM_NAME);
+       }
+       altgr_mask = 1 << i;
+       altgr_keysym = keysym;
+      }
+    }
+  }
+  XFreeModifiermap(modifiers);
+
+  if (altgr_keysym != XK_Mode_switch) {
+    fprintf(stderr, "%s: Mode_switch not available as a modifier\n", PROGRAM_NAME);
+    if (altgr_keysym == XK_ISO_Level3_Shift)
+      fprintf(stderr, "%s: although ISO_Level3_Shift is used instead, AltGr may not work correctly\n", PROGRAM_NAME);
+    else
+      fprintf(stderr, "%s: AltGr can't be used\n", PROGRAM_NAME);
+  }
+
+  w = XtNameToWidget(toplevel, "*Multi_key");
+  if (w != None) {
+    if (XKeysymToKeycode(target_dpy, XK_Multi_key) == NoSymbol) {
+      if (!appres.auto_add_keysym || AddKeysym(XK_Multi_key, FALSE) == NoSymbol)
+       XtSetSensitive(w, FALSE);
+    }
+  }
+  w = XtNameToWidget(toplevel, "*Mode_switch");
+  if (w != None) {
+    if (appres.xtest && 0 < appres.altgr_keycode) {
+      XtSetSensitive(w, TRUE);
+      if (appres.debug)
+       fprintf(stderr, "%s: keycode %d will be used for AltGr - it was specified with altgrKeycode\n",
+               PROGRAM_NAME, appres.altgr_keycode);
+    } else if (altgr_mask) {
+      XtSetSensitive(w, TRUE);
+    } else {
+      XtSetSensitive(w, FALSE);
+      if (shift_state & last_altgr_mask) {
+       shift_state &= ~last_altgr_mask;
+       Highlight("Mode_switch", FALSE);
+      }
+    }
+  }
+}
+
+/*
+ * This will called when X error is detected when attempting to
+ * send a event to a client window;  this will normally caused
+ * when the client window is destroyed.
+ */
+static int MyErrorHandler(Display *my_dpy, XErrorEvent *event)
+{
+  char msg[200];
+
+  error_detected = TRUE;
+  if (event->error_code == BadWindow) {
+    if (appres.debug)
+      fprintf(stderr, "%s: BadWindow - couldn't find target window 0x%lX (destroyed?)\n",
+             PROGRAM_NAME, (long)focused_window);
+    return 0;
+  }
+  XGetErrorText(my_dpy, event->error_code, msg, sizeof(msg) - 1);
+  fprintf(stderr, "X error trapped: %s, request-code=%d\n", msg, event->request_code);
+  return 0;
+}
+
+/*
+ * Send event to the focused window.
+ * If input focus is specified explicitly, select the window
+ * before send event to the window.
+ */
+static void SendEvent(XKeyEvent *event)
+{
+  static Boolean first = TRUE;
+
+  if (!appres.no_sync) {
+    XSync(event->display, FALSE);
+    XSetErrorHandler(MyErrorHandler);
+  }
+
+  error_detected = FALSE;
+  if (focused_window != None) {
+    /* set input focus if input focus is set explicitly */
+    if (appres.debug)
+      fprintf(stderr, "Set input focus to window 0x%lX (0x%lX)\n",
+              (long)focused_window, (long)event->window);
+    XSetInputFocus(event->display, focused_window, RevertToParent, CurrentTime);
+    if (!appres.no_sync) XSync(event->display, FALSE);
+  }
+  if (!error_detected) {
+    if (appres.xtest) {
+#ifdef USE_XTEST
+      if (appres.debug)
+       fprintf(stderr, "XTestFakeKeyEvent(0x%lx, %ld, %d)\n",
+               (long)event->display, (long)event->keycode, event->type == KeyPress);
+      if (appres.jump_pointer) {
+       Window root, child, w;
+       int root_x, root_y, x, y;
+       unsigned int mask;
+       int revert_to;
+
+       w = None;
+       if (first || strlen(appres.text) == 0 || appres.jump_pointer_back) {
+         first = FALSE;
+
+         w = focused_subwindow;
+         if (w == None && appres.jump_pointer_always)
+           XGetInputFocus(event->display, &w, &revert_to);
+
+         if (w != None) {
+           if (appres.debug)
+             fprintf(stderr, "SendEvent: jump pointer to window 0x%lx\n", (long)w);
+
+           XQueryPointer(event->display, w,
+                         &root, &child, &root_x, &root_y, &x, &y, &mask);
+           XWarpPointer(event->display, None, w, 0, 0, 0, 0, 1, 1);
+           XFlush(event->display);
+         }
+       }
+
+       XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
+       XFlush(event->display);
+
+       if (w != None && appres.jump_pointer_back) {
+         XWarpPointer(event->display, None, root, 0, 0, 0, 0, root_x, root_y);
+         XFlush(event->display);
+       }
+      } else {
+       XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0);
+       XFlush(event->display);
+      }
+#else
+      fprintf(stderr, "%s: this binary is compiled without XTEST support\n",
+             PROGRAM_NAME);
+#endif
+    } else {
+      XSendEvent(event->display, event->window, TRUE, KeyPressMask, (XEvent *)event);
+      if (!appres.no_sync) XSync(event->display, FALSE);
+
+      if (error_detected
+         && (focused_subwindow != None) && (focused_subwindow != event->window)) {
+       error_detected = FALSE;
+       event->window = focused_subwindow;
+       if (appres.debug)
+         fprintf(stderr, "   retry: send event to window 0x%lX (0x%lX)\n",
+                 (long)focused_window, (long)event->window);
+       XSendEvent(event->display, event->window, TRUE, KeyPressMask, (XEvent *)event);
+       if (!appres.no_sync) XSync(event->display, FALSE);
+      }
+    }
+  }
+
+  if (error_detected) {
+    /* reset focus because focused window is (probably) no longer exist */
+    XBell(dpy, 0);
+    focused_window = None;
+    focused_subwindow = None;
+  }
+
+  XSetErrorHandler(NULL);
+}
+
+/*
+ * Insert a specified keysym to unused position in the keymap table.
+ * This will be called to add required keysyms on-the-fly.
+ * if the second parameter is TRUE, the keysym will be added to the
+ * non-shifted position - this may be required for modifier keys
+ * (e.g. Mode_switch) and some special keys (e.g. F20).
+ */
+static int AddKeysym(KeySym keysym, Boolean top)
+{
+  int keycode, pos, max_pos, inx, phase;
+
+  if (top) {
+    max_pos = 0;
+  } else {
+    max_pos = keysym_per_keycode - 1;
+    if (4 <= max_pos) max_pos = 3;
+    if (2 <= max_pos && altgr_keysym != XK_Mode_switch) max_pos = 1;
+  }
+
+  for (phase = 0; phase < 2; phase++) {
+    for (keycode = max_keycode; min_keycode <= keycode; keycode--) {
+      for (pos = max_pos; 0 <= pos; pos--) {
+       inx = (keycode - min_keycode) * keysym_per_keycode;
+       if ((phase != 0 || keysym_table[inx] == NoSymbol) && keysym_table[inx] < 0xFF00) {
+         /* In the first phase, to avoid modifing existing keys, */
+         /* add the keysym only to the keys which has no keysym in the first position. */
+         /* If no place fuond in the first phase, add the keysym for any keys except */
+         /* for modifier keys and other special keys */
+         if (keysym_table[inx + pos] == NoSymbol) {
+           if (appres.debug)
+             fprintf(stderr, "*** Adding keysym \"%s\" at keycode %d position %d/%d\n",
+                     XKeysymToString(keysym), keycode, pos, keysym_per_keycode);
+           keysym_table[inx + pos] = keysym;
+           XChangeKeyboardMapping(target_dpy, keycode, keysym_per_keycode, &keysym_table[inx], 1);
+           XFlush(target_dpy);
+           return keycode;
+         }
+       }
+      }
+    }
+  }
+  fprintf(stderr, "%s: couldn't add \"%s\" to keymap\n",
+         PROGRAM_NAME, XKeysymToString(keysym));
+  XBell(dpy, 0);
+  return NoSymbol;
+}
+
+/*
+ * Add the specified key as a new modifier.
+ * This is used to use Mode_switch (AltGr) as a modifier.
+ */
+static void AddModifier(KeySym keysym)
+{
+  XModifierKeymap *modifiers;
+  int keycode, i, pos;
+
+  keycode = XKeysymToKeycode(target_dpy, keysym);
+  if (keycode == NoSymbol) keycode = AddKeysym(keysym, TRUE);
+  
+  modifiers = XGetModifierMapping(target_dpy);
+  for (i = 7; 3 < i; i--) {
+    if (modifiers->modifiermap[i * modifiers->max_keypermod] == NoSymbol
+       || ((keysym_table[(modifiers->modifiermap[i * modifiers->max_keypermod]
+                          - min_keycode) * keysym_per_keycode]) == XK_ISO_Level3_Shift
+           && keysym == XK_Mode_switch)) {
+      for (pos = 0; pos < modifiers->max_keypermod; pos++) {
+       if (modifiers->modifiermap[i * modifiers->max_keypermod + pos] == NoSymbol) {
+         if (appres.debug)
+           fprintf(stderr, "Adding modifier \"%s\" as %dth modifier\n",
+                   XKeysymToString(keysym), i);
+         modifiers->modifiermap[i * modifiers->max_keypermod + pos] = keycode;
+         XSetModifierMapping(target_dpy, modifiers);
+         return;
+       }
+      }
+    }
+  }
+  fprintf(stderr, "%s: couldn't add \"%s\" as modifier\n",
+         PROGRAM_NAME, XKeysymToString(keysym));
+  XBell(dpy, 0);
+}
+
+/*
+ * Send sequence of KeyPressed/KeyReleased events to the focused
+ * window to simulate keyboard.  If modifiers (shift, control, etc)
+ * are set ON, many events will be sent.
+ */
+static void SendKeyPressedEvent(KeySym keysym, unsigned int shift)
+{
+  Window cur_focus;
+  int revert_to;
+  XKeyEvent event;
+  int keycode;
+  Window root, *children;
+  unsigned int n_children;
+  int phase, inx;
+  Boolean found;
+
+  if (focused_subwindow != None)
+    cur_focus = focused_subwindow;
+  else
+    XGetInputFocus(target_dpy, &cur_focus, &revert_to);
+
+  if (appres.debug) {
+    char ch = '?';
+    if ((keysym & ~0x7f) == 0 && isprint(keysym)) ch = keysym;
+    fprintf(stderr, "SendKeyPressedEvent: focus=0x%lX, key=0x%lX (%c), shift=0x%lX\n",
+            (long)cur_focus, (long)keysym, ch, (long)shift);
+  }
+
+  if (XtWindow(toplevel) != None) {
+    if (toplevel_parent == None) {
+      XQueryTree(target_dpy, RootWindow(target_dpy, DefaultScreen(target_dpy)),
+                 &root, &toplevel_parent, &children, &n_children);
+      XFree(children);
+    }
+    if (cur_focus == None || cur_focus == PointerRoot
+       || cur_focus == XtWindow(toplevel) || cur_focus == toplevel_parent) {
+      /* notice user when no window focused or the xvkbd window is focused */
+      XBell(dpy, 0);
+      return;
+    }
+  }
+
+  found = FALSE;
+  keycode = 0;
+  if (keysym != NoSymbol) {
+    for (phase = 0; phase < 2; phase++) {
+      for (keycode = min_keycode; !found && (keycode <= max_keycode); keycode++) {
+       /* Determine keycode for the keysym:  we use this instead
+          of XKeysymToKeycode() because we must know shift_state, too */
+       inx = (keycode - min_keycode) * keysym_per_keycode;
+       if (keysym_table[inx] == keysym) {
+         shift &= ~altgr_mask;
+         if (keysym_table[inx + 1] != NoSymbol) shift &= ~ShiftMask;
+         found = TRUE;
+         break;
+       } else if (keysym_table[inx + 1] == keysym) {
+         shift &= ~altgr_mask;
+         shift |= ShiftMask;
+         found = TRUE;
+         break;
+       }
+      }
+      if (!found && altgr_mask && 3 <= keysym_per_keycode) {
+       for (keycode = min_keycode; !found && (keycode <= max_keycode); keycode++) {
+         inx = (keycode - min_keycode) * keysym_per_keycode;
+         if (keysym_table[inx + 2] == keysym) {
+           shift &= ~ShiftMask;
+           shift |= altgr_mask;
+           found = TRUE;
+           break;
+         } else if (4 <= keysym_per_keycode && keysym_table[inx + 3] == keysym) {
+           shift |= ShiftMask | altgr_mask;
+           found = TRUE;
+           break;
+         }
+       }
+      }
+      if (found || !appres.auto_add_keysym) break;
+
+      if (0xF000 <= keysym) {
+       /* for special keys such as function keys,
+          first try to add it in the non-shifted position of the keymap */
+       if (AddKeysym(keysym, TRUE) == NoSymbol) AddKeysym(keysym, FALSE);
+      } else {
+       AddKeysym(keysym, FALSE);
+      }
+    }
+    if (appres.debug) {
+      if (found)
+       fprintf(stderr, "SendKeyPressedEvent: keysym=0x%lx, keycode=%ld, shift=0x%lX\n",
+               (long)keysym, (long)keycode, (long)shift);
+      else
+       fprintf(stderr, "SendKeyPressedEvent: keysym=0x%lx - keycode not found\n",
+               (long)keysym);
+    }
+  }
+
+  event.display = target_dpy;
+  event.window = cur_focus;
+  event.root = RootWindow(event.display, DefaultScreen(event.display));
+  event.subwindow = None;
+  event.time = CurrentTime;
+  event.x = 1;
+  event.y = 1;
+  event.x_root = 1;
+  event.y_root = 1;
+  event.same_screen = TRUE;
+
+#ifdef USE_XTEST
+  if (appres.xtest) {
+    Window root, child;
+    int root_x, root_y, x, y;
+    unsigned int mask;
+
+    XQueryPointer(target_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
+
+    event.type = KeyRelease;
+    event.state = 0;
+    if (mask & ControlMask) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Control_L);
+      SendEvent(&event);
+    }
+    if (mask & alt_mask) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Alt_L);
+      SendEvent(&event);
+    }
+    if (mask & meta_mask) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Meta_L);
+      SendEvent(&event);
+    }
+    if (mask & altgr_mask) {
+      if (0 < appres.altgr_keycode)
+       event.keycode = appres.altgr_keycode;
+      else
+       event.keycode = XKeysymToKeycode(target_dpy, altgr_keysym);
+      SendEvent(&event);
+    }
+    if (mask & ShiftMask) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Shift_L);
+      SendEvent(&event);
+    }
+    if (mask & LockMask) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Caps_Lock);
+      SendEvent(&event);
+    }
+  }
+#endif
+
+  event.type = KeyPress;
+  event.state = 0;
+  if (shift & ControlMask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Control_L);
+    SendEvent(&event);
+    event.state |= ControlMask;
+  }
+  if (shift & alt_mask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Alt_L);
+    SendEvent(&event);
+    event.state |= alt_mask;
+  }
+  if (shift & meta_mask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Meta_L);
+    SendEvent(&event);
+    event.state |= meta_mask;
+  }
+  if (shift & altgr_mask) {
+    if (0 < appres.altgr_keycode)
+      event.keycode = appres.altgr_keycode;
+    else
+      event.keycode = XKeysymToKeycode(target_dpy, altgr_keysym);
+    SendEvent(&event);
+    event.state |= altgr_mask;
+  }
+  if (shift & ShiftMask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Shift_L);
+    SendEvent(&event);
+    event.state |= ShiftMask;
+  }
+
+  if (keysym != NoSymbol) {  /* send event for the key itself */
+    event.keycode = found ? keycode : XKeysymToKeycode(target_dpy, keysym);
+    if (event.keycode == NoSymbol) {
+      if ((keysym & ~0x7f) == 0 && isprint(keysym))
+        fprintf(stderr, "%s: no such key: %c\n",
+                PROGRAM_NAME, (char)keysym);
+      else if (XKeysymToString(keysym) != NULL)
+        fprintf(stderr, "%s: no such key: keysym=%s (0x%lX)\n",
+                PROGRAM_NAME, XKeysymToString(keysym), (long)keysym);
+      else
+        fprintf(stderr, "%s: no such key: keysym=0x%lX\n",
+                PROGRAM_NAME, (long)keysym);
+      XBell(dpy, 0);
+    } else {
+      SendEvent(&event);
+      event.type = KeyRelease;
+      SendEvent(&event);
+    }
+  }
+
+  event.type = KeyRelease;
+  if (shift & ShiftMask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Shift_L);
+    SendEvent(&event);
+    event.state &= ~ShiftMask;
+  }
+  if (shift & altgr_mask) {
+    if (0 < appres.altgr_keycode)
+      event.keycode = appres.altgr_keycode;
+    else
+      event.keycode = XKeysymToKeycode(target_dpy, altgr_keysym);
+    SendEvent(&event);
+    event.state &= ~altgr_mask;
+  }
+  if (shift & meta_mask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Meta_L);
+    SendEvent(&event);
+    event.state &= ~meta_mask;
+  }
+  if (shift & alt_mask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Alt_L);
+    SendEvent(&event);
+    event.state &= ~alt_mask;
+  }
+  if (shift & ControlMask) {
+    event.keycode = XKeysymToKeycode(target_dpy, XK_Control_L);
+    SendEvent(&event);
+    event.state &= ~ControlMask;
+  }
+
+  if (appres.no_sync) XFlush(dpy);
+}
+
+/*
+ * Word completion - list of words which match the prefix entered
+ * via xvkbd can be listed, and choosing one of them will send the
+ * suffix to the clients.
+ * Words for completion will be read from dictionary file specified
+ * with xvkbd.dictFile resource, such as /usr/dict/words.
+ */
+static Widget completion_panel = None;
+static Widget completion_entry = None;
+static Widget completion_list = None;
+
+static Widget props_dict_entry = None;
+
+static char completion_text[100] = "";
+
+#define HASH_SIZE 100
+
+#define Hash(str)   ((toupper(str[0]) * 26 + toupper(str[1])) % HASH_SIZE)
+
+static struct WORDLIST {
+  struct WORDLIST *next;
+  char *word;
+} completion_words[HASH_SIZE];
+static int n_completion_words = 0;
+
+#define MAX_WORDS 200
+
+static String word_list[MAX_WORDS + 1];
+static int n_word_list = 0;
+
+static void SetDefaultDictionary(void)
+{
+  strncpy(dict_filename, appres.dict_file, sizeof(dict_filename));
+  XtVaSetValues(props_dict_entry, XtNstring, dict_filename, NULL);
+}
+
+static void ReadCompletionDictionary(void)
+{
+  static Boolean first = TRUE;
+  static char cur_dict_filename[PATH_MAX] = "";
+  FILE *fp;
+  struct WORDLIST *node_ptr;
+  char str[50];
+  int i;
+  struct WORDLIST *p;
+
+  if (strcmp(cur_dict_filename, dict_filename) == 0) return;
+  strcpy(cur_dict_filename, dict_filename);
+
+  if (!first) {
+    int cnt = 0;
+    for (i = 0; i < HASH_SIZE; i++) {
+      while (completion_words[i].next != NULL) {
+       p = completion_words[i].next;
+       completion_words[i].next = p->next;
+       free(p);
+       cnt++;
+      }
+    }
+    if (appres.debug)
+      fprintf(stderr, "ReadCompletionDictionary: %d words freed\n", cnt);
+  }
+  first = FALSE;
+
+  for (i = 0; i < HASH_SIZE; i++) {
+    completion_words[i].next = NULL;
+    completion_words[i].word = NULL;
+  }
+
+  n_completion_words = 0;
+  fp = fopen(dict_filename, "r");
+  if (fp == NULL) {
+    fprintf(stderr, "%s: can't read dictionary file %s: %s\n",
+           PROGRAM_NAME, dict_filename, strerror(errno));
+  } else {
+    while (fgets(str, sizeof(str) - 1, fp)) {
+      if (3 < strlen(str)) {
+       str[strlen(str) - 1] = '\0';
+       node_ptr = &completion_words[Hash(str)];
+       while (node_ptr->word != NULL) node_ptr = node_ptr->next;
+
+       node_ptr->word = XtNewString(str);
+       node_ptr->next = malloc(sizeof(struct WORDLIST));
+       node_ptr->next->next = NULL;
+       node_ptr->next->word = NULL;
+       n_completion_words++;
+      }
+    }
+    fclose(fp);
+
+    if (appres.debug)
+      fprintf(stderr, "ReadCompletionDictionary: %d words allocated\n", n_completion_words);
+  }
+}
+
+static void AddToCompletionText(KeySym keysym)
+{
+  int len;
+  struct WORDLIST *node_ptr;
+
+  if (completion_entry != None) {
+
+    if (n_completion_words == 0) {
+      XtVaSetValues(completion_entry, XtNlabel, "Couldn't read dictionary file", NULL);
+      return;
+    }
+
+    len = strlen(completion_text);
+    if (keysym == XK_BackSpace || keysym == XK_Delete) {
+      if (0 < len) completion_text[len - 1] = '\0';
+    } else if (keysym != NoSymbol
+              && !ispunct((char)keysym) && !isspace((char)keysym)) {
+      if (len < sizeof(completion_text) - 2) {
+       completion_text[len + 1] = '\0';
+       completion_text[len] = keysym;
+      }
+    } else {
+      completion_text[0] = '\0';
+    }
+    XtVaSetValues(completion_entry, XtNlabel, completion_text, NULL);
+
+    n_word_list = 0;
+    if (2 <= strlen(completion_text)) {
+      node_ptr = &completion_words[Hash(completion_text)];
+      while (node_ptr->word != NULL && n_word_list < MAX_WORDS) {
+       if (strlen(completion_text) + 1 < strlen(node_ptr->word) &&
+           strncasecmp(node_ptr->word, completion_text, strlen(completion_text)) == 0) {
+         word_list[n_word_list] = node_ptr->word;
+         n_word_list = n_word_list + 1;
+       }
+       node_ptr = node_ptr->next;
+      }
+    }
+    word_list[n_word_list] = NULL;
+    XawListChange(completion_list, word_list, 0, 0, TRUE);
+  }
+}
+
+static void CompletionWordSelected(Widget w, XtPointer client_data, XtPointer call_data)
+{
+  Boolean capitalize;
+  unsigned char ch;
+  int n, i;
+
+  n = ((XawListReturnStruct *)call_data)->list_index;
+  if (0 <= n && n < n_word_list) {
+    capitalize = TRUE;
+    for (i = 0; completion_text[i] != '\0'; i++) {
+      if (islower(completion_text[i])) capitalize = FALSE;
+    }
+    for (i = strlen(completion_text); word_list[n][i] != '\0'; i++) {
+      ch = word_list[n][i];
+      if (capitalize) ch = toupper(ch);
+      SendKeyPressedEvent(ch, 0);
+    }
+  }
+  AddToCompletionText(NoSymbol);
+}
+
+static void PopupCompletionPanel(void)
+{
+  Widget form, label, view;
+  char msg[100];
+
+  if (completion_panel == None) {
+    completion_panel = XtVaCreatePopupShell("completion_panel", transientShellWidgetClass,
+                                       toplevel, NULL);
+    form = XtVaCreateManagedWidget("form", formWidgetClass, completion_panel, NULL);
+    label = XtVaCreateManagedWidget("label", labelWidgetClass, form, NULL);
+    completion_entry = XtVaCreateManagedWidget("entry", labelWidgetClass, form,
+                                   XtNfromHoriz, label, NULL);
+    view = XtVaCreateManagedWidget("view", viewportWidgetClass, form,
+                                   XtNfromVert, label, NULL);
+    completion_list = XtVaCreateManagedWidget("list", listWidgetClass, view, NULL);
+    XtAddCallback(completion_list, XtNcallback, CompletionWordSelected, NULL);
+    XtRealizeWidget(completion_panel);
+    XSetWMProtocols(dpy, XtWindow(completion_panel), &wm_delete_window, 1);
+
+    XtPopup(completion_panel, XtGrabNone);
+    AddToCompletionText(NoSymbol);
+    XFlush(dpy);
+  } else {
+    XtPopup(completion_panel, XtGrabNone);
+  }
+
+  ReadCompletionDictionary();
+
+  sprintf(msg, "%d words in the dictionary", n_completion_words);
+  XtVaSetValues(completion_entry, XtNlabel, msg, NULL);
+
+  completion_text[0] = '\0';
+  n_word_list = 0;
+  word_list[n_word_list] = NULL;
+  XawListChange(completion_list, word_list, 0, 0, TRUE);
+}
+
+/*
+ * Send given string to the focused window as if the string
+ * is typed from a keyboard.
+ */
+static void KeyPressed(Widget w, char *key, char *data);
+
+static void SendString(const unsigned char *str)
+{
+  const unsigned char *cp, *cp2;  /* I remember "unsigned" might be required for some systems */
+  char key[50];
+  int len;
+  int val;
+  Window target_root, child, junk_w;
+  int junk_i;
+  unsigned junk_u;
+  int cur_x, cur_y;
+
+  shift_state = 0;
+  for (cp = str; *cp != '\0'; cp++) {
+    if (0 < appres.text_delay) usleep(appres.text_delay * 1000);
+    if (*cp == '\\') {
+      cp++;
+      switch (*cp) {
+      case '\0':
+        fprintf(stderr, "%s: missing character after \"\\\"\n",
+                PROGRAM_NAME);
+        return;
+      case '[':  /* we can write any keysym as "\[the-keysym]" here */
+        cp2 = strchr(cp, ']');
+        if (cp2 == NULL) {
+          fprintf(stderr, "%s: no closing \"]\" after \"\\[\"\n",
+                  PROGRAM_NAME);
+        } else {
+          len = cp2 - cp - 1;
+          if (sizeof(key) <= len) len = sizeof(key) - 1;
+          strncpy(key, cp + 1, len);
+          key[len] = '\0';
+          KeyPressed(None, key, NULL);
+          cp = cp2;
+        }
+        break;
+      case 'S': shift_state |= ShiftMask; break;
+      case 'C': shift_state |= ControlMask; break;
+      case 'A': shift_state |= alt_mask; break;
+      case 'M': shift_state |= meta_mask; break;
+      case 'b': SendKeyPressedEvent(XK_BackSpace, shift_state); shift_state = 0; break;
+      case 't': SendKeyPressedEvent(XK_Tab, shift_state); shift_state = 0; break;
+      case 'n': SendKeyPressedEvent(XK_Linefeed, shift_state); shift_state = 0; break;
+      case 'r': SendKeyPressedEvent(XK_Return, shift_state); shift_state = 0; break;
+      case 'e': SendKeyPressedEvent(XK_Escape, shift_state); shift_state = 0; break;
+      case 'd': SendKeyPressedEvent(XK_Delete, shift_state); shift_state = 0; break;
+      case 'D':  /* delay */
+       cp++;
+       if ('1' <= *cp && *cp <= '9') {
+         usleep((*cp - '0') * 100000);
+       } else {
+          fprintf(stderr, "%s: no digit after \"\\m\"\n",
+                  PROGRAM_NAME);
+       }
+       break;
+      case 'm':  /* simulate click mouse button */
+       cp++;
+       if ('1' <= *cp && *cp <= '9') {
+         if (appres.debug) fprintf(stderr, "XTestFakeButtonEvent(%d)\n", *cp - '0');
+         XTestFakeButtonEvent(target_dpy, *cp - '0', True, CurrentTime);
+         XTestFakeButtonEvent(target_dpy, *cp - '0', False, CurrentTime);
+         XFlush(dpy);
+       } else {
+          fprintf(stderr, "%s: no digit after \"\\m\"\n",
+                  PROGRAM_NAME);
+       }
+       break;
+      case 'x':
+      case 'y':  /* move mouse pointer */
+       sscanf(cp + 1, "%d", &val);
+       target_root = RootWindow(target_dpy, DefaultScreen(target_dpy));
+       XQueryPointer(target_dpy, target_root, &junk_w, &child,
+                     &cur_x, &cur_y, &junk_i, &junk_i, &junk_u);
+       if (*cp == 'x') {
+         if (isdigit(*(cp + 1))) cur_x = val;
+         else cur_x += val;
+       } else {
+         if (isdigit(*(cp + 1))) cur_y = val;
+         else cur_y += val;
+       }
+       XWarpPointer(target_dpy, None, target_root, 0, 0, 0, 0, cur_x, cur_y);
+       XFlush(dpy);
+       cp++;
+       while (isdigit(*(cp + 1)) || *(cp + 1) == '+' || *(cp + 1) == '-') cp++;
+        break;
+      default:
+       SendKeyPressedEvent(*cp, shift_state);
+       shift_state = 0;
+       break;
+      }
+    } else {
+      SendKeyPressedEvent(*cp, shift_state);
+      shift_state = 0;
+    }
+  }
+}
+
+/*
+ * Send content of the file as if the it is typed from a keyboard.
+ */
+static void SendFileContent(const char *file)
+{
+  FILE *fp;
+  int ch;
+
+  fp = stdin;
+  if (strcmp(file, "-") != 0) fp = fopen(file, "r");
+
+  if (fp == NULL) {
+    fprintf(stderr, "%s: can't read the file: %s\n", PROGRAM_NAME, file);
+    exit(1);
+  }
+  while ((ch = fgetc(fp)) != EOF) {
+    if (0 < appres.text_delay) usleep(appres.text_delay * 1000);
+    if (ch == '\n') {  /* newline - send Return instead */
+      SendKeyPressedEvent(XK_Return, 0);
+    } else if (ch == '\033') {  /* ESC */
+      SendKeyPressedEvent(XK_Escape, 0);
+    } else if (ch == '\177') {  /* DEL */
+      SendKeyPressedEvent(XK_Delete, 0);
+    } else if (1 <= ch && ch <= 26) {  /* Ctrl-x */
+      SendKeyPressedEvent('a' + ch - 1, ControlMask);
+    } else {  /* normal characters */
+      SendKeyPressedEvent(ch, 0);
+    }
+  }
+  if (strcmp(file, "-") != 0) fclose(fp);
+}
+
+/*
+ * Highlight/unhighligh spcified modifier key on the screen.
+ */
+static void Highlight(char *name, Boolean state)
+{
+  char name1[50];
+  Widget w;
+
+  sprintf(name1, "*%s", name);
+  w = XtNameToWidget(toplevel, name1);
+  if (w != None) {
+    if (strstr(name, "Focus") != NULL) {
+      if (target_dpy == dpy)
+        XtVaSetValues(w, XtNbackground, appres.focus_background, NULL);
+      else
+        XtVaSetValues(w, XtNbackground, appres.remote_focus_background, NULL);
+      if (state)
+        XtVaSetValues(w, XtNforeground, appres.highlight_foreground, NULL);
+      else
+        XtVaSetValues(w, XtNforeground, appres.special_foreground, NULL);
+    } else {
+      if (state)
+        XtVaSetValues(w, XtNbackground, appres.highlight_background,
+                      XtNforeground, appres.highlight_foreground, NULL);
+      else
+        XtVaSetValues(w, XtNbackground, appres.special_background,
+                      XtNforeground, appres.special_foreground, NULL);
+    }
+  }
+}
+
+/*
+ * Highlight/unhighligh keys on the screen to reflect the state.
+ */
+static void RefreshShiftState(Boolean force)
+{
+  static Boolean first = TRUE;
+  static int last_shift_state = 0;
+  static int last_mouse_shift = 0;
+  static int last_num_lock_state = FALSE;
+  static Display *last_target_dpy = NULL;
+  static long last_focus = 0;
+  int cur_shift;
+  int changed;
+  int first_row, row, col;
+  Boolean shifted;
+  char *label;
+  int mask;
+
+  cur_shift = shift_state | mouse_shift;
+  changed = cur_shift ^ (last_shift_state | last_mouse_shift);
+  if (first || force) changed = 0xffff;
+
+  if (changed & ShiftMask) {
+    Highlight("Shift_L", cur_shift & ShiftMask);
+    Highlight("Shift_R", cur_shift & ShiftMask);
+  }
+  if (changed & ControlMask) {
+    Highlight("Control_L", cur_shift & ControlMask);
+    Highlight("Control_R", cur_shift & ControlMask);
+  }
+  if (changed & alt_mask) {
+    Highlight("Alt_L", cur_shift & alt_mask);
+    Highlight("Alt_R", cur_shift & alt_mask);
+  }
+  if (changed & meta_mask) {
+    Highlight("Meta_L", cur_shift & meta_mask);
+    Highlight("Meta_R", cur_shift & meta_mask);
+  }
+  if (changed & LockMask) {
+    Highlight("Caps_Lock", cur_shift & LockMask);
+  }
+  if (changed & altgr_mask) {
+    Highlight("Mode_switch", cur_shift & altgr_mask);
+  }
+  if (last_num_lock_state != appres.num_lock_state) {
+    Highlight("Num_Lock", appres.num_lock_state);
+    Highlight("keypad_panel*Num_Lock", appres.num_lock_state);
+  }
+  if (last_target_dpy != target_dpy || last_focus != focused_window) {
+    Highlight("Focus", focused_window != 0);
+    Highlight("keypad*Focus", focused_window != 0);
+    Highlight("keypad_panel*Focus", focused_window != 0);
+    last_target_dpy = target_dpy;
+    last_focus = focused_window;
+  }
+
+  mask = ShiftMask | LockMask | altgr_mask;
+  changed = (shift_state & mask) ^ (last_shift_state & mask);
+  if (first || force) changed = TRUE;
+  if (changed && !appres.keypad_only
+      && (appres.modal_keytop || toplevel_height < appres.modal_threshold)) {
+    first_row = appres.function_key ? 0 : 1;
+    for (row = first_row; row < NUM_KEY_ROWS; row++) {
+      for (col = 0; col < NUM_KEY_COLS; col++) {
+       shifted = (shift_state & ShiftMask);
+       if (key_widgets[row][col] != None) {
+         if ((shift_state & altgr_mask) && altgr_key_labels[row][col] != NULL) {
+           if (shifted && shift_altgr_key_labels[row][col] != NULL)
+             label = shift_altgr_key_labels[row][col];
+           else
+             label = altgr_key_labels[row][col];
+         } else {
+           if ((shift_state & LockMask)
+               && isalpha(keys_normal[row][col][0]) && keys_normal[row][col][1] == '\0')
+             shifted = !shifted;
+           if (shifted && shift_key_labels[row][col] != NULL)
+             label = shift_key_labels[row][col];
+           else
+             label = normal_key_labels[row][col];
+         }
+         if (label == NULL) {
+           fprintf(stderr, "%s: no label for key %d,%d\n", PROGRAM_NAME, row, col);
+           label = "";
+         }
+         if (strcmp(label, "space") == 0) label = "";
+         XtVaSetValues(key_widgets[row][col], XtNlabel, label, NULL);
+       }
+      }
+    }
+  }
+
+  last_shift_state = shift_state;
+  last_mouse_shift = mouse_shift;
+  last_num_lock_state = appres.num_lock_state;
+  first = FALSE;
+
+#ifdef USE_XTEST
+  if (appres.xtest && strlen(appres.positive_modifiers) != 0) {
+    /* modifiers specified in positiveModifiers resouce will be hold down
+       so that it can be used with, for example, mouse operations */
+
+    Window root, child;
+    int root_x, root_y, x, y;
+    unsigned int mask;
+
+    XKeyEvent event;
+
+    event.display = target_dpy;
+    event.window = RootWindow(event.display, DefaultScreen(event.display));
+    event.root = event.window;
+    event.subwindow = None;
+    event.time = CurrentTime;
+    event.x = 1;
+    event.y = 1;
+    event.x_root = 1;
+    event.y_root = 1;
+    event.same_screen = TRUE;
+    event.state = 0;
+
+    XQueryPointer(target_dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask);
+
+    if (strstr(appres.positive_modifiers, "shift") != NULL
+       && (shift_state & ShiftMask) != (mask & ShiftMask)) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Shift_L);
+      event.type = (shift_state & ShiftMask) ? KeyPress : KeyRelease;
+      SendEvent(&event);
+    }
+    if (strstr(appres.positive_modifiers, "control") != NULL
+       && (shift_state & ControlMask) != (mask & ControlMask)) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Control_L);
+      event.type = (shift_state & ControlMask) ? KeyPress : KeyRelease;
+      SendEvent(&event);
+    }
+    if (strstr(appres.positive_modifiers, "alt") != NULL
+       && (shift_state & alt_mask) != (mask & alt_mask)) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Alt_L);
+      event.type = (shift_state & alt_mask) ? KeyPress : KeyRelease;
+      SendEvent(&event);
+    }
+    if (strstr(appres.positive_modifiers, "meta") != NULL
+       && (shift_state & meta_mask) != (mask & meta_mask)) {
+      event.keycode = XKeysymToKeycode(target_dpy, XK_Meta_L);
+      event.type = (shift_state & meta_mask) ? KeyPress : KeyRelease;
+      SendEvent(&event);
+    }
+  }
+#endif
+}
+
+
+/*
+ * This function will be called when mouse button is pressed on a key
+ * on the screen.  Most operation will be performed in KeyPressed()
+ * which will be called as callback for the Command widgets, and we
+ * only need to check which mouse button is pressed here.
+ */
+static unsigned int n_key_repeat;
+
+static void ButtonDownAction(Widget w, XEvent *event, String *pars, Cardinal *n_pars)
+{
+  n_key_repeat = 0;
+
+  switch (event->xbutton.button) {
+  case Button2:
+    mouse_shift |= ControlMask;
+    break;
+  case Button3:
+  case Button4:
+    mouse_shift |= ShiftMask;
+    break;
+  }
+  RefreshShiftState(FALSE);
+}
+
+/*
+ * This function will be called when mouse button is released on a key
+ * on the screen, after callback is called.
+ */
+static void ButtonUpAction(Widget w, XEvent *event, String *pars, Cardinal *n_pars)
+{
+  if (appres.quick_modifiers) {
+    if (n_key_repeat == 1) XtCallCallbacks(w, XtNcallback, NULL);
+  }
+  mouse_shift = 0;
+  RefreshShiftState(FALSE);
+}
+
+/*
+ * Get the geometry of the base window.
+ */
+static char *GetWindowGeometry(Widget w)
+{
+  static char geom[50];
+
+  Position x0, y0;
+  Window root;
+  int x1, y1;
+  unsigned int wd, ht, bd, dp;
+
+  XtVaGetValues(w, XtNx, &x0, XtNy, &y0, NULL);
+  XGetGeometry(dpy, XtWindow(w), &root, &x1, &y1, &wd, &ht, &bd, &dp);
+  sprintf(geom, "%dx%d+%d+%d", wd, ht, (int)(x0 - x1), (int)(y0 - y1));
+
+  return geom;
+}
+
+/*
+ * Set window manager hint.
+ * ("Extended Window Manager Hints", http://standards.freedesktop.org/wm-spec/)
+ */
+static void SetWindowManagerHint(Boolean initial)
+{
+  if (initial) {
+    if (appres.wm_toolbar) {
+      Atom net_wm_window_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+      Atom net_wm_window_type_toolbar = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
+      XChangeProperty(dpy, XtWindow(toplevel),
+         net_wm_window_type, XA_ATOM, 32,
+         PropModeReplace,
+         (unsigned char *) &net_wm_window_type_toolbar, 1);
+      if (appres.debug)
+       fprintf(stderr, "SetWindowManagerHint: set _NET_WM_WINDOW_TYPE_TOOLBAR\n");
+    }
+  }
+
+  if (!initial || appres.always_on_top) {
+    const int net_wm_state_remove = 0;
+    const int net_wm_state_add = 1;
+    Atom net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
+    Atom net_wm_state_above = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
+    XClientMessageEvent ev;
+    ev.type = ClientMessage;
+    ev.display = dpy;
+    ev.window = XtWindow(toplevel);
+    ev.message_type = net_wm_state;
+    ev.format = 32;
+    ev.data.l[0] = appres.always_on_top ? net_wm_state_add : net_wm_state_remove;
+    ev.data.l[1] = net_wm_state_above;
+    ev.data.l[2] = 0;
+    XSendEvent(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+              FALSE, SubstructureNotifyMask | SubstructureRedirectMask,
+              (XEvent *)&ev);
+    if (appres.debug)
+      fprintf(stderr, "SetWindowManagerHint: _NET_WM_STATE_ABOVE = %d\n", ev.data.l[0]);
+  }
+}
+
+/*
+ * Restart the program to (possibly) change the keyboard layout,
+ * by loading the app-default file for the selected "customization".
+ */
+static void LayoutSelected(Widget w, char *key, char *data)
+{
+  static char *env_lang, *env_xenv;
+  char name[50];
+  char customization[30] = "", lang[30] = "C";
+  char *xenv = NULL;
+
+  int i;
+
+  if (key != NULL) {
+    if (strcmp(key, "default") != 0) {
+      sscanf(key, "%29[^/]/%29s", customization, lang);
+      sprintf(name, "XVkbd-%s", customization);
+      xenv = XtResolvePathname(dpy, "app-defaults", name, NULL, NULL, NULL, 0, NULL);
+      if (xenv == NULL) {
+       fprintf(stderr, "%s: app-default file \"%s\" not installed\n",
+               PROGRAM_NAME, name);
+      }
+    }
+
+    env_lang = malloc(strlen("LC_ALL=") + strlen(lang) + 1);
+    sprintf(env_lang, "LC_ALL=%s", lang);
+    putenv(env_lang);
+    if (xenv != NULL) {
+      env_xenv = malloc(strlen("XENVIRONMENT=") + strlen(xenv) + 1);
+      sprintf(env_xenv, "XENVIRONMENT=%s", xenv);
+      putenv(env_xenv);
+    } else if (getenv("XENVIRONMENT") != NULL) {
+      putenv("XENVIRONMENT=");
+    }
+  }
+
+  for (i = 1; i < argc1; i++) {
+    if (strncmp(argv1[i], "-geom", strlen("-geom")) == 0) {
+      if (appres.inherit_geometry) {
+       argv1[i + 1] = GetWindowGeometry(toplevel);
+      } else if (i + 2 == argc1) {
+       argv1[i] = NULL;
+       argc1 = i;
+      }
+      break;
+    }
+  }
+  if (i == argc1 && appres.inherit_geometry) {
+    argv1[argc1++] = "-geometry";
+    argv1[argc1++] = GetWindowGeometry(toplevel);
+    argv1[argc1] = NULL;
+  }
+
+  if (appres.debug) {
+    fprintf(stderr, "XENVIRONMENT=%s, LC_ALL=%s\n", (xenv != NULL) ? xenv : "", lang);
+    fprintf(stderr, "Exec:");
+    for (i = 0; i < argc1; i++) fprintf(stderr, " %s", argv1[i]);
+    fprintf(stderr, "\n");
+  }
+
+  execvp(argv1[0], argv1);
+}
+
+/*
+ * Popup a window to select the (possibly) keyboard layout.
+ * The "XVkbd.customizations" resource will define the list,
+ * such as "default,german,swissgerman,french,latin1,jisx6004/ja".
+ * For example, "german" here will make this program to load
+ * "XVkbd-german" app-default file.  Locale for each configuration
+ * can be specified by putting the locale name after "/".
+ */
+static void PopupLayoutPanel(void)
+{
+  static Widget layout_panel = None;
+
+  char *customizations;
+  char *cp, *cp2;
+  Widget box, button;
+
+  if (layout_panel == None) {
+    layout_panel = XtVaCreatePopupShell("layout_panel", transientShellWidgetClass,
+                                       toplevel, NULL);
+    box = XtVaCreateManagedWidget("box", boxWidgetClass, layout_panel, NULL);
+
+    customizations = XtNewString(appres.customizations);
+    cp = strtok(customizations, " \t,");
+    while (cp != NULL) {
+      cp2 = strchr(cp, '/');
+      if (cp2 != NULL) *cp2 = '\0';  /* temporary remove '/' */
+      button = XtVaCreateManagedWidget(cp, commandWidgetClass, box, NULL);
+      if (cp2 != NULL) *cp2 = '/';
+      XtAddCallback(button, XtNcallback, (XtCallbackProc)LayoutSelected, XtNewString(cp));
+      cp = strtok(NULL, " \t,");
+    }
+    XtRealizeWidget(layout_panel);
+    XSetWMProtocols(dpy, XtWindow(layout_panel), &wm_delete_window, 1);
+
+    XtFree(customizations);
+  }
+
+  XtPopup(layout_panel, XtGrabNone);
+}
+
+/*
+ * Property panel
+ */
+static void SaveFunctionKey(void);  /* forward */
+
+static Widget props_panel = None;
+static Widget autoclick_buttons = None;
+static Widget click_buttons = None;
+static Boolean props_panel_active = FALSE;
+
+static void PropsItemToggled(Widget w, char *key, char *data)
+{
+  Boolean last_wm_toolbar = appres.wm_toolbar;
+
+  if (!props_panel_active) return;
+
+#ifdef USE_XTEST
+  XtVaGetValues(XtNameToWidget(props_panel, "*use_xtest"),
+               XtNstate, &appres.xtest, NULL);
+#endif
+  XtVaGetValues(XtNameToWidget(props_panel, "*quick_modifiers"),
+               XtNstate, &appres.quick_modifiers, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*shift_lock"),
+               XtNstate, &appres.shift_lock, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*altgr_lock"),
+               XtNstate, &appres.altgr_lock, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*modifiers_lock"),
+               XtNstate, &appres.modifiers_lock, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*always_on_top"),
+               XtNstate, &appres.always_on_top, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*wm_toolbar"),
+               XtNstate, &appres.wm_toolbar, NULL);
+  XtVaGetValues(XtNameToWidget(props_panel, "*jump_pointer"),
+               XtNstate, &appres.jump_pointer, NULL);
+
+  appres.key_click_duration = (int)XawToggleGetCurrent(click_buttons);
+  appres.autoclick_delay = (int)XawToggleGetCurrent(autoclick_buttons);
+
+  SaveFunctionKey();
+  SetWindowManagerHint(FALSE);
+
+  if (appres.wm_toolbar != last_wm_toolbar) LayoutSelected(None, NULL, NULL);
+}
+
+static void PropsSetState(void)
+{
+#ifdef USE_XTEST
+  XtVaSetValues(XtNameToWidget(props_panel, "*use_xtest"),
+               XtNstate, appres.xtest, NULL);
+#endif
+  XtVaSetValues(XtNameToWidget(props_panel, "*quick_modifiers"),
+               XtNstate, appres.quick_modifiers, NULL);
+  XtVaSetValues(XtNameToWidget(props_panel, "*shift_lock"),
+               XtNstate, appres.shift_lock, NULL);
+  if (XtNameToWidget(toplevel, "*Mode_switch") == None) {
+    XtSetSensitive(XtNameToWidget(props_panel, "*altgr_lock"), FALSE);
+    XtVaSetValues(XtNameToWidget(props_panel, "*altgr_lock"),
+                 XtNstate, FALSE, NULL);
+  } else {
+    XtVaSetValues(XtNameToWidget(props_panel, "*altgr_lock"),
+                 XtNstate, appres.altgr_lock, NULL);
+  }
+  XtVaSetValues(XtNameToWidget(props_panel, "*modifiers_lock"),
+               XtNstate, appres.modifiers_lock, NULL);
+  XtVaSetValues(XtNameToWidget(props_panel, "*always_on_top"),
+               XtNstate, appres.always_on_top, NULL);
+  XtVaSetValues(XtNameToWidget(props_panel, "*wm_toolbar"),
+               XtNstate, appres.wm_toolbar, NULL);
+
+  XtVaSetValues(XtNameToWidget(props_panel, "*jump_pointer"),
+               XtNstate, appres.jump_pointer, NULL);
+
+  XawToggleSetCurrent(click_buttons, (XtPointer)appres.key_click_duration);
+  XawToggleSetCurrent(autoclick_buttons, (XtPointer)appres.autoclick_delay);
+}
+
+static void ClosePropsPanel(void)
+{
+  XtPopdown(props_panel);
+  XFlush(dpy);
+
+  SaveFunctionKey();
+  if (completion_panel != None) XtPopdown(completion_panel);
+}
+
+static void PopupPropsPanel(void)
+{
+  static char *props_items[] = {
+    "quick_modifiers",
+    "shift_lock", "altgr_lock", "modifiers_lock",
+    "always_on_top",
+    "wm_toolbar",
+#ifdef USE_XTEST
+    "use_xtest",
+#endif
+    "jump_pointer",
+  };
+
+  if (props_panel == None) {
+    Widget label, button;
+    Widget form, w;
+    int i;
+    int val;
+
+    props_panel = XtVaCreatePopupShell("props_panel", transientShellWidgetClass,
+                                      toplevel, NULL);
+    form = XtVaCreateManagedWidget("form", formWidgetClass, props_panel, NULL);
+
+    w = None;
+    for (i = 0; i < XtNumber(props_items); i++) {
+      w = XtVaCreateManagedWidget(props_items[i], toggleWidgetClass,
+                                 form, XtNfromVert, w, NULL);
+      XtAddCallback(w, XtNcallback, (XtCallbackProc)PropsItemToggled,
+                   (XtPointer)props_items[i]);
+    }
+
+    label = XtVaCreateManagedWidget("click", labelWidgetClass,
+                                   form, XtNfromVert, w, NULL);
+    button = XtVaCreateManagedWidget("OFF", toggleWidgetClass,
+                                    form, XtNfromVert, w, XtNfromHoriz, label,
+                                    XtNwidth, 0, XtNhorizDistance, 0, NULL);
+    XtVaSetValues(button, XtNradioGroup, button, XtNradioData, (XtPointer)0, NULL);
+    XtAddCallback(button, XtNcallback, (XtCallbackProc)PropsItemToggled,
+                 (XtPointer)0);
+    click_buttons = button;
+    for (val = 1; val <= 50; val *= 2) {
+      char s1[10];
+      sprintf(s1, "%dms", val);
+      button = XtVaCreateManagedWidget(s1, toggleWidgetClass,
+                              form, XtNfromVert, w, XtNfromHoriz, button,
+                              XtNradioData, (XtPointer)val,
+                              XtNradioGroup, click_buttons,
+                              XtNwidth, 0, XtNhorizDistance, 0, NULL);
+      XtAddCallback(button, XtNcallback, (XtCallbackProc)PropsItemToggled,
+                   NULL);
+    }
+
+    w = label;
+    label = XtVaCreateManagedWidget("autoclick", labelWidgetClass,
+                                   form, XtNfromVert, w, NULL);
+    button = XtVaCreateManagedWidget("OFF", toggleWidgetClass,
+                                    form, XtNfromVert, w, XtNfromHoriz, label,
+                                    XtNwidth, 0, XtNhorizDistance, 0, NULL);
+    XtVaSetValues(button, XtNradioGroup, button, XtNradioData, (XtPointer)0, NULL);
+    XtAddCallback(button, XtNcallback, (XtCallbackProc)PropsItemToggled,
+                 (XtPointer)0);
+    autoclick_buttons = button;
+    for (val = 500; val <= 1000; val += 100) {
+      char s1[10];
+      sprintf(s1, "%dms", val);
+      button = XtVaCreateManagedWidget(s1, toggleWidgetClass,
+                              form, XtNfromVert, w, XtNfromHoriz, button,
+                              XtNradioData, (XtPointer)val,
+                              XtNradioGroup, autoclick_buttons,
+                              XtNwidth, 0, XtNhorizDistance, 0, NULL);
+      XtAddCallback(button, XtNcallback, (XtCallbackProc)PropsItemToggled,
+                   (XtPointer)val);
+    }
+
+    w = label;
+    label = XtVaCreateManagedWidget("dict_entry_label", labelWidgetClass,
+                                   form, XtNfromVert, w, NULL);
+    props_dict_entry = XtVaCreateManagedWidget("dict_entry", asciiTextWidgetClass, form,
+                                         XtNfromVert, w, XtNfromHoriz, label,
+                                         XtNuseStringInPlace, True,
+                                         XtNstring, dict_filename,
+                                         XtNeditType, XawtextEdit,
+                                         XtNlength, sizeof(dict_filename) - 1,
+                                         NULL);
+    button = XtVaCreateManagedWidget("dict_default_button", commandWidgetClass,
+                            form, XtNfromVert, w, XtNfromHoriz, props_dict_entry,
+                            NULL);
+    XtAddCallback(button, XtNcallback, (XtCallbackProc)SetDefaultDictionary, NULL);
+    
+
+    w = XtVaCreateManagedWidget("dismiss", commandWidgetClass, form,
+                               XtNfromVert, label, NULL);
+    XtAddCallback(w, XtNcallback, (XtCallbackProc)ClosePropsPanel, NULL);
+
+    XtRealizeWidget(props_panel);
+    XSetWMProtocols(dpy, XtWindow(props_panel), &wm_delete_window, 1);
+  }
+  XtPopup(props_panel, XtGrabNone);
+  PropsSetState();
+
+  props_panel_active = TRUE;
+
+  if (completion_panel != None) XtPopdown(completion_panel);
+}
+
+/*
+ * Callback for main menu (activated from "xvkbd" logo).
+ */
+static Widget about_panel = None;
+static Widget keypad_panel = None;
+static Widget sun_fkey_panel = None;
+static Widget deadkey_panel = None;
+static Widget display_panel = None;
+static Widget display_status = None;
+
+#define DISPLAY_NAME_LENGTH 50
+
+static void OpenRemoteDisplay(Widget w, char *display_name, char *data)
+{
+  static char name[DISPLAY_NAME_LENGTH + 10];
+  char *cp;
+
+  focused_window = None;
+  focused_subwindow = None;
+  if (target_dpy != NULL && target_dpy != dpy) XCloseDisplay(target_dpy);
+
+  strncpy(name, (display_name == NULL) ? "" : display_name, sizeof(name));
+  for (cp = name; isascii(*cp) && isprint(*cp); cp++) ;
+  *cp = '\0';
+
+  if (strlen(name) == 0) {
+    target_dpy = dpy;
+    XtVaSetValues(display_status, XtNlabel, "Disconnected - local display selected", NULL);
+    XtPopdown(display_panel);
+  } else {
+    if (strchr(name, ':') == NULL) strcat(name, ":0");
+    target_dpy = XOpenDisplay(name);
+    if (target_dpy == NULL) {
+      XtVaSetValues(display_status, XtNlabel, "Couldn't connect to the display", NULL);
+      target_dpy = dpy;
+      XBell(dpy, 0);
+    } else {
+      XtVaSetValues(display_status, XtNlabel, "Connected", NULL);
+      XtPopdown(display_panel);
+    }
+  }
+
+  ReadKeymap();
+  if (!altgr_mask && appres.auto_add_keysym) AddModifier(XK_Mode_switch);
+
+  RefreshMainMenu();
+  RefreshShiftState(FALSE);
+}
+
+static void MenuSelected(Widget w, char *key)
+{
+  Widget form;
+  
+  if (strcmp(key, "man") == 0) {
+    if (!appres.secure) system(appres.show_manual_command);
+  } else if (strcmp(key, "about") == 0) {
+    if (about_panel == None) {
+      about_panel = XtVaCreatePopupShell("about_panel", transientShellWidgetClass,
+                                         toplevel, NULL);
+      XtVaCreateManagedWidget("message", labelWidgetClass, about_panel,
+                             XtNlabel, appres.description, NULL);
+      XtRealizeWidget(about_panel);
+      XSetWMProtocols(dpy, XtWindow(about_panel), &wm_delete_window, 1);
+    }
+    XtPopup(about_panel, XtGrabNone);
+  } else if (strcmp(key, "keypad") == 0) {
+    if (keypad_panel == None) {
+      keypad_panel = XtVaCreatePopupShell("keypad_panel", transientShellWidgetClass,
+                                         toplevel, NULL);
+      form = XtVaCreateManagedWidget("form", formWidgetClass, keypad_panel, NULL);
+      MakeKeypad(form, None, None);
+      XtRealizeWidget(keypad_panel);
+      XSetWMProtocols(dpy, XtWindow(keypad_panel), &wm_delete_window, 1);
+    }
+    XtPopup(keypad_panel, XtGrabNone);
+  } else if (strcmp(key, "sun_fkey") == 0) {
+    if (sun_fkey_panel == None) {
+      sun_fkey_panel = XtVaCreatePopupShell("sun_fkey_panel", transientShellWidgetClass,
+                                         toplevel, NULL);
+      form = XtVaCreateManagedWidget("form", formWidgetClass, sun_fkey_panel, NULL);
+      MakeSunFunctionKey(form, None, None);
+      XtRealizeWidget(sun_fkey_panel);
+      XSetWMProtocols(dpy, XtWindow(sun_fkey_panel), &wm_delete_window, 1);
+    }
+    XtPopup(sun_fkey_panel, XtGrabNone);
+  } else if (strcmp(key, "deadkey") == 0) {
+    if (deadkey_panel == None) {
+      deadkey_panel = XtVaCreatePopupShell("deadkey_panel", transientShellWidgetClass,
+                                         toplevel, NULL);
+      form = XtVaCreateManagedWidget("form", formWidgetClass, deadkey_panel, NULL);
+      MakeDeadkeyPanel(form);
+      XtRealizeWidget(deadkey_panel);
+      XSetWMProtocols(dpy, XtWindow(deadkey_panel), &wm_delete_window, 1);
+    }
+    XtPopup(deadkey_panel, XtGrabNone);
+  } else if (strcmp(key, "completion") == 0) {
+    PopupCompletionPanel();
+  } else if (strcmp(key, "select_layout") == 0) {
+    PopupLayoutPanel();
+  } else if (strcmp(key, "edit_fkey") == 0) {
+    PopupFunctionKeyEditor();
+  } else if (strcmp(key, "show_keypad") == 0
+            || strcmp(key, "show_functionkey") == 0) {
+    if (strcmp(key, "show_keypad") == 0) appres.keypad = !appres.keypad;
+    else appres.function_key = !appres.function_key;
+    MakeKeyboard(TRUE);
+  } else if (strcmp(key, "props") == 0) {
+    PopupPropsPanel();
+  } else if (strcmp(key, "open_display") == 0) {
+    if (display_panel == None) {
+      Widget label, entry, button;
+      static char display_name[DISPLAY_NAME_LENGTH] = "";
+      display_panel = XtVaCreatePopupShell("display_panel", transientShellWidgetClass,
+                                         toplevel, NULL);
+      form = XtVaCreateManagedWidget("form", formWidgetClass, display_panel, NULL);
+      label = XtVaCreateManagedWidget("label", labelWidgetClass, form, NULL);
+      entry = XtVaCreateManagedWidget("entry", asciiTextWidgetClass, form,
+                                     XtNfromHoriz, label,
+                                     XtNuseStringInPlace, True,
+                                     XtNeditType, XawtextEdit,
+                                     XtNstring, display_name,
+                                     XtNlength, sizeof(display_name) - 1,
+                                     NULL);
+
+      button = XtVaCreateManagedWidget("ok", commandWidgetClass, form,
+                                      XtNfromHoriz, entry, NULL);
+      XtAddCallback(button, XtNcallback, (XtCallbackProc)OpenRemoteDisplay, (XtPointer)display_name);
+
+      display_status = XtVaCreateManagedWidget("status", labelWidgetClass, form,
+                                              XtNfromVert, label,
+                                              XtNlabel, "", NULL);
+      XtRealizeWidget(display_panel);
+      XSetWMProtocols(dpy, XtWindow(display_panel), &wm_delete_window, 1);
+
+      XtSetKeyboardFocus(display_panel, entry);
+    }
+    XtPopup(display_panel, XtGrabNone);
+  } else if (strcmp(key, "close_display") == 0) {
+    OpenRemoteDisplay(None, NULL, NULL);
+  } else if (strcmp(key, "quit") == 0) {
+    DeleteWindowProc(None, NULL, NULL, NULL);
+  }
+}
+
+static void ClosePopupPanel(Widget w)
+{
+  if (w == keypad_panel) {
+    XtDestroyWidget(w);
+    keypad_panel = None;
+  } else if (w == props_panel) {
+    ClosePropsPanel();
+  } else {
+    XtPopdown(w);
+  }
+}
+
+/*
+ * Iconify/uniconify the xvkbd window even if window manager is not
+ * available.
+ */
+static void IconifyWindow(Widget w, Boolean iconify)
+{
+  static Widget iconified_window = None;
+  static Widget uniconify_button = None;
+  static Position x0, y0;
+  static int x1, y1;
+  static unsigned int wd, ht, bd, dp;
+
+  if (iconify) {
+    Window root;
+    int i;
+
+    XUnmapWindow(dpy, XtWindow(toplevel));
+
+    if (iconified_window == None) {
+      Widget box;
+
+      iconified_window = XtVaCreatePopupShell("iconified_window", transientShellWidgetClass,
+                                             toplevel, XtNoverrideRedirect, TRUE, NULL);
+      box = XtVaCreateManagedWidget("form", boxWidgetClass, iconified_window, NULL);
+      uniconify_button = XtVaCreateManagedWidget("uniconify_button", commandWidgetClass, box,
+                                                XtNbitmap, xvkbd_pixmap,
+                                                XtNhorizDistance, 10, XtNvertDistance, 0,
+                                                NULL);
+      XtAddCallback(uniconify_button, XtNcallback, (XtCallbackProc)IconifyWindow, FALSE);
+
+      XtRealizeWidget(iconified_window);
+      XSetWMProtocols(dpy, XtWindow(iconified_window), &wm_delete_window, 1);
+    }
+
+    XtVaGetValues(toplevel, XtNx, &x0, XtNy, &y0, NULL);
+    XGetGeometry(dpy, XtWindow(toplevel), &root, &x1, &y1, &wd, &ht, &bd, &dp);
+
+    XMoveResizeWindow(dpy, XtWindow(iconified_window), x0 + bd, y0 + bd, wd, ht);
+    XtPopup(iconified_window, XtGrabNone);
+    for (i = 9; 0 < i; i--) {
+      Dimension btn_wd, btn_ht;
+      Dimension wd1, ht1;
+
+      wd1 = wd * i / 10;
+      ht1 = ht * i / 10;
+      XtVaGetValues(uniconify_button, XtNwidth, &btn_wd, XtNheight, &btn_ht, NULL);
+      if (i == 1 || wd1 < btn_wd) wd1 = btn_wd;
+      if (i == 1 || ht1 < btn_ht) ht1 = btn_ht;
+      XMoveResizeWindow(dpy, XtWindow(iconified_window), x0 + bd, y0 + (ht - ht1) + bd, wd1, ht1);
+      XFlush(dpy);
+      usleep(10000);
+    }
+  } else {
+    if (iconified_window != None) XtPopdown(iconified_window);
+    XMapWindow(dpy, XtWindow(toplevel));
+  }
+}
+
+static void SignalUser1(void)
+{
+  XWindowAttributes attr;
+  XGetWindowAttributes(dpy, XtWindow(toplevel), &attr);
+  IconifyWindow(None, attr.map_state != IsUnmapped);
+  XSync(dpy, FALSE);
+}
+
+/*
+ * This will be called when user pressed a key on the screen.
+ */
+static const char *FindFunctionKeyValue(const char *key, Boolean shiftable);
+static void ShowBalloon(Widget w, XEvent *event, String *pars, Cardinal *n_pars);
+static void KeyClick(void);
+static void StopAutoclick(void);
+
+static void KeyPressed(Widget w, char *key, char *data)
+{
+  int row, col;
+  int cur_shift;
+  char *key1;
+  KeySym keysym;
+  Boolean shifted;
+  const char *value;
+  Boolean found;
+
+  if (appres.debug) fprintf(stderr, "KeyPressed: key=%s, widget=%lx\n", key, (long)w);
+
+  value = FindFunctionKeyValue(key, TRUE);
+  if (value != NULL) {
+    if (appres.debug) fprintf(stderr, "Assigned string: %s\n", value);
+    if (value[0] == '!') {
+      if (appres.debug) fprintf(stderr, "Launching: %s\n", value + 1);
+      if (!appres.secure) system(value + 1);
+    } else {
+      if (value[0] == '\\') value = value + 1;
+      if (appres.debug) fprintf(stderr, "Sending: %s\n", value);
+      SendString(value);
+    }
+    ShowBalloon(w, NULL, NULL, NULL);
+    return;
+  }
+
+  if (strncmp(key, "Shift", strlen("Shift")) == 0) {
+    if (shift_state & ShiftMask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= ShiftMask;
+  } else if (strncmp(key, "Control", strlen("Control")) == 0) {
+    if (shift_state & ControlMask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= ControlMask;
+  } else if (strncmp(key, "Alt", strlen("Alt")) == 0) {
+    if (shift_state & alt_mask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= alt_mask;
+  } else if (strncmp(key, "Meta", strlen("Meta")) == 0) {
+    if (shift_state & meta_mask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= meta_mask;
+  } else if (strcmp(key, "Caps_Lock") == 0) {
+    if (shift_state & LockMask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= LockMask;
+  } else if (strcmp(key, "Mode_switch") == 0) {
+    if (shift_state & altgr_mask) SendKeyPressedEvent(NoSymbol, shift_state);
+    shift_state ^= altgr_mask;
+  } else if (strcmp(key, "Num_Lock") == 0) {
+    appres.num_lock_state = !appres.num_lock_state;
+  } else if (strcmp(key, "Focus") == 0) {
+    cur_shift = shift_state | mouse_shift;
+    if (cur_shift & ShiftMask) {
+      focused_window = None;
+      focused_subwindow = None;
+    } else {
+      GetFocusedWindow();
+    }
+  } else {
+    if (appres.quick_modifiers && mouse_shift == 0 && w != None) {
+      Window junk_w;
+      int junk_i;
+      unsigned junk_u;
+      int cur_x, cur_y;
+      Dimension btn_wd, btn_ht;
+
+      n_key_repeat = n_key_repeat + 1;
+      if (n_key_repeat == 1) return;
+
+      XtVaGetValues(w, XtNwidth, &btn_wd, XtNheight, &btn_ht, NULL);
+      XQueryPointer(dpy, XtWindow(w), &junk_w, &junk_w,
+                   &junk_i, &junk_i, &cur_x, &cur_y, &junk_u);
+
+      mouse_shift = 0;
+      if (cur_x < 0 && btn_ht < cur_y) {
+       mouse_shift |= alt_mask;  /* left-down */
+      } else {
+       if (cur_y < 0) mouse_shift |= ShiftMask;  /* up */
+       else if (btn_ht < cur_y) mouse_shift |= meta_mask;  /* down */
+       if (cur_x < 0) mouse_shift |= ControlMask;  /* left */
+       else if (btn_wd < cur_x) mouse_shift |= altgr_mask;  /* right */
+      }
+    }
+    cur_shift = shift_state | mouse_shift;
+    shifted = (cur_shift & ShiftMask);
+    key1 = key;
+    if (w != None) {
+      if (sscanf(key, "pad%d,%d", &row, &col) == 2) {
+       if (appres.num_lock_state) shifted = !shifted;
+       key1 = shifted ? keypad_shift[row][col]: keypad[row][col];
+      } else {
+       found = FALSE;
+       if (sscanf(key, "%d,%d", &row, &col) == 2) {
+         found = TRUE;
+       } else if (w != None) {
+         int first_row = appres.function_key ? 0 : 1;
+         for (row = first_row; row < NUM_KEY_ROWS; row++) {
+           for (col = 0; col < NUM_KEY_COLS; col++) {
+             if (key_widgets[row][col] == w) {
+               found = TRUE;
+               break;
+             }
+           }
+           if (col < NUM_KEY_COLS) break;
+         }
+       }
+       if (found) {
+         if ((cur_shift & LockMask)
+             && isalpha(keys_normal[row][col][0]) && keys_normal[row][col][1] == '\0')
+           shifted = !shifted;
+         if ((cur_shift & altgr_mask) && keys_altgr[row][col] != NULL) {
+           if (shifted && keys_shift_altgr[row][col] != NULL) {
+             key1 = keys_shift_altgr[row][col];
+             if (strcmp(keys_altgr[row][col], keys_shift_altgr[row][col]) != 0)
+               cur_shift &= ~ShiftMask;
+           } else {
+             key1 = keys_altgr[row][col];
+           }
+         } else {
+           if (shifted && keys_shift[row][col] != NULL) {
+             key1 = keys_shift[row][col];
+             if (strcmp(keys_normal[row][col], keys_shift[row][col]) != 0)
+               cur_shift &= ~ShiftMask;
+           } else {
+             key1 = keys_normal[row][col];
+           }
+         }
+       }  /* if (found) ... */
+      }  /* if (sscanf(key, "pad%d,%d", ... */
+    }  /* if (w != None) ... */
+    if (strlen(key1) == 1) {
+      SendKeyPressedEvent((KeySym)*key1 & 0xff, cur_shift);
+      AddToCompletionText((KeySym)*key1);
+    } else {
+      if (islower(key1[0]) && key1[1] == ':') {
+       switch (key1[0]) {
+       case 's': cur_shift |= ShiftMask; break;
+       case 'c': cur_shift |= ControlMask; break;
+       case 'a': cur_shift |= alt_mask; break;
+       case 'm': cur_shift |= meta_mask; break;
+       default: fprintf(stderr, "%s: unknown modidier: %s\n",
+                        PROGRAM_NAME, key1); break;
+       }
+       key1 = key1 + 2;
+      }
+      keysym = XStringToKeysym(key1);
+      if ((!appres.keypad_keysym && strncmp(key1, "KP_", 3) == 0)
+         || XKeysymToKeycode(target_dpy, keysym) == NoSymbol) {
+       switch ((unsigned)keysym) {
+       case XK_KP_Equal: keysym = XK_equal; break;
+       case XK_KP_Divide: keysym = XK_slash; break;
+       case XK_KP_Multiply: keysym = XK_asterisk; break;
+       case XK_KP_Add: keysym = XK_plus; break;
+       case XK_KP_Subtract: keysym = XK_minus; break;
+       case XK_KP_Enter: keysym = XK_Return; break;
+       case XK_KP_1: keysym = XK_1; break;
+       case XK_KP_2: keysym = XK_2; break;
+       case XK_KP_3: keysym = XK_3; break;
+       case XK_KP_4: keysym = XK_4; break;
+       case XK_KP_5: keysym = XK_5; break;
+       case XK_KP_6: keysym = XK_6; break;
+       case XK_KP_7: keysym = XK_7; break;
+       case XK_KP_8: keysym = XK_8; break;
+       case XK_KP_9: keysym = XK_9; break;
+       case XK_Shift_L: keysym = XK_Shift_R; break;
+       case XK_Shift_R: keysym = XK_Shift_L; break;
+       case XK_Control_L: keysym = XK_Control_R; break;
+       case XK_Control_R: keysym = XK_Control_L; break;
+       case XK_Alt_L: keysym = XK_Alt_R; break;
+       case XK_Alt_R: keysym = XK_Alt_L; break;
+       case XK_Meta_L: keysym = XK_Meta_R; break;
+       case XK_Meta_R: keysym = XK_Meta_L; break;
+       default:
+         if (keysym == NoSymbol || !appres.auto_add_keysym)
+           fprintf(stderr, "%s: no such key: %s\n",
+                   PROGRAM_NAME, key1); break;
+       }
+      }
+      SendKeyPressedEvent(keysym, cur_shift);
+      AddToCompletionText(keysym);
+
+      if ((cur_shift & ControlMask) && (cur_shift & alt_mask)) {
+        if (strstr(XServerVendor(dpy), "XFree86") != NULL) {
+          if (strcmp(key1, "KP_Add") == 0) {
+            if (!appres.secure) system("xvidtune -next");
+          } else if (strcmp(key1, "KP_Subtract") == 0) {
+            if (!appres.secure) system("xvidtune -prev");
+          }
+        }
+      }
+    }
+    if (!appres.shift_lock)
+      shift_state &= ~ShiftMask;
+    if (!appres.modifiers_lock)
+      shift_state &= ~(ControlMask | alt_mask | meta_mask);
+    if (!appres.altgr_lock)
+      shift_state &= ~altgr_mask;
+  }
+  RefreshShiftState(FALSE);
+
+  if (w != None) {
+    KeyClick();
+/*     StopAutoclick(); */
+  }
+}
+
+/*
+ * Redefine keyboard layout.
+ * "spec" is a sequence of words separated with spaces, and it is
+ * usally specified in app-defaults file, as:
+ * 
+ *   xvkbd.AltGrKeys: \
+ *      F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 BackSpace \n\
+ *      Escape \271 \262 \263 \243 \254 \251 { [ ] } \\ ' ^ ' \n\
+ *      ...
+ *
+ * White spaces separate the keys, and " \n" (note that white space
+ * before the \n) separate the rows of keys.
+ */
+static void RedefineKeys(char *array[NUM_KEY_ROWS][NUM_KEY_COLS], const char *spec)
+{
+  char *s = XtNewString(spec);
+  char *cp;
+  int row, col;
+  int key_rows = NUM_KEY_ROWS;
+  int key_cols = NUM_KEY_COLS;
+
+  for (row = 0; row < key_rows; row++) {
+    for (col = 0; col < key_cols; col++) array[row][col] = NULL;
+  }
+  row = 0;
+  col = 0;
+  cp = strtok(s, " ");
+  while (cp != NULL) {
+    if (*cp == '\n') {
+      row = row + 1;
+      col = 0;
+      cp = cp + 1;
+    }
+    if (*cp != '\0') {
+      if (key_rows <= row) {
+        fprintf(stderr, "%s: too many key rows: \"%s\" ignored\n",
+                PROGRAM_NAME, cp);
+      } else if (key_cols <= col) {
+        fprintf(stderr, "%s: too many keys in a row: \"%s\" ignored\n",
+                PROGRAM_NAME, cp);
+      } else {
+        array[row][col] = XtNewString(cp);
+        col = col + 1;
+      }
+    }
+    cp = strtok(NULL, " ");
+  }
+  XtFree(s);
+}
+
+/*
+ * Create keyboard on the screen.
+ */
+static Widget MakeKey(Widget parent, const char *name, const char *label, Pixel color)
+{
+  static Pixmap up_pixmap = None;
+  static Pixmap down_pixmap = None;
+  static Pixmap left_pixmap = None;
+  static Pixmap right_pixmap = None;
+  static Pixmap back_pixmap = None;
+  Widget w;
+  Window scr = RootWindow(dpy, DefaultScreen(dpy));
+  char str[50];
+  int len;
+
+  if (!appres.auto_repeat
+      || strncmp(name, "Shift", strlen("Shift")) == 0
+      || strncmp(name, "Control", strlen("Control")) == 0
+      || strncmp(name, "Alt", strlen("Alt")) == 0
+      || strncmp(name, "Meta", strlen("Meta")) == 0
+      || strcmp(name, "Caps_Lock") == 0
+      || strcmp(name, "Mode_switch") == 0
+      || strcmp(name, "Num_Lock") == 0
+      || strcmp(name, "Focus") == 0) {
+    w = XtVaCreateManagedWidget(name, commandWidgetClass, parent,
+                                XtNbackground, color, NULL);
+  } else {
+    w = XtVaCreateManagedWidget(name, repeaterWidgetClass, parent,
+                                XtNbackground, color, NULL);
+  }
+  XtAddCallback(w, XtNcallback, (XtCallbackProc)KeyPressed, (XtPointer)name);
+
+  if (label != NULL) {
+    strncpy(str, label, sizeof(str) - 1);
+    if (strcmp(str, "space") == 0) strcpy(str, "");
+    len = strlen(str);
+    if (3 <= len) {
+      if (str[1] == '_') str[1] = ' ';
+      if (str[len - 2] == '_') str[len - 2] = ' ';
+    }
+    XtVaSetValues(w, XtNlabel, str, NULL);
+
+    if (strcmp(label, "up") == 0) {
+      if (up_pixmap == None)
+        up_pixmap = XCreateBitmapFromData(dpy, scr,
+                                (char *)up_bits, up_width, up_height);
+      XtVaSetValues(w, XtNbitmap, up_pixmap, NULL);
+    } else if (strcmp(label, "down") == 0) {
+      if (down_pixmap == None)
+        down_pixmap = XCreateBitmapFromData(dpy, scr,
+                                (char *)down_bits, down_width, down_height);
+      XtVaSetValues(w, XtNbitmap, down_pixmap, NULL);
+    } else if (strcmp(label, "left") == 0) {
+      if (left_pixmap == None)
+        left_pixmap = XCreateBitmapFromData(dpy, scr,
+                                (char *)left_bits, left_width, left_height);
+      XtVaSetValues(w, XtNbitmap, left_pixmap, NULL);
+    } else if (strcmp(label, "right") == 0) {
+      if (right_pixmap == None)
+        right_pixmap = XCreateBitmapFromData(dpy, scr,
+                                (char *)right_bits, right_width, right_height);
+      XtVaSetValues(w, XtNbitmap, right_pixmap, NULL);
+    } else if (strcmp(label, "back") == 0) {
+      if (back_pixmap == None)
+        back_pixmap = XCreateBitmapFromData(dpy, scr,
+                                (char *)back_bits, back_width, back_height);
+      XtVaSetValues(w, XtNbitmap, back_pixmap, NULL);
+    }
+  }
+
+  return w;
+}
+
+static void MakeKeypad(Widget form, Widget from_vert, Widget from_horiz)
+{
+  Widget key, left, upper;
+  Pixel color;
+  XFontStruct *font;
+  int row, col;
+  Widget keypad_box;
+  Widget keypad_row[NUM_KEYPAD_ROWS];
+  char name[50];
+
+  keypad_box = XtVaCreateManagedWidget("keypad", formWidgetClass, form, NULL);
+  if (from_horiz != None)
+    XtVaSetValues(keypad_box, XtNfromHoriz, from_horiz, NULL);
+  else
+    XtVaSetValues(keypad_box, XtNhorizDistance, 0, NULL);
+  if (from_vert != None)
+    XtVaSetValues(keypad_box, XtNfromVert, from_vert, NULL);
+  else
+    XtVaSetValues(keypad_box, XtNvertDistance, 0, NULL);
+  upper = None;
+  for (row = 0; row < NUM_KEYPAD_ROWS; row++) {
+    left = None;
+    for (col = 0; keypad[row][col] != NULL; col++) {
+      font = appres.keypad_font;
+      if (strlen(keypad_label[row][col]) == 1) font = appres.letter_font;
+      color = appres.special_background;
+      if (strcmp(keypad[row][col], "Focus") == 0)
+       color = appres.focus_background;
+      else if (strcmp(keypad_shift[row][col], ".") == 0
+              || (strncmp(keypad_shift[row][col], "KP_", 3) == 0
+                  && isdigit(keypad_shift[row][col][3])))
+       color = appres.general_background;
+      strcpy(name, keypad[row][col]);
+      if (strcmp(name, "Focus") != 0 && strcmp(name, "Num_Lock") != 0)
+       sprintf(name, "pad%d,%d", row, col);
+      key = MakeKey(keypad_box, XtNewString(name),
+                   keypad_label[row][col], color);
+      XtVaSetValues(key, XtNfont, font, NULL);
+      if (row != 0)
+       XtVaSetValues(key, XtNfromVert, keypad_row[row - 1], NULL);
+      if (left != None)
+       XtVaSetValues(key, XtNfromHoriz, left, NULL);
+      if (col == 0)
+       keypad_row[row] = key;
+      left = key;
+    }
+  }
+}
+
+static void MakeSunFunctionKey(Widget form, Widget from_vert, Widget from_horiz)
+{
+  Widget key, left, upper;
+  int row, col;
+  Widget fkey_box;
+  Widget fkey_row[NUM_SUN_FKEY_ROWS];
+
+  fkey_box = XtVaCreateManagedWidget("fkey", formWidgetClass, form, NULL);
+  if (from_horiz != None)
+    XtVaSetValues(fkey_box, XtNfromHoriz, from_horiz, NULL);
+  else
+    XtVaSetValues(fkey_box, XtNhorizDistance, 0, NULL);
+  if (from_vert != None)
+    XtVaSetValues(fkey_box, XtNfromVert, from_vert, NULL);
+  else
+    XtVaSetValues(fkey_box, XtNvertDistance, 0, NULL);
+  upper = None;
+  for (row = 0; row < NUM_SUN_FKEY_ROWS; row++) {
+    left = None;
+    for (col = 0; sun_fkey[row][col] != NULL; col++) {
+      key = MakeKey(fkey_box, sun_fkey[row][col],
+                   sun_fkey_label[row][col], appres.special_background);
+      XtVaSetValues(key, XtNfont, appres.keypad_font, NULL);
+      if (row != 0)
+       XtVaSetValues(key, XtNfromVert, fkey_row[row - 1], NULL);
+      if (left != None)
+       XtVaSetValues(key, XtNfromHoriz, left, NULL);
+      if (col == 0)
+       fkey_row[row] = key;
+      left = key;
+    }
+  }
+}
+
+static void MakeDeadkeyPanel(Widget form)
+{
+  Widget deadkey_box, left, key;
+  char *deadkeys, *cp, *cp2;
+
+  deadkeys = XtNewString(appres.deadkeys);
+
+  deadkey_box = XtVaCreateManagedWidget("deadkey", formWidgetClass, form, NULL);
+  left = None;
+  cp = strtok(deadkeys, " \t,");
+  while (cp != NULL) {
+    cp2 = XtNewString(cp);
+    key = MakeKey(deadkey_box, cp2, NULL, appres.general_background);
+    if (left != None) XtVaSetValues(key, XtNfromHoriz, left, NULL);
+    left = key;
+    cp = strtok(NULL, " \t,");
+  }
+  XtFree(deadkeys);
+}
+
+static void RefreshMainMenu(void)
+{
+  static Pixmap check_pixmap = None;
+
+  if (check_pixmap == None) {
+    check_pixmap = XCreateBitmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+                                (char *)check_bits, check_width, check_height);
+  }
+  XtVaSetValues(XtNameToWidget(main_menu, "*show_keypad"),
+               XtNrightBitmap, appres.keypad ? check_pixmap : None, NULL);
+  XtVaSetValues(XtNameToWidget(main_menu, "*show_functionkey"),
+               XtNrightBitmap, appres.function_key ? check_pixmap : None, NULL);
+
+  XtSetSensitive(XtNameToWidget(main_menu, "*edit_fkey"), appres.function_key);
+  XtSetSensitive(XtNameToWidget(main_menu, "*close_display"), target_dpy != dpy);
+}
+
+static void MakeKeyboard(Boolean remake)
+{
+  static char *main_menu_items[] = {
+    "about", "man", "keypad", "sun_fkey", "deadkey", "completion", "",
+    "select_layout",
+    "edit_fkey",
+    "show_keypad",
+    "show_functionkey",
+    "props",
+    "",
+    "open_display", "close_display", "",
+    "quit" };
+
+  Widget form, key, left;
+  Pixel color;
+  XFontStruct *font;
+  Dimension wd, max_wd;
+  int row, col, first_row;
+  char name[50], *label;
+  Widget key_box[NUM_KEY_ROWS];
+  Widget menu_entry;
+  int i;
+
+#include "xvkbd.xbm"
+#include "iconify.xbm"
+
+  if (remake) {
+    appres.geometry = GetWindowGeometry(toplevel);
+    XtUnrealizeWidget(toplevel);
+    XtDestroyWidget(XtNameToWidget(toplevel, "form"));
+  }
+
+  form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, NULL);
+
+  key_box[0] = None;
+  key_box[1] = None;
+  first_row = appres.function_key ? 0 : 1;
+  if (!appres.keypad_only) {
+    for (row = first_row; row < NUM_KEY_ROWS; row++) {
+      if (keys_normal[row][0] == NULL) continue;
+
+      sprintf(name, "row%d", row);
+      key_box[row] = XtVaCreateManagedWidget(name, formWidgetClass, form, NULL);
+      key_box[row + 1] = None;
+      if (row != first_row)
+        XtVaSetValues(key_box[row], XtNfromVert, key_box[row - 1], NULL);
+      else if (!appres.function_key)
+        XtVaSetValues(key_box[row], XtNvertDistance, 0, NULL);
+        
+      left = None;
+      for (col = 0; keys_normal[row][col] != NULL; col++) {
+        strcpy(name, keys_normal[row][col]);
+       if (strcmp(name, "MainMenu") == 0) {
+         Widget iconify_button = None;
+
+         if (appres.minimizable) {
+           Pixmap iconify_pixmap = XCreateBitmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+                                                 (char *)iconify_bits, iconify_width, iconify_height);
+           iconify_button = XtVaCreateManagedWidget("Iconify", commandWidgetClass, key_box[row],
+                                                    XtNbitmap, iconify_pixmap, NULL);
+           XtAddCallback(iconify_button, XtNcallback, (XtCallbackProc)IconifyWindow, (void *)TRUE);
+         }
+
+         xvkbd_pixmap = XCreateBitmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+                              (char *)xvkbd_bits, xvkbd_width, xvkbd_height);
+         key = XtVaCreateManagedWidget("MainMenu", menuButtonWidgetClass, key_box[row],
+                                       XtNbitmap, xvkbd_pixmap, XtNfromHoriz, iconify_button, NULL);
+         main_menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, key, NULL);
+         for (i = 0; i < XtNumber(main_menu_items); i++) {
+           if (strlen(main_menu_items[i]) == 0) {
+             XtVaCreateManagedWidget("separator", smeLineObjectClass, main_menu, NULL);
+           } else {
+             menu_entry = XtVaCreateManagedWidget(main_menu_items[i], smeBSBObjectClass,
+                                                  main_menu, NULL);
+             XtAddCallback(menu_entry, XtNcallback, (XtCallbackProc)MenuSelected,
+                           (XtPointer)main_menu_items[i]);
+           }
+         }
+       } else {
+         label = appres.modal_keytop ? normal_key_labels[row][col] : key_labels[row][col];
+         if (isascii(name[0]) && isupper(name[0])) {
+           if (strcmp(name, "Focus") == 0) {
+             color = appres.focus_background;
+             font = appres.keypad_font;
+           } else {
+             color = appres.special_background;
+             if (label != NULL && strchr(label, '\n') != NULL) font = appres.keypad_font;
+             else font = appres.special_font;
+           }
+         } else {
+           color = appres.general_background;
+           font = appres.general_font;
+           if (isalpha(name[0])) font = appres.letter_font;
+           if (strcmp(name, "space") != 0) sprintf(name, "%d,%d", row, col);
+         }
+         key = MakeKey(key_box[row], XtNewString(name), label, color);
+         XtVaGetValues(key, XtNwidth, &wd, NULL);
+         if (wd <= 1) {
+           /* keys can be removed by setting its width to 1 */
+           XtDestroyWidget(key);
+           key = None;
+         } else {
+           XtVaSetValues(key, XtNfont, font, NULL);
+#ifdef USE_I18N
+           if (font == appres.special_font || font == appres.keypad_font)
+             XtVaSetValues(key, XtNfontSet, appres.special_fontset, NULL);
+#endif
+         }
+       }
+       if (key != None) {
+         if (left != None) XtVaSetValues(key, XtNfromHoriz, left, NULL);
+         left = key;
+       }
+       key_widgets[row][col] = key;
+      }
+    }
+  }
+
+   if (appres.keypad) MakeKeypad(form, key_box[0], key_box[1]);
+
+  if (!appres.keypad_only && appres.function_key && appres.keypad) {
+    XtVaCreateManagedWidget("banner", labelWidgetClass, form,
+                            XtNfromHoriz, key_box[1],
+                            XtNlabel, PROGRAM_NAME_WITH_VERSION, NULL);
+  }
+
+
+  XtRealizeWidget(toplevel);
+  SetWindowManagerHint(TRUE);
+
+  if (!remake && strlen(appres.geometry) == 0) {
+    Window root;
+    int x1, y1;
+    unsigned int wd, ht, bd, dp;
+    int max_wd, max_ht;
+
+    XGetGeometry(dpy, XtWindow(toplevel), &root, &x1, &y1, &wd, &ht, &bd, &dp);
+    max_wd = XtScreen(toplevel)->width * appres.max_width_ratio;
+    max_ht = XtScreen(toplevel)->height * appres.max_height_ratio;
+    if (appres.debug)
+      fprintf(stderr, "window size: %dx%d, max size: %dx%d\n", wd, ht, max_wd, max_ht);
+    if (max_wd < wd || max_ht < ht) {
+      if (max_wd < wd) wd = max_wd;
+      if (max_ht < ht) ht = max_ht;
+      if (appres.debug)
+       fprintf(stderr, "setting window size: %dx%d\n", wd, ht);
+      XResizeWindow(dpy, XtWindow(toplevel), wd, ht);
+    }
+  }
+
+  if (!appres.debug && key_box[first_row] != None) {
+    if (appres.keypad) {
+      XtVaGetValues(key_box[1], XtNwidth, &max_wd, NULL);
+    } else {
+      max_wd = 0;
+      for (row = first_row; row < NUM_KEY_ROWS && key_box[row] != None; row++) {
+        XtVaGetValues(key_box[row], XtNwidth, &wd, NULL);
+        if (max_wd < wd) max_wd = wd;
+      }
+    }
+    for (row = first_row; row < NUM_KEY_ROWS && key_box[row] != None; row++) {
+      XtVaSetValues(key_box[row], XtNwidth, max_wd, NULL);
+    }
+  }
+  if (0 < strlen(appres.geometry)) {
+    if (appres.wm_toolbar) {
+      if (appres.debug)
+       fprintf(stderr, "window fgeometry ignored; _NET_WM_WINDOW_TYPE_TOOLBAR set on\n");
+    } else {
+      if (appres.debug)
+       fprintf(stderr, "setting window geometry: %s\n", appres.geometry);
+      XtVaSetValues(toplevel, XtNgeometry, appres.geometry, NULL);
+      XtUnrealizeWidget(toplevel);
+      XtRealizeWidget(toplevel);
+    }
+  }
+
+  ReadKeymap();
+  if (main_menu != None) RefreshMainMenu();
+  RefreshShiftState(FALSE);
+
+  XtMapWidget(toplevel);
+
+  if (wm_delete_window == None)
+    wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", FALSE);
+  XSetWMProtocols(dpy, XtWindow(toplevel), &wm_delete_window, 1);
+
+  XtVaGetValues(toplevel, XtNheight, &toplevel_height, NULL);
+}
+
+/*
+ * WM_DELETE_WINDOW has been sent - terminate the program.
+ */
+static void DeleteWindowProc(Widget w, XEvent *event,
+                             String *pars, Cardinal *n_pars)
+{
+  if (appres.nonexitable) {
+    XBell(dpy, 0);
+  } else {
+    shift_state = 0;
+    RefreshShiftState(TRUE);
+    XtDestroyApplicationContext(XtWidgetToApplicationContext(toplevel));
+    exit(0);
+  }
+}
+
+/*
+ * Callback for ConfigureNotify event, which will be invoked when
+ * the toplevel window is resized.
+ * We may need to switch the keytop labels when window becomes
+ * smaller than appres.modal_threshold, and vice versa.
+ */
+static void WindowResized(Widget w, XEvent *event,
+                         String *pars, Cardinal *n_pars)
+{
+  Dimension ht;
+
+  XtVaGetValues(toplevel, XtNheight, &ht, NULL);
+  if (appres.modal_threshold <= ht) {
+    if (toplevel_height < appres.modal_threshold) MakeKeyboard(TRUE);
+  } else {
+    toplevel_height = ht;
+  }
+  RefreshShiftState(TRUE);
+}
+
+/*
+ * Load list of text to be assigned to function keys.
+ * Each line contains name of the key (with optional modifier)
+ * and the text to be assigned to the key, as:
+ *
+ *   F1 text for F1
+ *   s:F2 text for Shift-F2
+ */
+#ifndef PATH_MAX
+# define PATH_MAX 300
+#endif
+
+static char fkey_filename[PATH_MAX] = "";
+
+static struct fkey_struct {
+  struct fkey_struct *next;
+  char *value;
+} *fkey_list = NULL;
+
+static void ReadFuncionKeys(void)
+{
+  FILE *fp;
+  char str[200], key[200];
+  struct fkey_struct *sp = NULL, *new_node;
+  char len;
+  int val;
+  const char *home;
+
+  /* If KeyFile is not started with "/", consider the filename is relative to $HOME */
+  /* and put value of the $HOME environment variable before the KeyFile. */
+  /* To avoid possible buffer overflow, $HOME will not be added when resulting filename */
+  /* is too long. */
+  home = getenv("HOME");
+  if (appres.key_file[0] != '/' && home != NULL
+      && strlen(home) + strlen(appres.key_file) + 1 < sizeof(fkey_filename))
+    sprintf(fkey_filename, "%s/%s", home, appres.key_file);
+  else
+    strncpy(fkey_filename, appres.key_file, sizeof(fkey_filename));
+
+  strncpy(dict_filename, appres.dict_file, sizeof(dict_filename));
+
+  fp = fopen(fkey_filename, "r");
+  if (fp == NULL) return;
+
+  while (fgets(str, sizeof(str) - 1, fp)) {
+    if (str[0] == '#') {
+      sscanf(&str[1], "%s %d", key, &val);
+      if (strcmp(key, "quick_modifiers") == 0)
+       appres.quick_modifiers = val;
+      else if (strcmp(key, "shift_lock") == 0)
+       appres.shift_lock = val;
+      else if (strcmp(key, "altgr_lock") == 0)
+       appres.altgr_lock = val;
+      else if (strcmp(key, "modifiers_lock") == 0)
+       appres.modifiers_lock = val;
+      else if (strcmp(key, "key_click") == 0)
+       appres.key_click_duration = val;
+      else if (strcmp(key, "autoclick") == 0)
+       appres.autoclick_delay = val;
+      else if (strcmp(key, "always_on_top") == 0)
+       appres.always_on_top = val;
+      else if (strcmp(key, "wm_toolbar") == 0)
+       appres.wm_toolbar = val;
+      else if (strcmp(key, "jump_pointer") == 0)
+       appres.jump_pointer = val;
+      else if (strcmp(key, "dict_file") == 0) {
+       sscanf(&str[1], "%*s %s", &key);
+       strncpy(dict_filename, key, sizeof(dict_filename));
+      }
+    } else if (isalpha(str[0])) {
+      len = strlen(str);
+      if (str[len - 1] == '\n') str[len - 1] = '\0';
+
+      new_node = malloc(sizeof(struct fkey_struct));
+      if (fkey_list == NULL) fkey_list = new_node;
+      else sp->next = new_node;
+      sp = new_node;
+
+      sp->next = NULL;
+      sp->value = XtNewString(str);
+    }
+  }
+  fclose(fp);
+}
+
+/*
+ * Edit string assigned for function keys.
+ * Modifiers (Shift, Ctrl, etc.) can't be handled here.
+ */
+static Widget edit_fkey_panel = None;
+static Widget fkey_menu_button = None;
+static Widget fkey_value_menu_button = None;
+static Widget fkey_value_entry = None;
+static char fkey_value[100] = "";
+static char cur_fkey[20] = "";
+static char *cur_fkey_value_mode = "";
+
+static void FKeyValueMenuSelected(Widget w, char *key)
+{
+  char *key1, *cp;
+
+  if (key[0] == 'c') {
+    cur_fkey_value_mode = "command";
+    key1 = "*command";
+  } else {
+    cur_fkey_value_mode = "string";
+    key1 = "*string";
+  }
+  XtVaGetValues(XtNameToWidget(fkey_value_menu_button, key1), XtNlabel, &cp, NULL);
+  XtVaSetValues(fkey_value_menu_button, XtNlabel, cp, NULL);
+}
+
+static void FKeyMenuSelected(Widget w, char *key)
+{
+  struct fkey_struct *sp, *sp2;
+  int len;
+  const char *value, *prefix;
+  char key2[20];
+
+  if (key == NULL)
+    strcpy(key2, "");
+  else if (strncmp(key, "Shift-", strlen("Shift-")) == 0)
+    sprintf(key2, "s:%s", &key[strlen("Shift-")]);
+  else
+    strcpy(key2, key);
+
+  if (strcmp(cur_fkey, key2) != 0) {
+    if (strlen(cur_fkey) != 0) {
+      len = strlen(cur_fkey);
+      sp2 = NULL;
+      for (sp = fkey_list; sp != NULL; sp = sp->next) {
+       if (strncmp(sp->value, cur_fkey, len) == 0 && isspace(sp->value[len]))
+         break;
+       sp2 = sp;
+      }
+      if (strlen(fkey_value) != 0) {  /* assign new string for the function key */
+       if (sp == NULL) {  /* it was not defined before now */
+         sp = malloc(sizeof(struct fkey_struct));
+         if (fkey_list == NULL) fkey_list = sp;
+         else sp2->next = sp;
+         sp->next = NULL;
+         sp->value = NULL;
+       }
+       sp->value = realloc(sp->value, len + strlen(fkey_value) + 5);
+       prefix = "";
+       if (cur_fkey_value_mode[0] == 'c') prefix = "!";
+       else if (fkey_value[0] == '!') prefix = "\\";
+       sprintf(sp->value, "%s %s%s", cur_fkey, prefix, fkey_value);
+      } else {  /* empty string - remove the entry for the function key */
+       if (sp != NULL) {
+         if (sp2 != NULL) sp2->next = sp->next;
+         else fkey_list = sp->next;
+         free(sp->value);
+         free(sp);
+       }
+      }
+    }
+
+    if (key != NULL) {
+      XtVaSetValues(fkey_menu_button, XtNlabel, key, NULL);
+  
+      value = FindFunctionKeyValue(key2, FALSE);
+      if (value == NULL) value = "";
+
+      FKeyValueMenuSelected(None, (value[0] == '!') ? "command" : "string");
+
+      if (value[0] == '!' || value[0] == '\\') value = value + 1;
+      strncpy(fkey_value, value, sizeof(fkey_value) - 1);
+      XtVaSetValues(fkey_value_entry, XtNstring, fkey_value, NULL);
+
+      strcpy(cur_fkey, key2);
+    }
+  }
+}
+
+static void CloseFunctionKeyPanel(void)
+{
+  XtPopdown(edit_fkey_panel);
+}
+
+static void SaveFunctionKey(void)
+{
+  struct fkey_struct *sp;
+  FILE *fp;
+
+  if (appres.debug) fprintf(stderr, "SaveFunctionKey\n");
+
+  if (edit_fkey_panel != None) FKeyMenuSelected(None, NULL);
+
+  fp = fopen(fkey_filename, "w");
+  if (fp == NULL) {
+    fprintf(stderr, "%s: can't open \"%s\": %s\n",
+           PROGRAM_NAME, fkey_filename, strerror(errno));
+    return;
+  }
+  fprintf(fp, "#quick_modifiers %d\n", appres.quick_modifiers);
+  fprintf(fp, "#shift_lock %d\n", appres.shift_lock);
+  fprintf(fp, "#altgr_lock %d\n", appres.altgr_lock);
+  fprintf(fp, "#modifiers_lock %d\n", appres.modifiers_lock);
+  fprintf(fp, "#key_click %d\n", appres.key_click_duration);
+  fprintf(fp, "#autoclick %d\n", appres.autoclick_delay);
+  fprintf(fp, "#always_on_top %d\n", appres.always_on_top);
+  fprintf(fp, "#wm_toolbar %d\n", appres.wm_toolbar);
+  fprintf(fp, "#jump_pointer %d\n", appres.jump_pointer);
+  fprintf(fp, "#dict_file %s\n", dict_filename);
+  for (sp = fkey_list; sp != NULL; sp = sp->next) {
+    fprintf(fp, "%s\n", sp->value);
+  }
+  fclose(fp);
+
+  if (edit_fkey_panel != None) CloseFunctionKeyPanel();
+}
+
+static void PopupFunctionKeyEditor(void)
+{
+  Widget form, form2, menu, menu_entry, button;
+  char label[20];
+  char *key;
+  int i, j;
+
+  if (edit_fkey_panel == None) {
+    edit_fkey_panel = XtVaCreatePopupShell("edit_fkey_panel", transientShellWidgetClass,
+                                          toplevel, NULL);
+    form = XtVaCreateManagedWidget("form", formWidgetClass, edit_fkey_panel, NULL);
+
+    form2 = XtVaCreateManagedWidget("form2", formWidgetClass, form, NULL);
+    XtVaCreateManagedWidget("fkey_label", labelWidgetClass, form2, NULL);
+    fkey_menu_button = XtVaCreateManagedWidget("fkey_menu", menuButtonWidgetClass,
+                                              form2, NULL);
+    menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, fkey_menu_button, NULL);
+    for (j = 0; j <= 1; j++) {
+      for (i = 1; i <= appres.editable_function_keys; i++) {
+       if (j == 0)
+         sprintf(label, "F%d", i);
+       else 
+         sprintf(label, "Shift-F%d", i);
+       key = XtNewString(label);
+       menu_entry = XtVaCreateManagedWidget(key, smeBSBObjectClass, menu, NULL);
+       XtAddCallback(menu_entry, XtNcallback, (XtCallbackProc)FKeyMenuSelected,
+                     (XtPointer)key);
+      }
+    }
+
+    fkey_value_menu_button = XtVaCreateManagedWidget("fkey_value_menu", menuButtonWidgetClass,
+                                                    form2, NULL);
+    menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, fkey_value_menu_button, NULL);
+    menu_entry = XtVaCreateManagedWidget("string", smeBSBObjectClass, menu, NULL);
+    XtAddCallback(menu_entry, XtNcallback, (XtCallbackProc)FKeyValueMenuSelected,
+                 (XtPointer)"string");
+    menu_entry = XtVaCreateManagedWidget("command", smeBSBObjectClass, menu, NULL);
+    XtAddCallback(menu_entry, XtNcallback, (XtCallbackProc)FKeyValueMenuSelected,
+                 (XtPointer)"command");
+
+    XtVaCreateManagedWidget("fkey_value_sep", labelWidgetClass, form2, NULL);
+
+    fkey_value_entry = XtVaCreateManagedWidget("fkey_value", asciiTextWidgetClass, form2,
+                                              XtNuseStringInPlace, True,
+                                              XtNeditType, XawtextEdit,
+                                              XtNstring, fkey_value,
+                                              XtNlength, sizeof(fkey_value) - 1,
+                                              NULL);
+
+    button = XtVaCreateManagedWidget("save_button", commandWidgetClass, form, NULL);
+    XtAddCallback(button, XtNcallback, (XtCallbackProc)SaveFunctionKey, NULL);
+
+    button = XtVaCreateManagedWidget("close_button", commandWidgetClass, form, NULL);
+    XtAddCallback(button, XtNcallback, (XtCallbackProc)CloseFunctionKeyPanel, NULL);
+
+    XtRealizeWidget(edit_fkey_panel);
+    XSetWMProtocols(dpy, XtWindow(edit_fkey_panel), &wm_delete_window, 1);
+
+    XtSetKeyboardFocus(edit_fkey_panel, fkey_value_entry);
+
+    FKeyMenuSelected(None, "F1");
+  }
+
+  XtPopup(edit_fkey_panel, XtGrabNone);
+}
+
+/*
+ * If text is assigned to the specified function key,
+ * return the text.  Otherwise, return NULL.
+ */
+static const char *FindFunctionKeyValue(const char *key, Boolean shiftable)
+{
+  char label[50];
+  char prefix;
+  struct fkey_struct *sp;
+  int len;
+
+  prefix = '\0';
+  if (shiftable) {
+    if (shift_state & meta_mask) prefix = 'm';
+    else if (shift_state & alt_mask) prefix = 'a';
+    else if (shift_state & ControlMask) prefix = 'c';
+    else if (shift_state & ShiftMask) prefix = 's';
+  }
+  if (prefix == '\0') sprintf(label, "%s", key);
+  else sprintf(label, "%c:%s", prefix, key);
+  len = strlen(label);
+  
+  for (sp = fkey_list; sp != NULL; sp = sp->next) {
+    if (strncmp(sp->value, label, len) == 0 && isspace(sp->value[len]))
+      return &(sp->value[len + 1]);
+  }
+  return NULL;
+}
+
+/*
+ * Key click
+ */
+void KeyClick(void)
+{
+  XKeyboardState ks;
+  XKeyboardControl kc;
+
+  if (0 < appres.key_click_duration) {
+    XGetKeyboardControl(dpy, &ks);
+
+    kc.bell_duration = ks.bell_duration;
+    kc.bell_pitch = appres.key_click_pitch;
+    kc.bell_duration = appres.key_click_duration;
+    XChangeKeyboardControl(dpy, KBBellPitch | KBBellDuration, &kc);
+    XBell(dpy, 0);
+    XSync(dpy, FALSE);
+
+    kc.bell_pitch = ks.bell_pitch;
+    kc.bell_duration = ks.bell_duration;
+    XChangeKeyboardControl(dpy, KBBellPitch | KBBellDuration, &kc);
+    XSync(dpy, FALSE);
+  }
+}
+
+/*
+ * Display balloon message for the function keys,
+ * if text is assigned to the key.
+ */
+static Boolean balloon_panel_open = FALSE;
+static Widget balloon_panel = None;
+
+static XtIntervalId autoclick_id = (XtIntervalId)0;
+
+static void StopAutoclick(void)
+{
+  if (autoclick_id != (XtIntervalId)0) {
+    if (appres.debug) fprintf(stderr, "StopAutoclick: %lx\n", (long)autoclick_id);
+
+    XtRemoveTimeOut(autoclick_id);
+    autoclick_id = (XtIntervalId)0;
+  }
+}
+
+static void Autoclick(void)
+{
+  StopAutoclick();
+
+  XTestFakeButtonEvent(target_dpy, 1, True, CurrentTime);
+  XTestFakeButtonEvent(target_dpy, 1, False, CurrentTime);
+}
+
+static void ShowBalloon(Widget w, XEvent *event, String *pars, Cardinal *n_pars)
+{
+  static Widget message;
+  Position x, y;
+  Dimension ht;
+  const char *value;
+
+  if (strcmp(XtName(w), "MainMenu") == 0) {
+    value = "Main menu";
+  } else {
+    if (0 < appres.autoclick_delay) {
+      autoclick_id = XtAppAddTimeOut(app_con, (long)appres.autoclick_delay,
+                          (XtTimerCallbackProc)Autoclick, (XtPointer)w);
+
+      if (appres.debug) fprintf(stderr, "ShowBalloon: auto click triggerd: %lx, %d\n",
+                               (long)autoclick_id, appres.autoclick_delay);
+    }
+    value = FindFunctionKeyValue(XtName(w), TRUE);
+    if (value == NULL) return;
+  }
+
+  if (balloon_panel == None) {
+    balloon_panel = XtVaCreatePopupShell("balloon_panel", transientShellWidgetClass, toplevel,
+                                        XtNoverrideRedirect, TRUE, NULL);
+    message = XtVaCreateManagedWidget("message", labelWidgetClass, balloon_panel, NULL);
+  }
+  XtVaGetValues(w, XtNheight, &ht, NULL);
+  XtTranslateCoords(w, 6, ht + 2, &x, &y);
+  XtVaSetValues(balloon_panel, XtNx, x, XtNy, y, NULL);
+  if (value[0] == '!') {
+    if (appres.secure) return;
+    XtVaSetValues(message, XtNlabel, value + 1,
+                 XtNbackground, appres.launch_balloon_background, NULL);
+  } else {
+    if (value[0] == '\\') value = value + 1;
+    XtVaSetValues(message, XtNlabel, value,
+                 XtNbackground, appres.balloon_background, NULL);
+  }
+  XtPopup(balloon_panel, XtGrabNone);
+
+  balloon_panel_open = TRUE;
+}
+
+static void CloseBalloon(Widget w, XEvent *event, String *pars, Cardinal *n_pars)
+{
+  StopAutoclick();
+  if (balloon_panel_open) {
+    XtPopdown(balloon_panel);
+    balloon_panel_open = FALSE;
+  }
+}
+
+/*
+ * Set icon image.
+ */
+static void SetIconBitmap(Widget w)
+{
+#include "xvkbd_icon.xbm"
+#include "xvkbd_iconmask.xbm"
+
+  Pixmap icon_pixmap, icon_mask;
+
+  icon_pixmap = XCreateBitmapFromData(XtDisplay(w), XtWindow(w),
+                                     (char *)xvkbd_icon_bits,
+                                     xvkbd_icon_width, xvkbd_icon_height);;
+  icon_mask = XCreateBitmapFromData(XtDisplay(w), XtWindow(w),
+                                   (char *)xvkbd_iconmask_bits,
+                                   xvkbd_iconmask_width, xvkbd_iconmask_height);
+  XtVaSetValues(w, XtNiconPixmap, icon_pixmap, XtNiconMask, icon_mask, NULL);
+}
+
+/*
+ * Callback for VisibilityChanged event, which will be invoked
+ * when xvkbd window is hidden by other window.  ** EXPERIMENTAL **
+ */
+static void VisibilityChanged(Widget w, XEvent *event,
+                             String *pars, Cardinal *n_pars)
+{
+  static cnt = 0;
+  static time_t t1 = 0;
+  time_t t2;
+
+  if (!appres.always_on_top) return;
+
+  if (balloon_panel_open) return;
+
+  if (main_menu != None && XtWindow(main_menu) != None) {
+    XWindowAttributes attr;
+    XGetWindowAttributes(dpy, XtWindow(main_menu), &attr);
+    if (attr.map_state != IsUnmapped) return;
+  }
+
+  t2 = time(NULL);
+  if (t1 != t2) cnt = 0;
+  t1 = t2;
+  cnt = cnt + 1;
+  if (appres.debug)
+    fprintf(stderr, "%s: visibility of the window changed (cnt = %d)\n", PROGRAM_NAME, cnt);
+  if (cnt < 5)
+    XRaiseWindow(XtDisplay(toplevel), XtWindow(toplevel));
+}
+
+/*
+ * The main program.
+ */
+int main(int argc, char *argv[])
+{
+  static XtActionsRec actions[] = {
+    { "DeleteWindowProc", DeleteWindowProc },
+    { "WindowResized", WindowResized },
+    { "VisibilityChanged", VisibilityChanged },
+    { "ReadKeymap", (XtActionProc)ReadKeymap },
+    { "ButtonDownAction", ButtonDownAction },
+    { "ButtonUpAction", ButtonUpAction },
+    { "ShowBalloon", ShowBalloon },
+    { "CloseBalloon", CloseBalloon },
+    { "ClosePopupPanel", (XtActionProc)ClosePopupPanel },
+  };
+  static String fallback_resources[] = {
+#include "XVkbd-common.h"
+    NULL,
+  };
+
+  Boolean open_keypad_panel = FALSE;
+  char ch;
+  Window child;
+  int op, ev, err;
+
+  argc1 = argc;
+  argv1 = malloc(sizeof(char *) * (argc1 + 5));
+  memcpy(argv1, argv, sizeof(char *) * argc1);
+  argv1[argc1] = NULL;
+
+#ifdef USE_I18N
+  XtSetLanguageProc(NULL, NULL, NULL);
+#endif
+
+  toplevel = XtVaAppInitialize(NULL, "XVkbd",
+                               options, XtNumber(options),
+                               &argc, argv, fallback_resources, NULL);
+  dpy = XtDisplay(toplevel);
+  app_con = XtWidgetToApplicationContext(toplevel);
+  XtAppAddActions(app_con, actions, XtNumber(actions));
+
+  target_dpy = dpy;
+
+  if (1 < argc) {
+    fprintf(stderr, "%s: illegal option: %s\n\n", PROGRAM_NAME, argv[1]);
+  }
+
+  XtGetApplicationResources(toplevel, &appres,
+            application_resources, XtNumber(application_resources),
+            NULL, 0);
+  if (appres.version) {
+    fprintf(stdout, "%s\n", appres.description);
+    exit(1);
+  }
+
+  if (appres.compact) {
+    appres.keypad = FALSE;
+    appres.function_key = FALSE;
+  }
+  if (appres.keypad_only && !appres.keypad) {
+    appres.keypad_only = FALSE;
+    open_keypad_panel = TRUE;
+  }
+
+  if (appres.no_sync) {
+    XSync(dpy, FALSE);
+    XSetErrorHandler(MyErrorHandler);
+  }
+  
+  if (0 < strlen(appres.window) || 0 < strlen(appres.instance)) {
+    if (strcmp(appres.window, "root") == 0) {
+      focused_window = RootWindow(dpy, DefaultScreen(dpy));
+    } else if (sscanf(appres.window, "0x%lX%c", &focused_window, &ch) != 1) {
+      if (sscanf(appres.window, "%ld%c", &focused_window, &ch) != 1) {
+        focused_window = FindWindow(RootWindow(dpy, DefaultScreen(dpy)),
+                                    appres.window);
+        if (focused_window == None) {
+          fprintf(stderr, "%s: no such window: window=%s and class=%s\n", PROGRAM_NAME, appres.window, appres.instance);
+         if (appres.no_root)
+           exit(-1);
+        }
+      }
+    }
+  }
+  focused_subwindow = focused_window;
+
+  ReadKeymap();
+  if (!altgr_mask && appres.auto_add_keysym) AddModifier(XK_Mode_switch);
+
+  if (strlen(appres.text) != 0 || strlen(appres.file) != 0) {
+    appres.keypad_keysym = TRUE;
+    if (focused_window != None &&
+        (appres.list_widgets || strlen(appres.widget) != 0)) {
+      XtVaSetValues(toplevel, XtNwidth, 1, XtNheight, 1, NULL);
+      XtRealizeWidget(toplevel);
+      child = FindWidget(toplevel, focused_window, appres.widget);
+      if (child != None) focused_subwindow = child;
+    }
+    if (strlen(appres.text) != 0)
+      SendString(appres.text);
+    else
+      SendFileContent(appres.file);
+    exit(0);
+ } else {
+    ReadFuncionKeys();
+
+    if (0 < strlen(appres.keys_normal))
+      RedefineKeys(keys_normal, appres.keys_normal);
+    if (0 < strlen(appres.keys_shift))
+      RedefineKeys(keys_shift, appres.keys_shift);
+    if (0 < strlen(appres.keys_altgr))
+      RedefineKeys(keys_altgr, appres.keys_altgr);
+    if (0 < strlen(appres.keys_shift_altgr))
+      RedefineKeys(keys_shift_altgr, appres.keys_shift_altgr);
+
+    if (0 < strlen(appres.key_labels))
+      RedefineKeys(key_labels, appres.key_labels);
+    if (0 < strlen(appres.normal_key_labels))
+      RedefineKeys(normal_key_labels, appres.normal_key_labels);
+    if (0 < strlen(appres.shift_key_labels))
+      RedefineKeys(shift_key_labels, appres.shift_key_labels);
+    if (0 < strlen(appres.altgr_key_labels))
+      RedefineKeys(altgr_key_labels, appres.altgr_key_labels);
+    if (0 < strlen(appres.shift_altgr_key_labels))
+      RedefineKeys(shift_altgr_key_labels, appres.shift_altgr_key_labels);
+
+    if (0 < strlen(appres.keypad_normal)) {
+      RedefineKeys(keypad, appres.keypad_normal);
+      RedefineKeys(keypad_shift, appres.keypad_normal);
+      RedefineKeys(keypad_label, appres.keypad_normal);
+    }
+    if (0 < strlen(appres.keypad_shift))
+      RedefineKeys(keypad_shift, appres.keypad_shift);
+    if (0 < strlen(appres.keypad_labels))
+      RedefineKeys(keypad_label, appres.keypad_labels);
+
+    MakeKeyboard(FALSE);
+
+    if (focused_window != None &&
+        (appres.list_widgets || strlen(appres.widget) != 0)) {
+      child = FindWidget(toplevel, focused_window, appres.widget);
+      if (child != None) focused_subwindow = child;
+    }
+
+    if (main_menu != None) {
+      if (strlen(dict_filename) == 0)
+       XtSetSensitive(XtNameToWidget(main_menu, "*completion"), FALSE);
+      if (strlen(appres.customizations) == 0)
+       XtSetSensitive(XtNameToWidget(main_menu, "*select_layout"), FALSE);
+      if (appres.nonexitable)
+       XtSetSensitive(XtNameToWidget(main_menu, "*quit"), FALSE);
+      if (appres.secure) {
+       XtSetSensitive(XtNameToWidget(main_menu, "*man"), FALSE);
+       XtSetSensitive(XtNameToWidget(main_menu, "*open_display"), FALSE);
+      }
+    }
+
+#ifdef USE_XTEST
+    if (!XQueryExtension(dpy, "XTEST", &op, &ev, &err)) {
+      if (appres.xtest) {
+       fprintf(stderr, "%s: XTEST extension is not supported by the X server\n",
+               PROGRAM_NAME);
+       fprintf(stderr, "%s: XSendEvent will be used instead\n",
+               PROGRAM_NAME);
+       appres.xtest = FALSE;
+      }
+      if (main_menu != None) {
+       XtSetSensitive(XtNameToWidget(main_menu, "*use_xtest"), FALSE);
+       RefreshMainMenu();
+      }
+    }
+#endif
+
+    if (!appres.debug) {
+#ifdef SYSV
+      signal(SIGINT, SIG_IGN);
+      signal(SIGQUIT, SIG_IGN);
+#else
+      struct sigaction sigact;
+      sigact.sa_handler = SIG_IGN;
+      sigemptyset(&sigact.sa_mask);
+      sigact.sa_flags = 0;
+      sigaction(SIGINT, &sigact, NULL);
+      sigaction(SIGQUIT, &sigact, NULL);
+#endif
+    }
+
+    {
+#ifdef SYSV
+      signal(SIGUSR1, SignalUser1);
+#else
+      struct sigaction sigact;
+      sigact.sa_handler = SignalUser1;
+      sigemptyset(&sigact.sa_mask);
+      sigact.sa_flags = 0;
+      sigaction(SIGUSR1, &sigact, NULL);
+#endif
+    }
+
+    SetIconBitmap(toplevel);
+
+    if (open_keypad_panel) MenuSelected(None, "keypad");
+
+
+    XtAppMainLoop(app_con);
+  }
+  exit(0);
+}
+
+/*
+ * Replace setlocale() in the standard library here, because
+ * it may not support some locales used for localized keyboards.
+ */
+#if defined(USE_I18N) && !defined(HAVE_SETLOCALE)
+
+char *setlocale(int category, const char *locale)
+{
+  static char old_locale[100] = "C";
+  static char cur_locale[100] = "C";
+  const char *s;
+  if (locale == NULL) {
+    return cur_locale;
+  } else if (category == LC_ALL) {
+    strcpy(old_locale, cur_locale);
+    if (locale[0] == '\0') {
+      s = getenv("LC_ALL");
+      if (s == NULL) s = "C";  /* LC_ALL not defined */
+    } else {
+      s = locale;
+    }
+    strncpy(cur_locale, s, sizeof(cur_locale) - 1);
+    return old_locale;
+  } else {
+    return cur_locale;
+  }
+}
+#endif  /* HAVE_SETLOCALE */
diff --git a/development/autotests/xvkbd/xvkbd.man b/development/autotests/xvkbd/xvkbd.man
new file mode 100644 (file)
index 0000000..8ba59a6
--- /dev/null
@@ -0,0 +1,1219 @@
+.TH xvkbd 1 2010-03-14
+
+
+.SH NAME
+\fPxvkbd\fP - virtual keyboard for X window system
+
+.SH DESCRIPTION
+.PP
+\fIxvkbd\fP is a virtual (graphical) keyboard program for X Window System
+which provides facility to enter characters onto other clients (softwares)
+by clicking on a keyboard displayed on the screen.
+This may be used for systems without a hardware keyboard
+such as kiosk terminals or handheld devices.
+This program also has facility to send characters
+specified as the command line option to another client.
+.PP
+The standard keyboard layout is based on the traditional US layout,
+but some other keyboard layout (see "Screen Shot")
+are also supported.
+The default window size may be too large for systems with small screen,
+but it can be configured to use smaller space (220x90 pixels, for example).
+For details,
+see also "Screen Shot"
+and "How to Customize \fIxvkbd\fP" below,
+and resouce files in the distribution.
+.PP
+\fIxvkbd\fP version 2.1 and later support word completion,
+which may make it easier to enter long words with \fIxvkbd\fP.
+.PP
+\fIIMPORTANT NOTE:\fP
+When invoking \fIxvkbd\fP from display managers such as XDM, GDM, etc.,
+always use \fIxvkbd\fP with \fB-secure\fP option
+or you will have serious security risk.
+
+.SH "Environment"
+\fIxvkbd\fP will work on X11R5 or X11R6.
+It is tested on \fIredhat Linux\fP and \fISolaris\fP,
+and it will work also on most UNIX-like systems.
+.PP
+This program uses \fIXaw\fP (use of \fIXaw3d\fP is recommended) 
+and no special library is required.
+
+.SH "Operation"
+
+.SH "    Input Keys"
+When \fIxvkbd\fP is started, the image of a keyboard 
+will be displayed on the screen.
+Clicking any key on the \fIxvkbd\fP window will send the character
+to the focused window
+as if the key had been actually typed with the hardware keyboard.
+.PP
+If you want to input upper-case alphabets
+or other characters on the upper position on the keyboard,
+you should click the key after selecting \fIShift\fP by clicking it,
+or click the key with mouse button 3 (maybe right button) or mouse button 4.
+In the similar manner, if you want to input \fIControl\fPed characters,
+you should click the key after clicking \fIControl\fP,
+or click the key with mouse button 2 (maybe middle button).
+\fIAlt\fP and \fIMeta\fP can be used in the similar manner with \fIControl\fP,
+but there are no shortcuts with mouse buttons.
+
+.SH "    ``Quick Modifiers''"
+\fIxvkbd\fP 2.5 and later support another way to input characters
+with modifiers such as \fIShift\fP, \fIControl\fP, \fIAltGr\fP, etc.,
+which may be useful especially for machines with touch panels such as PDAs
+- we would call it \fI"Quick Modifiers"\fP.
+.PP
+\fIQuick Modifiers\fP can be enabled/disabled by the
+``\fIEnable "Quick Modifiers?\fP'' entry on the
+property panel.
+If \fIQuick Modifiers\fP is enabled,
+it will be activated by pressing a key on the \fIxvkbd\fP window,
+move the pointer outside of the key,
+and then release the mouse button or equivalent.
+.PP
+The direction of the pointer motion will select the modifier:
+.sp
+.in +4
+.nf
+  up        - Shift
+  right     - AltGr
+  right-up  - Shift AltGr
+  left      - Control
+  left-up   - Shift Control
+  down      - Meta
+  left-down - Alt
+.fi
+.sp
+.in -4
+
+.SH "    Setting Input Focus"
+If you are using a window manager and clients
+where you can set input focus by clicking mouse button on the window 
+(and you don't have to keep pointer in the window after that),
+you can simply set input focus in the normal way
+and then click keys on the \fIxvkbd\fP window 
+- the character will be sent to the selected position.
+.PP
+If you are using a window manager or clients
+where you must keep the pointer in the input field to input from the keyboard,
+or if the input focus is switched to the \fIxvkbd\fP window
+when you clicked on the key on the \fIxvkbd\fP window,
+you must make \fIxvkbd\fP to set input focus explicitly
+by clicking the \fIFocus\fP button on the \fIxvkbd\fP window
+and then click on the input field.
+This input focus can be cleared by clicking \fIFocus\fP button
+with mouse button 3, or simply clicking \fIFocus\fP button twice.
+
+.SH "    Word Completion"
+Choosing ``\fIWord Completion...\fP'' in the main menu
+will popup the \fIWord Completion\fP panel.
+.PP
+When you entered characters by clicked keys on the \fIxvkbd\fP window as usual
+while the \fIWord Completion\fP panel open,
+words started with the characters will be listed in the panel,
+and you can enter the remaining characters of the selected word
+by clicking one of the words in the list.
+.PP
+The dictionary (list of words) file is \fB/usr/share/dict/words\fP by default,
+but it can be changed by \fB-dict\fP option or \fBxvkbd.dictFile\fP resouce,
+or on the Property panel.
+
+.SH "    Main Menu"
+Pressing the ``xvkbd'' logo on the main keyboard
+(placed near left-bottom corner in the default configuration)
+will popup the main menu.
+.PP
+The menu contains following items:
+.TP 4
+\fIAbout...\fP
+Show short description of this program.
+.TP 4
+\fIManual...\fP
+Launch manual page reader.
+.TP 4
+\fIKeypad...\fP
+Open the Keypad panel.
+.TP 4
+\fISun Function Keys...\fP
+Open the Sun Function Keys panel.
+.TP 4
+\fIDead Keys...\fP
+Open the Dead Keys panel
+which can be used to enter Latin characters with accent symbol in double stroke.
+.TP 4
+\fIWord Completion...\fP
+Open the Word Completion panel.
+.PP
+.TP 4
+\fIChange Keyboard Layout...\fP
+Open a popup window to change the keyboard layout.
+In the default configuration,
+Default (US),
+Belgian,
+Danish,
+French,
+German,
+Icelandic,
+Italian,
+Japanese (JIS-X-6002),
+Japanese (JIS-X-6004),
+Korean,
+Norwegian,
+Portuguese,
+Russian,
+Spanish,
+Swedish,
+Swiss/German,
+United Kingdom
+and Latin-1
+are available.
+.TP 4
+\fIEdit Function Keys...\fP
+Open a popup window to edit string assigned to function keys.
+See also "Assigning Text to Function Keys".
+.TP 4
+\fIShow Keypad?\fP
+Toggle show/hide of the keypad on the main window.
+.TP 4
+\fIShow Function Keys?\fP
+Toggle show/hide of the function keys on the main window.
+.TP 4
+\fIProperty...\fP
+Popup the Property panel.
+.TP 4
+\fIConnect to Remote Display...\fP
+Open a panel to specify the name of a remote display to be connected,
+so that following key events will be sent to windows on the remote display.
+.TP 4
+\fIRevert to Local Display\fP
+Disconnect from the remote display
+so that following key events will be sent to windows on the local display.
+
+.SH "    Property Panel"
+.TP 4
+\fIEnable "Quick Modifiers"?\fP
+Toggle enable/disable of the
+\fIQuick Modifiers\fP feature.
+.TP 4
+\fILock Shift?\fP
+Toggle locking/momentary of \fIShift\fP keys.
+.TP 4
+\fILock AltGr?\fP
+Toggle locking/momentary of \fIAltGr\fP key.
+.TP 4
+\fILock Control, Alt and Meta?\fP
+Toggle locking/momentary of \fIControl\fP, \fIAlt\fP and \fIMeta\fP keys.
+.TP 4
+\fIAlways on Top?\fP
+If this entry is set ON,
+\fIxvkbd\fP attempts to keep the \fIxvkbd\fP window always on the top of the display
+(i.e. not to be hidden by other windows).
+This feature is experimental,
+and care should be taken as this feature can cause problem in some situations.
+.TP 4
+\fIBehave as Toolbar Window?\fP
+\fIxvkbd\fP attempts to be a toolbar window when it is used with
+some kind of window managers such as Matchbox window manager.
+.TP 4
+\fIUse XTEST Extension?\fP
+XTEST extension will be used if this entry is checked.
+If this entry is set inactive,
+the X server does not support XTEST extension.
+.TP 4
+\fIJump Pointer?\fP
+If this entry is set ON,
+\fIxvkbd\fP will temporary jump the pointer to the focused window,
+if XTEST extension is to be used to simulate keyboard events.
+.TP 4
+\fIKey-Click Sound\fP
+Set on/off and duration of key-click sound.
+.TP 4
+\fIAutomatic Click\fP
+Set on/off of the automatic click feature
+and the delay before automatic click is activated.
+If this feature is set,
+\fIxvkbd\fP will work as if left mouse button is clicked
+when mouse pointer is moved on a button and stays long enough.
+You may want to set \fIJump Pointer?\fP to OFF to avoid auto-repeating.
+.TP 4
+\fICompletion Dictionary\fP
+Set the filename to be used for word completion.
+This setting take precedence over the `\fBxvkbd.dictFile\fP' resource
+and the \fB-dict\fP option.
+
+.SH "    Options"
+\fIxvkbd\fP accept following command line options, in addition to
+general options such as `\fB-display\fP'.
+.PP
+.TP 4
+.B "-version"
+Display version information and exit.
+.TP 4
+.B "-xsendevent"
+Make \fIxvkbd\fP to use \fIXSendEvent()\fP to simulate keyboard events,
+as it was in \fIxvkbd\fP version 1.0.
+\fIxvkbd\fP version 1.1 and later will try to use XTEST extension instead
+in the default configuration.
+.sp 0.5
+If XTEST extension is not supported by the X server,
+\fIxvkbd\fP will automatically switch to this mode.
+.sp 0.5
+Resource `\fBxvkbd.xtest: false\fP' has the same function.
+.TP 4
+.B "-no-sync"
+Normally, \fIxvkbd\fP attempts to synchronize with the destinating client step by step.
+This can cause problem when the client (or the X server) responded too slow.
+In such situation, maybe this \fB-no-sync\fP can solve the problem.
+.sp 0.5
+Resource `\fBxvkbd.noSync: true\fP' has the same function.
+.TP 4
+.B "-no-jump-pointer"
+Make \fIxvkbd\fP not to jump the pointer when sending events.
+In the default, \fIxvkbd\fP will temporary jump the pointer to the focused window,
+if input focus is set explicitly via \fIFocus\fP button,
+and XTEST extension is to be used to simulate keyboard events.
+.sp 0.5
+Resource `\fBxvkbd.jumpPointer: false\fP' has the same function.
+.TP 4
+.B "-no-back-pointer"
+Make \fIxvkbd\fP not to jump the pointer back to the original position
+after events has been sent.
+Maybe this can be useful when using \fIxvkbd\fP to move the pointer position.
+.sp 0.5
+Resource `\fBxvkbd.jumpPointerBack: false\fP' has the same function.
+.TP 4
+.B "-modal"
+Make labels on keys in the \fIxvkbd\fP window
+to be set independently for each of four shift states,
+not shifted, \fIShift\fP, \fIAltGr\fP and \fIShift\fP-\fIAltGr\fP.
+This is useful when you want to make the \fIxvkbd\fP window very small.
+.sp 0.5
+See also "Customizing Keyboard Layout"
+and resouce files in the distribution.
+.sp 0.5
+Resource `\fBxvkbd.modalKeytop: true\fP' has the same function.
+.TP 4
+.B "-geometry "[\fIwidth\fPx\fIheight\fP][\fB+\fIxoff\fP+\fIyoff\fP]
+Set window geometry (size and position).
+.sp 0.5
+You can use form like \fB-geometry 400x130\fP to specify the window size,
+\fB-geometry +100+100\fP to specify the window position from left/top edge of the screen,
+and \fB-geometry 400x130+100+100\fP to specify both the size and the position.
+You can specify position from right/bottom edge of the screen
+by using \fB-\fP instead of \fB+\fP,
+but please note that you must take account of size of the window border.
+(If you specify `\fB-geometry -0-0\fP',
+the window will not fit in the screen.)
+.sp 0.5
+This can be set by \fBxvkbd.windowGeometry\fP resource
+(note that it is not \fBxvkbd.geometry\fP), too.
+.TP 4
+.B "-no-repeat"
+Do not auto-repeat even if key is depressed long time.
+.sp 0.5
+If auto-repeat is enabled (this is the default),
+time before start auto-repeat can be set as
+`\fBxvkbd*Repeater.initialDelay: 600\fP',
+and period of repeat can be set as
+`\fBxvkbd*Repeater.minimumDelay: 100\fP' 
+(unit of there parameters are milli-seconds).
+.sp 0.5
+Resource `\fBxvkbd.autoRepeat: false\fP' has the same function.
+.TP 4
+.B "-no-functionkey"
+Do not display function keys.
+.sp 0.5
+Resource `\fBxvkbd.functionkey: false\fP' has the same function.
+.TP 4
+.B "-no-keypad"
+Do not display keypad.
+.sp 0.5
+Resource `\fBxvkbd.keypad: false\fP' has the same function.
+.TP 4
+.B "-compact"
+Do not display function keys nor keypad.
+.sp 0.5
+Resource `\fBxvkbd.compact: true\fP' has the same function.
+.TP 4
+.B "-keypad"
+Display only keypad.
+This option will be ignored
+if `\fB-no-keypad\fP' or `\fB-compact\fP' is specified.
+.sp 0.5
+Resource `\fBxvkbd.keypadOnly: true\fP' has the same function.
+.TP 4
+.BI "-text " string
+Send the string to the focused window
+(see also `\fB-window\fP' option).
+.sp 0.5
+If this option is specified,
+\fIxvkbd\fP will not open its window
+and terminate soon after sending the string.
+.sp 0.5
+The string can contain:
+.IP "    - " 6
+\fB\\r\fP - Return
+.IP "    - " 6
+\fB\\t\fP - Tab
+.IP "    - " 6
+\fB\\b\fP - Backspace
+.IP "    - " 6
+\fB\\e\fP - Escape
+.IP "    - " 6
+\fB\\d\fP - Delete
+.IP "    - " 6
+\fB\\S\fP - Shift (modify the next character;
+please note that modify with ``\fB\\S\fP'' will be ignored in many cases.
+For example, ``\fBa\\Cb\\ScD\\CE\fP'' will be interpreted as \fBa\fP,
+Control-\fBb\fP, \fBc\fP, Shift-\fBD\fP, and Control-Shift-\fBE\fP.)
+.IP "    - " 6
+\fB\\C\fP - Control (modify the next character)
+.IP "    - " 6
+\fB\\A\fP - Alt (modify the next character)
+.IP "    - " 6
+\fB\\M\fP - Meta (modify the next character)
+.IP "    - " 6
+\fB\\[\fP\fIkeysym\fP\fB]\fP - the keysym \fIkeysym\fP
+(e.g., \fB\\[Left]\fP)
+.IP "    - " 6
+\fB\\D\fP\fIdigit\fP - delay \fIdigit\fP * 100 ms
+.IP "    - " 6
+\fB\\x\fP\fIvalue\fP - move mouse pointer (use "+" or "-" for relative motion)
+.IP "    - " 6
+\fB\\y\fP\fIvalue\fP - move mouse pointer (use "+" or "-" for relative motion)
+.IP "    - " 6
+\fB\\m\fP\fIdigit\fP - simulate click of the specified mouse button
+.TP 4
+.BI "-file " filename
+Send the contents of the specified file to the focused window
+(see also `\fB-window\fP' option).
+If ``\fB-\fP'' was specified as the \fIfilename\fP,
+string to be sent will be read from the standard input (stdin).
+.sp 0.5
+If this option is specified,
+\fIxvkbd\fP will not open its window
+and terminate soon after sending the string.
+.TP 4
+.BI "-delay " value
+Put \fIvalue\fP ms of delay for evey characters
+when sending characters with \fB-text\fP or \fB-file\fP.
+Maybe this is useful when problem arises when characters are entered too fast.
+.TP 4
+.BI "-window " window
+Specify the ID 
+(hexadecimal value leaded with `\fB0x\fP', or decimal value),
+the name (instance name or class name) of the window,
+or the title of the window to set input focus.
+It is possible to use wildcard characters `\fB*\fP' and `\fB?\fP'
+to match the window name or the window title.
+.sp 0.5
+If this is not specified, \fIxvkbd\fP will use input focus
+under control of the window manager,
+unless focus is specified explicitly via \fIFocus\fP button.
+Even if this option is specified,
+you can set input focus to other windows using \fIFocus\fP button,
+or clear the input focus.
+.sp 0.5
+If there are two or more windows which have the name specified with this option,
+the window which was found first will be selected.
+.TP 4
+.BI "-widget " widget-name
+Specify the name of the widget to set the input focus.
+To use this feature, the client must support \fIEditres\fP protocol.
+In general, this option will be used with `\fB-window\fP' option.
+.sp 0.5
+If you want to set input focus to the widget \fBfoo.bar.zot\fP,
+you can write \fBzot\fP, \fBbar.zot\fP or \fBfoo.bar.zot\fP
+as \fIwidget-name\fP.
+To avoid confusion, the \fIwidget-name\fP should match
+with a single widget of the client.
+.sp 0.5
+For example,
+.sp
+.in +4
+\fBxvkbd -window xarchie -widget searchText -text "\\Ca\\Ckabc\\r\fP"
+.sp
+.in -4
+will enter the string ``\fBabc\fP'' to the ``Search Term'' field
+of a \fBxarchie\fP window.
+.TP 4
+.B "-true-keypad"
+If this option is specified,
+\fIxvkbd\fP will attempt to use \fIkeysym\fPs such as 
+\fIXK_KP_1\fP instead of \fIXK_1\fP.
+.sp 0.5
+Resource `\fBxvkbd.keypadKeysym: true\fP' has the same function.
+.TP 4
+.BI "-dict " filename
+Specify the default dictionary (list of words) file to be used for
+word completion.
+The `\fICompletion Dictionary\fP' filename
+set on the Property panel takes precedence over this.
+.sp 0.5
+Resource `\fBxvkbd.dictFile: \fP\fIfilename\fP' has the same function.
+.sp 0.5
+See also ``Making your own completion dictionary''.
+.TP 4
+.B "-minimizable"
+Make \fIxvkbd\fP window can be minimized (iconified)
+even if no window manager is in use.
+When this feature is enabled,
+small triangle will be displayed at left ot the \fIxvkbd\fP main menu,
+and \fIxvkbd\fP window will be minimized when the triangle is clicked.
+.sp 0.5
+Resource `\fBxvkbd.minimizable: true\fP' has the same function.
+.TP 4
+.B "-secure"
+Disable invocation of external commands,
+including user assigned command and the online manual reader.
+Connection to another displays would also be disabled.
+This option may be useful when \fIxvkbd\fP is to be run with some kind of privileges.
+.sp 0.5
+Resource `\fBxvkbd.secure: true\fP' has the same function.
+.TP 4
+.B "-nonexitable"
+Disable termination of the \fIxvkbd\fP program.
+This option may be useful when \fIxvkbd\fP is to be run automatically
+for systems with no keyboards and users should not terminate the \fIxvkbd\fP.
+.sp 0.5
+Resource `\fBxvkbd.nonexitable: true\fP' has the same function.
+.TP 4
+.B "-xdm"
+Same as \fB-secure -nonexitable\fP.
+When \fIxvkbd\fP is to be run for login screen,
+it would be suggested to use this option.
+.TP 4
+.BI "-modifiers " modifiers
+Normally, \fIxvkbd\fP will activate modifiers (control, shift, etc.)
+only while sending characters.
+If modifiers were specified with this option,
+the specified modifiers will be activated
+while corresponding key on the \fIxvkbd\fP window is in active.
+For example, you can specify \fB-modifiers shift,control,meta,alt\fP
+to apply this for those four modifiers.
+Maybe this can be useful when attempting to decorate
+the mouse operations with the modifiers.
+Please note that the modifiers will also be applied
+when attempting to click on the \fIxvkbd\fP window
+and which can prevent the correct operation in some situations.
+.sp 0.5
+Resource `\fBxvkbd.positiveModifiers: \fP\fImodifiers...\fP' has the same function.
+.TP 4
+.B "-debug"
+Make \fIxvkbd\fP to output debug information.
+It also disable keyboard width adjustment,
+to help adjusting key size when making keyboard layout file.
+.sp 0.5
+<!--
+.TP 4
+.B "-version"
+Output version information and exit.
+-->
+
+.SH "Screen Shot"
+.TP 4
+Default (US)
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-normal.gif
+.TP 4
+Belgian
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-belgian.gif
+.TP 4
+Danish
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-danish.gif
+.TP 4
+French
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-french.gif
+.sp 0.5
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-french2.gif
+.TP 4
+German
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-german.gif
+.TP 4
+Icelandic
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-icelandic.gif
+.TP 4
+Italian
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-italian.gif
+.TP 4
+Japanese (JIS-X-6002)
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-jisx6002.gif
+.TP 4
+Japanese (JIS-X-6004)
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-jisx6004.gif
+.TP 4
+Norwegian
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-norwegian.gif
+.TP 4
+Portuguese
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-portuguese.gif
+.TP 4
+Spanish
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-spanish.gif
+.TP 4
+Swedish
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-swedish.gif
+.TP 4
+Swiss/German
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-swissgerman.gif
+.TP 4
+United Kingdom
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-uk.gif
+.TP 4
+Latin-1
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-latin1.gif
+.TP 4
+Small Keyboard (maybe suitable for PDAs)
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-small.gif
+.TP 4
+Hebrew
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-hebrew.gif
+.TP 4
+Greek
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-greek.gif
+.TP 4
+Turkish
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-turkish.gif
+.TP 4
+Slovene
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-slovene.gif
+.TP 4
+Korean
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-korean.gif
+.TP 4
+Russian (Cyrillic)
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-russian.gif
+
+.SH "Download"
+.TP 4
+\fILatest Official Release\fP
+\fIhttp://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.2.tar.gz\fP
+.br
+- source of version 3.2 (2010-03-14)
+.TP 4
+previous release
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.1.tar.gz
+.br
+- source of version 3.1 (2010-01-17)
+.sp 0.5
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-3.0.tar.gz
+.br
+- source of version 3.0 (2008-05-05)
+.PP
+\fIxvkbd\fP is distributed under the terms of the
+GNU General Public License.
+
+.SH "Install"
+.IP "  o " 4
+\fIuntar\fP the source in a directory,
+and move to the directory
+.IP "  o " 4
+If you wish to use genuine \fIXaw\fP insead of \fIXaw3d\fP,
+edit \fBImakefile\fP and remove (or comment-out) `\fB#define XAW3D\fP'.
+.sp 0.5
+When you are installing \fIxvkbd\fP (for example) in very old systems,
+you may also want to remove `\fB#define XTEST\fP' and `\fB#define I18N\fP'
+to disable XTEST and internationalization facility respectively.
+.IP "  o " 4
+Run \fBxmkmf; make install install.man\fP
+
+.SH "Customization"
+
+.SH "    How to Customize \fIxvkbd\fP"
+Some degree of customization of \fIxvkbd\fP is possible
+by setting resources.
+Some resources are already described above,
+and resources to customizing keyboard layout are described below.
+.PP
+To set resources, you can:
+.IP "  o " 4
+put them in your \fB$HOME/.Xdefaults\fP file, or
+.IP "  o " 4
+load them via \fIxrdb\fP(1), or
+.IP "  o " 4
+set the filename to the \fB$XENVIRONMENT\fP environment variable, or
+.IP "  o " 4
+put them in application default directory as `\fBXVkbd-\fP\fIsuffix\fP'
+and set resource ``\fBxvkbd.customization: -\fP\fIsuffix\fP'', or
+.IP "  o " 4
+put them in application default directory as \fBXVkbd\fP.
+.PP
+Here, \fIapplication default directory\fP can be either of:
+.IP "  o " 4
+directories specified with \fB$XUSERFILESEACHPATH\fP,
+\fB$XAPPLRESDIR\fP or else \fB$HOME\fP environment variable
+.IP "  o " 4
+system's application default directory specified with
+\fB$XFILESEACHPATH\fP environment variable,
+or else the directory specified when compiling the X
+(e.g., \fB/usr/lib/X11/app-defaults\fP)
+.PP
+When the application default file is to be stored
+in the system's application default directory,
+the file must contain ``\fB#include "XVkbd-common"\fP''
+near top of the file.
+.PP
+\fIxvkbd\fP is distributed with some application default files,
+and they will be installed in the system's application default directory.
+
+.SH "    Making Window Small"
+Size (and position) of \fIxvkbd\fP window can be set
+by `\fBxvkbd.windowGeometry\fP' resource.
+When making window small, you may need to choose the smaller font, too.
+.sp
+.in +4
+.nf
+  xvkbd.windowGeometry: 220x90
+  xvkbd.compact: true
+  xvkbd*Font: 6x12
+.fi
+.sp
+.in -4
+.PP
+You may also want to set:
+.sp
+.in +4
+.nf
+  xvkbd.modalKeytop: true
+.fi
+.sp
+.in -4
+to display only the labels for the current shift state,
+instead of trying to always display all of them in the small keytop.
+.PP
+See also \fBXVkbd-small.ad\fP in the \fIxvkbd\fP distribution.
+
+.SH "    Removing Unwanted Keys"
+Keys on \fIxvkbd\fP window can be removed by setting its width to 1.
+.PP
+To remove \fICompose\fP key and make \fIShift\fP key larger,
+you can write:
+.sp
+.in +4
+.nf
+  xvkbd*Multi_key.width: 1
+  xvkbd*Shift_R.width: 75
+.fi
+.sp
+.in -4
+.PP
+To remove right \fIAlt\fP and \fIMeta\fP key,
+you can write:
+.sp
+.in +4
+.nf
+  xvkbd*Alt_R.width: 1
+  xvkbd*Meta_R.width: 1
+.fi
+.sp
+.in -4
+
+.SH "    Customizing Keyboard Layout"
+Layout of keys on the \fIxvkbd\fP window can be customized
+with following resources:
+.TP 4
+.B "xvkbd.NormalKeys"
+list of keys available when neighter of \fIShift\fP and \fIAltGr\fP are selected
+.TP 4
+.B "xvkbd.ShiftKeys"
+list of keys available when \fIShift\fP is selected
+.TP 4
+.B "xvkbd.AltgrKeys"
+list of keys available when \fIAltGr\fP is selected
+.TP 4
+.B "xvkbd.ShiftAltgrKeys"
+list of keys available when both \fIAltGr\fP and \fIShift\fP are selected
+.TP 4
+.B "xvkbd.KeyLabels"
+list of labels displayed on the keys
+.TP 4
+.B "xvkbd.NormalKeyLabels"
+list of labels displayed on the keys
+  when neither of \fIShift\fP and \fIAltGr\fP are selected.
+.TP 4
+.B "xvkbd.ShiftKeyLabels"
+list of labels displayed on the keys
+  when \fIShift\fP is selected
+.TP 4
+.B "xvkbd.AltgrKeyLabels"
+list of labels displayed on the keys
+  when \fIAltGr\fP is selected
+.TP 4
+.B "xvkbd.ShiftAltgrKeyLabels"
+list of labels displayed on the keys
+  when both \fIAltGr\fP and \fIShift\fP are selected
+.PP
+Four resources to set labels on the keys
+(\fBxvkbd.NormalKeyLabels\fP, \fBxvkbd.ShiftKeyLabels\fP,
+\fBxvkbd.AltgrKeyLabels\fP and \fBxvkbd.ShiftAltgrKeyLabels\fP)
+will be used instead of \fBxvkbd.KeyLabels\fP
+when \fBxvkbd.modalKeytop\fP resoruce is set \fBtrue\fP.
+.PP
+In all of those resources, each keys are separated by spaces,
+and rows of keys are terminated with `\fB \\n\\\fP'
+(note that `\fB\\n\fP' must have space before it).
+Please refer \fBXVkbd-german.ad\fP and \fBXVkbd-latin1.ad\fP
+in the \fIxvkbd\fP distribution for more about these resources.
+.PP
+\fBXVkbd-german\fP and \fBXVkbd-latin1\fP will be installed
+in the system's application default directory,
+and setting the resource ``\fBxvkbd.customization: -german\fP''
+will make \fIxvkbd\fP to use the German layout.
+For another method to activate those settings, please refer
+"How to Customize \fIxvkbd\fP" above.
+
+.SH "    Assigning Text to Function Keys"
+Text can be assigned to each function keys
+(and, actually, to most other keys).
+If text is assigned to the function key,
+clicking on the key will send the assigned text
+instead of the function key itself.
+When pointer is on a key where text is assigned,
+the text will be displayed near the key.
+.PP
+The setting will be read from a text file
+which contains text for each function keys as:
+.sp
+.in +4
+.nf
+  F1 text for F1
+  F2 text for F2
+  s:F1 text for Shift-F1
+  c:F1 text for Control-F1
+  m:F1 text for Meta-F1
+  a:F1 text for Alt-F1
+  ...
+.fi
+.sp
+.in -4
+.PP
+`\fBs:\fP', `\fBc:\fP', `\fBm:\fP' and `\fBa:\fP'
+before the keys name indicates four modifiers
+(\fIShift\fP, \fIControl\fP, \fIMeta\fP and \fIAlt\fP) respectively.
+.PP
+If the first character of the assigned string is `\fB!\fP',
+the string will be used as command to be executed when the key is clicked.
+To assign string starting with `\fB!\fP' or `\fB\\\fP',
+put `\fB\\\fP' before the string.
+.PP
+The file is \fB$HOME/.xvkbd\fP in default,
+and it can be changed by setting the filename
+with \fBxvkbd.keyFile\fP resource.
+.PP
+For \fBF1\fP to \fBF12\fP with or without \fIShift\fP modifier,
+it is possible to edit the assigned string on a panel popped up via
+"\fIEdit Function Keys...\fP" in the main menu.
+
+.SH "Miscellaneous Informations"
+
+.SH "    Notes"
+.IP "  o " 4
+On \fIXFree86\fP, resolution switch with
+\fICtrl + Alt + Keypad-Plus\fP and \fICtrl + Alt + Keypad-Minus\fP 
+may be simulated.
+However, \fICtrl + Alt + Backspace\fP will not be simulated.
+.IP "  o " 4
+\fIShift\fP is used to decide key to be sent
+and it will not used to set modifier bit when sending the event.
+You can use \fBxev\fP command to check what is actually sent.
+.IP "  o " 4
+If \fIAlt\fP or \fIMeta\fP is not defined as modifier,
+the key can't be used as modifier.
+You can use `\fBxmodmap -pm\fP' to check how modifiers are defined.
+.IP "  o " 4
+\fINum Lock\fP (and maybe other modifiers) on the physical keyboard
+may not work correctly when \fIxvkbd\fP is in use.
+
+.SH "    Additional Informations"
+.TP 4
+FAQ - Possible Problems and Solutions
+http://homepage3.nifty.com/tsato/xvkbd/faq.html
+.TP 4
+Making your own completion dictionary
+http://homepage3.nifty.com/tsato/xvkbd/make-dic.html
+.TP 4
+Hints to use \fBxvkbd -text\fP
+http://homepage3.nifty.com/tsato/xvkbd/xvkbd-text.html
+.TP 4
+Note about how to send key events
+http://homepage3.nifty.com/tsato/xvkbd/events.html
+
+.SH "Change Log"
+.TP 4
+Version 0.1 (2000-05-13)
+.IP "    - " 6
+
+The first release, not announced anywhere.
+.TP 4
+Version 0.2 (2000-09-15)
+.IP "    - " 6
+Compose key is added.
+In the environments where Compose key is supported,
+some characters (mainly letters with accent symbol)
+which can't be entered directly from keyboard
+can be entered using dedicated key combinations.
+.IP "    - " 6
+Make keyboard layout not to be disturbed when
+window size if specified with \fB-geometry\fP option.
+.IP "    - " 6
+Sample app-defaults file is added.
+.TP 4
+Version 0.3 (2000-10-05)
+.IP "    - " 6
+\fB-text\fP option can now accept some modifiers
+(\fB\\S\fP, \fB\\C\fP, etc.) and any keysyms 
+(\fB\\[\fP\fIkeysym\fP\fB]\fP).
+.IP "    - " 6
+In addition to the window ID,
+\fB-window\fP option can now accept window name.
+.IP "    - " 6
+New \fB-widget\fP option to specify the widget to set the input focus.
+.TP 4
+Version 1.0 (2000-11-03)
+.IP "    - " 6
+Keyboard layout can be now configured with resources.
+See "Customizing Keyboard Layout" above,
+and \fBXVkbd-german.ad\fP in the distribution.
+.IP "    - " 6
+\fIxvkbd\fP can now send keys
+with \fIMode_switch\fP (\fIAltGr\fP) modifier,
+which enables those characters in the position to be entered.
+.IP "    - " 6
+\fIxvkbd\fP now support \fIAltGr\fP key
+so that German (and some other) keyboard layout can be used.
+See \fBXVkbd-german.ad\fP in the distribution.
+.IP "    - " 6
+\fBXVkbd-german\fP and \fBXVkbd-latin1\fP are included
+in the distribution, which modifies keyboard layout
+and put some non-ASCII keys on the \fIxvkbd\fP window.
+.IP "    - " 6
+\fICapsLock\fP key is supported now.
+.TP 4
+Version 1.1 (2000-12-23)
+.IP "    - " 6
+\fIxvkbd\fP can now use XTEST extension to simulate keyboard events.
+It can still use \fIXSendEvent()\fP, as it was in the older release.
+(thanks, Bjoern)
+.IP "    - " 6
+Labels on keys can now be set independently for each of four shift states,
+not shifted, \fIShift\fP, \fIAltGr\fP and \fIShift\fP-\fIAltGr\fP.
+(thanks, Jim)
+.IP "    - " 6
+\fB-kterm\fP option and \fBxvkbd.kterm\fP resource are removed.
+.TP 4
+Version 1.2 (2001-02-18)
+.IP "    - " 6
+\fIFocus\fP button is now placed in the main keyboard, too,
+so that it will be available also in compact mode.
+If you don't need it,
+it can be removed by setting ``\fBxvkbd*row5.Focus.width: 1\fP''.
+.IP "    - " 6
+Input focus set by \fIFocus\fP button can now be cleard
+by clicking \fIFocus\fP button twice.
+Clicking \fIFocus\fP button with mouse button 3 will
+still clear the input focus, too.
+.IP "    - " 6
+Text can now be assigned to function keys
+(and, actually, to most other keys).
+.IP "    - " 6
+It is now possible to assign keys modified with
+\fIShift\fP, \fIControl\fP, \fIAlt\fP and \fIMeta\fP on the main keyboard,
+by putting `\fBs:\fP', `\fBc:\fP', `\fBa:\fP' and `\fBm:\fP'
+before those keysym name when
+customizing the keyboard layout.
+.IP "    - " 6
+\fIxvkbd\fP now ignores SIGINT and SIGQUIT
+so that it will not terminated accidently.
+.TP 4
+Version 1.3 (2001-03-19)
+.IP "    - " 6
+New app-defaults file for Swiss-German layout, \fBXVkbd-swissgerman.ad\fP.
+(contributed from Marcel Portner)
+.IP "    - " 6
+\fIxvkbd\fP now catches MappingNotify event and reload the new mapping.
+This allows users to use \fBxmodmap\fP while \fIxvkbd\fP is running.
+.IP "    - " 6
+\fINumLock\fP key is supported now.
+(I'd removed \fIPrint\fP, \fIScrLk\fP and \fIPause\fP from keypad
+- somebody need them?)
+.TP 4
+Version 1.4 (2001-04-22)
+.IP "    - " 6
+Auto-repeat didn't work
+when focus was set explicitly via \fIFocus\fP button.
+It is now fixed.
+.IP "    - " 6
+When required keysym was not defined in the keymap table,
+\fIxvkbd\fP will now add it on-the-fly.
+This means that we don't have to add them via \fIxmodmap\fP.
+.IP "    - " 6
+Keypad panel can now be popped up from the main keyboard
+as a separate window.
+.IP "    - " 6
+Sun function keys is now supported.
+It can be popped up from the main keyboard as a separate window.
+.IP "    - " 6
+Manual page is now available.
+.TP 4
+Version 1.5 (2001-10-08)
+.IP "    - " 6
+Key events can now be sent to windows on a remote display
+(i.e. windows on other X servers)
+- use "\fIConnect to Remote Display...\fP" in the main menu
+to connect to remote display.
+.IP "    - " 6
+\fIShift\fP, \fIControl\fP, \fIAlt\fP and \fIMeta\fP can now be locked
+- use "\fILock Shift?\fP" and "\fILock Control, Alt and Meta?\fP"
+in the main menu.
+Those initial settings can be set by 
+\fBxvkbd.shiftLock\fP and \fBxvkbd.modifiersLock\fP resource.
+.IP "    - " 6
+If the first keysym for a key is an alphabet
+and the second keysym is \fINoSymbol\fP,
+it is now interpreted as if the first keysym is lowercase alphabet
+and the second keysym is uppercase alphabet.
+Keymap may be defined in this way in some systems including Solaris,
+and older \fIxvkbd\fP may not work correctly in such situation.
+.TP 4
+Version 1.6 (2001-11-10)
+.IP "    - " 6
+New `\fB-file\fP' option to send characters in the specified file.
+(thanks, Gregory)
+.IP "    - " 6
+New entry `\fIUse XTEST Extension?\fP' is added
+to the main menu,
+mainly to indicate the availability of the XTEST extension.
+.IP "    - " 6
+\fIxvkbd\fP would crash when the window explicitly focused
+via \fIFocus\fP button becomes was destroyed.
+This problem is now fixed.
+.TP 4
+Version 2.0 (2001-12-09)
+.IP "    - " 6
+Keyboard layout (default, German, French, etc.) can now be changed
+after \fIxvkbd\fP is invoked.
+.IP "    - " 6
+Show/hide of the keypad and funcion keys on the main window
+can now be toggled from the main menu.
+.IP "    - " 6
+New app-defaults file for French layout, \fBXVkbd-french.ad\fP.
+(contributed from Jean-Pierre Demailly)
+.TP 4
+Version 2.1 (2002-01-27)
+.IP "    - " 6
+When height of the \fIxvkbd\fP window is smaller than
+\fBXVkbd.modalThreshold\fP,
+\fIxvkbd\fP will now automatically switch the keytop
+as if \fB-modal\fP option was specified.
+.IP "    - " 6
+\fB\\[\fP\fIkeysym\fP\fB]\fP in \fB-text\fP option
+would send wrong keys - this problem is now fixed.
+.IP "    - " 6
+Target \fBdistclean\fP in the \fBImakefile\fP is renamed
+to avoid the possible confusion on some systems.
+.IP "    - " 6
+Word completion is now supported.
+.TP 4
+Version 2.2 (2002-03-17)
+.IP "    - " 6
+String assigned to function keys can now be edited on a panel popped up via
+"\fIEdit Function Keys...\fP" in the main menu.
+.IP "    - " 6
+When ``\fB-\fP'' was specified as the filename parameter
+for \fB-file\fP option, \fIxvkbd\fP will now read
+its standard input (stdin) to get the string to be sent.
+.IP "    - " 6
+In the previous release,
+less-portable \fBsetenv()\fP function was used
+instead of \fBputenv()\fP function,
+may cause compilation error on some systems including Solaris.
+.TP 4
+Version 2.3 (2002-04-05)
+.IP "    - " 6
+New "Dead Keys" panel added.
+Which can be used to enter Latin characters with accent symbol in double stroke.
+.IP "    - " 6
+More localized keyboard layout:
+Belgian,
+Danish,
+French,
+German,
+Icelandic,
+Italian,
+Japanese (JIS-X-6004),
+Norwegian,
+Portuguese,
+Spanish,
+Swedish,
+Swiss/German,
+United Kingdom
+and Latin-1.
+.IP "    - " 6
+\fB-keypad\fP option would crash previous version of \fIxvkbd\fP
+- this problem is now fixed.
+.TP 4
+Version 2.4 (2002-10-02)
+.IP "    - " 6
+Command can now be assigned to function keys
+so that clicking on the function key will execute the command
+instead of sending the string to clients.
+.IP "    - " 6
+Assigned string for \fBF1\fP to \fBF12\fP
+with \fIShift\fP modifier can now be edited on a panel popped up via
+"\fIEdit Function Keys...\fP" in the main menu.
+.TP 4
+Version 2.5 (2002-10-12)
+.IP "    - " 6
+\fIQuick Modifier\fP feature added
+- now, it is possible to enter characters with modifiers
+by pressing a key and then move the pointer.
+(suggested by Niklas Rokaeus)
+.IP "    - " 6
+``\fILock AltGr?\fP'' entry is added in the main menu.
+.IP "    - " 6
+Status of ``\fILock Shift?\fP'', ``\fILock AltGr\fP'',
+``\fILock Control, Alt and Meta?\fP'' will be recorded in \fB$HOME/.xvkbd\fP file
+and it will be read when \fIxvkbd\fP is invoked next time.
+.TP 4
+Version 2.5a (2003-06-25)
+.IP "    - " 6
+``Fitaly'' layout is now supported
+- may be useful for PDAs.
+.TP 4
+Version 2.6 (2004-05-04)
+.IP "    - " 6
+Code to adding keysyms which were not found in the keymap table is revised.
+\fIxvkbd\fP now avoid to add keysyms in the shifted position of keys
+which already have a keysym defined in the non-shifted position,
+and entries in the keymap table which is modified keys will be redefined
+rather than redefining the entire keymap table.
+This change is to avoid possible problem (\fIAltGr\fP key could be effectively disabled)
+which may caused in some systems where \fIXGetKeyboardMapping()\fP can produce
+incorrect map when keys have more then two keysyms.
+.IP "    - " 6
+If \fIMode_switch\fP is not defined in the modifier table
+but \fIISO_Level3_Shift\fP is defined,
+\fIxvkbd\fP now attempt to add \fIMode_switch\fP as the same modifier
+with \fIISO_Level3_Shift\fP.
+.IP "    - " 6
+Korean layout is now supported.
+Although Hangul characters will be displayed on the keys,
+\fIxvkbd\fP will simply generate alphabet characters when those keys are clicked.
+It is intented to be used with "ami" or similar Hangul input program.
+.IP "    - " 6
+URL of the \fIxvkbd\fP main page is now changes to
+http://homepage3.nifty.com/tsato/xvkbd/.
+.TP 4
+Version 2.7 (2005-05-05)
+.IP "    - " 6
+Yet another Japanese keyboard layout, JIS X 6002, is now supported.
+.IP "    - " 6
+It is now possible to minimize (iconify) the main window
+even if no window manager is in use.
+This feature can be activated by \fB-minimizable\fP option
+or \fBxvkbd.minimizable\fP resource.
+.IP "    - " 6
+Experimental code to keep the \fIxvkbd\fP window always on the top of the display.
+This feature can be activated by \fB-always-on-top\fP option,
+\fBxvkbd.alwaysOnTop\fP resource
+or the "Always on Top?" entry in the main menu.
+Care should be taken as this feature can cause problem in some situations.
+.IP "    - " 6
+\fB-text\fP option now support combinations of modifiers and a special key.
+For example, \fB-text '\\C\\A\\d'\fP can be used for Control-Alt-Delete key combination.
+.IP "    - " 6
+New options:
+\fB-secure\fP option (\fBxvkbd.secure\fP resource)
+which disables invocation of external commands,
+\fB-nonexitable\fP option (\fBxvkbd.nonexitable\fP resource)
+which inhibits termination of the program,
+and \fB-xdm\fP option which is equivalent to \fB-secure -nonexitable\fP
+and maybe useful when run \fIxvkbd\fP from a display manager.
+.TP 4
+Version 2.7a (2005-05-07)
+.IP "    - " 6
+Fixed a problem that \fIxvkbd\fP could cause segmentation fault on startup.
+.TP 4
+Version 2.8 (2006-09-10)
+.IP "    - " 6
+\fIISO_Level3_Shift\fP is now to be prefered over \fIMode_switch\fP
+so that \fIAltGr\fP can be used on relatively new systems
+where we must use \fIISO_Level3_Shift\fP instead of \fIMode_switch\fP.
+.IP "    - " 6
+Reference to the target bitmap is changed from
+\fB/usr/X11R6/include/X11/bitmaps/target\fP to \fB/usr/include/X11/bitmaps/target\fP.
+.IP "    - " 6
+New options: \fB-no-back-pointer\fP, \fB-no-sync\fP, \fB-modifiers\fP.
+.TP 4
+Version 2.9 (2008-03-30)
+.IP "    - " 6
+Russian (Cyrillic) keyboard layout supported. (thanks, Victor)
+.IP "    - " 6
+New \fB-delay\fP option.
+.IP "    - " 6
+\fB\\D\fP special sequence in \fB-text\fP can be used to put a delay in specific position.
+.IP "    - " 6
+\fB-text\fP can now simulate mouse operation
+via \fB\\x\fP, \fB\\y\fP and \fB\\m\fP special sequences.
+.TP 4
+Version 3.0 (2008-05-05)
+.IP "    - " 6
+New Property panel.
+.IP "    - " 6
+New automatic click feature.
+.IP "    - " 6
+Key-click sounds when key is pressed.
+.TP 4
+Version 3.1 (2010-01-17)
+.IP "    - " 6
+Changed the default setting for automatic click to OFF, which was set ON in the previous release in error and caused confusion.
+.IP "    - " 6
+The keypad is now customizable, too (see XVkbd-strip.ad for the example).
+.IP "    - " 6
+Up to 25x25 keys can now be supported both for the main keyboard and the keypad.
+.IP "    - " 6
+Able to open the keypad panel when startup, by setting `\fBxvkbd.keypad: false\fP' and `\fBxvkbd.keypadOnly: true\fP'.
+.IP "    - " 6
+Fixed errors in some keyboard layout files (Korean, Slovene, UK).
+.IP "    - " 6
+A new sample layout file XVkbd-strip.ad.
+.TP 4
+Version 3.2 (2010-03-14)
+.IP "    - " 6
+New option `\fIBehave as Toolbar Window?\fP' on the Property panel,
+  which may make xvkbd works better with some kind of window managers
+  such as Matchbox window manager. (Thanks, Patrick)
+.IP "    - " 6
+`\fIAlways on Top\fP' will work rather better with window managers
+  which support extended window manager hint \fB_NET_WM_STATE_ABOVE\fP.
+.IP "    - " 6
+\fB-window\fP option can now find window which have title match with
+  the specified string.
+.IP "    - " 6
+\fB-window\fP option now accept wildcard characters
+  `\fB*\fP' and `\fB?\fP'.
+.IP "    - " 6
+Word completion dictionary file to be used with `\fIWord Completion...\fP'
+  can now be specified on the Property panel.
+.IP "    - " 6
+Only the words which have two or more characters will be appeared
+  in the word completion list.
+.IP "    - " 6
+New \fB-version\fP option to display version information.
+
+.SH "Author"
+\fIxvkbd\fP was written by Tom Sato,
+and it is distributed under the terms of the
+GNU General Public License
+Version 2 or any later version.
+.PP
+Please send any feedback (such as bug reports, requests or comments) to
+Tom Sato <VEF00200@nifty.ne.jp>.
+.PP
+The latest version of this software
+and more information about it may be available at
+http://homepage3.nifty.com/tsato/xvkbd/.
+Release of the new version will be announced
+on the Freshmeat (http://freshmeat.net),
+and you can probably receive the announce via e-mail if you wish.
diff --git a/development/autotests/xvkbd/xvkbd.xbm b/development/autotests/xvkbd/xvkbd.xbm
new file mode 100644 (file)
index 0000000..1d1d726
--- /dev/null
@@ -0,0 +1,10 @@
+#define xvkbd_width 28
+#define xvkbd_height 20
+static unsigned char xvkbd_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
+   0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x07,
+   0x00, 0x10, 0x82, 0x05, 0x00, 0x10, 0xda, 0x04, 0x00, 0x90, 0x56, 0x04,
+   0x00, 0xdc, 0x62, 0x04, 0x40, 0x54, 0xa2, 0x06, 0x60, 0x36, 0xb2, 0x03,
+   0xd6, 0x72, 0x1a, 0x00, 0x9c, 0xd2, 0x06, 0x00, 0x98, 0x93, 0x01, 0x00,
+   0x38, 0x11, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+   0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/development/autotests/xvkbd/xvkbd_icon.xbm b/development/autotests/xvkbd/xvkbd_icon.xbm
new file mode 100644 (file)
index 0000000..7ef37b8
--- /dev/null
@@ -0,0 +1,27 @@
+#define xvkbd_icon_width 48
+#define xvkbd_icon_height 48
+static unsigned char xvkbd_icon_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x05, 0xa0, 0xaa, 0x02,
+   0xaa, 0xaa, 0x2a, 0x54, 0x55, 0x15, 0x54, 0x55, 0x55, 0xaa, 0xaa, 0x2a,
+   0x00, 0x00, 0x68, 0x14, 0x00, 0x34, 0x00, 0x00, 0xf0, 0x0a, 0x00, 0x78,
+   0x00, 0x00, 0xe0, 0xc5, 0x03, 0x71, 0x00, 0x00, 0xc0, 0xc2, 0x83, 0x60,
+   0x00, 0x00, 0xe0, 0x85, 0x47, 0x70, 0x00, 0x00, 0xc0, 0x02, 0x4f, 0x60,
+   0x00, 0x00, 0xe0, 0x05, 0x2e, 0x70, 0x00, 0x00, 0xc0, 0x02, 0x16, 0x60,
+   0x00, 0x00, 0xe0, 0x05, 0x3a, 0x70, 0x00, 0x00, 0xc0, 0x02, 0x79, 0x60,
+   0x00, 0x00, 0xe0, 0x05, 0xf1, 0x70, 0x00, 0x00, 0xc0, 0x82, 0xf0, 0x60,
+   0x00, 0x00, 0xe0, 0x45, 0xe0, 0x71, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x60,
+   0x00, 0x00, 0xe0, 0x05, 0x00, 0x70, 0x00, 0x00, 0xd0, 0x0a, 0x00, 0x68,
+   0x00, 0x00, 0x68, 0x14, 0x00, 0x34, 0x54, 0x55, 0x75, 0xba, 0xaa, 0x3a,
+   0xfe, 0xff, 0x3f, 0xfc, 0xff, 0x1f, 0xfe, 0xff, 0x0f, 0xf0, 0xff, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x2a,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x15, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x08, 0x10, 0x0a, 0x00,
+   0x00, 0x00, 0x08, 0x1c, 0x04, 0x00, 0x00, 0x40, 0x08, 0x16, 0x0a, 0x00,
+   0x00, 0x40, 0x68, 0x13, 0x04, 0x00, 0x00, 0x40, 0x5a, 0x11, 0x0a, 0x00,
+   0x00, 0x70, 0x8b, 0x11, 0x04, 0x00, 0x00, 0x51, 0x89, 0x1a, 0x0a, 0x00,
+   0x80, 0xd9, 0xc8, 0x0e, 0x04, 0x00, 0x58, 0xcb, 0x69, 0x00, 0x0a, 0x00,
+   0x70, 0x4a, 0x1b, 0x00, 0x04, 0x00, 0x60, 0x4e, 0x06, 0x00, 0x0a, 0x00,
+   0xe0, 0x44, 0x00, 0x00, 0x14, 0x00, 0xb0, 0x04, 0x00, 0x00, 0x28, 0x00,
+   0x10, 0x01, 0x00, 0x00, 0x74, 0x15, 0x18, 0x00, 0x00, 0x00, 0xf8, 0x3f,
+   0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/development/autotests/xvkbd/xvkbd_iconmask.xbm b/development/autotests/xvkbd/xvkbd_iconmask.xbm
new file mode 100644 (file)
index 0000000..ab48300
--- /dev/null
@@ -0,0 +1,27 @@
+#define xvkbd_iconmask_width 48
+#define xvkbd_iconmask_height 48
+static unsigned char xvkbd_iconmask_bits[] = {
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};