2007-06-07 08:47:22

by Hans de Goede

[permalink] [raw]
Subject: problem with softraw and keycodes > 128

<Note: I'm not on the please keep me CC-ed>

Hi all,

First a short intro I'm a Linux enthousiast and developer. I mainly write
userspace code, but I've also written 2 kernel drivers of which one is in the
mainline and the other is waiting for review.

I've been experimenting with getting the internetkeys on several keyboards to
work. My biggest problem with this currently is the following:

Step 1: press key, dmesg says:
atkbd.c: Unknown key released (translated set 2, code 0xa3 on isa0060/serio0).
atkbd.c: Use 'setkeycodes e023 <keycode>' to make it known.

Step 2: map key: setkeycodes e023 163

Step 3: run xev, press key. X-keycode is: 153 instead of 163 ?

Problem, as the xkb files for these keyboards expect the X-keycode to be 163,
as just it is under the console. Now I know that X-keycodes !=
console-keycodes, for example the A key is 30 on the console and 38 in X, but
in the case of this special keys, both the xkb files for these internet
keyboards (written by suse) and config files for special daemons like lineak,
expect them to be identical. Doing:
echo -n 0 >/sys/devices/platform/i8042/serio1/softraw
However does make them identical.

I don't know if this is an xorg or a kernel problem, but I do know that this
behavior is rather annoying, and IMHO a bug. I've been reading the kernel code
from input.c and atkbd.c but I cannot find anything explaining this there, so
now I'm looking at the xorg kbd driver. I have the feeling though that this
require someone with some more knowledge of the whole input subsystem, hence
this mail.

<Note: I'm not on the please keep me CC-ed>

Thanks & Regards,

Hans



2007-06-07 13:14:51

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

On Thu, Jun 07, 2007 at 10:21:33AM +0200, Hans de Goede wrote:

Hans,

> I've been experimenting with getting the internetkeys on several
> keyboards to work. My biggest problem with this currently is the
> following:

> Step 1: press key, dmesg says:
> atkbd.c: Unknown key released (translated set 2, code 0xa3 on isa0060/serio0).
> atkbd.c: Use 'setkeycodes e023 <keycode>' to make it known.
> Step 2: map key: setkeycodes e023 163
> Step 3: run xev, press key. X-keycode is: 153 instead of 163 ?


> Doing:
> echo -n 0 >/sys/devices/platform/i8042/serio1/softraw
> However does make them identical.

this is a well known problem. It's not easy to explain and next to
impossible to fix within the scope of operation of your test case -
otherwsie it'd be fixed ages ago.

The explanation why this happen will be a little longer, and will follow
the life of a keystroke as it passes through the different layers.

1. First, the user presses a key. Since we're talking a 102-key
PS/2-type keyboard here, the keyboard scans its matrix and figures out
the position of the key. Then, since the connection to the PC is running
in AT mode, it translates the key to a string (one to eight bytes) of
AT-compatible scancodes.

2. The i8042 in the computer receives the scancodes, translates them to
XT-compatible scancodes and makes them available to the OS.

3. In OS the i8042.c gets the scancodes and forwards them to atkbd.c

4. atkbd.c decodes the string of scancodes and turns them into a single
Linux input event, and forwards it to the input core.

5. The Linux input core dispatches the events to char/keyboard.c.

6. keyboard.c, a part of the VT driver, sees that X told the VT that it
wants the "raw mode", which means that the VT should give the keystrokes
as the original string of XT scancodes. Hence (when softraw is 1), it
consults a table and synthesizes what it thinks the original string of
bytes could have been and gives that to X. For all keys that atkbd.c
knows by default, this string is IDENTICAL to what atkbd.c has received.

7. X takes the string, and using an algorithm similar to, but DIFFERENT
from the algoithm that atkbd.c uses, it converts them to an X scancode.
The X scancodes are similar to, but different from the Linux event
keycodes, for historical reasons going back to the 90's.

8. Using an xmodmap table compiled from xkb sources, X converts the X
scancode to an X keysym.

