BSD 4_3_Tahoe release
[unix-history] / usr / src / new / X / libsun / events.c
CommitLineData
ca67e7b4
C
1#ifndef lint
2static char *rcsid_events_c = "$Header: events.c,v 10.4 86/12/17 20:36:45 swick Exp $";
3#endif lint
4#ifdef sun
5/*
6 * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided
7 * for unrestricted use provided that this legend is included on all tape
8 * media and as a part of the software program in whole or part. Users
9 * may copy or modify these drivers without charge, but are not authorized
10 * to license or distribute them to anyone else except as part of a product or
11 * program developed by the user.
12 *
13 * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
14 * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A
15 * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE
16 * PRACTICE.
17 *
18 * The Sun X Drivers are provided with no support and without any obligation
19 * on the part of Sun Microsystems, Inc. to assist in their use, correction,
20 * modification or enhancement.
21 *
22 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
23 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X
24 * DRIVERS OR ANY PART THEREOF.
25 *
26 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
27 * or profits or other special, indirect and consequential damages, even if
28 * Sun has been advised of the possibility of such damages.
29 *
30 * Sun Microsystems, Inc.
31 * 2550 Garcia Avenue
32 * Mountain View, California 94043
33 */
34
35#ifndef lint
36static char sccsid[] = "@(#)events.c 2.1 86/01/28 Copyright 1986 Sun Micro";
37#endif
38
39/*-
40 * Copyright (c) 1986 by Sun Microsystems, Inc.
41 */
42
43/*
44 * ToDo:
45 * Up events on regular keys
46 */
47
48#include <stdio.h>
49#include <sys/types.h>
50#include <sys/time.h>
51#include <sys/errno.h>
52#include "../X/X.h"
53#include "../X/vsinput.h"
54#include "../X/Xdev.h"
55#include <sundev/kbd.h>
56#ifdef RAW_KBD
57#include <sundev/kbio.h>
58#endif
59#include <sunwindow/win_input.h>
60
61#ifndef event_is_ascii
62#define event_is_ascii(e) (e->ie_code >= ASCII_FIRST && e->ie_code <= ASCII_LAST)
63#endif
64#ifndef event_is_meta
65#define event_is_meta(e) (e->ie_code >= META_FIRST && e->ie_code <= META_LAST)
66#endif
67/* Should be qevent.h */
68#define VSE_LEFT_BUTTON 0
69#define VSE_MIDDLE_BUTTON 1
70#define VSE_RIGHT_BUTTON 2
71#define NOT_A_KEY 9
72
73extern int errno;
74extern int vsdev;
75extern DEVICE *CurrentDevice;
76
77int sunthreshold = 0;
78int sunaccel = 0;
79
80#ifdef RAW_KBD
81extern unsigned state_mask;
82#endif
83
84/*ARGSUSED*/
85ProcessInput(ev)
86 register vsEvent *ev;
87{
88 /*NOTREACHED*/
89}
90
91#include "lk201.h"
92
93#ifdef RAW_KBD
94extern struct kiockey sunkeymap[];
95
96/*
97 * Convert from a Sun event to an X event
98 */
99unsigned
100ConvertEvent(se, xe)
101struct inputevent *se;
102vsEvent *xe;
103{
104 int key;
105 unsigned kludgekey;
106 /* Map the coordinates */
107 xe->vse_x = se->ie_locx;
108 xe->vse_y = se->ie_locy;
109 /* Map the time stamps */
110 xe->vse_time = (se->ie_time.tv_usec/10000 + se->ie_time.tv_sec);
111 /* Set direction */
112 xe->vse_direction = (win_inputposevent(se) ? VSE_KBTDOWN : VSE_KBTUP);
113 /* Sort out the event codes */
114
115 if (se->ie_code >= VKEY_FIRSTSHIFT && se->ie_code <= VKEY_LASTSHIFT) {
116 /*
117 * this makes ie_code between 0 and 0200 inclusive.
118 */
119 se->ie_code -= VKEY_FIRSTSHIFT;
120 key = SHIFTKEYS + se->ie_code;
121 } else if (se->ie_code >= 0 && se->ie_code < 0200)
122 key = sunkeymap[se->ie_code].kio_entry;
123 else
124 key = -1;
125
126 kludgekey = 0;
127 if (key >= 0) {
128 xe->vse_device = VSE_DKB;
129 xe->vse_type = VSE_BUTTON;
130
131 /*
132 * First deal with special keycodes
133 */
134 if (key & 0x80) {
135 switch(key & 0xf0) {
136 case SHIFTKEYS:
137 /*
138 * The static count is keeping track of how many
139 * keys I have down for the given function.
140 * Only need to do this for shift and meta.
141 * On an up event I decrease the count. If it is
142 * not the last one up then I convert to a down event
143 * which really won't do anything. I should ignore
144 * the event, but this works.
145 * At odd times the sun keyboard gets confused and I
146 * miss an UP event. This may get you stuck in
147 * shift mode. I assume there is only 2 shift keys
148 * and only two meta keys. If count ever goes above
149 * 2 I make it 2 again, assuming I have missed an up
150 * event. If you get stuck in shifted mode, just his
151 * both shift keys and you should be fixed.
152 */
153 switch(key & 0x0f) {
154 case 11:
155 case 14:
156 case LEFTSHIFT:
157 case RIGHTSHIFT: {
158 static count;
159
160 kludgekey = 0256;
161
162 if (win_inputposevent(se)) {
163 if (++count > 2)
164 count = 2;
165 } else if (--count > 0)
166 xe->vse_direction = VSE_KBTDOWN;
167 else if (count < 0)
168 count = 0;
169 break;
170 }
171 /* LEFT/RIGHT key */
172 case 9:
173 default: {
174 static count;
175
176 kludgekey = 0261;
177
178 if (win_inputposevent(se)) {
179 if (++count > 2)
180 count = 2;
181 } else if (--count > 0)
182 xe->vse_direction = VSE_KBTDOWN;
183 else if (count < 0)
184 count = 0;
185 break;
186 }
187 case 10:
188 case 13:
189 case CAPSLOCK:
190 case SHIFTLOCK:
191 kludgekey = 0260;
192 break;
193 case 12:
194 case 15:
195 case LEFTCTRL:
196 case RIGHTCTRL:
197 kludgekey = 0257;
198 break;
199 }
200 break;
201 case STRING:
202 switch(key & 0xf) {
203 default:
204 case HOMEARROW:
205 kludgekey = 0206;
206 break;
207 case UPARROW:
208 kludgekey = 0252;
209 break;
210 case DOWNARROW:
211 kludgekey = 0251;
212 break;
213 case LEFTARROW:
214 kludgekey = 0247;
215 break;
216 case RIGHTARROW:
217 kludgekey = 0250;
218 break;
219 }
220 break;
221 case RIGHTFUNC:
222 kludgekey = RightKeys[key&0xf];
223 break;
224 case LEFTFUNC:
225 kludgekey = LeftKeys[key&0xf];
226 break;
227 case TOPFUNC:
228 kludgekey = TopKeys[key&0xf];
229 break;
230 case BOTTOMFUNC:
231 kludgekey = BotKeys[key&0xf];
232 break;
233 case BUCKYBITS:
234 case FUNNY:
235 default:
236 kludgekey = 0;
237 }
238 } else {
239 /*
240 * Now deal with regular keys.
241 * Note, I look up the key in the shift/ctrl/caps tables
242 * in case the keys are not quite like a lk201.
243 * I assume that a regular key shifted/ctrled/caped is also a
244 * regular key. This may be naive.
245 */
246 if (key == '\033' /*ESC*/ )
247 kludgekey = 0161;
248 else if (key == '\b')
249 kludgekey = 0162;
250 else if (key == '\n')
251 kludgekey = 0163;
252 else if (key == '\r')
253 kludgekey = 0275;
254 else if (key == '\t')
255 kludgekey = 0276;
256 else if (key == '\006' /*ALT*/)
257 kludgekey = 0245;
258 else if (key == '\177' /*DEL*/)
259 kludgekey = 0274;
260 else if(state_mask & ControlMask)
261 kludgekey = LK201[sunkeymap[se->ie_code+00200].kio_entry];
262 else if(state_mask & ShiftMask)
263 kludgekey = LK201[sunkeymap[se->ie_code+00600].kio_entry];
264 else if(state_mask & ShiftLockMask)
265 kludgekey = LK201[sunkeymap[se->ie_code+00400].kio_entry];
266 else
267 kludgekey = LK201[key];
268 }
269 xe->vse_key = kludgekey & 0377;
270 kludgekey &= (~state_mask)&(ControlMask|ShiftMask);
271 } else switch (se->ie_code) {
272 case LOC_MOVE:
273 xe->vse_device = VSE_MOUSE; /* XXX - should query shift state here but ... */
274 xe->vse_type = VSE_MMOTION;
275 break;
276 case MS_LEFT:
277 xe->vse_key = VSE_LEFT_BUTTON;
278 xe->vse_device = VSE_MOUSE;
279 xe->vse_type = VSE_BUTTON;
280 break;
281 case MS_MIDDLE:
282 xe->vse_device = VSE_MOUSE;
283 xe->vse_type = VSE_BUTTON;
284 xe->vse_key = VSE_MIDDLE_BUTTON;
285 break;
286 case MS_RIGHT:
287 xe->vse_key = VSE_RIGHT_BUTTON;
288 xe->vse_device = VSE_MOUSE;
289 xe->vse_type = VSE_BUTTON;
290 break;
291 default:
292 xe->vse_key = NOT_A_KEY;
293 xe->vse_device = VSE_MOUSE;
294 xe->vse_type = VSE_BUTTON;
295 break;
296 }
297 return(kludgekey);
298}
299
300#define INPBUFSIZE 128
301
302/*
303 * Read pending input events
304 */
305InputReader()
306{
307 struct inputevent sunevents[INPBUFSIZE];
308 int n, m;
309
310 if ((n = read(vsdev, sunevents, INPBUFSIZE * sizeof sunevents[0])) < 0
311 && errno != EWOULDBLOCK) {
312 /*
313 * Error reading events
314 */
315 /* XXX_DO_SOMETHING(); */
316 return;
317 }
318 for (n /= sizeof sunevents[0], m = 0; m < n; m++) {
319 vsEvent Xevent;
320
321 unsigned kludgekey = ConvertEvent(&(sunevents[m]), &Xevent);
322
323 if (Xevent.vse_type == VSE_MMOTION) {
324 if (sunthreshold) {
325 int dx = Xevent.vse_x - CurrentDevice->mouse->x;
326 int dy = Xevent.vse_y - CurrentDevice->mouse->y;
327
328 if (sunthreshold <= (dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)) {
329 Xevent.vse_x = CurrentDevice->mouse->x + dx * sunaccel;
330 Xevent.vse_y = CurrentDevice->mouse->y + dy * sunaccel;
331 }
332
333 }
334 SetCursorPosition((vsCursor *) &Xevent); /* XXX - tacky */
335 }
336
337 Xevent.vse_key;
338
339 if (Xevent.vse_type == VSE_MMOTION) {
340 register vsBox *b = CurrentDevice->mbox;
341 register vsCursor *m = CurrentDevice->mouse;
342 /*
343 * Has it left the box?
344 */
345 if (m->y >= b->bottom || m->y < b->top ||
346 m->x >= b->right || m->x < b->left) {
347 b->bottom = 0;
348 Deal_with_movement();
349 }
350 } else if (Xevent.vse_key != NOT_A_KEY ||
351 Xevent.vse_device != VSE_MOUSE) {
352 state_mask |= kludgekey;
353 Deal_with_input(&Xevent);
354 state_mask &= ~kludgekey;
355 }
356 }
357}
358#else
359static int
360SunToXKeyCode(s)
361int s;
362{
363 register int ret = LK201[s&0177];
364 char *c = "^.";
365 char *f = ".";
366
367 c[1] = (s&0177)|0100;
368 f[0] = (s&0177);
369
370 return(ret);
371}
372
373/*
374 * Convert from a Sun event to an X event
375 */
376int
377ConvertEvent(se, xe)
378struct inputevent *se;
379vsEvent *xe;
380{
381 static unsigned lstate_mask;
382
383 /* Map the coordinates */
384 xe->vse_x = se->ie_locx;
385 xe->vse_y = se->ie_locy;
386 /* Map the time stamps */
387 xe->vse_time = (se->ie_time.tv_usec/10000 + se->ie_time.tv_sec);
388 /* Set direction */
389 xe->vse_direction = (win_inputposevent(se) ? VSE_KBTDOWN : VSE_KBTUP);
390 /* Sort out the event codes */
391 if (event_is_ascii(se)) {
392 /* ASCII keystroke */
393 int key = SunToXKeyCode(se->ie_code);
394 xe->vse_key = (key & 0377);
395 xe->vse_device = VSE_DKB;
396 xe->vse_type = VSE_BUTTON;
397 lstate_mask = (lstate_mask & ~(ControlMask|MetaMask|ShiftMask))
398 | (key & (ControlMask|MetaMask|ShiftMask));
399 } else if (event_is_meta(se)) {
400 /* META keystroke - map to ASCII for now */
401 int key = SunToXKeyCode(se->ie_code - META_FIRST + ASCII_FIRST) | MetaMask;
402 xe->vse_key = (key & 0377);
403 xe->vse_device = VSE_DKB;
404 xe->vse_type = VSE_BUTTON;
405 lstate_mask = (lstate_mask & ~(ControlMask|MetaMask|ShiftMask))
406 | (key & (ControlMask|MetaMask|ShiftMask));
407 } else switch (se->ie_code) {
408 case LOC_MOVE:
409 xe->vse_device = VSE_MOUSE; /* XXX - should query shift state here but ... */
410 xe->vse_type = VSE_MMOTION;
411 break;
412 case MS_LEFT:
413 xe->vse_key = VSE_LEFT_BUTTON;
414 xe->vse_device = VSE_MOUSE;
415 xe->vse_type = VSE_BUTTON;
416 if (xe->vse_direction == VSE_KBTUP)
417 lstate_mask &= ~LeftMask;
418 else
419 lstate_mask |= LeftMask;
420 goto ShiftKeys;
421 case MS_MIDDLE:
422 xe->vse_device = VSE_MOUSE;
423 xe->vse_type = VSE_BUTTON;
424 xe->vse_key = VSE_MIDDLE_BUTTON;
425 if (xe->vse_direction == VSE_KBTUP)
426 lstate_mask &= ~MiddleMask;
427 else
428 lstate_mask |= MiddleMask;
429 goto ShiftKeys;
430 case MS_RIGHT:
431 xe->vse_key = VSE_RIGHT_BUTTON;
432 xe->vse_device = VSE_MOUSE;
433 xe->vse_type = VSE_BUTTON;
434 if (xe->vse_direction == VSE_KBTUP)
435 lstate_mask &= ~RightMask;
436 else
437 lstate_mask |= RightMask;
438 goto ShiftKeys;
439 default:
440 xe->vse_key = NOT_A_KEY;
441 xe->vse_device = VSE_MOUSE;
442 xe->vse_type = VSE_BUTTON;
443 if (xe->vse_direction == VSE_KBTUP)
444 lstate_mask &= ~ShiftLockMask;
445 else
446 lstate_mask |= ShiftLockMask;
447ShiftKeys:
448 if (se->ie_shiftmask & SHIFTMASK)
449 lstate_mask |= ShiftMask;
450 else
451 lstate_mask &= ~ShiftMask;
452 if (se->ie_shiftmask & CTRLMASK)
453 lstate_mask |= ControlMask;
454 else
455 lstate_mask &= ~ControlMask;
456#ifdef META_SHIFT_MASK
457 if (se->ie_shiftmask & META_SHIFT_MASK)
458 lstate_mask |= MetaMask;
459 else
460 lstate_mask &= ~MetaMask;
461#endif
462 break;
463 }
464 return (lstate_mask);
465}
466
467#define INPBUFSIZE 128
468
469/*
470 * Read pending input events
471 */
472InputReader()
473{
474 struct inputevent sunevents[INPBUFSIZE];
475 int n, m;
476 static int last_mask;
477
478 if ((n = read(vsdev, sunevents, INPBUFSIZE * sizeof sunevents[0])) < 0
479 && errno != EWOULDBLOCK) {
480 /*
481 * Error reading events
482 */
483 /* XXX_DO_SOMETHING(); */
484 return;
485 }
486 for (n /= sizeof sunevents[0], m = 0; m < n; m++) {
487 vsEvent Xevent, Sevent;
488 int mask;
489
490 mask = ConvertEvent(&(sunevents[m]), &Xevent);
491 if (Xevent.vse_type == VSE_MMOTION) {
492 if (sunthreshold) {
493 int dx = Xevent.vse_x - CurrentDevice->mouse->x;
494 int dy = Xevent.vse_y - CurrentDevice->mouse->y;
495
496 if (sunthreshold <= (dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)) {
497 Xevent.vse_x = CurrentDevice->mouse->x + dx * sunaccel;
498 Xevent.vse_y = CurrentDevice->mouse->y + dy * sunaccel;
499 }
500
501 }
502 SetCursorPosition((vsCursor *) &Xevent); /* XXX - tacky */
503 }
504
505 if (mask != last_mask) {
506 last_mask ^= mask;
507 Sevent.vse_device = VSE_DKB;
508 Sevent.vse_x = Xevent.vse_x;
509 Sevent.vse_y = Xevent.vse_y;
510 Sevent.vse_time = Xevent.vse_time;
511 if (last_mask & ShiftMask) {
512 if (mask & ShiftMask)
513 Sevent.vse_direction = VSE_KBTDOWN;
514 else
515 Sevent.vse_direction = VSE_KBTUP;
516 Sevent.vse_key = 0256;
517 Deal_with_input(&Sevent);
518 }
519 if (last_mask & ControlMask) {
520 if (mask & ControlMask)
521 Sevent.vse_direction = VSE_KBTDOWN;
522 else
523 Sevent.vse_direction = VSE_KBTUP;
524 Sevent.vse_key = 0257;
525 Deal_with_input(&Sevent);
526 }
527 if (last_mask & ShiftLockMask) {
528 if (mask & ShiftLockMask)
529 Sevent.vse_direction = VSE_KBTDOWN;
530 else
531 Sevent.vse_direction = VSE_KBTUP;
532 Sevent.vse_key = 0260;
533 Deal_with_input(&Sevent);
534 }
535 if (last_mask & MetaMask) {
536 if (mask & MetaMask)
537 Sevent.vse_direction = VSE_KBTDOWN;
538 else
539 Sevent.vse_direction = VSE_KBTUP;
540 Sevent.vse_key = 0261;
541 Deal_with_input(&Sevent);
542 }
543 last_mask = mask;
544 }
545 if (Xevent.vse_type == VSE_MMOTION) {
546 register vsBox *b = CurrentDevice->mbox;
547 register vsCursor *m = CurrentDevice->mouse;
548 /*
549 * Has it left the box?
550 */
551 if (m->y >= b->bottom || m->y < b->top ||
552 m->x >= b->right || m->x < b->left) {
553 b->bottom = 0;
554 Deal_with_movement();
555 }
556 } else if (Xevent.vse_key != NOT_A_KEY ||
557 Xevent.vse_device != VSE_MOUSE)
558 Deal_with_input(&Xevent);
559 }
560}
561#endif
562#endif sun