153889Smckusick /* 253889Smckusick * Copyright (c) 1992 The Regents of the University of California. 353889Smckusick * All rights reserved. 453889Smckusick * 553889Smckusick * This code is derived from software contributed to Berkeley by 653889Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 753889Smckusick * 853889Smckusick * %sccs.include.redist.c% 953889Smckusick * 1053889Smckusick * from: $Hdr: kb_encode.c,v 4.300 91/06/09 06:14:51 root Rel41 $ SONY 1153889Smckusick * 12*55762Sbostic * @(#)kb_encode.c 7.2 (Berkeley) 07/28/92 1353889Smckusick */ 1453889Smckusick 1553889Smckusick #include "../include/fix_machine_type.h" 1653889Smckusick 1753889Smckusick #ifdef IPC_MRX 1853889Smckusick #include "../../h/param.h" 19*55762Sbostic #include "../../h/systm.h" 2053889Smckusick #include "../../h/types.h" 2153889Smckusick #include "../../h/ioctl.h" 2253889Smckusick #include "../../iop/keyboard.h" 2353889Smckusick #include "../../iop/kbreg.h" 2453889Smckusick #else 2553889Smckusick #include "param.h" 26*55762Sbostic #include "systm.h" 2753889Smckusick #include "types.h" 2853889Smckusick #include "ioctl.h" 2953889Smckusick #include "../iop/keyboard.h" 3053889Smckusick #include "../iop/kbreg.h" 3153889Smckusick #endif 3253889Smckusick #include "malloc.h" 3353889Smckusick 3453889Smckusick extern int tmode; 3553889Smckusick extern int country; 3653889Smckusick extern Pfk_table pfk_table[]; 3753889Smckusick extern Pfk_table pfk_init[]; 3853889Smckusick extern Key_table *key_table_addr; 3953889Smckusick 4053889Smckusick int kbd_status; 4153889Smckusick int shifttype; 4253889Smckusick extern int iscaps; 4353889Smckusick 4453889Smckusick /* 4553889Smckusick * kbd_encode(c) 4653889Smckusick * int c; keyboard address code 4753889Smckusick * 4853889Smckusick * kbd_encode() converts keyboard address code to character code. 4953889Smckusick * kbd_encode() calls back machine dependent function 5053889Smckusick * 5153889Smckusick * put_code(buf, cnt) 5253889Smckusick * char *buf; encoded characters 5353889Smckusick * int cnt; character count 5453889Smckusick * 5553889Smckusick * to store encoded data. 5653889Smckusick */ 5753889Smckusick kbd_encode(c) 5853889Smckusick register int c; 5953889Smckusick { 6053889Smckusick register Key_table *kp; 6153889Smckusick register int c_mask; 6253889Smckusick 6353889Smckusick c_mask = c & 0x7f; 6453889Smckusick c &= 0xff; 6553889Smckusick if (c_mask > N_KEY) 6653889Smckusick return (0); 6753889Smckusick kp = &key_table_addr[c_mask]; 6853889Smckusick if (c & OFF) 6953889Smckusick kp->key_flags &= ~KEY_PRESS; 7053889Smckusick else if ((kp->key_flags & KEY_PRESS) && 7153889Smckusick ((kbd_status & KBD_NOTREPT) || (kp->key_flags & NOT_REPT))) 7253889Smckusick return (0); 7353889Smckusick else 7453889Smckusick kp->key_flags |= KEY_PRESS; 7553889Smckusick 7653889Smckusick if (kp->key_flags & (PSH_SHFT|SW_SHFT)) { 7753889Smckusick kbd_shift(c); 7853889Smckusick return (0); 7953889Smckusick } 8053889Smckusick if ((kp->key_flags & ALT_FUNC) && (kbd_status & KBD_ALT) || 8153889Smckusick (kp->key_flags & PRG_FUNC)) 8253889Smckusick return (kbd_pfunc(c)); 8353889Smckusick return (kbd_normal(c)); 8453889Smckusick } 8553889Smckusick 8653889Smckusick 8753889Smckusick #define KFLAGSW(a, b) ((a) ? (kbd_status |= (b)) : (kbd_status &= ~(b))) 8853889Smckusick #define LOCKTYPE(a, b) (shifttype = ((a) ? (a) : (b))) 8953889Smckusick 9053889Smckusick static 9153889Smckusick kbd_shift(c) 9253889Smckusick register int c; 9353889Smckusick { 9453889Smckusick register Key_table *kp = &key_table_addr[c & 0x7f]; 9553889Smckusick register int push = (c & OFF) == 0; 9653889Smckusick 9753889Smckusick switch (kp->normal_code) { 9853889Smckusick 9953889Smckusick case S_CTRL: 10053889Smckusick KFLAGSW(push, KBD_CTRL); 10153889Smckusick break; 10253889Smckusick 10353889Smckusick case S_RSHFT: 10453889Smckusick KFLAGSW(push, KBD_RSHIFT); 10553889Smckusick break; 10653889Smckusick 10753889Smckusick case S_LSHFT: 10853889Smckusick KFLAGSW(push, KBD_LSHIFT); 10953889Smckusick break; 11053889Smckusick 11153889Smckusick case S_ALT: 11253889Smckusick KFLAGSW(push, KBD_ALT); 11353889Smckusick break; 11453889Smckusick 11553889Smckusick case S_CAPS: 11653889Smckusick if (push) { 11753889Smckusick kbd_status ^= KBD_CAPS; 11853889Smckusick LOCKTYPE(iscaps, CAPSLOCK); 11953889Smckusick } 12053889Smckusick break; 12153889Smckusick 12253889Smckusick case S_AN: 12353889Smckusick if (push) { 12453889Smckusick kbd_status &= ~KBD_KANA; 12553889Smckusick } 12653889Smckusick break; 12753889Smckusick 12853889Smckusick case S_KANA: 12953889Smckusick if (push) { 13053889Smckusick switch (country) { 13153889Smckusick case K_JAPANESE_J: 13253889Smckusick kbd_status |= KBD_KANA; 13353889Smckusick default: 13453889Smckusick break; 13553889Smckusick } 13653889Smckusick } 13753889Smckusick break; 13853889Smckusick 13953889Smckusick case S_ALTGR: 14053889Smckusick KFLAGSW(push, KBD_ALTGR); 14153889Smckusick break; 14253889Smckusick 14353889Smckusick default: 14453889Smckusick break; 14553889Smckusick 14653889Smckusick } 14753889Smckusick return (0); 14853889Smckusick } 14953889Smckusick 15053889Smckusick static 15153889Smckusick kbd_pfunc(c) 15253889Smckusick register int c; 15353889Smckusick { 15453889Smckusick register Pfk_table *kp; 15553889Smckusick 15653889Smckusick if (c & OFF) 15753889Smckusick return (0); 15853889Smckusick for (kp = pfk_table; kp < pfk_table + N_PFK; kp++) { 15953889Smckusick if (kp->pfk_addr != c) 16053889Smckusick continue; 16153889Smckusick if (kbd_status & KBD_SHIFT) 16253889Smckusick return (put_code(kp->pfk_shift.key_string, 16353889Smckusick kp->pfk_shift.key_length)); 16453889Smckusick return (put_code(kp->pfk_normal.key_string, 16553889Smckusick kp->pfk_normal.key_length)); 16653889Smckusick } 16753889Smckusick return (0); 16853889Smckusick } 16953889Smckusick 17053889Smckusick #define PUT(cond, code, len) ((cond) ? put_code(code, len) : 0) 17153889Smckusick #define PUT_KANA(cond, code, len) ((cond) ? put_kana(code, len) : 0) 17253889Smckusick 17353889Smckusick static 17453889Smckusick kbd_normal(c) 17553889Smckusick int c; 17653889Smckusick { 17753889Smckusick register Key_table *kp = &key_table_addr[c & 0x7f]; 17853889Smckusick 17953889Smckusick if (c & OFF) 18053889Smckusick return (0); 18153889Smckusick if (kbd_status & KBD_ALT) 18253889Smckusick return (PUT(kp->key_flags & A, &kp->alt_code, 1)); 18353889Smckusick if (kbd_status & KBD_CTRL) 18453889Smckusick return (PUT(kp->key_flags & C, &kp->ctrl_code, 1)); 18553889Smckusick if (kbd_status & KBD_ALTGR) 18653889Smckusick return (PUT(kp->key_flags & G, &kp->kana_code, 1)); 18753889Smckusick if (kbd_status & KBD_KANA) { 18853889Smckusick if (kbd_status & KBD_SHIFT) 18953889Smckusick return (PUT_KANA(kp->key_flags & J, &kp->kshft_code, 1)); 19053889Smckusick return (PUT_KANA(kp->key_flags & K, &kp->kana_code, 1)); 19153889Smckusick } 19253889Smckusick if (kbd_status & KBD_CAPS) { 19353889Smckusick if ((kbd_status & KBD_SHIFT) && (kp->key_flags & S)) { 19453889Smckusick if (kp->key_flags & CAP_LOCK) { 19553889Smckusick switch (shifttype) { 19653889Smckusick 19753889Smckusick case CAPSLOCK: 19853889Smckusick return (put_code(&kp->shift_code, 1)); 19953889Smckusick 20053889Smckusick case SHIFTLOCK: 20153889Smckusick case SHIFTLOCK2: 20253889Smckusick return (put_code(&kp->normal_code, 1)); 20353889Smckusick 20453889Smckusick default: 20553889Smckusick return (0); 20653889Smckusick } 20753889Smckusick } 20853889Smckusick switch (shifttype) { 20953889Smckusick 21053889Smckusick case CAPSLOCK: 21153889Smckusick case SHIFTLOCK: 21253889Smckusick return (put_code(&kp->shift_code, 1)); 21353889Smckusick 21453889Smckusick case SHIFTLOCK2: 21553889Smckusick return (put_code(&kp->normal_code, 1)); 21653889Smckusick 21753889Smckusick default: 21853889Smckusick return (0); 21953889Smckusick } 22053889Smckusick } 22153889Smckusick if (kp->key_flags & N) { 22253889Smckusick if (kp->key_flags & CAP_LOCK) 22353889Smckusick return (put_code(&kp->shift_code, 1)); 22453889Smckusick switch (shifttype) { 22553889Smckusick 22653889Smckusick case CAPSLOCK: 22753889Smckusick case SHIFTLOCK: 22853889Smckusick return (put_code(&kp->normal_code, 1)); 22953889Smckusick 23053889Smckusick case SHIFTLOCK2: 23153889Smckusick return (put_code(&kp->shift_code, 1)); 23253889Smckusick 23353889Smckusick default: 23453889Smckusick return (0); 23553889Smckusick } 23653889Smckusick } 23753889Smckusick } 23853889Smckusick if (kbd_status & KBD_SHIFT) 23953889Smckusick return (PUT(kp->key_flags & S, &kp->shift_code, 1)); 24053889Smckusick return (PUT(kp->key_flags & N, &kp->normal_code, 1)); 24153889Smckusick } 24253889Smckusick 24353889Smckusick kbd_string(cmd, p) 24453889Smckusick int cmd; 24553889Smckusick register Pfk_string *p; 24653889Smckusick { 24753889Smckusick register Key_string *pk; 24853889Smckusick 24953889Smckusick if (p->pfk_num < 0 || p->pfk_num >= N_PFK) 25053889Smckusick return (0); 25153889Smckusick switch (p->pfk_shift) { 25253889Smckusick 25353889Smckusick case PF_NORMAL: 25453889Smckusick pk = &pfk_table[p->pfk_num].pfk_normal; 25553889Smckusick break; 25653889Smckusick 25753889Smckusick case PF_SHIFT: 25853889Smckusick pk = &pfk_table[p->pfk_num].pfk_shift; 25953889Smckusick break; 26053889Smckusick 26153889Smckusick default: 26253889Smckusick return (0); 26353889Smckusick } 26453889Smckusick switch (cmd) { 26553889Smckusick 26653889Smckusick case KIOCSETS: 26753889Smckusick if (pk->key_string != NULL) { 26853889Smckusick free(pk->key_string, M_DEVBUF); 26953889Smckusick pk->key_string = NULL; 27053889Smckusick pk->key_length = 0; 27153889Smckusick } 27253889Smckusick if (pk->key_length = p->pfk_string.key_length) { 27353889Smckusick pk->key_string = 27453889Smckusick (char *)malloc(p->pfk_string.key_length, M_DEVBUF, M_WAITOK); 27553889Smckusick bcopy(p->pfk_string.key_string, pk->key_string, 27653889Smckusick p->pfk_string.key_length); 27753889Smckusick } else 27853889Smckusick pk->key_string = NULL; 27953889Smckusick bcopy(p->pfk_string.key_string, pk->key_string, 28053889Smckusick p->pfk_string.key_length); 28153889Smckusick pk->key_length = p->pfk_string.key_length; 28253889Smckusick break; 28353889Smckusick 28453889Smckusick case KIOCGETS: 28553889Smckusick p->pfk_string.key_length = 286*55762Sbostic min(p->pfk_string.key_length, pk->key_length); 28753889Smckusick bcopy(pk->key_string, p->pfk_string.key_string, 28853889Smckusick p->pfk_string.key_length); 28953889Smckusick break; 29053889Smckusick 29153889Smckusick default: 29253889Smckusick return (0); 29353889Smckusick } 29453889Smckusick return (0); 29553889Smckusick } 29653889Smckusick 29753889Smckusick kbd_init() 29853889Smckusick { 29953889Smckusick int i; 30053889Smckusick Pfk_string pfk_buf; 30153889Smckusick 30253889Smckusick for (i = 0; i < N_PFK; i++) { 30353889Smckusick pfk_table[i].pfk_addr = pfk_init[i].pfk_addr; 30453889Smckusick if (pfk_init[i].pfk_normal.key_length > 0) { 30553889Smckusick pfk_buf.pfk_num = i; 30653889Smckusick pfk_buf.pfk_shift = PF_NORMAL; 30753889Smckusick pfk_buf.pfk_string = pfk_init[i].pfk_normal; 30853889Smckusick kbd_string(KIOCSETS, &pfk_buf); 30953889Smckusick } 31053889Smckusick if (pfk_init[i].pfk_shift.key_length > 0) { 31153889Smckusick pfk_buf.pfk_num = i; 31253889Smckusick pfk_buf.pfk_shift = PF_SHIFT; 31353889Smckusick pfk_buf.pfk_string = pfk_init[i].pfk_shift; 31453889Smckusick kbd_string(KIOCSETS, &pfk_buf); 31553889Smckusick } 31653889Smckusick } 31753889Smckusick kbd_status = 0; 31853889Smckusick } 31953889Smckusick 32053889Smckusick kbd_repeat(f) 32153889Smckusick int f; 32253889Smckusick { 32353889Smckusick 32453889Smckusick if (f) 32553889Smckusick kbd_status &= ~KBD_NOTREPT; 32653889Smckusick else 32753889Smckusick kbd_status |= KBD_NOTREPT; 32853889Smckusick return (0); 32953889Smckusick } 33053889Smckusick 33153889Smckusick 33253889Smckusick static 33353889Smckusick put2char(c1, c2) 33453889Smckusick int c1, c2; 33553889Smckusick { 33653889Smckusick char buf[2]; 33753889Smckusick 33853889Smckusick buf[0] = c1; 33953889Smckusick buf[1] = c2; 34053889Smckusick return (put_code(buf, 2)); 34153889Smckusick } 34253889Smckusick 34353889Smckusick #define SS2 0x8e 34453889Smckusick 34553889Smckusick static 34653889Smckusick put_kana(s, len) 34753889Smckusick register u_char *s; 34853889Smckusick int len; 34953889Smckusick { 35053889Smckusick register int i; 35153889Smckusick register u_char *p; 35253889Smckusick u_char eucbuf[8]; 35353889Smckusick 35453889Smckusick if (len <= 0) 35553889Smckusick return (0); 35653889Smckusick #ifdef KM_EUC 35753889Smckusick if ((tmode == KM_EUC) && ((*s >= 0xa1) && (*s <= 0xdf))) { 35853889Smckusick p = eucbuf; 35953889Smckusick for (i = len; i > 0; i--) { 36053889Smckusick *p++ = SS2; 36153889Smckusick *p++ = *s++; 36253889Smckusick } 36353889Smckusick return (put_code(eucbuf, len * 2)); 36453889Smckusick } 36553889Smckusick #endif /* KM_EUC */ 36653889Smckusick return (put_code(s, len)); 36753889Smckusick } 368