xref: /csrg-svn/sys/news3400/bm/kb_encode.c (revision 63250)
153889Smckusick /*
2*63250Sbostic  * Copyright (c) 1992, 1993
3*63250Sbostic  *	The Regents of the University of California.  All rights reserved.
453889Smckusick  *
553889Smckusick  * This code is derived from software contributed to Berkeley by
653889Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753889Smckusick  *
853889Smckusick  * %sccs.include.redist.c%
953889Smckusick  *
1053889Smckusick  * from: $Hdr: kb_encode.c,v 4.300 91/06/09 06:14:51 root Rel41 $ SONY
1153889Smckusick  *
12*63250Sbostic  *	@(#)kb_encode.c	8.1 (Berkeley) 06/10/93
1353889Smckusick  */
1453889Smckusick 
1553889Smckusick #ifdef IPC_MRX
1657177Sutashiro #include <sys/param.h>
1757177Sutashiro #include <sys/systm.h>
1857177Sutashiro #include <sys/types.h>
1957177Sutashiro #include <sys/ioctl.h>
2057177Sutashiro #include <news3400/iop/keyboard.h>
2157177Sutashiro #include <news3400/iop/kbreg.h>
2253889Smckusick #else
2357177Sutashiro #include <sys/param.h>
2457177Sutashiro #include <sys/systm.h>
2557177Sutashiro #include <sys/types.h>
2657177Sutashiro #include <sys/ioctl.h>
2757177Sutashiro #include <news3400/iop/keyboard.h>
2857177Sutashiro #include <news3400/iop/kbreg.h>
2953889Smckusick #endif
3057177Sutashiro #include <sys/malloc.h>
3153889Smckusick 
3253889Smckusick extern int tmode;
3353889Smckusick extern int country;
3453889Smckusick extern Pfk_table pfk_table[];
3553889Smckusick extern Pfk_table pfk_init[];
3653889Smckusick extern Key_table *key_table_addr;
3753889Smckusick 
3853889Smckusick int	kbd_status;
3953889Smckusick int	shifttype;
4053889Smckusick extern int iscaps;
4153889Smckusick 
4257165Sutashiro static kbd_shift(), kbd_pfunc(), kbd_normal(), put_kana();
4357165Sutashiro 
4453889Smckusick /*
4553889Smckusick  *	kbd_encode(c)
4653889Smckusick  *		int c;		keyboard address code
4753889Smckusick  *
4853889Smckusick  *	kbd_encode() converts keyboard address code to character code.
4953889Smckusick  *	kbd_encode() calls back machine dependent function
5053889Smckusick  *
5153889Smckusick  *		put_code(buf, cnt)
5253889Smckusick  *			char *buf;	encoded characters
5353889Smckusick  *			int cnt;	character count
5453889Smckusick  *
5553889Smckusick  *	to store encoded data.
5653889Smckusick  */
kbd_encode(c)5753889Smckusick kbd_encode(c)
5853889Smckusick 	register int c;
5953889Smckusick {
6053889Smckusick 	register Key_table *kp;
6153889Smckusick 	register int c_mask;
6253889Smckusick 
6353889Smckusick 	c_mask = c & 0x7f;
6453889Smckusick 	c &= 0xff;
6553889Smckusick 	if (c_mask > N_KEY)
6653889Smckusick 		return (0);
6753889Smckusick 	kp = &key_table_addr[c_mask];
6853889Smckusick 	if (c & OFF)
6953889Smckusick 		kp->key_flags &= ~KEY_PRESS;
7053889Smckusick 	else if ((kp->key_flags & KEY_PRESS) &&
7153889Smckusick 	    ((kbd_status & KBD_NOTREPT) || (kp->key_flags & NOT_REPT)))
7253889Smckusick 		return (0);
7353889Smckusick 	else
7453889Smckusick 		kp->key_flags |= KEY_PRESS;
7553889Smckusick 
7653889Smckusick 	if (kp->key_flags & (PSH_SHFT|SW_SHFT)) {
7753889Smckusick 		kbd_shift(c);
7853889Smckusick 		return (0);
7953889Smckusick 	}
8053889Smckusick 	if ((kp->key_flags & ALT_FUNC) && (kbd_status & KBD_ALT) ||
8153889Smckusick 	    (kp->key_flags & PRG_FUNC))
8253889Smckusick 		return (kbd_pfunc(c));
8353889Smckusick 	return (kbd_normal(c));
8453889Smckusick }
8553889Smckusick 
8653889Smckusick 
8753889Smckusick #define KFLAGSW(a, b)	((a) ? (kbd_status |= (b)) : (kbd_status &= ~(b)))
8853889Smckusick #define	LOCKTYPE(a, b)	(shifttype = ((a) ? (a) : (b)))
8953889Smckusick 
9053889Smckusick static
kbd_shift(c)9153889Smckusick kbd_shift(c)
9253889Smckusick 	register int c;
9353889Smckusick {
9453889Smckusick 	register Key_table *kp = &key_table_addr[c & 0x7f];
9553889Smckusick 	register int push = (c & OFF) == 0;
9653889Smckusick 
9753889Smckusick 	switch (kp->normal_code) {
9853889Smckusick 
9953889Smckusick 	case S_CTRL:
10053889Smckusick 		KFLAGSW(push, KBD_CTRL);
10153889Smckusick 		break;
10253889Smckusick 
10353889Smckusick 	case S_RSHFT:
10453889Smckusick 		KFLAGSW(push, KBD_RSHIFT);
10553889Smckusick 		break;
10653889Smckusick 
10753889Smckusick 	case S_LSHFT:
10853889Smckusick 		KFLAGSW(push, KBD_LSHIFT);
10953889Smckusick 		break;
11053889Smckusick 
11153889Smckusick 	case S_ALT:
11253889Smckusick 		KFLAGSW(push, KBD_ALT);
11353889Smckusick 		break;
11453889Smckusick 
11553889Smckusick 	case S_CAPS:
11653889Smckusick 		if (push) {
11753889Smckusick 			kbd_status ^= KBD_CAPS;
11853889Smckusick 			LOCKTYPE(iscaps, CAPSLOCK);
11953889Smckusick 		}
12053889Smckusick 		break;
12153889Smckusick 
12253889Smckusick 	case S_AN:
12353889Smckusick 		if (push) {
12453889Smckusick 			kbd_status &= ~KBD_KANA;
12553889Smckusick 		}
12653889Smckusick 		break;
12753889Smckusick 
12853889Smckusick 	case S_KANA:
12953889Smckusick 		if (push) {
13053889Smckusick 			switch (country) {
13153889Smckusick 			case K_JAPANESE_J:
13253889Smckusick 				kbd_status |= KBD_KANA;
13353889Smckusick 			default:
13453889Smckusick 				break;
13553889Smckusick 			}
13653889Smckusick 		}
13753889Smckusick 		break;
13853889Smckusick 
13953889Smckusick 	case S_ALTGR:
14053889Smckusick 		KFLAGSW(push, KBD_ALTGR);
14153889Smckusick 		break;
14253889Smckusick 
14353889Smckusick 	default:
14453889Smckusick 		break;
14553889Smckusick 
14653889Smckusick 	}
14753889Smckusick 	return (0);
14853889Smckusick }
14953889Smckusick 
15053889Smckusick static
kbd_pfunc(c)15153889Smckusick kbd_pfunc(c)
15253889Smckusick 	register int c;
15353889Smckusick {
15453889Smckusick 	register Pfk_table *kp;
15553889Smckusick 
15653889Smckusick 	if (c & OFF)
15753889Smckusick 		return (0);
15853889Smckusick 	for (kp = pfk_table; kp < pfk_table + N_PFK; kp++) {
15953889Smckusick 		if (kp->pfk_addr != c)
16053889Smckusick 			continue;
16153889Smckusick 		if (kbd_status & KBD_SHIFT)
16253889Smckusick 			return (put_code(kp->pfk_shift.key_string,
16353889Smckusick 			    kp->pfk_shift.key_length));
16453889Smckusick 		return (put_code(kp->pfk_normal.key_string,
16553889Smckusick 		    kp->pfk_normal.key_length));
16653889Smckusick 	}
16753889Smckusick 	return (0);
16853889Smckusick }
16953889Smckusick 
17053889Smckusick #define	PUT(cond, code, len)		((cond) ? put_code(code, len) : 0)
17153889Smckusick #define	PUT_KANA(cond, code, len)	((cond) ? put_kana(code, len) : 0)
17253889Smckusick 
17353889Smckusick static
kbd_normal(c)17453889Smckusick kbd_normal(c)
17553889Smckusick 	int c;
17653889Smckusick {
17753889Smckusick 	register Key_table *kp = &key_table_addr[c & 0x7f];
17853889Smckusick 
17953889Smckusick 	if (c & OFF)
18053889Smckusick 		return (0);
18153889Smckusick 	if (kbd_status & KBD_ALT)
18253889Smckusick 		return (PUT(kp->key_flags & A, &kp->alt_code, 1));
18353889Smckusick 	if (kbd_status & KBD_CTRL)
18453889Smckusick 		return (PUT(kp->key_flags & C, &kp->ctrl_code, 1));
18553889Smckusick 	if (kbd_status & KBD_ALTGR)
18653889Smckusick 		return (PUT(kp->key_flags & G, &kp->kana_code, 1));
18753889Smckusick 	if (kbd_status & KBD_KANA) {
18853889Smckusick 		if (kbd_status & KBD_SHIFT)
18953889Smckusick 			return (PUT_KANA(kp->key_flags & J, &kp->kshft_code, 1));
19053889Smckusick 		return (PUT_KANA(kp->key_flags & K, &kp->kana_code, 1));
19153889Smckusick 	}
19253889Smckusick 	if (kbd_status & KBD_CAPS) {
19353889Smckusick 		if ((kbd_status & KBD_SHIFT) && (kp->key_flags & S)) {
19453889Smckusick 			if (kp->key_flags & CAP_LOCK) {
19553889Smckusick 				switch (shifttype) {
19653889Smckusick 
19753889Smckusick 				case CAPSLOCK:
19853889Smckusick 					return (put_code(&kp->shift_code, 1));
19953889Smckusick 
20053889Smckusick 				case SHIFTLOCK:
20153889Smckusick 				case SHIFTLOCK2:
20253889Smckusick 					return (put_code(&kp->normal_code, 1));
20353889Smckusick 
20453889Smckusick 				default:
20553889Smckusick 					return (0);
20653889Smckusick 				}
20753889Smckusick 			}
20853889Smckusick 			switch (shifttype) {
20953889Smckusick 
21053889Smckusick 			case CAPSLOCK:
21153889Smckusick 			case SHIFTLOCK:
21253889Smckusick 				return (put_code(&kp->shift_code, 1));
21353889Smckusick 
21453889Smckusick 			case SHIFTLOCK2:
21553889Smckusick 				return (put_code(&kp->normal_code, 1));
21653889Smckusick 
21753889Smckusick 			default:
21853889Smckusick 				return (0);
21953889Smckusick 			}
22053889Smckusick 		}
22153889Smckusick 		if (kp->key_flags & N) {
22253889Smckusick 			if (kp->key_flags & CAP_LOCK)
22353889Smckusick 				return (put_code(&kp->shift_code, 1));
22453889Smckusick 			switch (shifttype) {
22553889Smckusick 
22653889Smckusick 			case CAPSLOCK:
22753889Smckusick 			case SHIFTLOCK:
22853889Smckusick 				return (put_code(&kp->normal_code, 1));
22953889Smckusick 
23053889Smckusick 			case SHIFTLOCK2:
23153889Smckusick 				return (put_code(&kp->shift_code, 1));
23253889Smckusick 
23353889Smckusick 			default:
23453889Smckusick 				return (0);
23553889Smckusick 			}
23653889Smckusick 		}
23753889Smckusick 	}
23853889Smckusick 	if (kbd_status & KBD_SHIFT)
23953889Smckusick  		return (PUT(kp->key_flags & S, &kp->shift_code, 1));
24053889Smckusick 	return (PUT(kp->key_flags & N, &kp->normal_code, 1));
24153889Smckusick }
24253889Smckusick 
kbd_string(cmd,p)24353889Smckusick kbd_string(cmd, p)
24453889Smckusick 	int cmd;
24553889Smckusick 	register Pfk_string *p;
24653889Smckusick {
24753889Smckusick 	register Key_string *pk;
24853889Smckusick 
24953889Smckusick 	if (p->pfk_num < 0 || p->pfk_num >= N_PFK)
25053889Smckusick 		return (0);
25153889Smckusick 	switch (p->pfk_shift) {
25253889Smckusick 
25353889Smckusick 	case PF_NORMAL:
25453889Smckusick 		pk = &pfk_table[p->pfk_num].pfk_normal;
25553889Smckusick 		break;
25653889Smckusick 
25753889Smckusick 	case PF_SHIFT:
25853889Smckusick 		pk = &pfk_table[p->pfk_num].pfk_shift;
25953889Smckusick 		break;
26053889Smckusick 
26153889Smckusick 	default:
26253889Smckusick 		return (0);
26353889Smckusick 	}
26453889Smckusick 	switch (cmd) {
26553889Smckusick 
26653889Smckusick 	case KIOCSETS:
26753889Smckusick 		if (pk->key_string != NULL) {
26853889Smckusick 			free(pk->key_string, M_DEVBUF);
26953889Smckusick 			pk->key_string = NULL;
27053889Smckusick 			pk->key_length = 0;
27153889Smckusick 		}
27253889Smckusick 		if (pk->key_length = p->pfk_string.key_length) {
27353889Smckusick 			pk->key_string =
27453889Smckusick 			    (char *)malloc(p->pfk_string.key_length, M_DEVBUF, M_WAITOK);
27553889Smckusick 			bcopy(p->pfk_string.key_string, pk->key_string,
27653889Smckusick 			    p->pfk_string.key_length);
27753889Smckusick 		} else
27853889Smckusick 			pk->key_string = NULL;
27953889Smckusick 		bcopy(p->pfk_string.key_string, pk->key_string,
28053889Smckusick 		    p->pfk_string.key_length);
28153889Smckusick 		pk->key_length = p->pfk_string.key_length;
28253889Smckusick 		break;
28353889Smckusick 
28453889Smckusick 	case KIOCGETS:
28553889Smckusick 		p->pfk_string.key_length =
28655762Sbostic 		    min(p->pfk_string.key_length, pk->key_length);
28753889Smckusick 		bcopy(pk->key_string, p->pfk_string.key_string,
28853889Smckusick 		    p->pfk_string.key_length);
28953889Smckusick 		break;
29053889Smckusick 
29153889Smckusick 	default:
29253889Smckusick 		return (0);
29353889Smckusick 	}
29453889Smckusick 	return (0);
29553889Smckusick }
29653889Smckusick 
kbd_init()29753889Smckusick kbd_init()
29853889Smckusick {
29953889Smckusick 	int i;
30053889Smckusick 	Pfk_string pfk_buf;
30153889Smckusick 
30253889Smckusick 	for (i = 0; i < N_PFK; i++) {
30353889Smckusick 		pfk_table[i].pfk_addr = pfk_init[i].pfk_addr;
30453889Smckusick 		if (pfk_init[i].pfk_normal.key_length > 0) {
30553889Smckusick 			pfk_buf.pfk_num = i;
30653889Smckusick 			pfk_buf.pfk_shift = PF_NORMAL;
30753889Smckusick 			pfk_buf.pfk_string = pfk_init[i].pfk_normal;
30853889Smckusick 			kbd_string(KIOCSETS, &pfk_buf);
30953889Smckusick 		}
31053889Smckusick 		if (pfk_init[i].pfk_shift.key_length > 0) {
31153889Smckusick 			pfk_buf.pfk_num = i;
31253889Smckusick 			pfk_buf.pfk_shift = PF_SHIFT;
31353889Smckusick 			pfk_buf.pfk_string = pfk_init[i].pfk_shift;
31453889Smckusick 			kbd_string(KIOCSETS, &pfk_buf);
31553889Smckusick 		}
31653889Smckusick 	}
31753889Smckusick 	kbd_status = 0;
31853889Smckusick }
31953889Smckusick 
kbd_repeat(f)32053889Smckusick kbd_repeat(f)
32153889Smckusick 	int f;
32253889Smckusick {
32353889Smckusick 
32453889Smckusick 	if (f)
32553889Smckusick 		kbd_status &= ~KBD_NOTREPT;
32653889Smckusick 	else
32753889Smckusick 		kbd_status |= KBD_NOTREPT;
32853889Smckusick 	return (0);
32953889Smckusick }
33053889Smckusick 
33153889Smckusick 
33253889Smckusick static
put2char(c1,c2)33353889Smckusick put2char(c1, c2)
33453889Smckusick 	int c1, c2;
33553889Smckusick {
33653889Smckusick 	char buf[2];
33753889Smckusick 
33853889Smckusick 	buf[0] = c1;
33953889Smckusick 	buf[1] = c2;
34053889Smckusick 	return (put_code(buf, 2));
34153889Smckusick }
34253889Smckusick 
34353889Smckusick #define	SS2		0x8e
34453889Smckusick 
34553889Smckusick static
put_kana(s,len)34653889Smckusick put_kana(s, len)
34753889Smckusick 	register u_char *s;
34853889Smckusick 	int len;
34953889Smckusick {
35053889Smckusick 	register int i;
35153889Smckusick 	register u_char *p;
35253889Smckusick 	u_char eucbuf[8];
35353889Smckusick 
35453889Smckusick 	if (len <= 0)
35553889Smckusick 		return (0);
35653889Smckusick #ifdef KM_EUC
35753889Smckusick 	if ((tmode == KM_EUC) && ((*s >= 0xa1) && (*s <= 0xdf))) {
35853889Smckusick 		p = eucbuf;
35953889Smckusick 		for (i = len; i > 0; i--) {
36053889Smckusick 			*p++ = SS2;
36153889Smckusick 			*p++ = *s++;
36253889Smckusick 		}
36353889Smckusick 		return (put_code(eucbuf, len * 2));
36453889Smckusick 	}
36553889Smckusick #endif /* KM_EUC */
36653889Smckusick 	return (put_code(s, len));
36753889Smckusick }
368