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