# Dell Multimedia-keyboard SK-8135 special keys

## jsteidl

Hi there!

i started this thread to summarize all past information. Please look also at the other thread at https://forums.gentoo.org/viewtopic-p-4045103.html

I've got the Dell SK-8135 Multimedia Keyboard with some Audio-controll-Keys like skip, stop and a fancy Volume Knob. 

The Knob is not working out of the Box, as expected.

Though the Knob DOES something as this shows:

```
diego ~ # cat /dev/input/event2

�u?F�9 �����u?F�9�u?F<� �����u?F?��u?F�     �u?F�        �u?F

                                                                    �

                                                                      �u?F�

```

 The Ubuntu-People are (good for us  :Wink: ) having the same problems, so there has been some research going on in their forums.

They came up with a piece of code which i mirrored here

http://schokokeks.org/~johannes/misc/sk8135-pcm.c

and some instructions how to configure the system correctly

http://ubuntuforums.org/showpost.php?p=2299656&postcount=7

 *Quote:*   

> 1. Pre-requisites:
> 
>     * aumix
> 
>     * libxosd-dev (will install some other dependencies)
> ...

 

So i tried to use this with gentoo and came pretty far with it, until point 5 Acctually. When executing

```
udevinfo -a -p $(udevinfo -q path -n /dev/input/event2)
```

there is no Line saying anything about SYSFS.

Is anybody experiencing a urge to fix this?  :Wink:  No, really, does anybody had the same problem and solved it somehow or is there another, more elegant way of doing it?

----------

## MrEntropy

I would like to see the knob work.  There is no SYSF entry, like you said, but I did get this:

```
ATTRS{modalias}=="usb:v413Cp2010d0200dc00dsc00dp00ic03isc00ip00"
```

It looks to be the same, but with ATTRS instead of SYSF.  If you create a rule with it, it should work.

----------

## Kulfaangaren!

...I added this post yesterday https://forums.gentoo.org/viewtopic-t-562746-start-0-postdays-0-postorder-asc-highlight-sk8135.html

It is the same code you linked to in your post but I rewrote 95%+ of the code and made it work with KDE and Amarok and also added support for all the multimedia keys. I'v got it working flawlessly on my laptop + sk8135.

As it is today the code handles the multimedia keys and the volume knob and uses dcop client via system() to access Amarok.

The other "special" keys are not implemented in the code but the comments and structure of the code should make it easy even for a C novice (like myself) to modify it to handle those keys as well.

Installation and compile instructions are in the comments.

About the installation instructions you reposted in this thread...

The way I read the instructions they are meant to help you add missing event devices to an older form of udev and I do know that those changes to udev is not needed to get this to work.

The only change I did to my udev is to change the permissions of the event devices in the file /etc/udev/rules.d/50-udev.rules...

    I changed...

KERNEL=="event*",       NAME="input/%k", MODE="0600"

    ...to...

KERNEL=="event*",       NAME="input/%k", MODE="0644"

Re: Why I removed Xosd and aumix dependencies...

Basically it was because I weren't able to get the mute status from Amarok AND that Amarok has it's own OSD built-in and I decided to use that instead. Somewhere in the instructions I think they mentioned writing an init-script, but that doesn't work with Xosd because it relies on having a DISPLAY in the environment and refuses to show up if it is started before X.

Regarding aumix, I just felt like since I was using Amarok throughout the whole code anyway, I might as well use it's volume control instead of an extra program.

Cheers.

// FredrikLast edited by Kulfaangaren! on Wed Jun 06, 2007 10:16 pm; edited 1 time in total

----------

## Kulfaangaren!

...other MM-keyboards might work with a slightly modified version of the code I wrote, the only differences should be the types, codes and values the program gets from the event devices. Since the event devices are standard components in Linux and works the same way regardless of what is using them...it should work...in theory  :Smile: 

To get the values for the types,codes and values I would most likely add something like...

```
fprintf(stdout,"T: %d\tC: %d\tV: %d\n", ev[yalv].type, ev[yalv].code, ev[yalv].value );
```

...between the 'for' and 'switch' statements in my code and then just start the program against whatever event device is used by that unknown MM-keyboard.

That should print some nice info about the different types, codes and values that is used by that USB device and then it would just be a matter of modifying the code to use those numbers instead.

[Edit: Added some more thoughts on other MM-keyboards...]

