Blame


1 113867b8 2009-09-29 jas #define Point OSXPoint
2 113867b8 2009-09-29 jas #define Rect OSXRect
3 113867b8 2009-09-29 jas #define Cursor OSXCursor
4 113867b8 2009-09-29 jas #import <AppKit/AppKit.h>
5 113867b8 2009-09-29 jas #undef Rect
6 113867b8 2009-09-29 jas #undef Point
7 113867b8 2009-09-29 jas #undef Cursor
8 113867b8 2009-09-29 jas
9 113867b8 2009-09-29 jas /*
10 113867b8 2009-09-29 jas * Window system protocol server.
11 113867b8 2009-09-29 jas */
12 113867b8 2009-09-29 jas
13 113867b8 2009-09-29 jas #include <u.h>
14 113867b8 2009-09-29 jas #include <errno.h>
15 113867b8 2009-09-29 jas #include <sys/select.h>
16 113867b8 2009-09-29 jas #include <libc.h>
17 113867b8 2009-09-29 jas #include <draw.h>
18 113867b8 2009-09-29 jas #include <memdraw.h>
19 113867b8 2009-09-29 jas #include <memlayer.h>
20 113867b8 2009-09-29 jas #include <keyboard.h>
21 113867b8 2009-09-29 jas #include <mouse.h>
22 113867b8 2009-09-29 jas #include <cursor.h>
23 113867b8 2009-09-29 jas #include <drawfcall.h>
24 113867b8 2009-09-29 jas #include "osx-screen.h"
25 113867b8 2009-09-29 jas #include "devdraw.h"
26 113867b8 2009-09-29 jas
27 113867b8 2009-09-29 jas AUTOFRAMEWORK(AppKit)
28 113867b8 2009-09-29 jas
29 113867b8 2009-09-29 jas #import "osx-delegate.h"
30 113867b8 2009-09-29 jas
31 113867b8 2009-09-29 jas #undef time
32 113867b8 2009-09-29 jas
33 113867b8 2009-09-29 jas #define MouseMask (\
34 113867b8 2009-09-29 jas ButtonPressMask|\
35 113867b8 2009-09-29 jas ButtonReleaseMask|\
36 113867b8 2009-09-29 jas PointerMotionMask|\
37 113867b8 2009-09-29 jas Button1MotionMask|\
38 113867b8 2009-09-29 jas Button2MotionMask|\
39 113867b8 2009-09-29 jas Button3MotionMask)
40 113867b8 2009-09-29 jas
41 113867b8 2009-09-29 jas #define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|EnterWindowMask|LeaveWindowMask
42 113867b8 2009-09-29 jas
43 113867b8 2009-09-29 jas typedef struct Kbdbuf Kbdbuf;
44 113867b8 2009-09-29 jas typedef struct Mousebuf Mousebuf;
45 113867b8 2009-09-29 jas typedef struct Fdbuf Fdbuf;
46 113867b8 2009-09-29 jas typedef struct Tagbuf Tagbuf;
47 113867b8 2009-09-29 jas
48 113867b8 2009-09-29 jas struct Kbdbuf
49 113867b8 2009-09-29 jas {
50 113867b8 2009-09-29 jas Rune r[32];
51 113867b8 2009-09-29 jas int ri;
52 113867b8 2009-09-29 jas int wi;
53 113867b8 2009-09-29 jas int stall;
54 113867b8 2009-09-29 jas };
55 113867b8 2009-09-29 jas
56 113867b8 2009-09-29 jas struct Mousebuf
57 113867b8 2009-09-29 jas {
58 113867b8 2009-09-29 jas Mouse m[32];
59 113867b8 2009-09-29 jas Mouse last;
60 113867b8 2009-09-29 jas int ri;
61 113867b8 2009-09-29 jas int wi;
62 113867b8 2009-09-29 jas int stall;
63 113867b8 2009-09-29 jas };
64 113867b8 2009-09-29 jas
65 113867b8 2009-09-29 jas struct Tagbuf
66 113867b8 2009-09-29 jas {
67 113867b8 2009-09-29 jas int t[32];
68 113867b8 2009-09-29 jas int ri;
69 113867b8 2009-09-29 jas int wi;
70 113867b8 2009-09-29 jas };
71 113867b8 2009-09-29 jas
72 113867b8 2009-09-29 jas Kbdbuf kbd;
73 113867b8 2009-09-29 jas Mousebuf mouse;
74 113867b8 2009-09-29 jas Tagbuf kbdtags;
75 113867b8 2009-09-29 jas Tagbuf mousetags;
76 113867b8 2009-09-29 jas
77 113867b8 2009-09-29 jas void fdslide(Fdbuf*);
78 113867b8 2009-09-29 jas void runmsg(Wsysmsg*);
79 113867b8 2009-09-29 jas void replymsg(Wsysmsg*);
80 113867b8 2009-09-29 jas void matchkbd(void);
81 113867b8 2009-09-29 jas void matchmouse(void);
82 113867b8 2009-09-29 jas int fdnoblock(int);
83 113867b8 2009-09-29 jas Rectangle mouserect;
84 113867b8 2009-09-29 jas int mouseresized;
85 113867b8 2009-09-29 jas
86 113867b8 2009-09-29 jas
87 113867b8 2009-09-29 jas QLock lk;
88 113867b8 2009-09-29 jas void
89 113867b8 2009-09-29 jas zlock(void)
90 113867b8 2009-09-29 jas {
91 113867b8 2009-09-29 jas qlock(&lk);
92 113867b8 2009-09-29 jas }
93 113867b8 2009-09-29 jas
94 113867b8 2009-09-29 jas void
95 113867b8 2009-09-29 jas zunlock(void)
96 113867b8 2009-09-29 jas {
97 113867b8 2009-09-29 jas qunlock(&lk);
98 113867b8 2009-09-29 jas }
99 113867b8 2009-09-29 jas
100 113867b8 2009-09-29 jas int chatty;
101 113867b8 2009-09-29 jas int drawsleep;
102 113867b8 2009-09-29 jas int trace;
103 113867b8 2009-09-29 jas
104 113867b8 2009-09-29 jas void
105 113867b8 2009-09-29 jas usage(void)
106 113867b8 2009-09-29 jas {
107 113867b8 2009-09-29 jas fprint(2, "usage: devdraw (don't run directly)\n");
108 113867b8 2009-09-29 jas exits("usage");
109 113867b8 2009-09-29 jas }
110 113867b8 2009-09-29 jas
111 113867b8 2009-09-29 jas void
112 113867b8 2009-09-29 jas bell(void *v, char *msg)
113 113867b8 2009-09-29 jas {
114 113867b8 2009-09-29 jas if(strcmp(msg, "alarm") == 0)
115 113867b8 2009-09-29 jas drawsleep = drawsleep ? 0 : 1000;
116 113867b8 2009-09-29 jas noted(NCONT);
117 113867b8 2009-09-29 jas }
118 113867b8 2009-09-29 jas
119 113867b8 2009-09-29 jas int
120 113867b8 2009-09-29 jas main(int argc, char **argv)
121 113867b8 2009-09-29 jas {
122 113867b8 2009-09-29 jas NSAutoreleasePool *pool = nil;
123 113867b8 2009-09-29 jas NSApplication *application = nil;
124 cbcec5ad 2011-01-12 rsc DevdrawDelegate *app = nil;
125 113867b8 2009-09-29 jas /*
126 113867b8 2009-09-29 jas * Move the protocol off stdin/stdout so that
127 113867b8 2009-09-29 jas * any inadvertent prints don't screw things up.
128 113867b8 2009-09-29 jas */
129 113867b8 2009-09-29 jas dup(0, 3);
130 113867b8 2009-09-29 jas dup(1, 4);
131 113867b8 2009-09-29 jas close(0);
132 113867b8 2009-09-29 jas close(1);
133 113867b8 2009-09-29 jas open("/dev/null", OREAD);
134 113867b8 2009-09-29 jas open("/dev/null", OWRITE);
135 113867b8 2009-09-29 jas
136 113867b8 2009-09-29 jas trace = 1;
137 113867b8 2009-09-29 jas fmtinstall('W', drawfcallfmt);
138 113867b8 2009-09-29 jas
139 113867b8 2009-09-29 jas ARGBEGIN{
140 113867b8 2009-09-29 jas case 'D':
141 113867b8 2009-09-29 jas chatty++;
142 113867b8 2009-09-29 jas break;
143 113867b8 2009-09-29 jas default:
144 113867b8 2009-09-29 jas usage();
145 113867b8 2009-09-29 jas }ARGEND
146 113867b8 2009-09-29 jas
147 113867b8 2009-09-29 jas /*
148 113867b8 2009-09-29 jas * Ignore arguments. They're only for good ps -a listings.
149 113867b8 2009-09-29 jas */
150 113867b8 2009-09-29 jas
151 113867b8 2009-09-29 jas notify(bell);
152 113867b8 2009-09-29 jas
153 113867b8 2009-09-29 jas pool = [[NSAutoreleasePool alloc] init];
154 113867b8 2009-09-29 jas application = [NSApplication sharedApplication];
155 cbcec5ad 2011-01-12 rsc app = [[DevdrawDelegate alloc] init];
156 cbcec5ad 2011-01-12 rsc [application setDelegate:app];
157 113867b8 2009-09-29 jas [application run];
158 113867b8 2009-09-29 jas [application setDelegate:nil];
159 cbcec5ad 2011-01-12 rsc [app release];
160 113867b8 2009-09-29 jas [pool release];
161 113867b8 2009-09-29 jas return 0;
162 113867b8 2009-09-29 jas }
163 113867b8 2009-09-29 jas
164 113867b8 2009-09-29 jas void
165 113867b8 2009-09-29 jas replyerror(Wsysmsg *m)
166 113867b8 2009-09-29 jas {
167 113867b8 2009-09-29 jas char err[256];
168 113867b8 2009-09-29 jas
169 113867b8 2009-09-29 jas rerrstr(err, sizeof err);
170 113867b8 2009-09-29 jas m->type = Rerror;
171 113867b8 2009-09-29 jas m->error = err;
172 113867b8 2009-09-29 jas replymsg(m);
173 113867b8 2009-09-29 jas }
174 113867b8 2009-09-29 jas
175 113867b8 2009-09-29 jas /*
176 113867b8 2009-09-29 jas * Handle a single wsysmsg.
177 113867b8 2009-09-29 jas * Might queue for later (kbd, mouse read)
178 113867b8 2009-09-29 jas */
179 113867b8 2009-09-29 jas void
180 113867b8 2009-09-29 jas runmsg(Wsysmsg *m)
181 113867b8 2009-09-29 jas {
182 113867b8 2009-09-29 jas static uchar buf[65536];
183 113867b8 2009-09-29 jas int n;
184 113867b8 2009-09-29 jas Memimage *i;
185 113867b8 2009-09-29 jas
186 113867b8 2009-09-29 jas switch(m->type){
187 113867b8 2009-09-29 jas case Tinit:
188 113867b8 2009-09-29 jas memimageinit();
189 113867b8 2009-09-29 jas i = attachscreen(m->label, m->winsize);
190 113867b8 2009-09-29 jas _initdisplaymemimage(i);
191 113867b8 2009-09-29 jas replymsg(m);
192 113867b8 2009-09-29 jas break;
193 113867b8 2009-09-29 jas
194 113867b8 2009-09-29 jas case Trdmouse:
195 113867b8 2009-09-29 jas // zlock();
196 113867b8 2009-09-29 jas mousetags.t[mousetags.wi++] = m->tag;
197 113867b8 2009-09-29 jas if(mousetags.wi == nelem(mousetags.t))
198 113867b8 2009-09-29 jas mousetags.wi = 0;
199 113867b8 2009-09-29 jas if(mousetags.wi == mousetags.ri)
200 113867b8 2009-09-29 jas sysfatal("too many queued mouse reads");
201 113867b8 2009-09-29 jas mouse.stall = 0;
202 113867b8 2009-09-29 jas matchmouse();
203 113867b8 2009-09-29 jas // zunlock();
204 113867b8 2009-09-29 jas break;
205 113867b8 2009-09-29 jas
206 113867b8 2009-09-29 jas case Trdkbd:
207 113867b8 2009-09-29 jas zlock();
208 113867b8 2009-09-29 jas kbdtags.t[kbdtags.wi++] = m->tag;
209 113867b8 2009-09-29 jas if(kbdtags.wi == nelem(kbdtags.t))
210 113867b8 2009-09-29 jas kbdtags.wi = 0;
211 113867b8 2009-09-29 jas if(kbdtags.wi == kbdtags.ri)
212 113867b8 2009-09-29 jas sysfatal("too many queued keyboard reads");
213 113867b8 2009-09-29 jas kbd.stall = 0;
214 113867b8 2009-09-29 jas matchkbd();
215 113867b8 2009-09-29 jas zunlock();
216 113867b8 2009-09-29 jas break;
217 113867b8 2009-09-29 jas
218 113867b8 2009-09-29 jas case Tmoveto:
219 113867b8 2009-09-29 jas setmouse(m->mouse.xy);
220 113867b8 2009-09-29 jas replymsg(m);
221 113867b8 2009-09-29 jas break;
222 113867b8 2009-09-29 jas
223 113867b8 2009-09-29 jas case Tcursor:
224 113867b8 2009-09-29 jas if(m->arrowcursor)
225 113867b8 2009-09-29 jas setcursor(nil);
226 113867b8 2009-09-29 jas else
227 113867b8 2009-09-29 jas setcursor(&m->cursor);
228 113867b8 2009-09-29 jas replymsg(m);
229 113867b8 2009-09-29 jas break;
230 113867b8 2009-09-29 jas
231 113867b8 2009-09-29 jas case Tbouncemouse:
232 113867b8 2009-09-29 jas // _xbouncemouse(&m->mouse);
233 113867b8 2009-09-29 jas replymsg(m);
234 113867b8 2009-09-29 jas break;
235 113867b8 2009-09-29 jas
236 113867b8 2009-09-29 jas case Tlabel:
237 113867b8 2009-09-29 jas kicklabel(m->label);
238 113867b8 2009-09-29 jas replymsg(m);
239 113867b8 2009-09-29 jas break;
240 113867b8 2009-09-29 jas
241 113867b8 2009-09-29 jas case Trdsnarf:
242 113867b8 2009-09-29 jas m->snarf = getsnarf();
243 113867b8 2009-09-29 jas replymsg(m);
244 113867b8 2009-09-29 jas free(m->snarf);
245 113867b8 2009-09-29 jas break;
246 113867b8 2009-09-29 jas
247 113867b8 2009-09-29 jas case Twrsnarf:
248 113867b8 2009-09-29 jas putsnarf(m->snarf);
249 113867b8 2009-09-29 jas replymsg(m);
250 113867b8 2009-09-29 jas break;
251 113867b8 2009-09-29 jas
252 113867b8 2009-09-29 jas case Trddraw:
253 113867b8 2009-09-29 jas n = m->count;
254 113867b8 2009-09-29 jas if(n > sizeof buf)
255 113867b8 2009-09-29 jas n = sizeof buf;
256 113867b8 2009-09-29 jas n = _drawmsgread(buf, n);
257 113867b8 2009-09-29 jas if(n < 0)
258 113867b8 2009-09-29 jas replyerror(m);
259 113867b8 2009-09-29 jas else{
260 113867b8 2009-09-29 jas m->count = n;
261 113867b8 2009-09-29 jas m->data = buf;
262 113867b8 2009-09-29 jas replymsg(m);
263 113867b8 2009-09-29 jas }
264 113867b8 2009-09-29 jas break;
265 113867b8 2009-09-29 jas
266 113867b8 2009-09-29 jas case Twrdraw:
267 113867b8 2009-09-29 jas if(_drawmsgwrite(m->data, m->count) < 0)
268 113867b8 2009-09-29 jas replyerror(m);
269 113867b8 2009-09-29 jas else
270 113867b8 2009-09-29 jas replymsg(m);
271 113867b8 2009-09-29 jas break;
272 113867b8 2009-09-29 jas
273 113867b8 2009-09-29 jas case Ttop:
274 113867b8 2009-09-29 jas // _xtopwindow();
275 113867b8 2009-09-29 jas replymsg(m);
276 113867b8 2009-09-29 jas break;
277 113867b8 2009-09-29 jas
278 113867b8 2009-09-29 jas case Tresize:
279 113867b8 2009-09-29 jas // _xresizewindow(m->rect);
280 113867b8 2009-09-29 jas replymsg(m);
281 113867b8 2009-09-29 jas break;
282 113867b8 2009-09-29 jas }
283 113867b8 2009-09-29 jas }
284 113867b8 2009-09-29 jas
285 113867b8 2009-09-29 jas /*
286 113867b8 2009-09-29 jas * Reply to m.
287 113867b8 2009-09-29 jas */
288 113867b8 2009-09-29 jas QLock replylock;
289 113867b8 2009-09-29 jas void
290 113867b8 2009-09-29 jas replymsg(Wsysmsg *m)
291 113867b8 2009-09-29 jas {
292 113867b8 2009-09-29 jas int n;
293 113867b8 2009-09-29 jas static uchar *mbuf;
294 113867b8 2009-09-29 jas static int nmbuf;
295 113867b8 2009-09-29 jas
296 113867b8 2009-09-29 jas /* T -> R msg */
297 113867b8 2009-09-29 jas if(m->type%2 == 0)
298 113867b8 2009-09-29 jas m->type++;
299 113867b8 2009-09-29 jas
300 113867b8 2009-09-29 jas if(trace) fprint(2, "-> %W\n", m);
301 113867b8 2009-09-29 jas /* copy to output buffer */
302 113867b8 2009-09-29 jas n = sizeW2M(m);
303 113867b8 2009-09-29 jas
304 113867b8 2009-09-29 jas qlock(&replylock);
305 113867b8 2009-09-29 jas if(n > nmbuf){
306 113867b8 2009-09-29 jas free(mbuf);
307 113867b8 2009-09-29 jas mbuf = malloc(n);
308 113867b8 2009-09-29 jas if(mbuf == nil)
309 113867b8 2009-09-29 jas sysfatal("out of memory");
310 113867b8 2009-09-29 jas nmbuf = n;
311 113867b8 2009-09-29 jas }
312 113867b8 2009-09-29 jas convW2M(m, mbuf, n);
313 113867b8 2009-09-29 jas if(write(4, mbuf, n) != n)
314 113867b8 2009-09-29 jas sysfatal("write: %r");
315 113867b8 2009-09-29 jas qunlock(&replylock);
316 113867b8 2009-09-29 jas }
317 113867b8 2009-09-29 jas
318 113867b8 2009-09-29 jas /*
319 113867b8 2009-09-29 jas * Match queued kbd reads with queued kbd characters.
320 113867b8 2009-09-29 jas */
321 113867b8 2009-09-29 jas void
322 113867b8 2009-09-29 jas matchkbd(void)
323 113867b8 2009-09-29 jas {
324 113867b8 2009-09-29 jas Wsysmsg m;
325 113867b8 2009-09-29 jas
326 113867b8 2009-09-29 jas if(kbd.stall)
327 113867b8 2009-09-29 jas return;
328 113867b8 2009-09-29 jas while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){
329 113867b8 2009-09-29 jas m.type = Rrdkbd;
330 113867b8 2009-09-29 jas m.tag = kbdtags.t[kbdtags.ri++];
331 113867b8 2009-09-29 jas if(kbdtags.ri == nelem(kbdtags.t))
332 113867b8 2009-09-29 jas kbdtags.ri = 0;
333 113867b8 2009-09-29 jas m.rune = kbd.r[kbd.ri++];
334 113867b8 2009-09-29 jas if(kbd.ri == nelem(kbd.r))
335 113867b8 2009-09-29 jas kbd.ri = 0;
336 113867b8 2009-09-29 jas replymsg(&m);
337 113867b8 2009-09-29 jas }
338 113867b8 2009-09-29 jas }
339 113867b8 2009-09-29 jas
340 113867b8 2009-09-29 jas /*
341 113867b8 2009-09-29 jas * Match queued mouse reads with queued mouse events.
342 113867b8 2009-09-29 jas */
343 113867b8 2009-09-29 jas void
344 113867b8 2009-09-29 jas matchmouse(void)
345 113867b8 2009-09-29 jas {
346 113867b8 2009-09-29 jas Wsysmsg m;
347 113867b8 2009-09-29 jas
348 113867b8 2009-09-29 jas while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){
349 113867b8 2009-09-29 jas m.type = Rrdmouse;
350 113867b8 2009-09-29 jas m.tag = mousetags.t[mousetags.ri++];
351 113867b8 2009-09-29 jas if(mousetags.ri == nelem(mousetags.t))
352 113867b8 2009-09-29 jas mousetags.ri = 0;
353 113867b8 2009-09-29 jas m.mouse = mouse.m[mouse.ri];
354 113867b8 2009-09-29 jas m.resized = mouseresized;
355 113867b8 2009-09-29 jas /*
356 113867b8 2009-09-29 jas if(m.resized)
357 113867b8 2009-09-29 jas fprint(2, "sending resize\n");
358 113867b8 2009-09-29 jas */
359 113867b8 2009-09-29 jas mouseresized = 0;
360 113867b8 2009-09-29 jas mouse.ri++;
361 113867b8 2009-09-29 jas if(mouse.ri == nelem(mouse.m))
362 113867b8 2009-09-29 jas mouse.ri = 0;
363 113867b8 2009-09-29 jas replymsg(&m);
364 113867b8 2009-09-29 jas }
365 113867b8 2009-09-29 jas }
366 113867b8 2009-09-29 jas
367 113867b8 2009-09-29 jas void
368 113867b8 2009-09-29 jas mousetrack(int x, int y, int b, int ms)
369 113867b8 2009-09-29 jas {
370 113867b8 2009-09-29 jas Mouse *m;
371 113867b8 2009-09-29 jas
372 113867b8 2009-09-29 jas if(x < mouserect.min.x)
373 113867b8 2009-09-29 jas x = mouserect.min.x;
374 113867b8 2009-09-29 jas if(x > mouserect.max.x)
375 113867b8 2009-09-29 jas x = mouserect.max.x;
376 113867b8 2009-09-29 jas if(y < mouserect.min.y)
377 113867b8 2009-09-29 jas y = mouserect.min.y;
378 113867b8 2009-09-29 jas if(y > mouserect.max.y)
379 113867b8 2009-09-29 jas y = mouserect.max.y;
380 113867b8 2009-09-29 jas
381 113867b8 2009-09-29 jas // zlock();
382 113867b8 2009-09-29 jas // If reader has stopped reading, don't bother.
383 113867b8 2009-09-29 jas // If reader is completely caught up, definitely queue.
384 113867b8 2009-09-29 jas // Otherwise, queue only button change events.
385 113867b8 2009-09-29 jas if(!mouse.stall)
386 113867b8 2009-09-29 jas if(mouse.wi == mouse.ri || mouse.last.buttons != b){
387 113867b8 2009-09-29 jas m = &mouse.last;
388 113867b8 2009-09-29 jas m->xy.x = x;
389 113867b8 2009-09-29 jas m->xy.y = y;
390 113867b8 2009-09-29 jas m->buttons = b;
391 113867b8 2009-09-29 jas m->msec = ms;
392 113867b8 2009-09-29 jas
393 113867b8 2009-09-29 jas mouse.m[mouse.wi] = *m;
394 113867b8 2009-09-29 jas if(++mouse.wi == nelem(mouse.m))
395 113867b8 2009-09-29 jas mouse.wi = 0;
396 113867b8 2009-09-29 jas if(mouse.wi == mouse.ri){
397 113867b8 2009-09-29 jas mouse.stall = 1;
398 113867b8 2009-09-29 jas mouse.ri = 0;
399 113867b8 2009-09-29 jas mouse.wi = 1;
400 113867b8 2009-09-29 jas mouse.m[0] = *m;
401 113867b8 2009-09-29 jas }
402 113867b8 2009-09-29 jas matchmouse();
403 113867b8 2009-09-29 jas }
404 113867b8 2009-09-29 jas // zunlock();
405 113867b8 2009-09-29 jas }
406 113867b8 2009-09-29 jas
407 113867b8 2009-09-29 jas void
408 113867b8 2009-09-29 jas kputc(int c)
409 113867b8 2009-09-29 jas {
410 113867b8 2009-09-29 jas zlock();
411 113867b8 2009-09-29 jas kbd.r[kbd.wi++] = c;
412 113867b8 2009-09-29 jas if(kbd.wi == nelem(kbd.r))
413 113867b8 2009-09-29 jas kbd.wi = 0;
414 113867b8 2009-09-29 jas if(kbd.ri == kbd.wi)
415 113867b8 2009-09-29 jas kbd.stall = 1;
416 113867b8 2009-09-29 jas matchkbd();
417 113867b8 2009-09-29 jas zunlock();
418 113867b8 2009-09-29 jas }
419 113867b8 2009-09-29 jas
420 113867b8 2009-09-29 jas void
421 113867b8 2009-09-29 jas keystroke(int c)
422 113867b8 2009-09-29 jas {
423 113867b8 2009-09-29 jas static Rune k[10];
424 113867b8 2009-09-29 jas static int alting, nk;
425 113867b8 2009-09-29 jas int i;
426 113867b8 2009-09-29 jas
427 113867b8 2009-09-29 jas if(c == Kalt){
428 113867b8 2009-09-29 jas alting = !alting;
429 113867b8 2009-09-29 jas return;
430 113867b8 2009-09-29 jas }
431 113867b8 2009-09-29 jas if(!alting){
432 113867b8 2009-09-29 jas kputc(c);
433 113867b8 2009-09-29 jas return;
434 113867b8 2009-09-29 jas }
435 113867b8 2009-09-29 jas if(nk >= nelem(k)) // should not happen
436 113867b8 2009-09-29 jas nk = 0;
437 113867b8 2009-09-29 jas k[nk++] = c;
438 113867b8 2009-09-29 jas c = _latin1(k, nk);
439 113867b8 2009-09-29 jas if(c > 0){
440 113867b8 2009-09-29 jas alting = 0;
441 113867b8 2009-09-29 jas kputc(c);
442 113867b8 2009-09-29 jas nk = 0;
443 113867b8 2009-09-29 jas return;
444 113867b8 2009-09-29 jas }
445 113867b8 2009-09-29 jas if(c == -1){
446 113867b8 2009-09-29 jas alting = 0;
447 113867b8 2009-09-29 jas for(i=0; i<nk; i++)
448 113867b8 2009-09-29 jas kputc(k[i]);
449 113867b8 2009-09-29 jas nk = 0;
450 113867b8 2009-09-29 jas return;
451 113867b8 2009-09-29 jas }
452 113867b8 2009-09-29 jas // need more input
453 113867b8 2009-09-29 jas return;
454 113867b8 2009-09-29 jas }