Back to RTEMS Graphics Toolkit and i386 MWin keyboard problems

Pavel Pisa ppisa4lists at
Wed Mar 20 10:48:56 UTC 2013

On Monday 18 March 2013 14:54:53 Sebastian Huber wrote:
> Hello Pavel,
> > Please test GSoC result. It is not perfect there are more problems
> > to solve but I think that it is not worse than previous version.
> where can I find the GSoC results?

All info/pointers are in Experimental GSoC 2012 Version
section of RTEMS Graphic Toolkit Wiki page

  git clone
  cd rtems-graphics-toolkit
  git clone
  git clone
  export RTEMS_MAKEFILE_PATH=RTEMS_MAKEFILE_PATH=/opt/rtems4.11/i386-rtems4.11/pc686/
  ./do_it -A

The most annoying problem for test on i386 architecture under QEMU
is nonfunctional mapping of all control keys which do not have
direct ASCII representation.

This is most probably problem of all MicroWindows versions
which are incompatible with actual RTEMS i386 console code.

The problem source can be traced to the RTEMS patch

 2000-08-26  Rosimildo da Silva  <rdasilva at>
        * Major rework of the "/dev/console" driver.
        * Added termios support for stdin ( keyboard ).
        * Added ioctls() to support modes similar to Linux( XLATE,
        RAW, MEDIUMRAW ).

This change defines default PC console behavior to be in pair
with Linux/Unix console to transcode control keys (UP, DOWN, ...)
to the usual/conventional terminal ESCape sequences 0x1B ...

I have tried to investigate that problem little  more last night
and tried some modifications but result is not correct yet.
Some ideas for change the MicroWindows RTEMS KBD glue
according to microwin/kbd_ttyscan.c follows

diff --git microwin/src/drivers/kbd_rtems.c b/src/drivers/kbd_rtems.c
index 8f9697f..2b29778 100644
--- microwin/src/drivers/kbd_rtems.c
+++ microwin/src/drivers/kbd_rtems.c
@@ -30,9 +30,12 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <errno.h>
+#include <string.h>

 #include <rtems/mw_uid.h>
+#include <rtems/keyboard.h>
 #include "device.h"
+#include "keymap_standard.h"

 extern int close (int fd); /* RTEMS does not include close() in stdio.h */

@@ -45,6 +48,9 @@ void    MWKbd_Close (void);
 void   MWKbd_GetModifierInfo (MWKEYMOD *modifiers, MWKEYMOD *curmodifiers);
 int    MWKbd_Read (MWKEY *buf, MWKEYMOD *modifiers, MWSCANCODE *scancode);

+static MWKEY TranslateScancode(int scancode, MWKEYMOD modstate);
+static void LoadKernelKeymaps(int fd);
 KBDDEVICE kbddev = {

@@ -58,6 +64,24 @@ static int kbd_fd   = -1;
 static const char *Q_NAME        = "MWQ";
 #define            Q_MAX_MSGS      20

+#define KG_SHIFT        0
+#define KG_CTRL         2
+#define KG_ALT          3
+#define KG_ALTGR        1
+#define KG_SHIFTL       4
+#define KG_KANASHIFT    4
+#define KG_SHIFTR       5
+#define KG_CTRLL        6
+#define KG_CTRLR        7
+#define KG_CAPSSHIFT    8
+#define NR_SHIFT        9
+/* kernel unicode tables per shiftstate and scancode*/
+#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)       /* kernel key maps*/
+static unsigned short  os_keymap[NUM_VGAKEYMAPS][NR_KEYS];
+int mw_uid_old_mode;

  * Open the keyboard.
@@ -69,6 +93,13 @@ MWKbd_Open (KBDDEVICE *pkd)
        m_kbd.type = MV_UID_INVALID;
 #if RTEMS
        kbd_fd = fileno (stdin);
+       uid_set_kbd_mode(kbd_fd, K_MEDIUMRAW, &mw_uid_old_mode);
+       /* Load OS keymappings*/
+       LoadKernelKeymaps(kbd_fd);
        rc = uid_open_queue (Q_NAME, O_CREAT | O_RDWR, Q_MAX_MSGS);
        uid_register_device (kbd_fd, Q_NAME);
@@ -84,6 +115,12 @@ MWKbd_Close (void)
         uid_unregister_device (kbd_fd);
        uid_close_queue ();
 #if RTEMS
+       {
+               int dummy;
+               uid_set_kbd_mode(kbd_fd, mw_uid_old_mode, &dummy);
+       }
        close (kbd_fd);

@@ -111,9 +148,20 @@ MWKbd_Read (MWKEY *buf, MWKEYMOD *modifiers, MWSCANCODE *scancode)
         /* check if new KBD event has been posted */
         if( m_kbd.type != MV_UID_INVALID )
+               MWKEY keycode = TranslateScancode(m_kbd.m.kbd.code, m_kbd.m.kbd.modifiers);
+               printf("MWKbd_Read raw 0x%04x modifiers 0x%04x translated 0x%04x\n",
+                      (int)m_kbd.m.kbd.code, (int)m_kbd.m.kbd.modifiers, (int)keycode);
+               *buf = keycode;
+               *modifiers = m_kbd.m.kbd.modifiers;
+#else /*K_MEDIUMRAW*/
                *buf = m_kbd.m.kbd.code;
 //               *modifiers = m_kbd.m.kbd.modifiers;
                *modifiers = 0;
+               printf("MWKbd_Read 0x%04x modifiers 0x%04x\n",
+                      (int)m_kbd.m.kbd.code, (int)m_kbd.m.kbd.modifiers);
+#endif /*K_MEDIUMRAW*/
                /* consume event */
                m_kbd.type = MV_UID_INVALID;
 #if __ECOS
@@ -125,3 +173,118 @@ MWKbd_Read (MWKEY *buf, MWKEYMOD *modifiers, MWSCANCODE *scancode)
        return 0;
+/* translate a scancode and modifier state to an MWKEY*/
+static MWKEY
+TranslateScancode(int scancode, MWKEYMOD modstate)

I do not know when I find some more time to try to help with this
problem but I am sending what I have found till now to the list as well
to document my finding and help project to move forward.

Problem is probably not blocker for upgrade to GSOC 2012 used/adapted MWin
version because older MWin versions are (most probably) broken same

Best wishes,


More information about the devel mailing list