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