In the softraw == 0 case, the original string of XT scancodes is passed
all along the path to X, so that X really gets what the keyboard sent.

Since the table mapping Linux event keycodes to the synthesized XT
scancodes in step 6. is constant and shared for all (even USB and other)
keyboards, this means that the Linux kernel always presents a virtual
"Linux keyboard" to X.

The "Linux keyboard" always sends the same scancodes for keys with the
same meaning, regardless of what the real hardware does.

And this is why X sees a different code in softraw==1 mode than in
softraw==0 mode: In the first it gets the virtual "Linux keyboard", in
the other it gets access to the real hardware.

> Problem, as the xkb files for these keyboards expect the X-keycode to
> be 163, as just it is under the console. Now I know that X-keycodes !=
> console-keycodes, for example the A key is 30 on the console and 38 in
> X, but in the case of this special keys, both the xkb files for these
> internet keyboards (written by suse) and config files for special
> daemons like lineak, expect them to be identical.

This is wrong. Someone simply needs to write a xkb/lineak description
for the "Linux keyboard", and then all these problems will go away.

PS.: And it's best to use the 'evdev' driver for X instead the 'kbd'
driver, since that one gets the Linux keycodes directly from the kernel,
without any back/forward translation.

--
Vojtech Pavlik
Director SuSE Labs

2007-06-07 15:00:00

by Hans de Goede

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

Vojtech Pavlik wrote:
> On Thu, Jun 07, 2007 at 10:21:33AM +0200, Hans de Goede wrote:
>
> Hans,
>
>> I've been experimenting with getting the internetkeys on several
>> keyboards to work. My biggest problem with this currently is the
>> following:
>
>> Step 1: press key, dmesg says:
>> atkbd.c: Unknown key released (translated set 2, code 0xa3 on isa0060/serio0).
>> atkbd.c: Use 'setkeycodes e023 <keycode>' to make it known.
>> Step 2: map key: setkeycodes e023 163
>> Step 3: run xev, press key. X-keycode is: 153 instead of 163 ?
>
>
>> Doing:
>> echo -n 0 >/sys/devices/platform/i8042/serio1/softraw
>> However does make them identical.
>
> this is a well known problem. It's not easy to explain and next to
> impossible to fix within the scope of operation of your test case -
> otherwsie it'd be fixed ages ago.
>
> The explanation why this happen will be a little longer, and will follow
> the life of a keystroke as it passes through the different layers.
>
> 1. First, the user presses a key. Since we're talking a 102-key
> PS/2-type keyboard here, the keyboard scans its matrix and figures out
> the position of the key. Then, since the connection to the PC is running
> in AT mode, it translates the key to a string (one to eight bytes) of
> AT-compatible scancodes.
>
> 2. The i8042 in the computer receives the scancodes, translates them to
> XT-compatible scancodes and makes them available to the OS.
>
> 3. In OS the i8042.c gets the scancodes and forwards them to atkbd.c
>
> 4. atkbd.c decodes the string of scancodes and turns them into a single
> Linux input event, and forwards it to the input core.
>
> 5. The Linux input core dispatches the events to char/keyboard.c.
>
> 6. keyboard.c, a part of the VT driver, sees that X told the VT that it
> wants the "raw mode", which means that the VT should give the keystrokes
> as the original string of XT scancodes. Hence (when softraw is 1), it
> consults a table and synthesizes what it thinks the original string of
> bytes could have been and gives that to X. For all keys that atkbd.c
> knows by default, this string is IDENTICAL to what atkbd.c has received.
>
> 7. X takes the string, and using an algorithm similar to, but DIFFERENT
> from the algoithm that atkbd.c uses, it converts them to an X scancode.
> The X scancodes are similar to, but different from the Linux event
> keycodes, for historical reasons going back to the 90's.
>
> 8. Using an xmodmap table compiled from xkb sources, X converts the X
> scancode to an X keysym.
>
> In the softraw == 0 case, the original string of XT scancodes is passed
> all along the path to X, so that X really gets what the keyboard sent.
>
> Since the table mapping Linux event keycodes to the synthesized XT
> scancodes in step 6. is constant and shared for all (even USB and other)
> keyboards, this means that the Linux kernel always presents a virtual
> "Linux keyboard" to X.
>
> The "Linux keyboard" always sends the same scancodes for keys with the
> same meaning, regardless of what the real hardware does.
>

