|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1992 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * File: dtop_handlers.c
28: * Author: Alessandro Forin, Carnegie Mellon University
29: * Date: 1/92
30: *
31: * Handler functions for devices attached to the DESKTOP bus.
32: */
33:
34: #include <dtop.h>
35: #if NDTOP > 0
36:
37: #include <mach_kdb.h>
38:
39: #include <machine/machspl.h> /* spl definitions */
40: #include <mach/std_types.h>
41: #include <device/io_req.h>
42: #include <device/tty.h>
43:
44: #include <chips/busses.h>
45: #include <chips/serial_defs.h>
46: #include <chips/screen_defs.h>
47: #include <mips/PMAX/tc.h>
48:
49: #include <chips/dtop.h>
50: #include <chips/lk201.h>
51:
52: /*
53: * Default handler function
54: */
55: int
56: dtop_null_device_handler(
57: dtop_device_t dev,
58: dtop_message_t msg,
59: int event,
60: unsigned char outc)
61: {
62: /* See if the message was to the default address (powerup) */
63:
64: /* Uhmm, donno how to handle this. Drop it */
65: if (event == DTOP_EVENT_RECEIVE_PACKET)
66: dev->unknown_report = *msg;
67: return 0;
68: }
69:
70: /*
71: * Handler for locator devices (mice)
72: */
73: int
74: dtop_locator_handler(
75: dtop_device_t dev,
76: dtop_message_t msg,
77: int event,
78: unsigned char outc)
79: {
80: register unsigned short buttons;
81: register short coord;
82: #if BYTE_MSF
83: # define get_short(b0,b1) (((b1)<<8)|(b0))
84: #else
85: # define get_short(b0,b1) (((b0)<<8)|(b1))
86: #endif
87:
88: /*
89: * Do the position first
90: */
91: {
92: register int i;
93: register boolean_t moved;
94: int delta_coords[L_COORD_MAX];
95:
96: /*
97: * Get all coords, see if it moved at all (buttons!)
98: */
99: moved = FALSE;
100: for (i = 0; i < dev->locator.n_coords; i++) {
101:
102: coord = get_short(msg->body[2+(i<<1)],
103: msg->body[3+(i<<1)]);
104:
105: if (dev->locator.relative) {
106: /*
107: * Flame on
108: * I am getting tired of this, why do they have to
109: * keep this bug around ? Religion ? Damn, they
110: * design a keyboard for X11 use and forget the mouse ?
111: * Flame off
112: */
113: #define BOGUS_DEC_X_AXIS
114: #ifdef BOGUS_DEC_X_AXIS
115: if (i == 1) coord = - coord;
116: #endif /* BOGUS_DEC_X_AXIS */
117: /* dev->locator.coordinate[i] += coord; */
118: } else {
119: register unsigned int old_coord;
120:
121: old_coord = dev->locator.coordinate[i];
122: dev->locator.coordinate[i] = coord;
123: coord = old_coord - coord;
124: }
125: delta_coords[i] = coord;
126: if (coord != 0)
127: moved = TRUE;
128: }
129: if (moved) {
130: /* scale and threshold done higher up */
131: screen_motion_event( 0,
132: dev->locator.type,
133: delta_coords[0],
134: delta_coords[1]);
135: }
136: }
137:
138: /*
139: * Time for the buttons now
140: */
141: #define new_buttons coord
142: new_buttons = get_short(msg->body[0],msg->body[1]);
143: buttons = new_buttons ^ dev->locator.prev_buttons;
144: if (buttons) {
145: register int i, type;
146:
147: dev->locator.prev_buttons = new_buttons;
148: for (i = 0; buttons; i++, buttons >>= 1) {
149:
150: if ((buttons & 1) == 0) continue;
151:
152: type = (new_buttons & (1<<i)) ?
153: EVT_BUTTON_DOWN : EVT_BUTTON_UP;
154: screen_keypress_event( 0,
155: dev->locator.type,
156: dev->locator.button_code[i],
157: type);
158: }
159: }
160: #undef new_buttons
161: }
162:
163: /*
164: * Handler for keyboard devices
165: * Special case: outc set for recv packet means
166: * we are inside the kernel debugger
167: */
168: int
169: dtop_keyboard_handler(
170: dtop_device_t dev,
171: dtop_message_t msg,
172: int event,
173: unsigned char outc)
174: {
175: char save[11];
176: register int msg_len, c;
177:
178: /*
179: * Well, really this code handles just an lk401 and in
180: * a very primitive way at that. Should at least emulate
181: * an lk201 decently, and make that a pluggable module.
182: * Sigh.
183: */
184:
185: if (event != DTOP_EVENT_RECEIVE_PACKET) {
186: switch (event) {
187: case DTOP_EVENT_POLL:
188: {
189: register unsigned int t, t0;
190:
191: /*
192: * Note we will always have at least the
193: * end-of-list marker present (a zero)
194: * Here stop and trigger of autorepeat.
195: * Do not repeat shift keys, either.
196: */
197: {
198: register unsigned char uc, i = 0;
199:
200: rpt_char:
201: uc = dev->keyboard.last_codes[i];
202:
203: if (uc == DTOP_KBD_EMPTY) {
204: dev->keyboard.k_ar_state = K_AR_OFF;
205: return 0;
206: }
207: if ((uc >= LK_R_SHIFT) && (uc <= LK_R_ALT)) {
208: /* sometimes swapped. Grrr. */
209: if (++i < dev->keyboard.last_codes_count)
210: goto rpt_char;
211: dev->keyboard.k_ar_state = K_AR_OFF;
212: return 0;
213: }
214: c = uc;
215: }
216:
217: /*
218: * Got a char. See if enough time from stroke,
219: * or from last repeat.
220: */
221: t0 = (dev->keyboard.k_ar_state == K_AR_TRIGGER) ? 30 : 500;
222: t = approx_time_in_msec();
223: if ((t - dev->keyboard.last_msec) < t0)
224: return 0;
225:
226: dev->keyboard.k_ar_state = K_AR_TRIGGER;
227:
228: /*
229: * Simplest thing to do is to mimic lk201
230: */
231: outc = lk201_input(0, LK_REPEAT);
232: if ( ! screen_keypress_event( 0,
233: DEV_KEYBD,
234: c,
235: EVT_BUTTON_UP)) {
236: if (outc > 0) cons_input(0, outc, 0);
237: } else
238: screen_keypress_event( 0,
239: DEV_KEYBD,
240: c,
241: EVT_BUTTON_DOWN);
242: return 0;
243: }
244: default: gimmeabreak();/*fornow*/
245: }
246: return -1;
247: }
248:
249: msg_len = msg->code.val.len;
250:
251: /* Check for errors */
252: c = msg->body[0];
253: if ((c < DTOP_KBD_KEY_MIN) && (c != DTOP_KBD_EMPTY)) {
254: printf("Keyboard error: %x %x %x..\n", msg_len, c, msg->body[1]);
255: if (c != DTOP_KBD_OUT_ERR) return -1;
256: /* spec sez if scan list overflow still there is data */
257: msg->body[0] = 0;
258: }
259:
260: dev->keyboard.last_msec = approx_time_in_msec();
261:
262: switch (dev->keyboard.k_ar_state) {
263: case K_AR_IDLE:
264: /* if from debugger, timeouts might not be working yet */
265: if (outc == 0xff)
266: break;
267: dtop_keyboard_autorepeat( dev );
268: /* fall through */
269: case K_AR_TRIGGER:
270: dev->keyboard.k_ar_state = K_AR_ACTIVE;
271: break;
272: case K_AR_ACTIVE:
273: break;
274: case K_AR_OFF: gimmeabreak(); /* ??? */
275: dev->keyboard.k_ar_state = K_AR_IDLE;
276: }
277:
278: /*
279: * We can only assume that pressed keys are reported in the
280: * same order (a minimum of sanity, please) across scans.
281: * To make things readable, do a first pass cancelling out
282: * all keys that are still pressed, and a second one generating
283: * events. While generating events, do the upstrokes first
284: * from oldest to youngest, then the downstrokes from oldest
285: * to youngest. This copes with lost packets and provides
286: * a reasonable model even if scans are too slow.
287: */
288:
289: /* make a copy of new state first */
290: {
291: register char *p, *q, *e;
292:
293: p = save;
294: q = (char*)msg->body;
295: e = (char*)&msg->body[msg_len];
296:
297: while (q < e)
298: *p++ = *q++;
299: }
300:
301: /*
302: * Do the cancelling pass
303: */
304: {
305: register char *ls, *le, *ns, *ne, *sync;
306:
307: ls = (char*)dev->keyboard.last_codes;
308: le = (char*)&dev->keyboard.last_codes[dev->keyboard.last_codes_count];
309: ns = (char*)msg->body;
310: ne = (char*)&msg->body[msg_len];
311:
312: /* sync marks where to restart scanning, saving
313: time thanks to ordering constraints */
314: for (sync = ns; ls < le; ls++) {
315: register char c = *ls;
316: for (ns = sync; ns < ne; ns++)
317: if (c == *ns) {
318: *ls = *ns = 0;
319: sync = ns + 1;
320: break;
321: }
322: /* we could already tell if c is an upstroke,
323: but see the above discussion about errors */
324: }
325: }
326: /*
327: * Now generate all upstrokes
328: */
329: {
330: register char *ls, *le;
331: register unsigned char c;
332:
333: le = (char*)dev->keyboard.last_codes;
334: ls = (char*)&dev->keyboard.last_codes[dev->keyboard.last_codes_count - 1];
335:
336: for ( ; ls >= le; ls--)
337: if (c = *ls) {
338: /* keep kernel notion of lk201 state consistent */
339: (void) lk201_input(0,c);
340:
341: if (outc == 0)
342: screen_keypress_event(0,
343: DEV_KEYBD,
344: c,
345: EVT_BUTTON_UP);
346: }
347: }
348: /*
349: * And finally the downstrokes
350: */
351: {
352: register char *ns, *ne, c, retc;
353:
354: ne = (char*)msg->body;
355: ns = (char*)&msg->body[msg_len - 1];
356: retc = 0;
357:
358: for ( ; ns >= ne; ns--)
359: if (c = *ns) {
360: register unsigned char data;
361:
362: data = c;
363: c = lk201_input(0, data);
364:
365: if (c == -2) { /* just returned from kdb */
366: /* NOTE: many things have happened while
367: we were sitting on the stack, now it
368: is last_codes that holds the truth */
369: #if 1
370: /* But the truth might not be welcome.
371: If we get out because we hit RETURN
372: on the rconsole line all is well,
373: but if we did it from the keyboard
374: we get here on the downstroke. Then
375: we will get the upstroke which we
376: would give to X11. People complained
377: about this extra keypress.. so they
378: lose everything. */
379:
380: dev->keyboard.last_codes_count = 1;
381: dev->keyboard.last_codes[0] = 0;
382: #endif
383: return -1;
384: }
385:
386: /*
387: * If X11 had better code for the keyboard this
388: * would be an EVT_BUTTON_DOWN. But that would
389: * screwup the REPEAT function. Grrr.
390: */
391: /* outc non zero sez we are in the debugger */
392: if (outc == 0) {
393: if (screen_keypress_event(0,
394: DEV_KEYBD,
395: data,
396: EVT_BUTTON_DOWN))
397: c = -1; /* consumed by X */
398: else
399: if (c > 0) cons_input(0, c, 0);
400: }
401: /* return the xlated keycode anyways */
402: if ((c > 0) && (retc == 0))
403: retc = c;
404: }
405: outc = retc;
406: }
407: /* install new scan state */
408: {
409: register char *p, *q, *e;
410:
411: p = (char*)dev->keyboard.last_codes;
412: q = (char*)save;
413: e = (char*)&save[msg_len];
414:
415: while (q < e)
416: *p++ = *q++;
417: dev->keyboard.last_codes_count = msg_len;
418: }
419: return outc;
420: }
421:
422: /*
423: * Polled operations: we must do autorepeat by hand. Sigh.
424: */
425: dtop_keyboard_autorepeat(
426: dtop_device_t dev)
427: {
428: spl_t s = spltty();
429:
430: if (dev->keyboard.k_ar_state != K_AR_IDLE)
431: dtop_keyboard_handler( dev, 0, DTOP_EVENT_POLL, 0);
432:
433: if (dev->keyboard.k_ar_state == K_AR_OFF)
434: dev->keyboard.k_ar_state = K_AR_IDLE;
435: else
436: timeout( dtop_keyboard_autorepeat, dev, dev->keyboard.poll_frequency);
437:
438: splx(s);
439: }
440:
441: #endif /*NDTOP>0*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.