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