But doesn't it only know the meaning after doing a setkeycodes for easy-access
keys? I find it somewhat counter inituitive that doing "setkeycodes e023 163"
will give me a keycode 163 on the console (as reported by showkeys), but will
send a scancode of 153 to the X-server.

> And this is why X sees a different code in softraw==1 mode than in
> softraw==0 mode: In the first it gets the virtual "Linux keyboard", in
> the other it gets access to the real hardware.
>
>> Problem, as the xkb files for these keyboards expect the X-keycode to
>> be 163, as just it is under the console. Now I know that X-keycodes !=
>> console-keycodes, for example the A key is 30 on the console and 38 in
>> X, but in the case of this special keys, both the xkb files for these
>> internet keyboards (written by suse) and config files for special
>> daemons like lineak, expect them to be identical.
>
> This is wrong. Someone simply needs to write a xkb/lineak description
> for the "Linux keyboard", and then all these problems will go away.
>

Well to be honest I'm looking for a somewhat more quick fix then that. Let me
try to explain. Xorg comes with keyboard descriptions for many special-access
keys having keyboards. These descriptions can be easily selected by the end
user from the kde / gnome keyboard properties applets.

This however only works with softraw=0 for 2 reasons:
1) without softraw=0 the key presses never reach the server when there hasn't
been an setkeycodes command for the easy access key
2) even if a setkeycodes command was given, then the keycode given to
setkeycodes doesn't match the scancode seen by xorg, messing things up.
(unless one uses setkeycodes with a reverse mapping of the mapping done in
the kernel)

There are 3 ways out of this:
1) write special loadkey maps for all the easy access keyboards, since unlike X
loadkeys AFAIK doesn't support inheriting keys from a global layout, the
number of language-layout <-> keyboard model variants would become quite
frightening.

When loadkeys has been thought to map the special keys according to the
linuxkeyboard codes, then X needs to be tought how to handle a linux
keyboard and default to this

Also configuration utils need to be written to properly set things up for
loadkeys, as autodetecting this is impossible

2) Somehow fix things so that selecting the right model in gnome/kde
keyboard-preferences will make the keys work. Like it does now with
softraw=0. Which leads me to asking what are the downsides of using
softraw=0?
What about be default defining keycodes for all the 128+ scancodes not yet
defined, and defining these in such a way that the actual scancodes is what
gets send to X?
Or maybe it would be an option to send the raw scancode just like is done
with softraw=0 when there is no mapping (instead of ignoring the key as is
done now).

Since the xkb discriptions for most of the easy access keyboards have been
written by Suse, I assume the tested them and it works for them. Does anyone
know how suse does this?

3) Forget about all this and leave things as is, this one clearly does not have
my preference.

Regards,

Hans

2007-06-07 15:36:26

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

On Thu, Jun 07, 2007 at 04:55:23PM +0200, Hans de Goede wrote:

> >Since the table mapping Linux event keycodes to the synthesized XT
> >scancodes in step 6. is constant and shared for all (even USB and other)
> >keyboards, this means that the Linux kernel always presents a virtual
> >"Linux keyboard" to X.
> >
> >The "Linux keyboard" always sends the same scancodes for keys with the
> >same meaning, regardless of what the real hardware does.
>
> But doesn't it only know the meaning after doing a setkeycodes for
> easy-access keys?

Most microsoft-compatible keys work by default without setkeycodes. But
yes, for those that aren't in the default table, it only knows the
meaning after you tell it with setkeycodes.

> I find it somewhat counter inituitive that doing
> "setkeycodes e023 163" will give me a keycode 163 on the console (as
> reported by showkeys), but will send a scancode of 153 to the X-server.

