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