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