As I said, the algorithms/table to compute the keycode from the XT
scancodes are different in the kernel and in the X server, and that
can't be changed without breaking backwards compatibility.

The good news is that while the numbers aren't the same, there is a 1:1
mapping, that is, you'll get 153 in the server for 163 in the kernel,
always, regardless of the keyboard used or regardless of the actual key
you assigned this code to.

And I don't have the mapping table: It could likely be fairly easily
created by simply going through all the keys and writing the results
down.

> Well to be honest I'm looking for a somewhat more quick fix then that. Let
> me try to explain. Xorg comes with keyboard descriptions for many
> special-access keys having keyboards. These descriptions can be easily
> selected by the end user from the kde / gnome keyboard properties applets.
>
> This however only works with softraw=0 for 2 reasons:
> 1) without softraw=0 the key presses never reach the server when there
> hasn't
> been an setkeycodes command for the easy access key
> 2) even if a setkeycodes command was given, then the keycode given to
> setkeycodes doesn't match the scancode seen by xorg, messing things up.
> (unless one uses setkeycodes with a reverse mapping of the mapping done
> in
> the kernel)
>
> There are 3 ways out of this:
> 1) write special loadkey maps for all the easy access keyboards, since
> unlike X
> loadkeys AFAIK doesn't support inheriting keys from a global layout, the
> number of language-layout <-> keyboard model variants would become quite
> frightening.

No. You just need a 'setkeycodes' map for the extra keys, and that's
language-independent.

> When loadkeys has been thought to map the special keys according to the
> linuxkeyboard codes, then X needs to be tought how to handle a linux
> keyboard and default to this
>
> Also configuration utils need to be written to properly set things up for
> loadkeys, as autodetecting this is impossible

X doesn't get the loadkeys (keymap) processed data, it gets the
keycodes, which are only affected by setkeycodes.

> 2) Somehow fix things so that selecting the right model in gnome/kde
> keyboard-preferences will make the keys work. Like it does now with
> softraw=0. Which leads me to asking what are the downsides of using
> softraw=0?

It doesn't work with anything else but PS/2 keyboards. It's useless on
eg. USB.

> What about be default defining keycodes for all the 128+ scancodes
> not yet defined, and defining these in such a way that the actual
> scancodes is what gets send to X?

Ugly.

> Or maybe it would be an option to send the raw scancode just like
> is done with softraw=0 when there is no mapping (instead of
> ignoring the key as is done now).

That'd confuse people even more than the current situation.

> Since the xkb discriptions for most of the easy access keyboards
> have been written by Suse, I assume the tested them and it works
> for them. Does anyone know how suse does this?

I don't think it does work. One of our guys is trying to fix it by

1) Converting the xkb multimedia keyboard descriptions to setkeycodes descriptions
2) Creating a "linux keyboard" X xkb description

Then, after loading the setkeycodes at boot for the right keyboard
ty[e, AT keyboard will work fine, and USB and other keyboards will not
need *any* setup to have their multimedia keys working out of the box.

--
Vojtech Pavlik
Director SuSE Labs

2007-06-07 17:51:54

by Hans de Goede

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

Vojtech Pavlik wrote:
> On Thu, Jun 07, 2007 at 04:55:23PM +0200, Hans de Goede wrote:
>
>> 2) Somehow fix things so that selecting the right model in gnome/kde
>> keyboard-preferences will make the keys work. Like it does now with
>> softraw=0. Which leads me to asking what are the downsides of using
>> softraw=0?
>
> It doesn't work with anything else but PS/2 keyboards. It's useless on
> eg. USB.
>

This is an atkbd only setting, right, so indeed it doesn't affect USB, right?

What I'm wondering if is there is any harm to setting softraw to 0, atleast
until there is a better fix. With it set to 0, for ps/2 keyboards all the user
addtionally needs todo is select the correct model, for which there are nice
gui tools.

Add a usb-keyboard (which in reality is the linuxkeyboard) model to the mix,
for the user to select / to make default even, and things will work for usb
users to, right?

