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