Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4152 → Rev 4153

/branches/network/uspace/srv/kbd/arch/amd64
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/network/uspace/srv/kbd/arch/ppc64/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/ppc64/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/mips32/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/mips32/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/ia32/include/scanc.h
File deleted
/branches/network/uspace/srv/kbd/arch/ia32/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/ia32/src/scanc.c
File deleted
/branches/network/uspace/srv/kbd/arch/ia32/src/mouse.c
File deleted
/branches/network/uspace/srv/kbd/arch/ia32/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/sparc64/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/sparc64/src/scanc.c
File deleted
/branches/network/uspace/srv/kbd/arch/sparc64/include/scanc.h
File deleted
/branches/network/uspace/srv/kbd/arch/sparc64/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/ia64/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/ia64/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/arm32/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/arch/arm32/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/arm32/src/kbd_gxemul.c
File deleted
/branches/network/uspace/srv/kbd/arch/mips32eb
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/network/uspace/srv/kbd/arch/ppc32/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/arch/ppc32/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/ctl/pc.c
0,0 → 1,231
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief PC keyboard controller driver.
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
 
enum dec_state {
ds_s,
ds_e
};
 
static enum dec_state ds;
 
static int scanmap_simple[] = {
 
[0x29] = KC_BACKTICK,
 
[0x02] = KC_1,
[0x03] = KC_2,
[0x04] = KC_3,
[0x05] = KC_4,
[0x06] = KC_5,
[0x07] = KC_6,
[0x08] = KC_7,
[0x09] = KC_8,
[0x0a] = KC_9,
[0x0b] = KC_0,
 
[0x0c] = KC_MINUS,
[0x0d] = KC_EQUALS,
[0x0e] = KC_BACKSPACE,
 
[0x0f] = KC_TAB,
 
[0x10] = KC_Q,
[0x11] = KC_W,
[0x12] = KC_E,
[0x13] = KC_R,
[0x14] = KC_T,
[0x15] = KC_Y,
[0x16] = KC_U,
[0x17] = KC_I,
[0x18] = KC_O,
[0x19] = KC_P,
 
[0x1a] = KC_LBRACKET,
[0x1b] = KC_RBRACKET,
 
[0x3a] = KC_CAPS_LOCK,
 
[0x1e] = KC_A,
[0x1f] = KC_S,
[0x20] = KC_D,
[0x21] = KC_F,
[0x22] = KC_G,
[0x23] = KC_H,
[0x24] = KC_J,
[0x25] = KC_K,
[0x26] = KC_L,
 
[0x27] = KC_SEMICOLON,
[0x28] = KC_QUOTE,
[0x2b] = KC_BACKSLASH,
 
[0x2a] = KC_LSHIFT,
 
[0x2c] = KC_Z,
[0x2d] = KC_X,
[0x2e] = KC_C,
[0x2f] = KC_V,
[0x30] = KC_B,
[0x31] = KC_N,
[0x32] = KC_M,
 
[0x33] = KC_COMMA,
[0x34] = KC_PERIOD,
[0x35] = KC_SLASH,
 
[0x36] = KC_RSHIFT,
 
[0x1d] = KC_LCTRL,
[0x38] = KC_LALT,
[0x39] = KC_SPACE,
 
[0x01] = KC_ESCAPE,
 
[0x3b] = KC_F1,
[0x3c] = KC_F2,
[0x3d] = KC_F3,
[0x3e] = KC_F4,
[0x3f] = KC_F5,
[0x40] = KC_F6,
[0x41] = KC_F7,
 
[0x42] = KC_F8,
[0x43] = KC_F9,
[0x44] = KC_F10,
 
[0x57] = KC_F11,
[0x58] = KC_F12,
 
[0x46] = KC_SCROLL_LOCK,
 
[0x1c] = KC_ENTER,
 
[0x45] = KC_NUM_LOCK,
[0x37] = KC_NTIMES,
[0x4a] = KC_NMINUS,
[0x4e] = KC_NPLUS,
[0x47] = KC_N7,
[0x48] = KC_N8,
[0x49] = KC_N9,
[0x4b] = KC_N4,
[0x4c] = KC_N5,
[0x4d] = KC_N6,
[0x4f] = KC_N1,
[0x50] = KC_N2,
[0x51] = KC_N3,
[0x52] = KC_N0,
[0x53] = KC_NPERIOD
};
 
static int scanmap_e0[] = {
[0x38] = KC_RALT,
[0x1d] = KC_RSHIFT,
 
[0x37] = KC_PRTSCR,
 
[0x52] = KC_INSERT,
[0x47] = KC_HOME,
[0x49] = KC_PAGE_UP,
 
[0x53] = KC_DELETE,
[0x4f] = KC_END,
[0x51] = KC_PAGE_DOWN,
 
[0x48] = KC_UP,
[0x4b] = KC_LEFT,
[0x50] = KC_DOWN,
[0x4d] = KC_RIGHT,
 
[0x35] = KC_NSLASH,
[0x1c] = KC_NENTER
};
 
