SUPERSEDES 17289.64164.570641.111644(a)parhasard.net
I plan on committing this relatively soon; yeah, it’s a bit of a hack, but
I’m pretty sure there isn’t a better way to do it under X11.
lisp/ChangeLog addition:
2005-12-18 Aidan Kehoe <kehoea(a)parhasard.net>
* x-win-sun.el (x-win-init-sun):
* x-win-xfree86.el (x-win-init-xfree86):
Initialise the hardware-specific mapping from raw keycodes to the
US key layout.
man/ChangeLog addition:
2005-12-18 Aidan Kehoe <kehoea(a)parhasard.net>
* xemacs/keystrokes.texi (Keystrokes):
Add new node on keyboards with which one can't type Latin.
* xemacs/keystrokes.texi (Non-Latin keyboards):
Describe the support for falling back to a US key layout on
keyboards where typing the Roman alphabet is difficult.
src/ChangeLog addition:
2005-12-18 Aidan Kehoe <kehoea(a)parhasard.net>
* event-Xt.c:
Add two new lisp variables, x-us-keymap-description and
x-us-keymap-first-keycode to better provide a fallback to the US
layout with keyboards where typing the Roman alphabet and those
punctuation symbols that have command bindings associated with
them is difficult.
* event-Xt.c (x_event_to_emacs_event):
Use those two Lisp variables to improve Russian C-x processing.
* event-stream.c (command_builder_find_leaf):
Make a comment more readable.
XEmacs Trunk source patch:
Diff command: cvs -q diff -u
Files affected: src/event-Xt.c man/xemacs/keystrokes.texi lisp/x-win-xfree86.el
lisp/x-win-sun.el
Index: lisp/x-win-sun.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lisp/x-win-sun.el,v
retrieving revision 1.6
diff -u -u -r1.6 x-win-sun.el
--- lisp/x-win-sun.el 2001/05/04 22:42:18 1.6
+++ lisp/x-win-sun.el 2005/12/18 14:53:36
@@ -242,6 +242,21 @@
'SunF37 'f12 ; Used to be Stop & Again
))
+ ;; Initialise the information needed for processing of function keys on
+ ;; keyboards without Roman-alpabet characters available. This keyboard
+ ;; description was taken from gkb-new/xmodmap.sun/xmodmap.us in the
+ ;; gnome-applets 2.12.0 distribution.
+ (setq x-us-keymap-first-keycode 37
+ x-us-keymap-description
+ [[?1 ?!] [?2 ?@] [?3 ?\#] [?4 ?$] [?5 ?%] [?6 ?^] [?7 ?&] [?8 ?*]
+ [?9 ?\(] [?0 ?\)] [?- ?_] [?= ?+] [?\` ?~] nil nil nil ?/ ?* nil
+ nil ?\. nil nil ?\t [?q ?Q] [?w ?W] [?e ?E] [?r ?R] [?t ?T] [?y ?Y]
+ [?u ?U] [?i ?I] [?o ?O] [?p ?P] [?\[ ?{] [?\] ?}] nil nil ?7 ?8 ?9
+ ?- nil nil nil nil nil [?a ?A] [?s ?S] [?d ?D] [?f ?F] [?g ?G]
+ [?h ?H] [?j ?J] [?k ?K] [?l ?L] [?\; ?:] [?\' ?\"] [?\\ ?|] nil nil
+ ?4 ?5 ?6 ?0 nil nil nil nil nil [?z ?Z] [?x ?X] [?c ?C] [?v ?V]
+ [?b ?B] [?n ?N] [?m ?M] [?\, ?<] [?\. ?>] [?/ ?\?] nil nil ?1 ?2
+ ?3 nil nil nil nil nil nil ?\ nil nil nil ?+])
;;; OpenWindows-like "find" processing.
;;; As far as I know, the `find' key is a Sunism, so we do that binding
Index: lisp/x-win-xfree86.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lisp/x-win-xfree86.el,v
retrieving revision 1.5
diff -u -u -r1.5 x-win-xfree86.el
--- lisp/x-win-xfree86.el 2001/05/04 22:42:19 1.5
+++ lisp/x-win-xfree86.el 2005/12/18 14:53:36
@@ -46,6 +46,37 @@
;;;###autoload
(defun x-win-init-xfree86 ()
+
+ ;; We know this keyboard is an XFree86 keyboard. As such, we can predict
+ ;; what key scan codes will correspond to the keys on US keyboard layout,
+ ;; and we can use that information to fall back to the US layout when
+ ;; looking up commands that would otherwise fail. (Cf. the hard-coding of
+ ;; this information in /usr/X11R6/lib/X11/xkb/keycodes/xfree86 )
+ ;;
+ ;; These settings for x-us-keymap-first-keycode and
+ ;; x-us-keymap-description were determined with
+ ;;
+ ;; setxkbmap us
+ ;; xmodmap -pke > keyboard-description.txt
+ ;;
+ ;; "8" is the key code of the first line, x-us-keymap-description is
+ ;; taken from the column describing the bindings.
+
+ (setq x-us-keymap-first-keycode 8
+ x-us-keymap-description
+ [nil nil [?1 ?!] [?2 ?@] [?3 ?\#] [?4 ?$] [?5 ?%] [?6 ?^] [?7 ?&]
+ [?8 ?*] [?9 ?\(] [?0 ?\)] [?- ?_] [?= ?+] nil ?\t [?q ?Q]
+ [?w ?W] [?e ?E] [?r ?R] [?t ?T] [?y ?Y] [?u ?U] [?i ?I] [?o ?O]
+ [?p ?P] [?\[ ?{] [?\] ?}] nil nil [?a ?A] [?s ?S] [?d ?D]
+ [?f ?F] [?g ?G] [?h ?H] [?j ?J] [?k ?K] [?l ?L] [?\; ?:]
+ [?\' ?\"] [?\` ?~] nil [?\\ ?|] [?z ?Z] [?x ?X] [?c ?C]
+ [?v ?V] [?b ?B] [?n ?N] [?m ?M] [?\, ?<] [?\. ?>] [?/ ?\?]
+ nil ?* nil ?\ nil nil nil nil nil nil nil nil nil nil nil
+ nil nil ?7 ?8 ?9 ?- ?4 ?5 ?6 ?+ ?1 ?2 ?3 ?0 ?\. nil nil
+ [?< ?>] nil nil nil nil nil nil nil nil nil nil nil nil
+ nil nil nil nil nil ?/ nil nil nil nil nil nil nil nil
+ nil nil nil nil nil ?=])
+
(loop for (key sane-key) in
'((f13 f1)
(f14 f2)
Index: man/xemacs/keystrokes.texi
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/man/xemacs/keystrokes.texi,v
retrieving revision 1.4
diff -u -u -r1.4 keystrokes.texi
--- man/xemacs/keystrokes.texi 2001/04/12 18:22:28 1.4
+++ man/xemacs/keystrokes.texi 2005/12/18 14:53:36
@@ -36,6 +36,7 @@
* Super and Hyper Keys:: Adding modifier keys on certain keyboards.
* Character Representation:: How characters appear in Emacs buffers.
* Commands:: How commands are bound to key sequences.
+* Non-Latin keyboards:: Commands on keyboards where one can't type Latin.
@end menu
@node Intro to Keystrokes, Representing Keystrokes, Keystrokes, Keystrokes
@@ -456,7 +457,7 @@
The variable @code{ctl-arrow} may be used to alter this behavior.
@xref{Display Vars}.
-@node Commands, , Character Representation, Keystrokes
+@node Commands, Non-Latin keyboards, Character Representation, Keystrokes
@section Keys and Commands
@cindex binding
@@ -514,3 +515,38 @@
are ready to be interested, read the basic information on variables, and
then the information on individual variables will make sense.
@xref{Variables}.
+
+@node Non-Latin keyboards, ,Commands, Keystrokes
+
+@cindex russian
+@cindex greek
+@cindex ``russian c-x''
+@cindex try-alternate-layouts-for-commands
+
+ If your computer has a keyboard designed for a language like Russian or
+Greek, where you have to go to some trouble to type Roman-alphabet
+characters, then typing @kbd{C-f} to call @code{forward-character} is
+very inconvenient.
+
+To address this, XEmacs allows you to pretend that your keyboard has a
+US layout for such commands. That is, you can type @kbd{C-Cyrillic_che
+C-Cyrillic_a} and XEmacs will work out that it should call the command
+that @kbd{C-x C-f} is bound to@footnote{You can, of course, override
+this with an explicit binding for @kbd{C-Cyrillic_che C-Cyrillic_a} to
+something else.}. Function keys, like @key{F1},
+@key{Shift} or @key{Control} are not handled by this, just alphanumeric
+characters and punctuation.
+
+The main user variable associated with this functionality is
+@code{try-alternate-layouts-for-commands}. Setting this to @code{nil}
+inhibits this translation, which would be appropriate if your keyboard
+can handle the Roman alphabet but doesn't have the US layout, and you
+want to avoid the possible confusion.
+
+If @code{try-alternate-layouts-for-commands} is @code{t} but this
+functionality doesn't work for you under X11, check the value of the
+variable @code{x-us-keymap-description}. This is a hardware-specific
+map from key codes to the US layout, and can be initialized from the
+output of @code{xmodmap -pke}; see the documentation for that variable
+and for @code{x-us-keymap-first-keycode}.
+
Index: src/event-Xt.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/event-Xt.c,v
retrieving revision 1.90
diff -u -u -r1.90 event-Xt.c
--- src/event-Xt.c 2005/12/17 19:47:03 1.90
+++ src/event-Xt.c 2005/12/18 14:53:42
@@ -72,8 +72,8 @@
#endif
/* For Russian C-x processing. */
-#define FIRST_ALPHABETIC_QWERTY_KEYCODE 24
-#define LAST_ALPHABETIC_QWERTY_KEYCODE 58
+Lisp_Object Vx_us_keymap_description;
+Fixnum Vx_us_keymap_first_keycode;
/* used in glyphs-x.c */
void enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p);
@@ -1115,6 +1115,64 @@
if (NILP (keysym))
return 0;
+ /* If we have the map from keycodes to the US layout for our
+ keyboard available, store the US layout interpretation of
+ that key in the event structure, in case a binding lookup
+ fails and we want to fall back to the US layout binding.
+
+ This _might_ be possible within an XKB framework, changing
+ the keyboard to a US XKB layout for a moment at startup,
+ storing the correspondance, and changing it back. But that
+ won't work on non-XKB servers, it makes our already slow
+ startup slower, and it's not clear that it's really any
+ easier or more maintainable than storing a correspondence in
+ Lisp. */
+
+ if (!NILP(Vx_us_keymap_description) &&
+ VECTORP(Vx_us_keymap_description) &&
+ ev->keycode >= (unsigned)Vx_us_keymap_first_keycode &&
+ ev->keycode
+ < (unsigned)XVECTOR_LENGTH(Vx_us_keymap_description))
+ {
+ Lisp_Object entr = XVECTOR_DATA(Vx_us_keymap_description)
+ [ev->keycode - Vx_us_keymap_first_keycode];
+ Ichar alternate = '\0';
+
+ if (!NILP (entr))
+ {
+ if (CHARP(entr))
+ {
+ alternate = XCHAR(entr);
+ }
+ else if (VECTORP(entr))
+ {
+ if (modifiers & XEMACS_MOD_SHIFT
+ && XVECTOR_LENGTH(Vx_us_keymap_description) > 1)
+ {
+ entr = XVECTOR_DATA(entr)[1];
+ if (CHARP(entr))
+ {
+ alternate = XCHAR(entr);
+ }
+ }
+ else if (XVECTOR_LENGTH(Vx_us_keymap_description)
+ > 0)
+ {
+ entr = XVECTOR_DATA(entr)[0];
+ if (CHARP(entr))
+ {
+ alternate = XCHAR(entr);
+ }
+ }
+ }
+ if ('\0' != alternate)
+ {
+ SET_EVENT_KEY_ALT_KEYCHARS(emacs_event, KEYCHAR_QWERTY,
+ alternate);
+ }
+ }
+ }
+
/* More Caps_Lock garbage: Caps_Lock should *only* add the
shift modifier to two-case keys (that is, A-Z and
related characters). So at this point (after looking up
@@ -1130,6 +1188,7 @@
intermediate KeySym it used to calculate the string XEmacs
keysym. Then we can call keysym_obeys_caps_lock_p with
exactly the right argument. */
+
/* !!#### maybe fix for Mule
Hard, in the absence of a full case infrastructure for
@@ -1153,6 +1212,7 @@
in the modifiers slot. Neither the characters "a",
"A", "2", nor "@" normally have the shift bit set.
However, "F1" normally does. */
+
if (modifiers & XEMACS_MOD_SHIFT)
{
int Mode_switch_p = *state & xd->ModeMask;
@@ -1165,29 +1225,6 @@
SET_EVENT_TIMESTAMP (emacs_event, ev->time);
SET_EVENT_KEY_MODIFIERS (emacs_event, modifiers);
SET_EVENT_KEY_KEYSYM (emacs_event, keysym);
-
- if (ev->keycode >= FIRST_ALPHABETIC_QWERTY_KEYCODE
- && ev->keycode <= LAST_ALPHABETIC_QWERTY_KEYCODE)
- {
- /* This correspondence isn't guaranteed by the standards, to
- my knowledge. Also, it's incomplete--doesn't include the
- upper-case characters, etc--I need to get some feedback
- on it once this is out in the world and actually being
- used by Russians. */
- static const Ascbyte qwerty_map[] =
- { 'q', 'w', 'e', 'r', 't', 'y',
'u', 'i', 'o', 'p',
- '[', ']', '\015', '\014',
- 'a', 's', 'd', 'f', 'g', 'h',
'j', 'k', 'l',
- ';', '\'', '`', 0, '\\',
- 'z', 'x', 'c', 'v', 'b', 'n',
'm' };
- Ichar val = qwerty_map
- [ev->keycode - FIRST_ALPHABETIC_QWERTY_KEYCODE];
- if (val)
- {
- SET_EVENT_KEY_ALT_KEYCHARS(emacs_event, KEYCHAR_QWERTY,
- val);
- }
- }
}
else /* Mouse press/release event */
{
@@ -3155,6 +3192,35 @@
*/ );
debug_x_events = 0;
#endif
+ DEFVAR_LISP ("x-us-keymap-description", &Vx_us_keymap_description /*
+X11-specific vector describing the current keyboard hardware, and how to map
+from its keycodes to those alphanumeric and punctuation characters that
+would be produced by it if a US layout were configured in software.
+
+We use this to make possible the usage of standard key bindings on keyboards
+where the keys that those bindings assume are not available; for example, on
+a Russian keyboard, one can type C-Cyrillic_che C-Cyrillic_a and have XEmacs
+use the binding for C-x C-f, rather than give an error message that
+C-Cyrillic_che C-Cyrillic_a is not bound.
+
+Entries are either nil, which means the corresponding key code does not map
+to a non-function key in the US layout, a single character, meaning it maps to
+that character, or a vector of two characters, the first indicating the
+unshifted mapping, the second the shifted mapping for the US layout.
+
+`x-us-keymap-first-keycode' tells XEmacs the keycode of the first entry in
+this vector.
+*/ );
+ Vx_us_keymap_description = Qnil;
+
+ DEFVAR_INT ("x-us-keymap-first-keycode", &Vx_us_keymap_first_keycode /*
+The X11 keycode that the first entry in `x-us-keymap-description'
+corresponds to. See the documentation for that variable.
+
+The X11 documentation for XDisplayKeycodes says this can never be less than
+8, but XEmacs doesn't enforce any limitation on what you set it to.
+*/ );
+ Vx_us_keymap_first_keycode = 0;
}
/* This mess is a hack that patches the shell widget to treat visual inheritance
--
I AM IN JAIL AND ALLOWED SEND ONLY ONE CABLE SINCE WAS ARRESTED WHILE
MEASURING FIFTEEN FOOT WALL OUTSIDE PALACE AND HAVE JUST FINISHED COUNTING
THIRTY EIGHT THOUSAND FIVE HUNDERED TWENTY TWO NAMES WHOS WHO IN MIDEAST.