|
|
GNU Mach 1.0
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* File: lk201.c
* Author: Alessandro Forin, Carnegie Mellon University
* Date: 9/90
*
* Routines for the LK201 Keyboard Driver
*/
#include <lk.h>
#if NLK > 0
#include <bm.h>
#include <mach_kdb.h>
#include <mach/std_types.h>
#include <device/device_types.h>
#include <machine/machspl.h> /* spl definitions */
#include <sys/ioctl.h>
#include <machine/machspl.h>
#include <chips/lk201.h>
#include <chips/serial_defs.h>
#include <chips/screen_defs.h>
/*
* Structures describing the keyboard status
*/
typedef struct {
unsigned short kbd_flags;
unsigned short kbd_previous;
char kbd_gen_shift;
char kbd_ctrl;
char kbd_lock;
char kbd_meta;
char kbd_shift;
} lk201_kbd_state_t;
#define mapLOCKtoCNTRL 0x1 /* flags */
typedef struct {
char led_active;
char led_pattern;
char led_increasing;
char led_lights;
int led_interval;
int led_light_count;
} lk201_led_state_t;
/*
* Keyboard state
*/
struct lk201_softc {
lk201_kbd_state_t kbd;
lk201_led_state_t led;
int sl_unit;
} lk201_softc_data[NLK];
typedef struct lk201_softc *lk201_softc_t;
lk201_softc_t lk201_softc[NLK];
/*
* Forward decls
*/
io_return_t
lk201_translation(
int key,
char c,
int tabcode );
int
lk201_input(
int unit,
unsigned short data);
/*
* Autoconf (sort-of)
*/
lk201_probe(
int unit)
{
lk201_softc[unit] = &lk201_softc_data[unit];
return 1;
}
void lk201_attach(
int unit,
int sl_unit)
{
lk201_softc[unit]->sl_unit = sl_unit;
lk201_selftest(unit);
}
/*
* Keyboard initialization
*/
static unsigned char lk201_reset_string[] = {
LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf), /* show we are resetting */
LK_CMD_SET_DEFAULTS,
LK_CMD_MODE(LK_MODE_RPT_DOWN,1),
LK_CMD_MODE(LK_MODE_RPT_DOWN,2),
LK_CMD_MODE(LK_MODE_RPT_DOWN,3),
LK_CMD_MODE(LK_MODE_RPT_DOWN,4),
LK_CMD_MODE(LK_MODE_DOWN_UP,5),
LK_CMD_MODE(LK_MODE_DOWN_UP,6),
LK_CMD_MODE(LK_MODE_RPT_DOWN,7),
LK_CMD_MODE(LK_MODE_RPT_DOWN,8),
LK_CMD_MODE(LK_MODE_RPT_DOWN,9),
LK_CMD_MODE(LK_MODE_RPT_DOWN,10),
LK_CMD_MODE(LK_MODE_RPT_DOWN,11),
LK_CMD_MODE(LK_MODE_RPT_DOWN,12),
LK_CMD_MODE(LK_MODE_DOWN,13),
LK_CMD_MODE(LK_MODE_RPT_DOWN,14),
LK_CMD_ENB_RPT,
/* LK_CMD_ENB_KEYCLK, LK_PARAM_VOLUME(4), */
LK_CMD_DIS_KEYCLK,
LK_CMD_RESUME,
LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
};
void
lk201_reset(
int unit)
{
register int i, sl;
register spl_t s;
lk201_softc_t lk;
lk = lk201_softc[unit];
sl = lk->sl_unit;
s = spltty();
for (i = 0; i < sizeof(lk201_reset_string); i++) {
(*console_putc)(sl,
SCREEN_LINE_KEYBOARD,
lk201_reset_string[i]);
delay(100);
}
/* zero any state associated with previous keypresses */
bzero(lk, sizeof(*lk));
lk->sl_unit = sl;
splx(s);
}
lk201_selftest(
int unit)
{
int messg[4], sl;
spl_t s;
sl = lk201_softc[unit]->sl_unit;
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_REQ_ID);
delay(10000);/* arbitrary */
messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
splx(s);
printf("( lk201 id %x.%x", messg[0], messg[1]);
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_POWER_UP);
/* cannot do this, waiting too long might cause receiver overruns */
/* delay(80000);/* spec says 70 msecs or less */
messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
messg[2] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
messg[3] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE);
splx(s);
printf(", self-test ");
if (messg[0] != 0x01 || messg[1] || messg[2] || messg[3])
printf("bad [%x %x %x %x]",
messg[0], messg[1], messg[2], messg[3]);
else
printf("ok )");
lk201_reset(unit);
}
/*
* Tinkerbell
*/
void
lk201_ring_bell(
int unit)
{
spl_t s = spltty();
(*console_putc)(lk201_softc[unit]->sl_unit, SCREEN_LINE_KEYBOARD, LK_CMD_BELL);
splx(s);
}
/*
* Here is your LED toy, Bob
*/
void
lk201_lights(
int unit,
boolean_t on)
{
unsigned int sl;
spl_t s;
sl = lk201_softc[unit]->sl_unit;
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
if (on < 16 && on > 0) {
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(on));
}
splx(s);
}
lk201_led(
int unit)
{
lk201_led_state_t *leds = &lk201_softc[unit]->led;
unsigned int sl;
spl_t s;
sl = lk201_softc[unit]->sl_unit;
if (leds->led_interval) { /* leds are on */
if (leds->led_light_count <= 0) { /* hit this lights */
if (leds->led_lights <= 0) leds->led_lights= 1; /* sanity */
if (leds->led_lights > 16) leds->led_lights = 16;/* sanity */
leds->led_light_count = leds->led_interval; /* reset */
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
switch (leds->led_pattern) {
case LED_OFF:
leds->led_interval = 0; /* since you can now set */
break; /* the interval even if off */
case LED_COUNT:
leds->led_lights++;
if (leds->led_lights > 16) leds->led_lights = 1;
break;
case LED_ROTATE:
leds->led_lights <<= 1;
if (leds->led_lights > 8) leds->led_lights = 1;
break;
case LED_CYLON:
if (leds->led_increasing) {
leds->led_lights <<= 1;
if (leds->led_lights > 8) {
leds->led_lights >>= 2;
leds->led_increasing = 0;
}
} else {
leds->led_lights >>= 1;
if (leds->led_lights <= 0) {
leds->led_lights = 2;
leds->led_increasing = 1;
}
}
break;
}
(*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
(*console_putc)( sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(leds->led_lights));
splx(s);
}
leds->led_light_count--;
} else {
if (leds->led_lights) {
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0xf));
leds->led_lights = 0;
splx(s);
}
leds->led_active = 0;
#if NBM > 0
screen_enable_vretrace(unit, 0); /* interrupts off */
#endif
}
}
/*
* Special user-visible ops
*/
io_return_t
lk201_set_status(
int unit,
dev_flavor_t flavor,
dev_status_t status,
natural_t status_count)
{
lk201_led_state_t *leds = &lk201_softc[unit]->led;
lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
switch( flavor ) {
case LK201_SEND_CMD:{
register lk201_cmd_t *cmd = (lk201_cmd_t*)status;
unsigned int cnt, s, sl;
if ((status_count < (sizeof(*cmd)/sizeof(int))) ||
((cnt = cmd->len) > 2))
return D_INVALID_SIZE;
if (cnt == 0)
cmd->command |= LK_PARAM;
else
cmd->params[cnt-1] |= LK_PARAM;
sl = lk201_softc[unit]->sl_unit;
s = spltty();
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->command);
if (cnt > 0)
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[0]);
if (cnt > 1)
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, cmd->params[1]);
splx(s);
return D_SUCCESS;
}
case LK201_LED_PATTERN:{
register int ptn = * (int *) status;
if (ptn != LED_OFF && ptn != LED_COUNT &&
ptn != LED_ROTATE && ptn != LED_CYLON ) {
return -1;
} else {
leds->led_pattern = ptn;
}
break;
}
case LK201_LED_INTERVAL:{
register int lcnt = * (int *) status;
if (lcnt < 0)
lcnt = 1;
leds->led_interval = lcnt;
break;
}
case LK201_mapLOCKtoCNTRL:{
boolean_t enable = * (boolean_t*) status;
if (enable)
kbd->kbd_flags |= mapLOCKtoCNTRL;
else
kbd->kbd_flags &= ~mapLOCKtoCNTRL;
return D_SUCCESS;
}
case LK201_REMAP_KEY:{
register KeyMap *k = (KeyMap *) status;
int mode;
if (status_count < (sizeof(KeyMap)/sizeof(int)))
return D_INVALID_SIZE;
mode = k->shifted ? 1 : 0;
if (k->meta) mode += 2;
return lk201_translation( k->in_keyval,
k->out_keyval,
mode );
}
default:
return D_INVALID_OPERATION;
}
leds->led_lights = 1;
leds->led_active = 1;
#if NBM > 0
screen_enable_vretrace(unit, 1); /* interrupts on */
#endif
return D_SUCCESS;
}
/*
* Keycode translation tables
*
* NOTE: these tables have been compressed a little bit
* because the lk201 cannot generate very small codes.
*/
unsigned char lk201_xlate_key[] = {
/* 86 */ 0 ,0
/* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
/* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
/* 152 */ ,'3','4','5','6',',','7','8','9'
/* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
/* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 184 */ ,0 ,0 ,0 ,0 ,0x7f,'\r','\t','`'
/* 192 */ ,'1' ,'q' ,'a' ,'z' ,0 ,'2' ,'w' ,'s'
/* 200 */ ,'x' ,'<' ,0 ,'3' ,'e' ,'d' ,'c' ,0
/* 208 */ ,'4' ,'r' ,'f' ,'v' ,' ' ,0 ,'5' ,'t'
/* 216 */ ,'g' ,'b' ,0 ,'6' ,'y' ,'h' ,'n' ,0
/* 224 */ ,'7' ,'u' ,'j' ,'m' ,0 ,'8' ,'i' ,'k'
/* 232 */ ,',' ,0 ,'9' ,'o' ,'l' ,'.' ,0 ,'0'
/* 240 */ ,'p' ,0 ,';' ,'/' ,0 ,'=' ,']' ,'\\'
/* 248 */ ,0 ,'-' ,'[' ,'\'' ,0 ,0 ,0 ,0
};
unsigned char lk201_xlate_shifted[] = {
/* 86 */ 0 ,0
/* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
/* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
/* 152 */ ,'3','4','5','6',',','7','8','9'
/* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
/* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
/* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
/* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
/* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
/* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
/* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
/* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
/* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
/* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
};
unsigned char lk201_xlate_meta[] = {
/* 86 */ 0 ,0
/* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
/* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
/* 152 */ ,'3','4','5','6',',','7','8','9'
/* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
/* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
/* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
/* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
/* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
/* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
/* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
/* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
/* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
/* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
};
unsigned char lk201_xlate_shifted_meta[] = {
/* 86 */ 0 ,0
/* 88 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 96 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 104 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 112 */ ,0 ,0x1b ,0x08 ,'\n' ,0 ,0 ,0 ,0
/* 120 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 128 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 136 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 144 */ ,0 ,0 ,'0',0 ,'.','\r','1','2'
/* 152 */ ,'3','4','5','6',',','7','8','9'
/* 160 */ ,'-',0 ,0 ,0 ,0 ,0 ,0 ,0
/* 168 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 176 */ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
/* 184 */ ,0 ,0 ,0 ,0 ,0x7f ,'\r' ,'\t' ,'~'
/* 192 */ ,'!' ,'Q' ,'A' ,'Z' ,0 ,'@' ,'W' ,'S'
/* 200 */ ,'X' ,'>' ,0 ,'#' ,'E' ,'D' ,'C' ,0
/* 208 */ ,'$' ,'R' ,'F' ,'V' ,' ' ,0 ,'%' ,'T'
/* 216 */ ,'G' ,'B' ,0 ,'^' ,'Y' ,'H' ,'N' ,0
/* 224 */ ,'&' ,'U' ,'J' ,'M' ,0 ,'*' ,'I' ,'K'
/* 232 */ ,'<' ,0 ,'(' ,'O' ,'L' ,'>' ,0 ,')'
/* 240 */ ,'P' ,0 ,':' ,'?' ,0 ,'+' ,'}' ,'|'
/* 248 */ ,0 ,'_' ,'{' ,'"' ,0 ,0 ,0 ,0
};
io_return_t
lk201_translation(
int key,
char c,
int tabcode )
{
unsigned char *table;
if ((key &= 0xff) < LK_MINCODE)
return D_INVALID_OPERATION;
switch (tabcode) {
case 3:
table = lk201_xlate_shifted_meta;
break;
case 2:
table = lk201_xlate_meta;
break;
case 1:
table = lk201_xlate_shifted;
break;
case 0:
default:
table = lk201_xlate_key;
break;
}
table[key - LK_MINCODE] = c;
return D_SUCCESS;
}
/*
* Input character processing
*/
lk201_rint(
int unit,
unsigned short data,
boolean_t handle_shift,
boolean_t from_kernel)
{
int c;
lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
/*
* Keyboard touched, clean char to 8 bits.
*/
#if NBM > 0
ssaver_bump(unit);
#endif
data &= 0xff;
/* Translate keycode into ASCII */
if ((c = lk201_input(unit, data)) == -1)
return -1;
#if NBM > 0
/*
* Notify X, unless we are called from inside kernel
*/
if (!from_kernel &&
screen_keypress_event(unit, DEV_KEYBD, data, EVT_BUTTON_RAW))
return -1;
#endif
/* Handle shifting if need to */
if (kbd->kbd_gen_shift)
return (handle_shift) ? cngetc() : -1;
return c;
}
/*
* Routine to grock a character from LK201
*/
#if MACH_KDB
int lk201_allow_kdb = 1;
#endif
int lk201_debug = 0;
lk201_input(
int unit,
unsigned short data)
{
int c, sl;
lk201_kbd_state_t *kbd = &lk201_softc[unit]->kbd;
kbd->kbd_gen_shift = 0;
#if MACH_KDB
if (lk201_allow_kdb && (data == LK_DO)) {
kdb_kintr();
return -2;
}
#endif
/*
* Sanity checks
*/
if (data == LK_INPUT_ERR || data == LK_OUTPUT_ERR) {
printf(" Keyboard error, code = %x\n",data);
return -1;
}
if (data < LK_MINCODE)
return -1;
/*
* Check special keys: shifts, ups, ..
*/
if (data == LK_LOCK && (kbd->kbd_flags&mapLOCKtoCNTRL))
data = LK_CNTRL;
switch (data) {
case LK_LOCK:
kbd->kbd_lock ^= 1;
kbd->kbd_gen_shift = 1;
sl = lk201_softc[unit]->sl_unit;
/* called from interrupt, no need for spl */
if (kbd->kbd_lock)
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_ON);
else
(*console_putc)(sl,SCREEN_LINE_KEYBOARD, LK_CMD_LEDS_OFF);
(*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_PARAM_LED_MASK(0x4));
return 0;
case LK_ALT:
case LK_L_ALT:
case LK_R_ALT:
case LK_R_COMPOSE:
kbd->kbd_meta ^= 1;
kbd->kbd_gen_shift = 1;
return 0;
case LK_SHIFT:
case LK_R_SHIFT:
kbd->kbd_shift ^= 1;
kbd->kbd_gen_shift = 1;
return 0;
case LK_CNTRL:
kbd->kbd_ctrl ^= 1;
kbd->kbd_gen_shift = 1;
return 0;
case LK_ALLUP:
kbd->kbd_ctrl = 0;
kbd->kbd_shift = 0;
kbd->kbd_meta = 0;
kbd->kbd_gen_shift = 1;
return 0;
case LK_REPEAT:
c = kbd->kbd_previous;
break;
default:
/*
* Do the key translation to ASCII
*/
if (kbd->kbd_ctrl || kbd->kbd_lock || kbd->kbd_shift) {
c = ((kbd->kbd_meta) ?
lk201_xlate_shifted_meta : lk201_xlate_shifted)
[data - LK_MINCODE];
if (kbd->kbd_ctrl)
c &= 0x1f;
} else
c = ((kbd->kbd_meta) ?
lk201_xlate_meta : lk201_xlate_key)
[data-LK_MINCODE];
break;
}
kbd->kbd_previous = c;
/*
* DEBUG code DEBUG
*/
if (lk201_debug && (c == 0)) {
printf("lk201: [%x]\n", data);
}
return c;
}
#endif /* NLK > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.