# X and Satellite 5005 Keyboard

## revresxunil

Hello.  Its a well known issue with the satellite 5005 series that the keyboard likes to stutter in X, like double types some letters, really annoying if your trying to set or type in a password.  There is a fix, and I do have it, and it does work, but here is the thing:

I made a script runnable by all users called keyboardfix in usr/local/bin that runs xkbset.  Where is there an init file that will run when X starts so that the keyboard is automatically fixed upon gdm user/pass prompt?

If you havent figured, its a pain to try and type a password when it often double types on ya!  :Sad: 

----------

## revresxunil

Bump -- anyone able to help me figure out what GDM runs as an init file so I can run keyboard fix as gdm?

----------

## Nylle

Actually I doubt that will work if you are planning on using APM. I have a Tecra 9100, which has the same problem, and I was running xkbset every time a started X. However, if I suspended my laptop, X would forget the xkbsetting when I fired it up again. So you will need to figure out a way to run the script every time you wake up from suspend also.

I got tired of fiddling with xkbset and patched my kernel. Here is the diff from keyboard.c if you are interested:

```

root@moya char # diff keyboard.c ~/keyboard.c.orig

91d90

< static unsigned char prev_scancode;

217,230c216,219

<         /*            put_queue(scancode | up_flag); */

<         /* The following 'if' is a workaround for hardware

<          * which sometimes send the key release event twice */

<         unsigned char next_scancode = scancode|up_flag;

<         if (up_flag && next_scancode==prev_scancode) {

<           /* unexpected 2nd release event */

<         } else {

<           prev_scancode=next_scancode;

<           put_queue(next_scancode);

<         }

<

<         /* we do not return yet, because we want to maintain

<            the key_down array, so that we have the correct

<            values when finishing RAW mode or when changing VT's */

---

>               put_queue(scancode | up_flag);

>               /* we do not return yet, because we want to maintain

>                  the key_down array, so that we have the correct

>                  values when finishing RAW mode or when changing VT's */

```

//Andreas

----------

## X-SoCiaL

I read somewhere about this problem coz I got a Toshiba Satellite 5100-503 and problems with dual keystrokes. They recommended using AccessX to control this. You can then set a timevalue in milliseconds before X should echo another press of the same key.

----------

## revresxunil

AccessX is like xkbset, almost identical in idea.  The issue im having here is not the software used, but how to get it set when the login prompt of gdm gets going.

Nylle - I use acpi and dont think I can suspend, so thats not an issue.

I made a script called keyboardfix that runs all the xkbset configuration cmds and gets the keyboard working right, but I want to run this script (and have effects take place) in gdm login, as well as gnome when it loads up.  Right now, i have no keyboardfix in gdm login, and have to run keyboardfix in console when gnome starts.  Now, with the keys double typing, even running the keyboardfix is a pain lol.

Any other ideas??

----------

## X-SoCiaL

Did ya try to patch keyboard.c as suggested?

----------

## revresxunil

It will be a task, but ill try it.  Could you explian a bit how to do this diff?

----------

## X-SoCiaL

Guess we need some guidence from Nylle ...

Nylle ... are we suppossed to use 'patch' or what. I found the place in the keyboard.c file, but I dont want to hack it in by hand ... and if I have to .. do I begin at line 217? Tell us!

----------

## Nylle

Ok, I was a bit tired when I did the diff, so I reversed the names of the files, here is the correct output from the command

diff keyboard.c.orig /usr/src/linux/drivers/char/keyboard.c

```

90a91

> static unsigned char prev_scancode;

216,219c217,230

<               put_queue(scancode | up_flag);

<               /* we do not return yet, because we want to maintain

<                  the key_down array, so that we have the correct

<                  values when finishing RAW mode or when changing VT's */

---

>         /*            put_queue(scancode | up_flag); */

>         /* The following 'if' is a workaround for hardware

>          * which sometimes send the key release event twice */

>         unsigned char next_scancode = scancode|up_flag;

>         if (up_flag && next_scancode==prev_scancode) {

>           /* unexpected 2nd release event */

>         } else {

>           prev_scancode=next_scancode;

>           put_queue(next_scancode);

>         }

>

>         /* we do not return yet, because we want to maintain

>            the key_down array, so that we have the correct

>            values when finishing RAW mode or when changing VT's */

```

Basically paste this into a file, say keyb.diff, make a backup of keyboard.c from /usr/src/linuxdrivers/char/keyboard.c and patch the file with:

patch keyboard.c keyb.diff

Then copy it back to /usr/src/linuxdrivers/char/

Just remember to keep a backup of keyboard.c, in case anything goes wrong. If patch complains on the above command, your keyboard.c is probably different from mine. I'm using the linux-2.4.19-gentoo-r5 sources, but even if you are using a newer kernel, keyboard.c shouldn't have changed. However, if it has you will have to edit the file by hand.

//Andreas

----------

## X-SoCiaL

Ive tried the diff and I get 'unexpected end of line at 21' when patching.

When I tried to hack it in by hand I get 'undeclared variable: prev_scancode

----------

## Nylle

That is because you probably haven't daclared the variable...  :Wink: 

If you look at the diff, you'll see that you need to insert the line: 

static unsigned char prev_scancode;

around line 90. It is in the middle of a block of declarations looking something like (with the variable inserted):

```

int shift_state;

static int npadch = -1;         /* -1 or number assembled on pad */

static unsigned char prev_scancode;

static unsigned char diacr;

static char rep;         /* flag telling character repeat */

struct kbd_struct kbd_table[MAX_NR_CONSOLES];

static struct tty_struct **ttytab;

static struct kbd_struct * kbd = kbd_table;

static struct tty_struct * tty;

```

Insert it there, and recompile. If you have anymore troubles, make sure you have changed it exactly like it says in the diff, ie replaced the line

```

put_queue(scancode | up_flag);

```

with

```

   /*      put_queue(scancode | up_flag); */

    /* The following 'if' is a workaround for hardware

     * which sometimes send the key release event twice */

       unsigned char next_scancode = scancode|up_flag;

    if (up_flag && next_scancode==prev_scancode) {

      /* unexpected 2nd release event */

      } else {

       prev_scancode=next_scancode;

       put_queue(next_scancode);

      }

```

//Andreas

----------

## X-SoCiaL

Thank you very much ... will give it a try again ... and if Im lucky and it works I will make a new diff file for gentoo-sources R9

----------

## X-SoCiaL

Worked like a charm this time ... my diff files is as follows:

```
90a91

> static unsigned char prev_scancode;

216c217

<               put_queue(scancode | up_flag);

---

>               /* put_queue(scancode | up_flag); */

219a221,227

>               unsigned char next_scancode = scancode|up_flag;

>               if (up_flag && next_scancode == prev_scancode) {

>               /* unexpected 2nd release event */

>               } else {

>                       prev_scancode = next_scancode;

>                       put_queue(next_scancode);

>               }

```

And as I posted before I run gentoo-sources 2.4.19 r9

----------

