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