>> Since the xkb discriptions for most of the easy access keyboards
>> have been written by Suse, I assume the tested them and it works
>> for them. Does anyone know how suse does this?
>
> I don't think it does work. One of our guys is trying to fix it by
>
> 1) Converting the xkb multimedia keyboard descriptions to setkeycodes descriptions
> 2) Creating a "linux keyboard" X xkb description
>
> Then, after loading the setkeycodes at boot for the right keyboard
> ty[e, AT keyboard will work fine, and USB and other keyboards will not
> need *any* setup to have their multimedia keys working out of the box.
>

Thats good news, but what about gui tools to select the model, as this cannot
be autoprobed? And what about portability of said tools to for example freebsd?

Using xkb models should work across different OS's, and is available now. All
that is needed (for ps2 keyboards) is for the path of the special keys from the
kernel to X-server to not change the codes.

Regards,

Hans

2007-06-07 19:17:21

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

On Thu, Jun 07, 2007 at 08:05:42PM +0200, Hans de Goede wrote:

> This is an atkbd only setting, right, so indeed it doesn't affect USB,
> right?

Right, what I meant is that USB keyboards are affected by the very same
problem you describe (163 in kernel will be 153 in X), and it can't be
worked around by setting softraw to 0.

> What I'm wondering if is there is any harm to setting softraw to 0, atleast
> until there is a better fix. With it set to 0, for ps/2 keyboards all the
> user addtionally needs todo is select the correct model, for which there
> are nice gui tools.

By doing that, you'll be following a dead end road - and noone will fix
the issue for non-PS/2 keyboards.

> Add a usb-keyboard (which in reality is the linuxkeyboard) model to the
> mix, for the user to select / to make default even, and things will work
> for usb users to, right?

Yes, but once you create the linuxkeyboard description, you don't need
softraw=0.

> >> Since the xkb discriptions for most of the easy access keyboards
> >> have been written by Suse, I assume the tested them and it works
> >> for them. Does anyone know how suse does this?
> >
> >I don't think it does work. One of our guys is trying to fix it by
> >
> > 1) Converting the xkb multimedia keyboard descriptions to
> > setkeycodes descriptions
> > 2) Creating a "linux keyboard" X xkb description
> >
> >Then, after loading the setkeycodes at boot for the right keyboard
> >ty[e, AT keyboard will work fine, and USB and other keyboards will not
> >need *any* setup to have their multimedia keys working out of the box.
>
> Thats good news, but what about gui tools to select the model, as this
> cannot be autoprobed?

I'm sure SUSE will update some of the existing tools to work with the
kernel-based keyboard selection well.

> And what about portability of said tools to for example freebsd?

That will likely not work, obviously.

> Using xkb models should work across different OS's, and is available
> now. All that is needed (for ps2 keyboards) is for the path of the
> special keys from the kernel to X-server to not change the codes.

Yes, the linux kernel solution is linux specific. But a lot of other
interfaces that X uses are OS specific.

--
Vojtech Pavlik
Director SuSE Labs

2007-06-08 11:32:04

by Hans de Goede

[permalink] [raw]
Subject: Re: problem with softraw and keycodes > 128

On Thu, 7 Jun 2007 21:16:48 +0200
Vojtech Pavlik <[email protected]> wrote:
> On Thu, Jun 07, 2007 at 08:05:42PM +0200, Hans de Goede
> wrote:
>
> > This is an atkbd only setting, right, so indeed it
> doesn't affect USB,
> > right?
>
> Right, what I meant is that USB keyboards are affected by
> the very same
> problem you describe (163 in kernel will be 153 in X),
> and it can't be
> worked around by setting softraw to 0.
>

Yes, I see I've been thinking about this some more and I
tend to agree that doing the mapping at the kernel and
always represent an identical keyboard (fake)scancode wise,
is indeed the best way forward.

You said that someone at Suse is working on this, can you
disclose his mail address, I would like to help, atleast by
testing and I can probably do more then just that.

Thanks & Regards,

Hans