xref: /plan9/sys/src/cmd/vnc/kbds.c (revision ebe1d0a8b9996624470441a63d49d0fee1ba744c)
1f8e525acSDavid du Colombier #include	<u.h>
2f8e525acSDavid du Colombier #include	<libc.h>
3f8e525acSDavid du Colombier #include	"compat.h"
4f8e525acSDavid du Colombier #include	"kbd.h"
5*ebe1d0a8SDavid du Colombier #include   "ksym2utf.h"
6f8e525acSDavid du Colombier 
7f8e525acSDavid du Colombier enum
8f8e525acSDavid du Colombier {
9f8e525acSDavid du Colombier 	VKSpecial = 0xff00,
10f8e525acSDavid du Colombier 
11f8e525acSDavid du Colombier 	/*
12f8e525acSDavid du Colombier 	 * plan 9 key mappings
13f8e525acSDavid du Colombier 	 */
1488ebe47fSDavid du Colombier 	Spec=		0xF800,
15f8e525acSDavid du Colombier 
16f8e525acSDavid du Colombier 	PF=		Spec|0x20,	/* num pad function key */
17f8e525acSDavid du Colombier 	View=		Spec|0x00,	/* view (shift window up) */
18f8e525acSDavid du Colombier 	KF=		0xF000,	/* function key (begin Unicode private space) */
19f8e525acSDavid du Colombier 	Shift=		Spec|0x60,
20f8e525acSDavid du Colombier 	Break=		Spec|0x61,
21f8e525acSDavid du Colombier 	Ctrl=		Spec|0x62,
22f8e525acSDavid du Colombier 	Latin=		Spec|0x63,
23f8e525acSDavid du Colombier 	Caps=		Spec|0x64,
24f8e525acSDavid du Colombier 	Num=		Spec|0x65,
25f8e525acSDavid du Colombier 	Middle=		Spec|0x66,
26f8e525acSDavid du Colombier 	No=		0x00,		/* peter */
27f8e525acSDavid du Colombier 
28f8e525acSDavid du Colombier 	Home=		KF|13,
29f8e525acSDavid du Colombier 	Up=		KF|14,
30f8e525acSDavid du Colombier 	Pgup=		KF|15,
31f8e525acSDavid du Colombier 	Print=		KF|16,
32f8e525acSDavid du Colombier 	Left=		KF|17,
33f8e525acSDavid du Colombier 	Right=		KF|18,
34f8e525acSDavid du Colombier 	End=		'\r',
35f8e525acSDavid du Colombier 	Down=		View,
36f8e525acSDavid du Colombier 	Pgdown=		KF|19,
37f8e525acSDavid du Colombier 	Ins=		KF|20,
38f8e525acSDavid du Colombier 	Del=		0x7F,
39f8e525acSDavid du Colombier 	Scroll=		KF|21,
40f8e525acSDavid du Colombier 
41f8e525acSDavid du Colombier 	Esc = 0x1b,
42f8e525acSDavid du Colombier 	Delete = 0x7f,
43f8e525acSDavid du Colombier };
44f8e525acSDavid du Colombier 
45f8e525acSDavid du Colombier static Rune vnckeys[] =
46f8e525acSDavid du Colombier {
47f8e525acSDavid du Colombier [0x00]	No,	No,	No,	No,	No,	No,	No,	No,
48f8e525acSDavid du Colombier [0x08]	'\b',	'\t',	'\r',	No,	No,	'\n',	No,	No,
49f8e525acSDavid du Colombier [0x10]	No,	No,	No,	No,	Scroll,	No,	No,	No,
50f8e525acSDavid du Colombier [0x18]	No,	No,	No,	Esc,	No,	No,	No,	No,
51f8e525acSDavid du Colombier [0x20]	No,	No,	No,	No,	No,	No,	No,	No,
52f8e525acSDavid du Colombier [0x28]	No,	No,	No,	No,	No,	No,	No,	No,
53f8e525acSDavid du Colombier [0x30]	No,	No,	No,	No,	No,	No,	No,	No,
54f8e525acSDavid du Colombier [0x38]	No,	No,	No,	No,	No,	No,	No,	No,
55f8e525acSDavid du Colombier [0x40]	No,	No,	No,	No,	No,	No,	No,	No,
56f8e525acSDavid du Colombier [0x48]	No,	No,	No,	No,	No,	No,	No,	No,
57f8e525acSDavid du Colombier [0x50]	Home,	Left,	Up,	Right,	Down,	Pgup,	Pgdown,	No,
58f8e525acSDavid du Colombier [0x58]	No,	No,	No,	No,	No,	No,	No,	No,
59f8e525acSDavid du Colombier [0x60]	No,	Print,	No,	Ins,	No,	No,	No,	No,
60f8e525acSDavid du Colombier [0x68]	No,	No,	No,	Break,	No,	No,	No,	No,
61f8e525acSDavid du Colombier [0x70]	No,	No,	No,	No,	No,	No,	No,	No,
62f8e525acSDavid du Colombier [0x78]	No,	No,	No,	No,	No,	No,	No,	Num,
63f8e525acSDavid du Colombier [0x80]	No,	No,	No,	No,	No,	No,	No,	No,
64f8e525acSDavid du Colombier [0x88]	No,	No,	No,	No,	No,	No,	No,	No,
65f8e525acSDavid du Colombier [0x90]	No,	No,	No,	No,	No,	No,	No,	No,
66f8e525acSDavid du Colombier [0x98]	No,	No,	No,	No,	No,	No,	No,	No,
67f8e525acSDavid du Colombier [0xa0]	No,	No,	No,	No,	No,	No,	No,	No,
68f8e525acSDavid du Colombier [0xa8]	No,	No,	'*',	'+',	No,	'-',	'.',	'/',
69f8e525acSDavid du Colombier [0xb0]	'0',	'1',	'2',	'3',	'4',	'5',	'6',	'7',
70f8e525acSDavid du Colombier [0xb8]	'8',	'9',	No,	No,	No,	'=',	No,	No,
71f8e525acSDavid du Colombier [0xc0]	No,	No,	No,	No,	No,	No,	No,	No,
72f8e525acSDavid du Colombier [0xc8]	No,	No,	No,	No,	No,	No,	No,	No,
73f8e525acSDavid du Colombier [0xd0]	No,	No,	No,	No,	No,	No,	No,	No,
74f8e525acSDavid du Colombier [0xd8]	No,	No,	No,	No,	No,	No,	No,	No,
75f8e525acSDavid du Colombier [0xe0]	No,	Shift,	Shift,	Ctrl,	Ctrl,	Caps,	Caps,	No,
76f8e525acSDavid du Colombier [0xe8]	No,	Latin,	Latin,	No,	No,	No,	No,	No,
77f8e525acSDavid du Colombier [0xf0]	No,	No,	No,	No,	No,	No,	No,	No,
78f8e525acSDavid du Colombier [0xf8]	No,	No,	No,	No,	No,	No,	No,	Delete,
79f8e525acSDavid du Colombier };
80f8e525acSDavid du Colombier 
81f8e525acSDavid du Colombier /*
82f8e525acSDavid du Colombier  *  keyboard interrupt
83f8e525acSDavid du Colombier  */
84f8e525acSDavid du Colombier void
vncputc(int keyup,int c)85f8e525acSDavid du Colombier vncputc(int keyup, int c)
86f8e525acSDavid du Colombier {
87f8e525acSDavid du Colombier 	int i;
88f8e525acSDavid du Colombier 	static int esc1, esc2;
89f8e525acSDavid du Colombier 	static int alt, caps, ctl, num, shift;
90f8e525acSDavid du Colombier 	static int collecting, nk;
91f8e525acSDavid du Colombier 	static Rune kc[5];
92f8e525acSDavid du Colombier 
93f8e525acSDavid du Colombier 	if(caps && c<='z' && c>='a')
94f8e525acSDavid du Colombier 		c += 'A' - 'a';
95f8e525acSDavid du Colombier 
96f8e525acSDavid du Colombier 	/*
97f8e525acSDavid du Colombier  	 *  character mapping
98f8e525acSDavid du Colombier 	 */
99f8e525acSDavid du Colombier 	if((c & VKSpecial) == VKSpecial){
100f8e525acSDavid du Colombier 		c = vnckeys[c & 0xff];
101f8e525acSDavid du Colombier 		if(c == No)
102f8e525acSDavid du Colombier 			return;
103*ebe1d0a8SDavid du Colombier 	}
104*ebe1d0a8SDavid du Colombier 	/*
105*ebe1d0a8SDavid du Colombier 	 * map an xkeysym onto a utf-8 char
106*ebe1d0a8SDavid du Colombier 	 */
107*ebe1d0a8SDavid du Colombier 	if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
108*ebe1d0a8SDavid du Colombier 			c = ksym2utf[c];
109f8e525acSDavid du Colombier 
110f8e525acSDavid du Colombier 	/*
111f8e525acSDavid du Colombier 	 *  keyup only important for shifts
112f8e525acSDavid du Colombier 	 */
113f8e525acSDavid du Colombier 	if(keyup){
114f8e525acSDavid du Colombier 		switch(c){
115f8e525acSDavid du Colombier 		case Latin:
116f8e525acSDavid du Colombier 			alt = 0;
117f8e525acSDavid du Colombier 			break;
118f8e525acSDavid du Colombier 		case Shift:
119f8e525acSDavid du Colombier 			shift = 0;
120f8e525acSDavid du Colombier 			break;
121f8e525acSDavid du Colombier 		case Ctrl:
122f8e525acSDavid du Colombier 			ctl = 0;
123f8e525acSDavid du Colombier 			break;
124f8e525acSDavid du Colombier 		}
125f8e525acSDavid du Colombier 		return;
126f8e525acSDavid du Colombier 	}
127f8e525acSDavid du Colombier 
128f8e525acSDavid du Colombier 	/*
129f8e525acSDavid du Colombier  	 *  normal character
130f8e525acSDavid du Colombier 	 */
131f8e525acSDavid du Colombier 	if(!(c & (Spec|KF))){
132f8e525acSDavid du Colombier 		if(ctl){
133f8e525acSDavid du Colombier 			c &= 0x1f;
134f8e525acSDavid du Colombier 		}
135f8e525acSDavid du Colombier 		if(!collecting){
136f8e525acSDavid du Colombier 			kbdputc(c);
137f8e525acSDavid du Colombier 			return;
138f8e525acSDavid du Colombier 		}
139f8e525acSDavid du Colombier 		kc[nk++] = c;
140f8e525acSDavid du Colombier 		c = latin1(kc, nk);
141f8e525acSDavid du Colombier 		if(c < -1)	/* need more keystrokes */
142f8e525acSDavid du Colombier 			return;
143f8e525acSDavid du Colombier 		if(c != -1)	/* valid sequence */
144f8e525acSDavid du Colombier 			kbdputc(c);
145f8e525acSDavid du Colombier 		else	/* dump characters */
146f8e525acSDavid du Colombier 			for(i=0; i<nk; i++)
147f8e525acSDavid du Colombier 				kbdputc(kc[i]);
148f8e525acSDavid du Colombier 		nk = 0;
149f8e525acSDavid du Colombier 		collecting = 0;
150f8e525acSDavid du Colombier 		return;
151f8e525acSDavid du Colombier 	}else{
152f8e525acSDavid du Colombier 		switch(c){
153f8e525acSDavid du Colombier 		case Caps:
154f8e525acSDavid du Colombier 			caps ^= 1;
155f8e525acSDavid du Colombier 			return;
156f8e525acSDavid du Colombier 		case Num:
157f8e525acSDavid du Colombier 			num ^= 1;
158f8e525acSDavid du Colombier 			return;
159f8e525acSDavid du Colombier 		case Shift:
160f8e525acSDavid du Colombier 			shift = 1;
161f8e525acSDavid du Colombier 			return;
162f8e525acSDavid du Colombier 		case Latin:
163f8e525acSDavid du Colombier 			alt = 1;
164f8e525acSDavid du Colombier 			collecting = 1;
165f8e525acSDavid du Colombier 			nk = 0;
166f8e525acSDavid du Colombier 			return;
167f8e525acSDavid du Colombier 		case Ctrl:
168f8e525acSDavid du Colombier 			ctl = 1;
169f8e525acSDavid du Colombier 			return;
170f8e525acSDavid du Colombier 		}
171f8e525acSDavid du Colombier 	}
172f8e525acSDavid du Colombier 	kbdputc(c);
173f8e525acSDavid du Colombier }
174