int kbd_ctl_init(void)
{
ds = ds_s;
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
kbd_ev_type_t type;
unsigned int key;
int *map;
size_t map_length;
 
if (scancode == 0xe0) {
ds = ds_e;
return;
}
 
switch (ds) {
case ds_s:
map = scanmap_simple;
map_length = sizeof(scanmap_simple) / sizeof(int);
break;
case ds_e:
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
}
 
ds = ds_s;
 
if (scancode & 0x80) {
scancode &= ~0x80;
type = KE_RELEASE;
} else {
type = KE_PRESS;
}
 
if (scancode < 0 || scancode >= map_length)
return;
 
key = map[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/ctl/stty.c
0,0 → 1,229
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief Serial TTY-like keyboard controller driver.
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stroke.h>
 
/** Scancode parser */
static gsp_t sp;
 
/** Current parser state */
static int ds;
 
#include <stdio.h>
 
int seq_defs[] = {
/* Not shifted */
 
0, KC_BACKTICK, 0x60, GSP_END,
 
0, KC_1, 0x31, GSP_END,
0, KC_2, 0x32, GSP_END,
0, KC_3, 0x33, GSP_END,
0, KC_4, 0x34, GSP_END,
0, KC_5, 0x35, GSP_END,
0, KC_6, 0x36, GSP_END,
0, KC_7, 0x37, GSP_END,
0, KC_8, 0x38, GSP_END,
0, KC_9, 0x39, GSP_END,
0, KC_0, 0x30, GSP_END,
 
0, KC_MINUS, 0x2d, GSP_END,
0, KC_EQUALS, 0x3d, GSP_END,
0, KC_BACKSPACE, 0x08, GSP_END,
 
0, KC_TAB, 0x09, GSP_END,
 
0, KC_Q, 0x71, GSP_END,
0, KC_W, 0x77, GSP_END,
0, KC_E, 0x65, GSP_END,
0, KC_R, 0x72, GSP_END,
0, KC_T, 0x74, GSP_END,
0, KC_Y, 0x79, GSP_END,
0, KC_U, 0x75, GSP_END,
0, KC_I, 0x69, GSP_END,
0, KC_O, 0x6f, GSP_END,
0, KC_P, 0x70, GSP_END,
 
0, KC_LBRACKET, 0x5b, GSP_END,
0, KC_RBRACKET, 0x5d, GSP_END,
 
0, KC_A, 0x61, GSP_END,
0, KC_S, 0x73, GSP_END,
0, KC_D, 0x64, GSP_END,
0, KC_F, 0x66, GSP_END,
0, KC_G, 0x67, GSP_END,
0, KC_H, 0x68, GSP_END,
0, KC_J, 0x6a, GSP_END,
0, KC_K, 0x6b, GSP_END,
0, KC_L, 0x6c, GSP_END,
 
0, KC_SEMICOLON, 0x3b, GSP_END,
0, KC_QUOTE, 0x27, GSP_END,
0, KC_BACKSLASH, 0x5c, GSP_END,
 
0, KC_Z, 0x7a, GSP_END,
0, KC_X, 0x78, GSP_END,
0, KC_C, 0x63, GSP_END,
0, KC_V, 0x76, GSP_END,
0, KC_B, 0x62, GSP_END,
0, KC_N, 0x6e, GSP_END,
0, KC_M, 0x6d, GSP_END,
 
0, KC_COMMA, 0x2c, GSP_END,
0, KC_PERIOD, 0x2e, GSP_END,
0, KC_SLASH, 0x2f, GSP_END,
 
/* Shifted */
 
KM_SHIFT, KC_BACKTICK, 0x7e, GSP_END,
 
KM_SHIFT, KC_1, 0x21, GSP_END,
KM_SHIFT, KC_2, 0x40, GSP_END,
KM_SHIFT, KC_3, 0x23, GSP_END,
KM_SHIFT, KC_4, 0x24, GSP_END,
KM_SHIFT, KC_5, 0x25, GSP_END,
KM_SHIFT, KC_6, 0x5e, GSP_END,
KM_SHIFT, KC_7, 0x26, GSP_END,
KM_SHIFT, KC_8, 0x2a, GSP_END,
KM_SHIFT, KC_9, 0x28, GSP_END,
KM_SHIFT, KC_0, 0x29, GSP_END,
 
KM_SHIFT, KC_MINUS, 0x5f, GSP_END,
KM_SHIFT, KC_EQUALS, 0x2b, GSP_END,
 
KM_SHIFT, KC_Q, 0x51, GSP_END,
KM_SHIFT, KC_W, 0x57, GSP_END,
KM_SHIFT, KC_E, 0x45, GSP_END,
KM_SHIFT, KC_R, 0x52, GSP_END,
KM_SHIFT, KC_T, 0x54, GSP_END,
KM_SHIFT, KC_Y, 0x59, GSP_END,
KM_SHIFT, KC_U, 0x55, GSP_END,
KM_SHIFT, KC_I, 0x49, GSP_END,
KM_SHIFT, KC_O, 0x4f, GSP_END,
KM_SHIFT, KC_P, 0x50, GSP_END,
 
KM_SHIFT, KC_LBRACKET, 0x7b, GSP_END,
KM_SHIFT, KC_RBRACKET, 0x7d, GSP_END,
 
KM_SHIFT, KC_A, 0x41, GSP_END,
KM_SHIFT, KC_S, 0x53, GSP_END,
KM_SHIFT, KC_D, 0x44, GSP_END,
KM_SHIFT, KC_F, 0x46, GSP_END,
KM_SHIFT, KC_G, 0x47, GSP_END,
KM_SHIFT, KC_H, 0x48, GSP_END,
KM_SHIFT, KC_J, 0x4a, GSP_END,
KM_SHIFT, KC_K, 0x4b, GSP_END,
KM_SHIFT, KC_L, 0x4c, GSP_END,
 
KM_SHIFT, KC_SEMICOLON, 0x3a, GSP_END,
KM_SHIFT, KC_QUOTE, 0x22, GSP_END,
KM_SHIFT, KC_BACKSLASH, 0x7c, GSP_END,
 
KM_SHIFT, KC_Z, 0x5a, GSP_END,
KM_SHIFT, KC_X, 0x58, GSP_END,
KM_SHIFT, KC_C, 0x43, GSP_END,
KM_SHIFT, KC_V, 0x56, GSP_END,
KM_SHIFT, KC_B, 0x42, GSP_END,
KM_SHIFT, KC_N, 0x4e, GSP_END,
KM_SHIFT, KC_M, 0x4d, GSP_END,
 
KM_SHIFT, KC_COMMA, 0x3c, GSP_END,
KM_SHIFT, KC_PERIOD, 0x3e, GSP_END,
KM_SHIFT, KC_SLASH, 0x3f, GSP_END,
 
/* ... */
 
0, KC_SPACE, 0x20, GSP_END,
0, KC_ENTER, 0x0a, GSP_END,
0, KC_ENTER, 0x0d, GSP_END,
 
0, KC_ESCAPE, 0x1b, 0x1b, GSP_END,
 
0, KC_F1, 0x1b, 0x4f, 0x50, GSP_END,
0, KC_F2, 0x1b, 0x4f, 0x51, GSP_END,
0, KC_F3, 0x1b, 0x4f, 0x52, GSP_END,
0, KC_F4, 0x1b, 0x4f, 0x53, GSP_END,
0, KC_F5, 0x1b, 0x5b, 0x31, 0x35, 0x7e, GSP_END,
0, KC_F6, 0x1b, 0x5b, 0x31, 0x37, 0x7e, GSP_END,
0, KC_F7, 0x1b, 0x5b, 0x31, 0x38, 0x7e, GSP_END,
0, KC_F8, 0x1b, 0x5b, 0x31, 0x39, 0x7e, GSP_END,
0, KC_F9, 0x1b, 0x5b, 0x32, 0x30, 0x7e, GSP_END,
0, KC_F10, 0x1b, 0x5b, 0x32, 0x31, 0x7e, GSP_END,
0, KC_F11, 0x1b, 0x5b, 0x32, 0x33, 0x7e, GSP_END,
0, KC_F12, 0x1b, 0x5b, 0x32, 0x34, 0x7e, GSP_END,
 
0, KC_INSERT, 0x1b, 0x5b, 0x32, 0x7e, GSP_END,
0, KC_HOME, 0x1b, 0x5b, 0x48, GSP_END,
0, KC_PAGE_UP, 0x1b, 0x5b, 0x35, 0x7e, GSP_END,
0, KC_DELETE, 0x1b, 0x5b, 0x33, 0x7e, GSP_END,
0, KC_END, 0x1b, 0x5b, 0x46, GSP_END,
0, KC_PAGE_DOWN, 0x1b, 0x5b, 0x36, 0x7e, GSP_END,
 
0, KC_UP, 0x1b, 0x5b, 0x41, GSP_END,
0, KC_LEFT, 0x1b, 0x5b, 0x44, GSP_END,
0, KC_DOWN, 0x1b, 0x5b, 0x42, GSP_END,
0, KC_RIGHT, 0x1b, 0x5b, 0x43, GSP_END,
 
0, 0
};
 
int kbd_ctl_init(void)
{
ds = 0;
 
gsp_init(&sp);
return gsp_insert_defs(&sp, seq_defs);
}
 
void kbd_ctl_parse_scancode(int scancode)
{
unsigned mods, key;
 
ds = gsp_step(&sp, ds, scancode, &mods, &key);
if (key != 0) {
stroke_sim(mods, key);
}
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/ctl/sun.c
0,0 → 1,209
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief Sun keyboard controller driver.
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <kbd_ctl.h>
 
#define KBD_KEY_RELEASE 0x80
#define KBD_ALL_KEYS_UP 0x7f
 
static int scanmap_simple[];
 
int kbd_ctl_init(void)
{
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
kbd_ev_type_t type;
unsigned int key;
 
if (scancode < 0 || scancode >= 0x100)
return;
 
if (scancode == KBD_ALL_KEYS_UP)
return;
 
if (scancode & KBD_KEY_RELEASE) {
scancode &= ~KBD_KEY_RELEASE;
type = KE_RELEASE;
} else {
type = KE_PRESS;
}
 
key = scanmap_simple[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
/** Primary meaning of scancodes. */
static int scanmap_simple[] = {
[0x00] = 0,
[0x01] = 0,
[0x02] = 0,
[0x03] = 0,
[0x04] = 0,
[0x05] = KC_F1,
[0x06] = KC_F2,
[0x07] = KC_F10,
[0x08] = KC_F3,
[0x09] = KC_F11,
[0x0a] = KC_F4,
[0x0b] = KC_F12,
[0x0c] = KC_F5,
[0x0d] = KC_RALT,
[0x0e] = KC_F6,
[0x0f] = 0,
[0x10] = KC_F7,
[0x11] = KC_F8,
[0x12] = KC_F9,
[0x13] = KC_LALT,
[0x14] = KC_UP,
[0x15] = KC_PAUSE,
[0x16] = 0,
[0x17] = KC_SCROLL_LOCK,
[0x18] = KC_LEFT,
[0x19] = 0,
[0x1a] = 0,
[0x1b] = KC_DOWN,
[0x1c] = KC_RIGHT,
[0x1d] = KC_ESCAPE,
[0x1e] = KC_1,
[0x1f] = KC_2,
[0x20] = KC_3,
[0x21] = KC_4,
[0x22] = KC_5,
[0x23] = KC_6,
[0x24] = KC_7,
[0x25] = KC_8,
[0x26] = KC_9,
[0x27] = KC_0,
[0x28] = KC_MINUS,
[0x29] = KC_EQUALS,
[0x2a] = KC_BACKTICK,
[0x2b] = KC_BACKSPACE,
[0x2c] = KC_INSERT,
[0x2d] = 0,
[0x2e] = KC_NSLASH,
[0x2f] = KC_NTIMES,
[0x30] = 0,
[0x31] = 0,
[0x32] = KC_NPERIOD,
[0x33] = 0,
[0x34] = KC_HOME,
[0x35] = KC_TAB,
[0x36] = KC_Q,
[0x37] = KC_W,
[0x38] = KC_E,
[0x39] = KC_R,
[0x3a] = KC_T,
[0x3b] = KC_Y,
[0x3c] = KC_U,
[0x3d] = KC_I,
[0x3e] = KC_O,
[0x3f] = KC_P,
[0x40] = KC_LBRACKET,
[0x41] = KC_RBRACKET,
[0x42] = KC_DELETE,
[0x43] = 0,
[0x44] = KC_N7,
[0x45] = KC_N8,
[0x46] = KC_N9,
[0x47] = KC_NMINUS,
[0x48] = 0,
[0x49] = 0,
[0x4a] = KC_END,
[0x4b] = 0,
[0x4c] = KC_LCTRL,
[0x4d] = KC_A,
[0x4e] = KC_S,
[0x4f] = KC_D,
[0x50] = KC_F,
[0x51] = KC_G,
[0x52] = KC_H,
[0x53] = KC_J,
[0x54] = KC_K,
[0x55] = KC_L,
[0x56] = KC_SEMICOLON,
[0x57] = KC_QUOTE,
[0x58] = KC_BACKSLASH,
[0x59] = KC_ENTER,
[0x5a] = KC_NENTER,
[0x5b] = KC_N4,
[0x5c] = KC_N5,
[0x5d] = KC_N6,
[0x5e] = KC_N0,
[0x5f] = 0,
[0x60] = KC_PAGE_UP,
[0x61] = 0,
[0x62] = KC_NUM_LOCK,
[0x63] = KC_LSHIFT,
[0x64] = KC_Z,
[0x65] = KC_X,
[0x66] = KC_C,
[0x67] = KC_V,
[0x68] = KC_B,
[0x69] = KC_N,
[0x6a] = KC_M,
[0x6b] = KC_COMMA,
[0x6c] = KC_PERIOD,
[0x6d] = KC_SLASH,
[0x6e] = KC_RSHIFT,
[0x6f] = 0,
[0x70] = KC_N1,
[0x71] = KC_N2,
[0x72] = KC_N3,
[0x73] = 0,
[0x74] = 0,
[0x75] = 0,
[0x76] = 0,
[0x77] = KC_CAPS_LOCK,
[0x78] = 0,
[0x79] = KC_SPACE,
[0x7a] = 0,
[0x7b] = KC_PAGE_DOWN,
[0x7c] = 0,
[0x7d] = KC_NPLUS,
[0x7e] = 0,
[0x7f] = 0
};
 
/** @}
*/
/branches/network/uspace/srv/kbd/ctl/gxe_fb.c
0,0 → 1,229
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief GXEmul framebuffer-mode keyboard controller driver.
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stroke.h>
 
/** Scancode parser */
static gsp_t sp;
 
/** Current parser state */
static int ds;
 
#include <stdio.h>
 
int seq_defs[] = {
/* Not shifted */
 
0, KC_BACKTICK, 0x60, GSP_END,
 
0, KC_1, 0x31, GSP_END,
0, KC_2, 0x32, GSP_END,
0, KC_3, 0x33, GSP_END,
0, KC_4, 0x34, GSP_END,
0, KC_5, 0x35, GSP_END,
0, KC_6, 0x36, GSP_END,
0, KC_7, 0x37, GSP_END,
0, KC_8, 0x38, GSP_END,
0, KC_9, 0x39, GSP_END,
0, KC_0, 0x30, GSP_END,
 
0, KC_MINUS, 0x2d, GSP_END,
0, KC_EQUALS, 0x3d, GSP_END,
0, KC_BACKSPACE, 0x08, GSP_END,
 
0, KC_TAB, 0x09, GSP_END,
 
0, KC_Q, 0x71, GSP_END,
0, KC_W, 0x77, GSP_END,
0, KC_E, 0x65, GSP_END,
0, KC_R, 0x72, GSP_END,
0, KC_T, 0x74, GSP_END,
0, KC_Y, 0x79, GSP_END,
0, KC_U, 0x75, GSP_END,
0, KC_I, 0x69, GSP_END,
0, KC_O, 0x6f, GSP_END,
0, KC_P, 0x70, GSP_END,
 
0, KC_LBRACKET, 0x5b, GSP_END,
0, KC_RBRACKET, 0x5d, GSP_END,
 
0, KC_A, 0x61, GSP_END,
0, KC_S, 0x73, GSP_END,
0, KC_D, 0x64, GSP_END,
0, KC_F, 0x66, GSP_END,
0, KC_G, 0x67, GSP_END,
0, KC_H, 0x68, GSP_END,
0, KC_J, 0x6a, GSP_END,
0, KC_K, 0x6b, GSP_END,
0, KC_L, 0x6c, GSP_END,
 
0, KC_SEMICOLON, 0x3b, GSP_END,
0, KC_QUOTE, 0x27, GSP_END,
0, KC_BACKSLASH, 0x5c, GSP_END,
 
0, KC_Z, 0x7a, GSP_END,
0, KC_X, 0x78, GSP_END,
0, KC_C, 0x63, GSP_END,
0, KC_V, 0x76, GSP_END,
0, KC_B, 0x62, GSP_END,
0, KC_N, 0x6e, GSP_END,
0, KC_M, 0x6d, GSP_END,
 
0, KC_COMMA, 0x2c, GSP_END,
0, KC_PERIOD, 0x2e, GSP_END,
0, KC_SLASH, 0x2f, GSP_END,
 
/* Shifted */
 
KM_SHIFT, KC_BACKTICK, 0x7e, GSP_END,
 
KM_SHIFT, KC_1, 0x21, GSP_END,
KM_SHIFT, KC_2, 0x40, GSP_END,
KM_SHIFT, KC_3, 0x23, GSP_END,
KM_SHIFT, KC_4, 0x24, GSP_END,
KM_SHIFT, KC_5, 0x25, GSP_END,
KM_SHIFT, KC_6, 0x5e, GSP_END,
KM_SHIFT, KC_7, 0x26, GSP_END,
KM_SHIFT, KC_8, 0x2a, GSP_END,
KM_SHIFT, KC_9, 0x28, GSP_END,
KM_SHIFT, KC_0, 0x29, GSP_END,
 
KM_SHIFT, KC_MINUS, 0x5f, GSP_END,
KM_SHIFT, KC_EQUALS, 0x2b, GSP_END,
 
KM_SHIFT, KC_Q, 0x51, GSP_END,
KM_SHIFT, KC_W, 0x57, GSP_END,
KM_SHIFT, KC_E, 0x45, GSP_END,
KM_SHIFT, KC_R, 0x52, GSP_END,
KM_SHIFT, KC_T, 0x54, GSP_END,
KM_SHIFT, KC_Y, 0x59, GSP_END,
KM_SHIFT, KC_U, 0x55, GSP_END,
KM_SHIFT, KC_I, 0x49, GSP_END,
KM_SHIFT, KC_O, 0x4f, GSP_END,
KM_SHIFT, KC_P, 0x50, GSP_END,
 
KM_SHIFT, KC_LBRACKET, 0x7b, GSP_END,
KM_SHIFT, KC_RBRACKET, 0x7d, GSP_END,
 
KM_SHIFT, KC_A, 0x41, GSP_END,
KM_SHIFT, KC_S, 0x53, GSP_END,
KM_SHIFT, KC_D, 0x44, GSP_END,
KM_SHIFT, KC_F, 0x46, GSP_END,
KM_SHIFT, KC_G, 0x47, GSP_END,
KM_SHIFT, KC_H, 0x48, GSP_END,
KM_SHIFT, KC_J, 0x4a, GSP_END,
KM_SHIFT, KC_K, 0x4b, GSP_END,
KM_SHIFT, KC_L, 0x4c, GSP_END,
 
KM_SHIFT, KC_SEMICOLON, 0x3a, GSP_END,
KM_SHIFT, KC_QUOTE, 0x22, GSP_END,
KM_SHIFT, KC_BACKSLASH, 0x7c, GSP_END,
 
KM_SHIFT, KC_Z, 0x5a, GSP_END,
KM_SHIFT, KC_X, 0x58, GSP_END,
KM_SHIFT, KC_C, 0x43, GSP_END,
KM_SHIFT, KC_V, 0x56, GSP_END,
KM_SHIFT, KC_B, 0x42, GSP_END,
KM_SHIFT, KC_N, 0x4e, GSP_END,
KM_SHIFT, KC_M, 0x4d, GSP_END,
 
KM_SHIFT, KC_COMMA, 0x3c, GSP_END,
KM_SHIFT, KC_PERIOD, 0x3e, GSP_END,
KM_SHIFT, KC_SLASH, 0x3f, GSP_END,
 
/* ... */
 
0, KC_SPACE, 0x20, GSP_END,
0, KC_ENTER, 0x0a, GSP_END,
0, KC_ENTER, 0x0d, GSP_END,
 
0, KC_ESCAPE, 0x1b, 0x1b, GSP_END,
 
0, KC_F1, 0x1b, 0x5b, 0x4f, 0x50, GSP_END,
0, KC_F2, 0x1b, 0x5b, 0x4f, 0x51, GSP_END,
0, KC_F3, 0x1b, 0x5b, 0x4f, 0x52, GSP_END,
0, KC_F4, 0x1b, 0x5b, 0x4f, 0x53, GSP_END,
0, KC_F5, 0x1b, 0x5b, 0x31, 0x35, GSP_END,
0, KC_F6, 0x1b, 0x5b, 0x31, 0x37, GSP_END,
0, KC_F7, 0x1b, 0x5b, 0x31, 0x38, GSP_END,
0, KC_F8, 0x1b, 0x5b, 0x31, 0x39, GSP_END,
0, KC_F9, 0x1b, 0x5b, 0x32, 0x38, GSP_END,
0, KC_F10, 0x1b, 0x5b, 0x32, 0x39, GSP_END,
0, KC_F11, 0x1b, 0x5b, 0x32, 0x33, GSP_END,
0, KC_F12, 0x1b, 0x5b, 0x32, 0x34, GSP_END,
 
0, KC_INSERT, 0x1b, 0x5b, 0x32, 0x7e, GSP_END,
0, KC_HOME, 0x1b, 0x5b, 0x48, GSP_END,
0, KC_PAGE_UP, 0x1b, 0x5b, 0x35, 0x7e, GSP_END,
0, KC_DELETE, 0x1b, 0x5b, 0x33, 0x7e, GSP_END,
0, KC_END, 0x1b, 0x5b, 0x46, GSP_END,
0, KC_PAGE_DOWN, 0x1b, 0x5b, 0x36, 0x7e, GSP_END,
 
0, KC_UP, 0x1b, 0x5b, 0x41, GSP_END,
0, KC_LEFT, 0x1b, 0x5b, 0x44, GSP_END,
0, KC_DOWN, 0x1b, 0x5b, 0x42, GSP_END,
0, KC_RIGHT, 0x1b, 0x5b, 0x43, GSP_END,
 
0, 0
};
 
int kbd_ctl_init(void)
{
ds = 0;
 
gsp_init(&sp);
return gsp_insert_defs(&sp, seq_defs);
}
 
void kbd_ctl_parse_scancode(int scancode)
{
unsigned mods, key;
 
ds = gsp_step(&sp, ds, scancode, &mods, &key);
if (key != 0) {
stroke_sim(mods, key);
}
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/include/keys.h
File deleted
/branches/network/uspace/srv/kbd/include/gsp.h
0,0 → 1,84
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdgen generic
* @brief Generic scancode parser.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_GSP_H_
#define KBD_GSP_H_
 
#include <libadt/hash_table.h>
 
enum {
GSP_END = -1, /**< Terminates a sequence. */
GSP_DEFAULT = -2 /**< Wildcard, catches unhandled cases. */
};
 
/** Scancode parser description */
typedef struct {
/** Transition table, (state, input) -> (state, output) */
hash_table_t trans;
 
/** Number of states */
int states;
} gsp_t;
 
/** Scancode parser transition. */
typedef struct {
link_t link; /**< Link to hash table in @c gsp_t */
 
/* Preconditions */
 
int old_state; /**< State before transition */
int input; /**< Input symbol (scancode) */
 
/* Effects */
 
int new_state; /**< State after transition */
 
/* Output emitted during transition */
 
unsigned out_mods; /**< Modifier to emit */
unsigned out_key; /**< Keycode to emit */
} gsp_trans_t;
 
extern void gsp_init(gsp_t *);
extern int gsp_insert_defs(gsp_t *, const int *);
extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
 
#endif
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/include/layout.h
0,0 → 1,49
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_LAYOUT_H_
#define KBD_LAYOUT_H_
 
#include <kbd/kbd.h>
 
extern char layout_parse_ev(kbd_event_t *);
 
#endif
 
/**
* @}
*/
 
/branches/network/uspace/srv/kbd/include/kbd.h
39,10 → 39,18
 
#include <key_buffer.h>
 
extern int kbd_arch_init(void);
extern int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call);
extern int mouse_arch_process(int phoneid, ipc_call_t *call);
#define KBD_EVENT 1024
#define KBD_MS_LEFT 1025
#define KBD_MS_RIGHT 1026
#define KBD_MS_MIDDLE 1027
#define KBD_MS_MOVE 1028
 
extern int cir_service;
extern int cir_phone;
 
extern void kbd_push_scancode(int);
extern void kbd_push_ev(int, unsigned int);
 
#endif
 
/**
/branches/network/uspace/srv/kbd/include/key_buffer.h
38,23 → 38,25
#define __KEY_BUFFER_H__
 
#include <sys/types.h>
#include <kbd/kbd.h>
 
/** Size of buffer for pressed keys */
#define KEYBUFFER_SIZE 128
 
typedef struct {
int fifo[KEYBUFFER_SIZE];
kbd_event_t fifo[KEYBUFFER_SIZE];
unsigned long head;
unsigned long tail;
unsigned long items;
} keybuffer_t;
 
void keybuffer_free(keybuffer_t *keybuffer);
void keybuffer_init(keybuffer_t *keybuffer);
int keybuffer_available(keybuffer_t *keybuffer);
int keybuffer_empty(keybuffer_t *keybuffer);
void keybuffer_push(keybuffer_t *keybuffer, int key);
int keybuffer_pop(keybuffer_t *keybuffer, int *c);
extern void keybuffer_free(keybuffer_t *);
extern void keybuffer_init(keybuffer_t *);
extern int keybuffer_available(keybuffer_t *);
extern int keybuffer_empty(keybuffer_t *);
extern void keybuffer_push(keybuffer_t *, const kbd_event_t *);
extern void keybuffer_push0(keybuffer_t *, int c);
extern int keybuffer_pop(keybuffer_t *, kbd_event_t *);
 
#endif
 
/branches/network/uspace/srv/kbd/include/kbd_ctl.h
0,0 → 1,49
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_CTL_H_
#define KBD_CTL_H_
 
extern void kbd_ctl_parse_scancode(int);
extern int kbd_ctl_init(void);
 
 
#endif
 
/**
* @}
*/
 
/branches/network/uspace/srv/kbd/include/kbd_port.h
0,0 → 1,47
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_PORT_H_
#define KBD_PORT_H_
 
extern int kbd_port_init(void);
 
#endif
 
/**
* @}
*/
 
/branches/network/uspace/srv/kbd/include/stroke.h
0,0 → 1,47
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbdgen generic
* @brief Generic scancode parser.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_STROKE_H_
#define KBD_STROKE_H_
 
extern void stroke_sim(unsigned, unsigned);
 
#endif
 
/**
* @}
*/
 
/branches/network/uspace/srv/kbd/port/gxemul.c
0,0 → 1,87
/*
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @{
* @ingroup kbd
*/
/** @file
* @brief GXEmul keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
 
static irq_cmd_t gxemul_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2,
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t gxemul_kbd = {
sizeof(gxemul_cmds) / sizeof(irq_cmd_t),
gxemul_cmds
};
 
static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
/** Initializes keyboard handler. */
int kbd_port_init(void)
{
async_set_interrupt_received(gxemul_irq_handler);
gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &gxemul_kbd);
return 0;
}
 
/** Process data sent when a key is pressed.
*
* @param keybuffer Buffer of pressed keys.
* @param call IPC call.
*
* @return Always 1.
*/
static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/ns16550.c
0,0 → 1,115
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief NS16550 port driver.
*/
 
#include <ipc/ipc.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <ddi.h>
 
/* NS16550 registers */
#define RBR_REG 0 /** Receiver Buffer Register. */
#define IER_REG 1 /** Interrupt Enable Register. */
#define IIR_REG 2 /** Interrupt Ident Register (read). */
#define FCR_REG 2 /** FIFO control register (write). */
#define LCR_REG 3 /** Line Control register. */
#define MCR_REG 4 /** Modem Control Register. */
#define LSR_REG 5 /** Line Status Register. */
 
#define LSR_DATA_READY 0x01
 
static irq_cmd_t ns16550_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = LSR_DATA_READY,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
irq_code_t ns16550_kbd = {
sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
ns16550_cmds
};
 
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
static uintptr_t ns16550_physical;
static uintptr_t ns16550_kernel;
 
int kbd_port_init(void)
{
void *vaddr;
 
async_set_interrupt_received(ns16550_irq_handler);
 
ns16550_physical = sysinfo_value("kbd.address.physical");
ns16550_kernel = sysinfo_value("kbd.address.kernel");
ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &ns16550_kbd);
return pio_enable((void *) ns16550_physical, 8, &vaddr);
}
 
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/msim.c
0,0 → 1,92
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Msim keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
 
irq_cmd_t msim_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
irq_code_t msim_kbd = {
sizeof(msim_cmds) / sizeof(irq_cmd_t),
msim_cmds
};
 
static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
async_set_interrupt_received(msim_irq_handler);
msim_cmds[0].addr = sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &msim_kbd);
return 0;
}
 
static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
// static int esc_count=0;
 
// if (scan_code == 0x1b) {
// esc_count++;
// if (esc_count == 3)
// __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
// } else {
// esc_count=0;
// }
 
// if (fb_fb)
// return kbd_arch_process_fb(keybuffer, scan_code);
 
kbd_push_scancode(scan_code);
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/i8042.c
0,0 → 1,169
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief i8042 port driver.
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <ipc/ipc.h>
#include <async.h>
#include <unistd.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
#include "i8042.h"
 
/* Interesting bits for status register */
#define i8042_OUTPUT_FULL 0x1
#define i8042_INPUT_FULL 0x2
#define i8042_MOUSE_DATA 0x20
 
/* Command constants */
#define i8042_CMD_KBD 0x60
#define i8042_CMD_MOUSE 0xd4
 
/* Keyboard cmd byte */
#define i8042_KBD_IE 0x1
#define i8042_MOUSE_IE 0x2
#define i8042_KBD_DISABLE 0x10
#define i8042_MOUSE_DISABLE 0x20
#define i8042_KBD_TRANSLATE 0x40
 
/* Mouse constants */
#define MOUSE_OUT_INIT 0xf4
#define MOUSE_ACK 0xfa
 
static irq_cmd_t i8042_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = i8042_OUTPUT_FULL,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t i8042_kbd = {
sizeof(i8042_cmds) / sizeof(irq_cmd_t),
i8042_cmds
};
 
static uintptr_t i8042_physical;
static uintptr_t i8042_kernel;
static i8042_t * i8042;
 
static void wait_ready(void) {
while (pio_read_8(&i8042->status) & i8042_INPUT_FULL)
;
}
 
static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
int mouseenabled = 0;
void *vaddr;
 
i8042_physical = sysinfo_value("kbd.address.physical");
i8042_kernel = sysinfo_value("kbd.address.kernel");
if (pio_enable((void *) i8042_physical, sizeof(i8042_t), &vaddr) != 0)
return -1;
i8042 = vaddr;
 
async_set_interrupt_received(i8042_irq_handler);
 
/* Disable kbd, enable mouse */
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->data, i8042_KBD_DISABLE);
wait_ready();
 
