1*53889Smckusick /* 2*53889Smckusick * Copyright (c) 1992 The Regents of the University of California. 3*53889Smckusick * All rights reserved. 4*53889Smckusick * 5*53889Smckusick * This code is derived from software contributed to Berkeley by 6*53889Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7*53889Smckusick * 8*53889Smckusick * %sccs.include.redist.c% 9*53889Smckusick * 10*53889Smckusick * from: $Hdr: kb_encode.c,v 4.300 91/06/09 06:14:51 root Rel41 $ SONY 11*53889Smckusick * 12*53889Smckusick * @(#)kb_encode.c 7.1 (Berkeley) 06/04/92 13*53889Smckusick */ 14*53889Smckusick 15*53889Smckusick #include "../include/fix_machine_type.h" 16*53889Smckusick 17*53889Smckusick #ifdef IPC_MRX 18*53889Smckusick #include "../../h/param.h" 19*53889Smckusick #include "../../h/types.h" 20*53889Smckusick #include "../../h/ioctl.h" 21*53889Smckusick #include "../../iop/keyboard.h" 22*53889Smckusick #include "../../iop/kbreg.h" 23*53889Smckusick #else 24*53889Smckusick #include "param.h" 25*53889Smckusick #include "types.h" 26*53889Smckusick #include "ioctl.h" 27*53889Smckusick #include "../iop/keyboard.h" 28*53889Smckusick #include "../iop/kbreg.h" 29*53889Smckusick #endif 30*53889Smckusick #include "malloc.h" 31*53889Smckusick 32*53889Smckusick extern int tmode; 33*53889Smckusick extern int country; 34*53889Smckusick extern Pfk_table pfk_table[]; 35*53889Smckusick extern Pfk_table pfk_init[]; 36*53889Smckusick extern Key_table *key_table_addr; 37*53889Smckusick 38*53889Smckusick int kbd_status; 39*53889Smckusick int shifttype; 40*53889Smckusick extern int iscaps; 41*53889Smckusick 42*53889Smckusick /* 43*53889Smckusick * kbd_encode(c) 44*53889Smckusick * int c; keyboard address code 45*53889Smckusick * 46*53889Smckusick * kbd_encode() converts keyboard address code to character code. 47*53889Smckusick * kbd_encode() calls back machine dependent function 48*53889Smckusick * 49*53889Smckusick * put_code(buf, cnt) 50*53889Smckusick * char *buf; encoded characters 51*53889Smckusick * int cnt; character count 52*53889Smckusick * 53*53889Smckusick * to store encoded data. 54*53889Smckusick */ 55*53889Smckusick kbd_encode(c) 56*53889Smckusick register int c; 57*53889Smckusick { 58*53889Smckusick register Key_table *kp; 59*53889Smckusick register int c_mask; 60*53889Smckusick 61*53889Smckusick c_mask = c & 0x7f; 62*53889Smckusick c &= 0xff; 63*53889Smckusick if (c_mask > N_KEY) 64*53889Smckusick return (0); 65*53889Smckusick kp = &key_table_addr[c_mask]; 66*53889Smckusick if (c & OFF) 67*53889Smckusick kp->key_flags &= ~KEY_PRESS; 68*53889Smckusick else if ((kp->key_flags & KEY_PRESS) && 69*53889Smckusick ((kbd_status & KBD_NOTREPT) || (kp->key_flags & NOT_REPT))) 70*53889Smckusick return (0); 71*53889Smckusick else 72*53889Smckusick kp->key_flags |= KEY_PRESS; 73*53889Smckusick 74*53889Smckusick if (kp->key_flags & (PSH_SHFT|SW_SHFT)) { 75*53889Smckusick kbd_shift(c); 76*53889Smckusick return (0); 77*53889Smckusick } 78*53889Smckusick if ((kp->key_flags & ALT_FUNC) && (kbd_status & KBD_ALT) || 79*53889Smckusick (kp->key_flags & PRG_FUNC)) 80*53889Smckusick return (kbd_pfunc(c)); 81*53889Smckusick return (kbd_normal(c)); 82*53889Smckusick } 83*53889Smckusick 84*53889Smckusick 85*53889Smckusick #define KFLAGSW(a, b) ((a) ? (kbd_status |= (b)) : (kbd_status &= ~(b))) 86*53889Smckusick #define LOCKTYPE(a, b) (shifttype = ((a) ? (a) : (b))) 87*53889Smckusick 88*53889Smckusick static 89*53889Smckusick kbd_shift(c) 90*53889Smckusick register int c; 91*53889Smckusick { 92*53889Smckusick register Key_table *kp = &key_table_addr[c & 0x7f]; 93*53889Smckusick register int push = (c & OFF) == 0; 94*53889Smckusick 95*53889Smckusick switch (kp->normal_code) { 96*53889Smckusick 97*53889Smckusick case S_CTRL: 98*53889Smckusick KFLAGSW(push, KBD_CTRL); 99*53889Smckusick break; 100*53889Smckusick 101*53889Smckusick case S_RSHFT: 102*53889Smckusick KFLAGSW(push, KBD_RSHIFT); 103*53889Smckusick break; 104*53889Smckusick 105*53889Smckusick case S_LSHFT: 106*53889Smckusick KFLAGSW(push, KBD_LSHIFT); 107*53889Smckusick break; 108*53889Smckusick 109*53889Smckusick case S_ALT: 110*53889Smckusick KFLAGSW(push, KBD_ALT); 111*53889Smckusick break; 112*53889Smckusick 113*53889Smckusick case S_CAPS: 114*53889Smckusick if (push) { 115*53889Smckusick kbd_status ^= KBD_CAPS; 116*53889Smckusick LOCKTYPE(iscaps, CAPSLOCK); 117*53889Smckusick } 118*53889Smckusick break; 119*53889Smckusick 120*53889Smckusick case S_AN: 121*53889Smckusick if (push) { 122*53889Smckusick kbd_status &= ~KBD_KANA; 123*53889Smckusick } 124*53889Smckusick break; 125*53889Smckusick 126*53889Smckusick case S_KANA: 127*53889Smckusick if (push) { 128*53889Smckusick switch (country) { 129*53889Smckusick case K_JAPANESE_J: 130*53889Smckusick kbd_status |= KBD_KANA; 131*53889Smckusick default: 132*53889Smckusick break; 133*53889Smckusick } 134*53889Smckusick } 135*53889Smckusick break; 136*53889Smckusick 137*53889Smckusick case S_ALTGR: 138*53889Smckusick KFLAGSW(push, KBD_ALTGR); 139*53889Smckusick break; 140*53889Smckusick 141*53889Smckusick default: 142*53889Smckusick break; 143*53889Smckusick 144*53889Smckusick } 145*53889Smckusick return (0); 146*53889Smckusick } 147*53889Smckusick 148*53889Smckusick static 149*53889Smckusick kbd_pfunc(c) 150*53889Smckusick register int c; 151*53889Smckusick { 152*53889Smckusick register Pfk_table *kp; 153*53889Smckusick 154*53889Smckusick if (c & OFF) 155*53889Smckusick return (0); 156*53889Smckusick for (kp = pfk_table; kp < pfk_table + N_PFK; kp++) { 157*53889Smckusick if (kp->pfk_addr != c) 158*53889Smckusick continue; 159*53889Smckusick if (kbd_status & KBD_SHIFT) 160*53889Smckusick return (put_code(kp->pfk_shift.key_string, 161*53889Smckusick kp->pfk_shift.key_length)); 162*53889Smckusick return (put_code(kp->pfk_normal.key_string, 163*53889Smckusick kp->pfk_normal.key_length)); 164*53889Smckusick } 165*53889Smckusick return (0); 166*53889Smckusick } 167*53889Smckusick 168*53889Smckusick #define PUT(cond, code, len) ((cond) ? put_code(code, len) : 0) 169*53889Smckusick #define PUT_KANA(cond, code, len) ((cond) ? put_kana(code, len) : 0) 170*53889Smckusick 171*53889Smckusick static 172*53889Smckusick kbd_normal(c) 173*53889Smckusick int c; 174*53889Smckusick { 175*53889Smckusick register Key_table *kp = &key_table_addr[c & 0x7f]; 176*53889Smckusick 177*53889Smckusick if (c & OFF) 178*53889Smckusick return (0); 179*53889Smckusick if (kbd_status & KBD_ALT) 180*53889Smckusick return (PUT(kp->key_flags & A, &kp->alt_code, 1)); 181*53889Smckusick if (kbd_status & KBD_CTRL) 182*53889Smckusick return (PUT(kp->key_flags & C, &kp->ctrl_code, 1)); 183*53889Smckusick if (kbd_status & KBD_ALTGR) 184*53889Smckusick return (PUT(kp->key_flags & G, &kp->kana_code, 1)); 185*53889Smckusick if (kbd_status & KBD_KANA) { 186*53889Smckusick if (kbd_status & KBD_SHIFT) 187*53889Smckusick return (PUT_KANA(kp->key_flags & J, &kp->kshft_code, 1)); 188*53889Smckusick return (PUT_KANA(kp->key_flags & K, &kp->kana_code, 1)); 189*53889Smckusick } 190*53889Smckusick if (kbd_status & KBD_CAPS) { 191*53889Smckusick if ((kbd_status & KBD_SHIFT) && (kp->key_flags & S)) { 192*53889Smckusick if (kp->key_flags & CAP_LOCK) { 193*53889Smckusick switch (shifttype) { 194*53889Smckusick 195*53889Smckusick case CAPSLOCK: 196*53889Smckusick return (put_code(&kp->shift_code, 1)); 197*53889Smckusick 198*53889Smckusick case SHIFTLOCK: 199*53889Smckusick case SHIFTLOCK2: 200*53889Smckusick return (put_code(&kp->normal_code, 1)); 201*53889Smckusick 202*53889Smckusick default: 203*53889Smckusick return (0); 204*53889Smckusick } 205*53889Smckusick } 206*53889Smckusick switch (shifttype) { 207*53889Smckusick 208*53889Smckusick case CAPSLOCK: 209*53889Smckusick case SHIFTLOCK: 210*53889Smckusick return (put_code(&kp->shift_code, 1)); 211*53889Smckusick 212*53889Smckusick case SHIFTLOCK2: 213*53889Smckusick return (put_code(&kp->normal_code, 1)); 214*53889Smckusick 215*53889Smckusick default: 216*53889Smckusick return (0); 217*53889Smckusick } 218*53889Smckusick } 219*53889Smckusick if (kp->key_flags & N) { 220*53889Smckusick if (kp->key_flags & CAP_LOCK) 221*53889Smckusick return (put_code(&kp->shift_code, 1)); 222*53889Smckusick switch (shifttype) { 223*53889Smckusick 224*53889Smckusick case CAPSLOCK: 225*53889Smckusick case SHIFTLOCK: 226*53889Smckusick return (put_code(&kp->normal_code, 1)); 227*53889Smckusick 228*53889Smckusick case SHIFTLOCK2: 229*53889Smckusick return (put_code(&kp->shift_code, 1)); 230*53889Smckusick 231*53889Smckusick default: 232*53889Smckusick return (0); 233*53889Smckusick } 234*53889Smckusick } 235*53889Smckusick } 236*53889Smckusick if (kbd_status & KBD_SHIFT) 237*53889Smckusick return (PUT(kp->key_flags & S, &kp->shift_code, 1)); 238*53889Smckusick return (PUT(kp->key_flags & N, &kp->normal_code, 1)); 239*53889Smckusick } 240*53889Smckusick 241*53889Smckusick kbd_string(cmd, p) 242*53889Smckusick int cmd; 243*53889Smckusick register Pfk_string *p; 244*53889Smckusick { 245*53889Smckusick register Key_string *pk; 246*53889Smckusick 247*53889Smckusick if (p->pfk_num < 0 || p->pfk_num >= N_PFK) 248*53889Smckusick return (0); 249*53889Smckusick switch (p->pfk_shift) { 250*53889Smckusick 251*53889Smckusick case PF_NORMAL: 252*53889Smckusick pk = &pfk_table[p->pfk_num].pfk_normal; 253*53889Smckusick break; 254*53889Smckusick 255*53889Smckusick case PF_SHIFT: 256*53889Smckusick pk = &pfk_table[p->pfk_num].pfk_shift; 257*53889Smckusick break; 258*53889Smckusick 259*53889Smckusick default: 260*53889Smckusick return (0); 261*53889Smckusick } 262*53889Smckusick switch (cmd) { 263*53889Smckusick 264*53889Smckusick case KIOCSETS: 265*53889Smckusick if (pk->key_string != NULL) { 266*53889Smckusick free(pk->key_string, M_DEVBUF); 267*53889Smckusick pk->key_string = NULL; 268*53889Smckusick pk->key_length = 0; 269*53889Smckusick } 270*53889Smckusick if (pk->key_length = p->pfk_string.key_length) { 271*53889Smckusick pk->key_string = 272*53889Smckusick (char *)malloc(p->pfk_string.key_length, M_DEVBUF, M_WAITOK); 273*53889Smckusick bcopy(p->pfk_string.key_string, pk->key_string, 274*53889Smckusick p->pfk_string.key_length); 275*53889Smckusick } else 276*53889Smckusick pk->key_string = NULL; 277*53889Smckusick bcopy(p->pfk_string.key_string, pk->key_string, 278*53889Smckusick p->pfk_string.key_length); 279*53889Smckusick pk->key_length = p->pfk_string.key_length; 280*53889Smckusick break; 281*53889Smckusick 282*53889Smckusick case KIOCGETS: 283*53889Smckusick p->pfk_string.key_length = 284*53889Smckusick MIN(p->pfk_string.key_length, pk->key_length); 285*53889Smckusick bcopy(pk->key_string, p->pfk_string.key_string, 286*53889Smckusick p->pfk_string.key_length); 287*53889Smckusick break; 288*53889Smckusick 289*53889Smckusick default: 290*53889Smckusick return (0); 291*53889Smckusick } 292*53889Smckusick return (0); 293*53889Smckusick } 294*53889Smckusick 295*53889Smckusick kbd_init() 296*53889Smckusick { 297*53889Smckusick int i; 298*53889Smckusick Pfk_string pfk_buf; 299*53889Smckusick 300*53889Smckusick for (i = 0; i < N_PFK; i++) { 301*53889Smckusick pfk_table[i].pfk_addr = pfk_init[i].pfk_addr; 302*53889Smckusick if (pfk_init[i].pfk_normal.key_length > 0) { 303*53889Smckusick pfk_buf.pfk_num = i; 304*53889Smckusick pfk_buf.pfk_shift = PF_NORMAL; 305*53889Smckusick pfk_buf.pfk_string = pfk_init[i].pfk_normal; 306*53889Smckusick kbd_string(KIOCSETS, &pfk_buf); 307*53889Smckusick } 308*53889Smckusick if (pfk_init[i].pfk_shift.key_length > 0) { 309*53889Smckusick pfk_buf.pfk_num = i; 310*53889Smckusick pfk_buf.pfk_shift = PF_SHIFT; 311*53889Smckusick pfk_buf.pfk_string = pfk_init[i].pfk_shift; 312*53889Smckusick kbd_string(KIOCSETS, &pfk_buf); 313*53889Smckusick } 314*53889Smckusick } 315*53889Smckusick kbd_status = 0; 316*53889Smckusick } 317*53889Smckusick 318*53889Smckusick kbd_repeat(f) 319*53889Smckusick int f; 320*53889Smckusick { 321*53889Smckusick 322*53889Smckusick if (f) 323*53889Smckusick kbd_status &= ~KBD_NOTREPT; 324*53889Smckusick else 325*53889Smckusick kbd_status |= KBD_NOTREPT; 326*53889Smckusick return (0); 327*53889Smckusick } 328*53889Smckusick 329*53889Smckusick 330*53889Smckusick static 331*53889Smckusick put2char(c1, c2) 332*53889Smckusick int c1, c2; 333*53889Smckusick { 334*53889Smckusick char buf[2]; 335*53889Smckusick 336*53889Smckusick buf[0] = c1; 337*53889Smckusick buf[1] = c2; 338*53889Smckusick return (put_code(buf, 2)); 339*53889Smckusick } 340*53889Smckusick 341*53889Smckusick #define SS2 0x8e 342*53889Smckusick 343*53889Smckusick static 344*53889Smckusick put_kana(s, len) 345*53889Smckusick register u_char *s; 346*53889Smckusick int len; 347*53889Smckusick { 348*53889Smckusick register int i; 349*53889Smckusick register u_char *p; 350*53889Smckusick u_char eucbuf[8]; 351*53889Smckusick 352*53889Smckusick if (len <= 0) 353*53889Smckusick return (0); 354*53889Smckusick #ifdef KM_EUC 355*53889Smckusick if ((tmode == KM_EUC) && ((*s >= 0xa1) && (*s <= 0xdf))) { 356*53889Smckusick p = eucbuf; 357*53889Smckusick for (i = len; i > 0; i--) { 358*53889Smckusick *p++ = SS2; 359*53889Smckusick *p++ = *s++; 360*53889Smckusick } 361*53889Smckusick return (put_code(eucbuf, len * 2)); 362*53889Smckusick } 363*53889Smckusick #endif /* KM_EUC */ 364*53889Smckusick return (put_code(s, len)); 365*53889Smckusick } 366