xref: /csrg-svn/sys/news3400/bm/kb_encode.c (revision 53889)
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