Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XChangeKeyboardMapping(...keysyms_per_keycode...)

76 views
Skip to first unread message

McSwell

unread,
Dec 31, 2009, 10:58:05 PM12/31/09
to
I have been experimenting with the XChangeKeyboardMapping() function,
and can't figure out how (or if?) the keysyms_per_keycode arg works.

The documentation says that keysyms_per_keycode "Specifies the number
of KeySyms per KeyCode." That's not much to go on, but what I gather
it means is that you could map a keycode to a sequence of keysyms.
Specifying a keysyms_per_keycode value of 2 (and giving a keysyms
array that's of length 2) should assign the sequence of keysyms to the
keycode, I would have thought. That's exactly what I want to do, but
I can't get it to work.

The code I'm using is this (extraneous detail omitted, but I've been
hard-coding this into Adrian Nye's 'mapkeys' program in his Xlib
Programming Manual):
KeySym NewSyms[2];
...
KeySym[0] = XStringToKeysym("Up");
KeySym[1] = XStringToKeysym("Left");
XChangeKeyboardMapping(display, XK_F1, 2, NewSyms, 1);
...
What I would expect this to do is to assign the sequence <Up><Left> to
the F1 key. It does not; it only assigns the first keysym, <Up>, to
the F1 key (the second keysym, <Left>, is apparently ignored). I've
tested this in applications, and with xev.

What am I doing wrong? Does anyone have examples of using the
XChangeKeyboardMapping() function with keysyms_per_keycode > 1? I've
googled for examples, but can't find any. (I did run across a 1992
posting to some newsgroup complaining that he couldn't get this to
work either, but there were no responses.)

BTW, the other numeric arg to XChangeKeyboardMapping(), num_codes,
seems to work just fine.

In case it matters, I'm testing this on the current version of Ubuntu,
with Gnome.

Mike Maxwell

Alan Curry

unread,
Jan 1, 2010, 12:05:46 AM1/1/10
to
In article <828ec768-f794-44a9...@u41g2000yqe.googlegroups.com>,

McSwell <max...@umiacs.umd.edu> wrote:
>I have been experimenting with the XChangeKeyboardMapping() function,
>and can't figure out how (or if?) the keysyms_per_keycode arg works.

You should go read the keyboard section of the X Window System Protocol
specification (look for a file called proto.txt, proto.ps, or proto.pdf),
which explains keycodes and keysyms and how they relate to each other.

The set of keysyms attached to a keycode is not a "sequence" like you want it
to be. It's the set of alternative symbols that can be generated by a key
depending on which modifiers (Shift, ShiftLock, CapsLock, NumLock, etc.) are
in effect.

Run "xmodmap -pke" to see a bunch of examples. Each line will show a single
keycode and a list of keysyms associated with it. You'll probably see that
most keycodes have 2 keysyms (regular and shifted), although some might have
more, especially in a non-US keyboard layout.

This line for example:

keycode 13 = 4 dollar

indicates that keycode 13 on my keyboard is the key which generates the
keysym XK_4 or XK_dollar, depending on whether the Shift modifier is in
effect. That key has 2 keysyms. Its keysyms_per_keycode is 2.

XKB adds more features on top of the minimal X protocol, but I don't think
"generating a series of multiple KeyPress/KeyRelease events in response to a
single physical keypress" is one of them. (Maybe I'm wrong... I tried to read
the XKB specification once, but it's soooo long and boring!)

--
Alan Curry

McSwell

unread,
Jan 1, 2010, 12:19:47 PM1/1/10
to
On Jan 1, 12:05 am, pac...@kosh.dhis.org (Alan Curry) wrote:
> The set of keysyms attached to a keycode is not a "sequence" like you want it
> to be. It's the set of alternative symbols that can be generated by a key
> depending on which modifiers (Shift, ShiftLock, CapsLock, NumLock, etc.) are
> in effect.

Rats, I was hoping that XChangeKeyboardMapping() would allow me to do
things that xkb and xmodmap do not. AFAIK, neither of them allows
generating a sequence of keysyms from a single keycode, either. (xkb
does have a 'count' arg, but it's only for "button presses" on other
devices, not for keyboard remapping; presumably this allows mapping a
middle button click on the mouse to a double left click, for example.
If there's a way to use the button press mechanism for the keyboard, I
haven't discovered it.)

So what do I need to do in order to map a keycode like ^D to a
sequence of keysyms (<down><down><down><down><down><down><down>)? Do
I need to intercept things at the keyboard driver level, and convert
<caps>D to the sequence there? (That would presumably require
interecepting the key strokes for press/release 'd' and checking
whether the <capslock> key was down. It's basically what I do in my
Microsoft Windows keystroke remapper.) Or is there some intermediate
level where I can do this--say, by mapping <caps>D to F15 (a key which
I don't use), and then at some later level mapping the F15 key to
<down><down><down><down><down><down><down>?

Mike Maxwell

Alan Curry

unread,
Jan 1, 2010, 3:59:33 PM1/1/10
to
In article <99d52b00-5c98-457c...@j19g2000yqk.googlegroups.com>,

McSwell <max...@umiacs.umd.edu> wrote:
>On Jan 1, 12:05�am, pac...@kosh.dhis.org (Alan Curry) wrote:
>> The set of keysyms attached to a keycode is not a "sequence" like you want it
>> to be. It's the set of alternative symbols that can be generated by a key
>> depending on which modifiers (Shift, ShiftLock, CapsLock, NumLock, etc.) are
>> in effect.
>
>Rats, I was hoping that XChangeKeyboardMapping() would allow me to do
>things that xkb and xmodmap do not. AFAIK, neither of them allows

xmodmap is nothing more or less than a shell-script-level interface to
XChangeKeyboardMapping (and a few other keyboard/pointer functions). There
shouldn't be any features that you can access by writing your own C code that
aren't exposed by xmodmap.

>So what do I need to do in order to map a keycode like ^D to a
>sequence of keysyms (<down><down><down><down><down><down><down>)? Do

Many programs allow you to specify a Translation Table via .Xresources, which
can bind multiple actions to a single input event.

Or... get xbindkeys and xmacro, write a shell script that invokes xmacro to
inject a series of key events, and use xbindkeys to run that script whenever
the key combination is pressed.

Or... study the xbindkeys and xmacro source code, and combine their
functionality into a single client dedicated to this purpose. (You just need
to understand XGrabKey, XSendEvent or XTest, and a basic event loop)

--
Alan Curry

0 new messages