1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/10/93
13 */
14
15 #ifdef IPC_MRX
16 #include <sys/param.h>
17 #include <sys/systm.h>
18 #include <sys/types.h>
19 #include <sys/ioctl.h>
20 #include <news3400/iop/keyboard.h>
21 #include <news3400/iop/kbreg.h>
22 #else
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/types.h>
26 #include <sys/ioctl.h>
27 #include <news3400/iop/keyboard.h>
28 #include <news3400/iop/kbreg.h>
29 #endif
30 #include <sys/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 static kbd_shift(), kbd_pfunc(), kbd_normal(), put_kana();
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 */
kbd_encode(c)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
kbd_shift(c)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
kbd_pfunc(c)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
kbd_normal(c)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
kbd_string(cmd,p)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
kbd_init()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
kbd_repeat(f)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
put2char(c1,c2)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
put_kana(s,len)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