Something you guys might want to check if you have a keyboard other then Dell sk-8135 is if it actually manages to handle press and release of the "special" keys correctly. sk-8135 sends at least two events every time a key is pressed, one press and one release event, but they never wait for you to actually release the key. It looks something like this using the fprintf(...) from above:

me@work ~> sk8135-pcm /dev/input/event5

T: 1    C: 163    V: 1                                               (Key press event)

T: 1    C: 163    V: 0                                               (Key release event)

T: 0    C: 0        V: 0                                               (Don't know what this is, Reset event ?)

An other MM-keyboard might actually wait for you to release the key before sending the release event that that could be really nice since you could then implement stuff like seeking forward and backward by holding the keys pressed.  :Smile: 

Cheers

// Fredrik

----------

## Kulfaangaren!

Ohh...when surfing the net I found this http://keytouch.sourceforge.net/index.php which is probably a much more elegant solution to any and all multimedia keyboard problems if you use Gnome....OR...don't mind the overhead of Gtk2 on your system.

It does not support Dell sk-8135 keyboard, but the package contains an editor that you can use to create your own keyboard mappings.

// Fredrik

----------

## MoridinBG

Here is the code for Logitech Corded Keyboard. Codes are basicly the same, with variations in the keys.

coarded_keyboard.c

```
                   /*

                   * Code values for keys

                   *

                   *   Implemented codes:

                   *   113      -   Mute

                   *   114      -   Volume Down

                   *   115      -   Volume Up

                   *   155      -   Mail

                   *   163      -   Next track

                   *   164      -   Toggle Play/Pause

                   *   165      -   Previous track

                   *   166      -   Stop

                   *   171      -   Start/Show player

                   *   172      -   Home

                   *   430      -   Messanger

                   *

                   *   Unimplemented codes:

                   *   140      -   Calculator

                   *   142      -   Sleep

         *   156   -   Favourites

                   *   418      -   Zoom In

                   *   419      -   Zoom Out

      * Function Keys - Mode F switches between normal F1-F12 Behaviour and Functions

                   *   271      -   Mode F

                   *   138      -   Help

                   *   421      -   Word

                   *   423      -   Excel

                   *   425      -   PowerPoint

                   *   131      -   Undo

                   *   182      -   Redo

                   *   210      -   Print

                   *   234      -   Save

                   *   264      -   a

                   *   265      -   b

                   *   266      -   c

                   *   267      -   d

                   */

#include <stdlib.h>

#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <linux/input.h>

#include <string.h>

int main (int argc, char **argv) {

   int fd = -1;              /* the file descriptor for the device */

   size_t read_bytes;        /* how many bytes were read */

   struct input_event ev[64];   /* the events (up to 64 at once) */

   int currEv;         /* Counter */

   char buffer[50];         /* Buffer for the commands for the system() call */

   if (argc != 2) { /* Check for the file descriptor to use with read() */

      fprintf(stderr, "usage: %s <event-device> (Example %s /dev/input/event5)\n", argv[0], argv[0]);

            exit(1);

   }

   if ((fd = open(argv[1], O_RDONLY)) < 0) { /* If there is a descriptor we try to open it */

      perror("Failed to open event device");

      exit(1);

   }

   while (1) { //The main loop observing the events

      read_bytes = read(fd, ev, sizeof(struct input_event) * 64); /* We read the event data */

            if (read_bytes < (int) sizeof(struct input_event)) { /* If we have read less bytes than a single event: error */

               perror("Failed to read events");

               exit (1);

            }

      for (currEv = 0; currEv < (int) (read_bytes / sizeof(struct input_event)); currEv++)/*Start processing each event that have                                  been read*/

                     if ( ev[currEv].value == 1 ) {

               bzero( (char *)buffer, 50 ); /* Fills the buffer with zeroes */

                        switch ( ev[currEv].code ) {

                              case 113: { /* Mute */

                                 strcpy( (char *)buffer, "dcop amarok player mute" );

                                 break;

                              }

                              case 114: { /* Volume Down */

                                 strcpy( (char *)buffer, "dcop amarok player volumeDown" );

                                 break;

                              }

                              case 115: { /* VolumeUp */

                                 strcpy( (char *)buffer, "dcop amarok player volumeUp" );

                                 break;

                              }

                  case 163: { /* Next track */

                     strcpy( (char *)buffer, "dcop amarok player next" );

                     break;

                  }

                  case 164: { /* Toggle play/pause */

                     strcpy( (char *)buffer, "dcop amarok player playPause" );

                     break;

                  }

                  case 165: { /* Previous track */

                     strcpy( (char *)buffer, "dcop amarok player prev" );

                     break;

                  }

                  case 166: { /* Stop */

                     strcpy( (char *)buffer, "dcop amarok player stop" );

                     break;

                  }

                  case 171: { /* Start/Show Amarok */

                     strcpy( (char *)buffer, "dcopstart amarok" );

                     break;

                  }

                              case 172: { /* Home */

                                 strcpy( (char *)buffer, "dcopstart konqueror ~" );

                                 break;

                              }

                  case 430: { /* Messanger */

                     strcpy( (char *)buffer, "dcopstart pidgin" );

                     break;

                  }

                  case 155: { /* Mail */

                     strcpy( (char *)buffer, "dcopstart thunderbird" );

                     break;

                  }

                  case 421: { /* Word */

                     strcpy( (char *)buffer, "dcopstart oowriter" );

                     break;

                  }

                  case 423: { /* Excel */

                     strcpy( (char *)buffer, "dcopstart oocalc" );

                     break;

                  }

                  case 425: { /* PowerPoint */

                     strcpy( (char *)buffer, "dcopstart ooimpress" );

                     break;

                  }

                        }

               system(buffer); /* Executes the coresponding command */

            }

   }

   close(fd);

   exit(0);

}

```

Also I wrote /Indeed modified the original c file to dump the code value instead of executing anything/ to check Key Codes:

kbd_find_keys:

```

#include <stdlib.h>

#include <stdio.h>

#include <fcntl.h>

#include <linux/input.h>

int main (int argc, char **argv) {

   int fd = -1;              /* the file descriptor for the device */

   size_t read_bytes;        /* how many bytes were read */

   struct input_event ev[64];   /* the events (up to 64 at once) */

   int currEv;         /* Counter */

   if (argc != 2) { /* Check for the file descriptor to use with read() */

      fprintf(stderr, "usage: %s <event-device> (Example %s /dev/input/event5)\n", argv[0], argv[0]);

            exit(1);

   }

   if ((fd = open(argv[1], O_RDONLY)) < 0) { /* If there is a descriptor we try to open it */

      perror("Failed to open event device");

      exit(1);

   }

   while (1) { //The main loop observing the events

      read_bytes = read(fd, ev, sizeof(struct input_event) * 64); /* We read the event data */

            if (read_bytes < (int) sizeof(struct input_event)) { /* If we have read less bytes than a single event: error */

               perror("Failed to read events");

               exit (1);

            }

      for (currEv = 0; currEv < (int) (read_bytes / sizeof(struct input_event)); currEv++)/*Start processing each event that have                                  been read*/

                     if ( ev[currEv].value == 1 ) /*Otherwise outputs twice for each key. Once for press and again for release plus zero output between them */

            fprintf(stderr,"Value: %d \n", ev[currEv].code); /*Prints the code for the key */

   }

   close(fd);

   exit(0);

}
```

But I thing it would be way more useful if a kernel keyboard driver can be written to redirect the multimedia keys value as standart key value so they could be used anywhere without intermediate applications. Later will check if it is possible.

----------

## Kulfaangaren!

Ok, so my theory about it working with almost any MM-keyboard was right...good.

You might to want to add exactly which Logitech Corded keyboard, they have many after all, that your changes support.

There is however a problem with the code for displaying the needed numbers for other keyboards. As you saw in the code some keyboards, like the sk-8135, requires the both the type and code to identify the events correctly and that is probably true for some other keyboards as well. Also the value could be of use IF the keyboard supports separate press and release events, I think you should have used my original fprintf()...

```
fprintf(stdout,"T: %d\tC: %d\tV: %d\n", ev[yalv].type, ev[yalv].code, ev[yalv].value );
```

First, before I complain  :Wink: , I want to say that it is nice that you want to help others by adding the code required to run the corded Logitech keyboard....however....In some circles it would be considered very rude to take code, modify it, change a few variable names and remove license and history. It could be viewed as trying to pass code of as your own original code. I don't really like to bitch and whine but I feel that in this case it is justified, Mathieu Virbel probably worked hard finding out how this is all working so that you and I could build on that.

// Fredrik

----------