/* Flush all current IO */
while (pio_read_8(&i8042->status) & i8042_OUTPUT_FULL)
(void) pio_read_8(&i8042->data);
/* Enable kbd */
i8042_kbd.cmds[0].addr = &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = &((i8042_t *) i8042_kernel)->data;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &i8042_kbd);
 
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
if (mouseenabled)
newcontrol |= i8042_MOUSE_IE;
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->data, newcontrol);
wait_ready();
return 0;
}
 
static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int status = IPC_GET_ARG1(*call);
 
if ((status & i8042_MOUSE_DATA))
return;
 
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
return;
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/z8530.c
0,0 → 1,108
/*
* Copyright (c) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Z8530 keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <ipc/bus.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sys/types.h>
#include <ddi.h>
 
#define CHAN_A_STATUS 4
#define CHAN_A_DATA 6
 
#define RR0_RCA 1
 
static irq_cmd_t z8530_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = RR0_RCA,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
irq_code_t z8530_kbd = {
sizeof(z8530_cmds) / sizeof(irq_cmd_t),
z8530_cmds
};
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
async_set_interrupt_received(z8530_irq_handler);
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.kernel") +
CHAN_A_STATUS;
z8530_cmds[3].addr = (void *) sysinfo_value("kbd.address.kernel") +
CHAN_A_DATA;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
sysinfo_value("kbd.inr"), &z8530_kbd);
return 0;
}
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
if (cir_service)
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
IPC_GET_METHOD(*call));
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/ski.c
0,0 → 1,110
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Ski console keyboard port driver.
*/
 
 
#include <stdlib.h>
#include <unistd.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sys/types.h>
#include <thread.h>
 
#define SKI_GETCHAR 21
 
#define POLL_INTERVAL 10000
 
static void *ski_thread_impl(void *arg);
static int32_t ski_getchar(void);
 
/** Initialize Ski port driver. */
int kbd_port_init(void)
{
thread_id_t tid;
int rc;
 
rc = thread_create(ski_thread_impl, NULL, "kbd_poll", &tid);
if (rc != 0) {
return rc;
}
 
return 0;
}
 
/** Thread to poll Ski for keypresses. */
static void *ski_thread_impl(void *arg)
{
int32_t c;
(void) arg;
 
while (1) {
while (1) {
c = ski_getchar();
if (c == 0)
break;
kbd_push_scancode(c);
}
 
usleep(POLL_INTERVAL);
}
}
 
/** Ask Ski if a key was pressed.
*
* Use SSC (Simulator System Call) to get character from the debug console.
* This call is non-blocking.
*
* @return ASCII code of pressed key or 0 if no key pressed.
*/
static int32_t ski_getchar(void)
{
uint64_t ch;
asm volatile (
"mov r15 = %1\n"
"break 0x80000;;\n" /* modifies r8 */
"mov %0 = r8;;\n"
 
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
 
return (int32_t) ch;
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/sgcn.c
0,0 → 1,164
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief SGCN (Serengeti Console) keyboard port driver.
*/
 
#include <as.h>
#include <ddi.h>
#include <async.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sysinfo.h>
#include <stdio.h>
#include <thread.h>
 
#define POLL_INTERVAL 10000
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[4];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/**
* Virtual address mapped to SRAM.
*/
static uintptr_t sram_virt_addr;
 
/**
* SGCN buffer offset within SGCN.
*/
static uintptr_t sram_buffer_offset;
 
/* polling thread */
static void *sgcn_thread_impl(void *arg);
 
 
/**
* Initializes the SGCN driver.
* Maps the physical memory (SRAM) and creates the polling thread.
*/
int kbd_port_init(void)
{
sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
if (physmem_map((void *) sysinfo_value("sram.address.physical"),
(void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
AS_AREA_READ | AS_AREA_WRITE) != 0) {
printf("SGCN: uspace driver could not map physical memory.");
return -1;
}
sram_buffer_offset = sysinfo_value("sram.buffer.offset");
 
thread_id_t tid;
int rc;
 
rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
if (rc != 0) {
return rc;
}
 
return 0;
}
 
/**
* Handler of the "key pressed" event. Reads codes of all the pressed keys from
* the buffer.
*/
static void sgcn_key_pressed(void)
{
char c;
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
while (*in_rdptr_ptr != *in_wrptr_ptr) {
c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
kbd_push_scancode(c);
}
}
 
/**
* Thread to poll SGCN for keypresses.
*/
static void *sgcn_thread_impl(void *arg)
{
(void) arg;
 
while (1) {
sgcn_key_pressed();
usleep(POLL_INTERVAL);
}
}
 
 
/** @}
*/
/branches/network/uspace/srv/kbd/port/i8042.h
0,0 → 1,55
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
 
/** @file
* @brief i8042 port driver.
*/
 
#ifndef KBD_PORT_i8042_H_
#define KBD_PORT_i8042_H_
 
#include <libarch/ddi.h>
#include <libarch/types.h>
 
struct i8042 {
ioport8_t data;
uint8_t pad[3];
ioport8_t status;
} __attribute__ ((packed));
typedef struct i8042 i8042_t;
 
#endif
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/port/dummy.c
0,0 → 1,46
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd_port
* @brief Dummy keyboard port driver.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#include <kbd_port.h>
#include <kbd.h>
 
int kbd_port_init(void)
{
return 0;
}
 
/** @}
*/
/branches/network/uspace/srv/kbd/genarch/include/kbd.h
File deleted
/branches/network/uspace/srv/kbd/genarch/include/scanc.h
File deleted
/branches/network/uspace/srv/kbd/genarch/src/kbd.c
File deleted
/branches/network/uspace/srv/kbd/genarch/stroke.c
0,0 → 1,84
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd
* @{
*/
/**
* @file
* @brief Stroke simulator.
*
* When simulating a keyboard using a serial TTY we need to convert the
* recognized strokes (such as Shift-A) to sequences of key presses and
* releases (such as 'press Shift, press A, release A, release Shift').
*/
 
#include <stroke.h>
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
 
/** Correspondence between modifers and the modifier keycodes. */
static unsigned int mods_keys[][2] = {
{ KM_LSHIFT, KC_LSHIFT },
{ 0, 0 }
};
 
/** Simulate keystroke using sequences of key presses and releases. */
void stroke_sim(unsigned mod, unsigned key)
{
int i;
 
/* Simulate modifier presses. */
i = 0;
while (mods_keys[i][0] != 0) {
if (mod & mods_keys[i][0]) {
kbd_push_ev(KE_PRESS, mods_keys[i][1]);
}
++i;
}
 
/* Simulate key press and release. */
if (key != 0) {
kbd_push_ev(KE_PRESS, key);
kbd_push_ev(KE_RELEASE, key);
}
 
/* Simulate modifier releases. */
i = 0;
while (mods_keys[i][0] != 0) {
if (mod & mods_keys[i][0]) {
kbd_push_ev(KE_RELEASE, mods_keys[i][1]);
}
++i;
}
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/genarch/gsp.c
0,0 → 1,288
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/**
* @addtogroup kbdgen generic
* @ingroup kbd
* @{
*/
/** @file
* @brief Generic scancode parser.
*
* The scancode parser is a simple finite state machine. It is described
* using sequences of input symbols (scancodes) and the corresponding output
* value (mods, key pair). When the parser recognizes a sequence,
* it outputs the value and restarts. If a transition is undefined,
* the parser restarts, too.
*
* Apart from precise values, GSP_DEFAULT allows to catch general cases.
* I.e. if we knew that after 0x1b 0x4f there always follow two more
* scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
* with null output. This will force the parser to read the entire sequence,
* not leaving garbage on the input if it does not recognize the specific
* sequence.
*/
 
#include <gsp.h>
#include <libadt/hash_table.h>
#include <stdlib.h>
#include <stdio.h>
 
#define TRANS_TABLE_CHAINS 256
 
/*
* Hash table operations for the transition function.
*/
 
static hash_index_t trans_op_hash(unsigned long key[]);
static int trans_op_compare(unsigned long key[], hash_count_t keys,
link_t *item);
static void trans_op_remove_callback(link_t *item);
 
static hash_table_operations_t trans_ops = {
.hash = trans_op_hash,
.compare = trans_op_compare,
.remove_callback = trans_op_remove_callback
};
 
static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
static void trans_insert(gsp_t *p, gsp_trans_t *t);
static gsp_trans_t *trans_new(void);
 
/** Initialise scancode parser. */
void gsp_init(gsp_t *p)
{
p->states = 1;
hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
}
 
/** Insert a series of definitions into the parser.
*
* @param p The parser.
* @param defs Definition list. Each definition starts with two output values
* (mods, key) and continues with a sequence of input values
* terminated with GSP_END. The definition list is terminated
* with two zeroes (0, 0) for output values.
*/
int gsp_insert_defs(gsp_t *p, const int *defs)
{
unsigned mods, key;
const int *dp;
int rc;
 
dp = defs;
 
while (1) {
/* Read the output values. */
mods = *dp++;
key = *dp++;
if (key == 0) break;
 
/* Insert one sequence. */
rc = gsp_insert_seq(p, dp, mods, key);
if (rc != 0)
return rc;
 
/* Skip to the next definition. */
while (*dp != GSP_END)
++dp;
++dp;
}
 
return 0;
}
 
/** Insert one sequence into the parser.
*
* @param p The parser.
* @param seq Sequence of input values terminated with GSP_END.
* @param mods Corresponsing output value.
* @param key Corresponsing output value.
*/
int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
{
int state;
gsp_trans_t *t;
 
state = 0;
t = NULL;
 
/* Input sequence must be non-empty. */
if (*seq == GSP_END)
return -1;
 
while (*(seq + 1) != GSP_END) {
t = trans_lookup(p, state, *seq);
if (t == NULL) {
/* Create new state. */
t = trans_new();
t->old_state = state;
t->input = *seq;
t->new_state = p->states++;
 
t->out_mods = 0;
t->out_key = 0;
 
trans_insert(p, t);
}
state = t->new_state;
++seq;
}
 
/* Process the last transition. */
t = trans_lookup(p, state, *seq);
if (t != NULL) {
exit(1);
return -1; /* Conflicting definition. */
}
 
t = trans_new();
t->old_state = state;
t->input = *seq;
t->new_state = 0;
 
t->out_mods = mods;
t->out_key = key;
 
trans_insert(p, t);
 
return 0;
}
 
/** Compute one parser step.
*
* Computes the next state and output values for a given state and input.
* This handles everything including restarts and default branches.
*
* @param p The parser.
* @param state Old state.
* @param input Input symbol (scancode).
* @param mods Output value (modifier).
* @param key Output value (key).
* @return New state.
*/
int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
{
gsp_trans_t *t;
 
t = trans_lookup(p, state, input);
if (t == NULL) {
t = trans_lookup(p, state, GSP_DEFAULT);
}
 
if (t == NULL) {
printf("gsp_step: not found\n");
*mods = NULL;
*key = NULL;
return 0;
}
 
*mods = t->out_mods;
*key = t->out_key;
return t->new_state;
}
 
/** Transition function lookup.
*
* Returns the value of the transition function for the given state
* and input. Note that the transition must be specified precisely,
* to obtain the default branch use input = GSP_DEFAULT.
*
* @param p Parser.
* @param state Current state.
* @param input Input value.
* @return The transition or @c NULL if not defined.
*/
static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
{
link_t *item;
unsigned long key[2];
 
key[0] = state;
key[1] = input;
 
item = hash_table_find(&p->trans, key);
if (item == NULL) return NULL;
 
return hash_table_get_instance(item, gsp_trans_t, link);
}
 
/** Define a new transition.
*
* @param p The parser.
* @param t Transition with all fields defined.
*/
static void trans_insert(gsp_t *p, gsp_trans_t *t)
{
unsigned long key[2];
 
key[0] = t->old_state;
key[1] = t->input;
 
hash_table_insert(&p->trans, &key, &t->link);
}
 
/** Allocate transition structure. */
static gsp_trans_t *trans_new(void)
{
gsp_trans_t *t;
 
t = malloc(sizeof(gsp_trans_t));
if (t == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
 
return t;
}
 
/*
* Transition function hash table operations.
*/
 
static hash_index_t trans_op_hash(unsigned long key[])
{
return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
}
 
static int trans_op_compare(unsigned long key[], hash_count_t keys,
link_t *item)
{
gsp_trans_t *t;
 
t = hash_table_get_instance(item, gsp_trans_t, link);
return (key[0] == t->old_state && key[1] == t->input);
}
 
static void trans_op_remove_callback(link_t *item)
{
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/generic/kbd.c
37,48 → 37,99
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sysinfo.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ipc/ns.h>
#include <async.h>
#include <errno.h>
#include <arch/kbd.h>
#include <libadt/fifo.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
 
#include <kbd.h>
#include <libadt/fifo.h>
#include <key_buffer.h>
#include <async.h>
#include <keys.h>
#include <kbd_port.h>
#include <kbd_ctl.h>
#include <layout.h>
 
#define NAME "kbd"
 
int cons_connected = 0;
int phone2cons = -1;
keybuffer_t keybuffer;
keybuffer_t keybuffer;
 
static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
/** Currently active modifiers. */
static unsigned mods = KM_NUM_LOCK;
 
/** Currently pressed lock keys. We track these to tackle autorepeat. */
static unsigned lock_keys;
 
int cir_service = 0;
int cir_phone = -1;
 
void kbd_push_scancode(int scancode)
{
int chr;
/* printf("scancode: 0x%x\n", scancode);*/
kbd_ctl_parse_scancode(scancode);
}
 
#ifdef MOUSE_ENABLED
if (mouse_arch_process(phone2cons, call))
return;
#endif
kbd_arch_process(&keybuffer, call);
void kbd_push_ev(int type, unsigned int key)
{
kbd_event_t ev;
unsigned mod_mask;
 
if (cons_connected && phone2cons != -1) {
/*
* recode to ASCII - one interrupt can produce more than one
* code so result is stored in fifo
*/
while (!keybuffer_empty(&keybuffer)) {
if (!keybuffer_pop(&keybuffer, (int *)&chr))
break;
switch (key) {
case KC_LCTRL: mod_mask = KM_LCTRL; break;
case KC_RCTRL: mod_mask = KM_RCTRL; break;
case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
case KC_LALT: mod_mask = KM_LALT; break;
case KC_RALT: mod_mask = KM_RALT; break;
default: mod_mask = 0; break;
}
 
async_msg_1(phone2cons, KBD_PUSHCHAR, chr);
if (mod_mask != 0) {
if (type == KE_PRESS)
mods = mods | mod_mask;
else
mods = mods & ~mod_mask;
}
 
switch (key) {
case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
default: mod_mask = 0; break;
}
 
if (mod_mask != 0) {
if (type == KE_PRESS) {
/*
* Only change lock state on transition from released
* to pressed. This prevents autorepeat from messing
* up the lock state.
*/
mods = mods ^ (mod_mask & ~lock_keys);
lock_keys = lock_keys | mod_mask;
} else {
lock_keys = lock_keys & ~mod_mask;
}
}
/*
printf("type: %d\n", type);
printf("mods: 0x%x\n", mods);
printf("keycode: %u\n", key);
*/
ev.type = type;
ev.key = key;
ev.mods = mods;
 
ev.c = layout_parse_ev(&ev);
 
async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
}
 
static void console_connection(ipc_callid_t iid, ipc_call_t *icall)
125,16 → 176,32
ipcarg_t phonead;
/* Initialize arch dependent parts */
if (kbd_arch_init())
if (sysinfo_value("kbd.cir.fhc") == 1)
cir_service = SERVICE_FHC;
else if (sysinfo_value("kbd.cir.obio") == 1)
cir_service = SERVICE_OBIO;
if (cir_service) {
while (cir_phone < 0) {
cir_phone = ipc_connect_me_to_blocking(PHONE_NS, cir_service,
0, 0);
}
}
/* Initialize port driver. */
if (kbd_port_init() != 0)
return -1;
 
/* Initialize controller driver. */
if (kbd_ctl_init() != 0)
return -1;
/* Initialize key buffer */
keybuffer_init(&keybuffer);
async_set_client_connection(console_connection);
async_set_interrupt_received(irq_handler);
/* Register service at nameserver */
 
/* Register service at nameserver. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, 0, &phonead) != 0)
return -1;
141,7 → 208,7
printf(NAME ": Accepting connections\n");
async_manager();
 
/* Never reached */
/* Not reached. */
return 0;
}
 
/branches/network/uspace/srv/kbd/generic/key_buffer.c
40,7 → 40,7
 
/** Clear key buffer.
*/
void keybuffer_free(keybuffer_t *keybuffer)
void keybuffer_free(keybuffer_t *keybuffer)
{
futex_down(&keybuffer_futex);
keybuffer->head = 0;
75,15 → 75,18
return (keybuffer->items == 0);
}
 
/** Push key to key buffer.
* If buffer is full, character is ignored.
* @param key code of stored key
/** Push key event to key buffer.
*
* If the buffer is full, the event is ignored.
*
* @param keybuffer The keybuffer.
* @param ev The event to push.
*/
void keybuffer_push(keybuffer_t *keybuffer, int key)
void keybuffer_push(keybuffer_t *keybuffer, const kbd_event_t *ev)
{
futex_down(&keybuffer_futex);
if (keybuffer->items < KEYBUFFER_SIZE) {
keybuffer->fifo[keybuffer->tail] = key;
keybuffer->fifo[keybuffer->tail] = *ev;
keybuffer->tail = (keybuffer->tail + 1) % KEYBUFFER_SIZE;
keybuffer->items++;
}
90,16 → 93,25
futex_up(&keybuffer_futex);
}
 
/** Pop character from buffer.
* @param c pointer to space where to store character from buffer.
* @return zero on empty buffer, nonzero else
void keybuffer_push0(keybuffer_t *keybuffer, int c)
{
kbd_event_t ev;
 
ev.key = c; ev.mods = 0; ev.c = c;
keybuffer_push(keybuffer, &ev);
}
 
/** Pop event from buffer.
*
* @param edst Pointer to where the event should be saved.
* @return Zero on empty buffer, nonzero otherwise.
*/
int keybuffer_pop(keybuffer_t *keybuffer, int *c)
int keybuffer_pop(keybuffer_t *keybuffer, kbd_event_t *edst)
{
futex_down(&keybuffer_futex);
if (keybuffer->items > 0) {
keybuffer->items--;
*c = (keybuffer->fifo[keybuffer->head]) ;
*edst = (keybuffer->fifo[keybuffer->head]) ;
keybuffer->head = (keybuffer->head + 1) % KEYBUFFER_SIZE;
futex_up(&keybuffer_futex);
return 1;
/branches/network/uspace/srv/kbd/Makefile
31,9 → 31,9
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
include ../../../Makefile.config
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -Iinclude -I../libadt/include
 
LIBS = $(LIBC_PREFIX)/libc.a
44,61 → 44,109
OUTPUT = kbd
GENERIC_SOURCES = \
generic/kbd.c \
genarch/gsp.c \
genarch/stroke.c \
generic/key_buffer.c
 
ARCH_SOURCES = \
arch/$(ARCH)/src/kbd.c
ARCH_SOURCES =
GENARCH_SOURCES =
 
ifeq ($(ARCH), ia32)
ARCH_SOURCES += \
arch/$(ARCH)/src/mouse.c \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
CFLAGS += -DMOUSE_ENABLED
ifeq ($(KBD_LAYOUT), us_qwerty)
GENARCH_SOURCES += layout/us_qwerty.c
endif
ifeq ($(ARCH), amd64)
ARCH_SOURCES += \
arch/$(ARCH)/src/mouse.c \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
CFLAGS += -DMOUSE_ENABLED
ifeq ($(KBD_LAYOUT), us_dvorak)
GENARCH_SOURCES += layout/us_dvorak.c
endif
ifeq ($(ARCH), sparc64)
ARCH_SOURCES += \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
 
ifeq ($(UARCH), amd64)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(ARCH), arm32)
ARCH_SOURCES += \
arch/$(ARCH)/src/kbd_gxemul.c
ifeq ($(UARCH), arm32)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
else
GENARCH_SOURCES += \
ctl/stty.c
endif
endif
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(MACHINE), i460GX)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(MACHINE), ski)
GENARCH_SOURCES += \
port/ski.c \
ctl/stty.c
endif
ifeq ($(MACHINE), msim)
GENARCH_SOURCES += \
port/msim.c \
ctl/stty.c
endif
ifeq ($(MACHINE), lgxemul)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
else
GENARCH_SOURCES += \
ctl/stty.c
endif
endif
ifeq ($(MACHINE), bgxemul)
GENARCH_SOURCES += \
port/gxemul.c \
ctl/stty.c
endif
ifeq ($(UARCH), ppc32)
GENARCH_SOURCES += \
port/dummy.c \
ctl/stty.c
endif
ifeq ($(UARCH), sparc64)
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/z8530.c \
ctl/sun.c
endif
endif
 
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
OBJECTS := $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS)
 
.PHONY: all clean depend disasm links
 
all: links $(OUTPUT) $(OUTPUT).disasm
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
links:
ln -sfn ../arch/$(ARCH)/include include/arch
ln -sfn ../genarch/include include/genarch
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend include/arch include/genarch
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(GENERIC_OBJECTS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
/branches/network/uspace/srv/kbd/layout/us_dvorak.c
0,0 → 1,238
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd
* @brief US Dvorak Simplified Keyboard layout.
* @{
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <layout.h>
 
static char map_lcase[] = {
[KC_R] = 'p',
[KC_T] = 'y',
[KC_Y] = 'f',
[KC_U] = 'g',
[KC_I] = 'c',
[KC_O] = 'r',
[KC_P] = 'l',
 
[KC_A] = 'a',
[KC_S] = 'o',
[KC_D] = 'e',
[KC_F] = 'u',
[KC_G] = 'i',
[KC_H] = 'd',
[KC_J] = 'h',
[KC_K] = 't',
[KC_L] = 'n',
 
[KC_SEMICOLON] = 's',
 
[KC_X] = 'q',
[KC_C] = 'j',
[KC_V] = 'k',
[KC_B] = 'x',
[KC_N] = 'b',
[KC_M] = 'm',
 
[KC_COMMA] = 'w',
[KC_PERIOD] = 'v',
[KC_SLASH] = 'z',
};
 
static char map_ucase[] = {
[KC_R] = 'P',
[KC_T] = 'Y',
[KC_Y] = 'F',
[KC_U] = 'G',
[KC_I] = 'C',
[KC_O] = 'R',
[KC_P] = 'L',
 
[KC_A] = 'A',
[KC_S] = 'O',
[KC_D] = 'E',
[KC_F] = 'U',
[KC_G] = 'I',
[KC_H] = 'D',
[KC_J] = 'H',
[KC_K] = 'T',
[KC_L] = 'N',
 
[KC_SEMICOLON] = 'S',
 
[KC_X] = 'Q',
[KC_C] = 'J',
[KC_V] = 'K',
[KC_B] = 'X',
[KC_N] = 'B',
[KC_M] = 'M',
 
[KC_COMMA] = 'W',
[KC_PERIOD] = 'V',
[KC_SLASH] = 'Z',
};
 
static char map_not_shifted[] = {
[KC_BACKTICK] = '`',
 
[KC_1] = '1',
[KC_2] = '2',
[KC_3] = '3',
[KC_4] = '4',
[KC_5] = '5',
[KC_6] = '6',
[KC_7] = '7',
[KC_8] = '8',
[KC_9] = '9',
[KC_0] = '0',
 
[KC_MINUS] = '[',
[KC_EQUALS] = ']',
 
[KC_Q] = '\'',
[KC_W] = ',',
[KC_E] = '.',
 
[KC_LBRACKET] = '/',
[KC_RBRACKET] = '=',
 
[KC_QUOTE] = '-',
[KC_BACKSLASH] = '\\',
 
[KC_Z] = ';',
};
 
static char map_shifted[] = {
[KC_BACKTICK] = '~',
 
[KC_1] = '!',
[KC_2] = '@',
[KC_3] = '#',
[KC_4] = '$',
[KC_5] = '%',
[KC_6] = '^',
[KC_7] = '&',
[KC_8] = '*',
[KC_9] = '(',
[KC_0] = ')',
 
[KC_MINUS] = '{',
[KC_EQUALS] = '}',
 
[KC_Q] = '"',
[KC_W] = '<',
[KC_E] = '>',
 
[KC_LBRACKET] = '?',
[KC_RBRACKET] = '+',
 
[KC_QUOTE] = '_',
[KC_BACKSLASH] = '|',
 
[KC_Z] = ':',
};
 
static char map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
[KC_ENTER] = '\n',
[KC_SPACE] = ' ',
 
[KC_NSLASH] = '/',
[KC_NTIMES] = '*',
[KC_NMINUS] = '-',
[KC_NPLUS] = '+',
[KC_NENTER] = '\n'
};
 
static char map_numeric[] = {
[KC_N7] = '7',
[KC_N8] = '8',
[KC_N9] = '9',
[KC_N4] = '4',
[KC_N5] = '5',
[KC_N6] = '6',
[KC_N1] = '1',
[KC_N2] = '2',
[KC_N3] = '3',
 
[KC_N0] = '0',
[KC_NPERIOD] = '.'
};
 
static int translate(unsigned int key, char *map, size_t map_length)
{
if (key >= map_length)
return 0;
return map[key];
}
 
char layout_parse_ev(kbd_event_t *ev)
{
char c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char));
if (c != 0)
return c;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char));
else
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) != 0)
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char));
else
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_NUM_LOCK) != 0)
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char));
else
c = 0;
 
return c;
}
 
/**
* @}
*/
/branches/network/uspace/srv/kbd/layout/us_qwerty.c
0,0 → 1,228
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @{
*/
 
#include <kbd.h>
#include <kbd/kbd.h>
#include <kbd/keycode.h>
#include <layout.h>
 
static char map_lcase[] = {
[KC_Q] = 'q',
[KC_W] = 'w',
[KC_E] = 'e',
[KC_R] = 'r',
[KC_T] = 't',
[KC_Y] = 'y',
[KC_U] = 'u',
[KC_I] = 'i',
[KC_O] = 'o',
[KC_P] = 'p',
 
[KC_A] = 'a',
[KC_S] = 's',
[KC_D] = 'd',
[KC_F] = 'f',
[KC_G] = 'g',
[KC_H] = 'h',
[KC_J] = 'j',
[KC_K] = 'k',
[KC_L] = 'l',
 
[KC_Z] = 'z',
[KC_X] = 'x',
[KC_C] = 'c',
[KC_V] = 'v',
[KC_B] = 'b',
[KC_N] = 'n',
[KC_M] = 'm',
};
 
static char map_ucase[] = {
[KC_Q] = 'Q',
[KC_W] = 'W',
[KC_E] = 'E',
[KC_R] = 'R',
[KC_T] = 'T',
[KC_Y] = 'Y',
[KC_U] = 'U',
[KC_I] = 'I',
[KC_O] = 'O',
[KC_P] = 'P',
 
[KC_A] = 'A',
[KC_S] = 'S',
[KC_D] = 'D',
[KC_F] = 'F',
[KC_G] = 'G',
[KC_H] = 'H',
[KC_J] = 'J',
[KC_K] = 'K',
[KC_L] = 'L',
 
[KC_Z] = 'Z',
[KC_X] = 'X',
[KC_C] = 'C',
[KC_V] = 'V',
[KC_B] = 'B',
[KC_N] = 'N',
[KC_M] = 'M',
};
 
static char map_not_shifted[] = {
[KC_BACKTICK] = '`',
 
[KC_1] = '1',
[KC_2] = '2',
[KC_3] = '3',
[KC_4] = '4',
[KC_5] = '5',
[KC_6] = '6',
[KC_7] = '7',
[KC_8] = '8',
[KC_9] = '9',
[KC_0] = '0',
 
[KC_MINUS] = '-',
[KC_EQUALS] = '=',
 
[KC_LBRACKET] = '[',
[KC_RBRACKET] = ']',
 
[KC_SEMICOLON] = ';',
[KC_QUOTE] = '\'',
[KC_BACKSLASH] = '\\',
 
[KC_COMMA] = ',',
[KC_PERIOD] = '.',
[KC_SLASH] = '/',
};
 
static char map_shifted[] = {
[KC_BACKTICK] = '~',
 
[KC_1] = '!',
[KC_2] = '@',
[KC_3] = '#',
[KC_4] = '$',
[KC_5] = '%',
[KC_6] = '^',
[KC_7] = '&',
[KC_8] = '*',
[KC_9] = '(',
[KC_0] = ')',
 
[KC_MINUS] = '_',
[KC_EQUALS] = '+',
 
[KC_LBRACKET] = '{',
[KC_RBRACKET] = '}',
 
[KC_SEMICOLON] = ':',
[KC_QUOTE] = '"',
[KC_BACKSLASH] = '|',
 
[KC_COMMA] = '<',
[KC_PERIOD] = '>',
[KC_SLASH] = '?',
};
 
static char map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
[KC_ENTER] = '\n',
[KC_SPACE] = ' ',
 
[KC_NSLASH] = '/',
[KC_NTIMES] = '*',
[KC_NMINUS] = '-',
[KC_NPLUS] = '+',
[KC_NENTER] = '\n'
};
 
static char map_numeric[] = {
[KC_N7] = '7',
[KC_N8] = '8',
[KC_N9] = '9',
[KC_N4] = '4',
[KC_N5] = '5',
[KC_N6] = '6',
[KC_N1] = '1',
[KC_N2] = '2',
[KC_N3] = '3',
 
[KC_N0] = '0',
[KC_NPERIOD] = '.'
};
 
static int translate(unsigned int key, char *map, size_t map_length)
{
if (key >= map_length) return 0;
return map[key];
}
 
char layout_parse_ev(kbd_event_t *ev)
{
char c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char));
if (c != 0) return c;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char));
else
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char));
 
if (c != 0) return c;
 
if ((ev->mods & KM_SHIFT) != 0)
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char));
else
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char));
 
if (c != 0) return c;
 
if ((ev->mods & KM_NUM_LOCK) != 0)
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char));
else
c = 0;
 
return c;
}
 
/**
* @}
*/