|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1992-1989 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: mouse.c
28: * Author: Alessandro Forin, Carnegie Mellon University
29: * Date: 9/90
30: *
31: * Driver code for Digital's mouse AND tablet
32: */
33:
34: /*
35: * XXX This should be rewritten to support other
36: * XXX sorts of mices and tablets. But for now
37: * XXX I have none to play with. Sorry about that.
38: */
39:
40: #include <lk.h> /* one mouse per lk201 */
41: #if NLK > 0
42:
43: #include <mach/std_types.h>
44: #include <machine/machspl.h> /* spl definitions */
45: #include <sys/time.h>
46: #include <kern/time_out.h>
47:
48: #include <chips/serial_defs.h>
49: #include <chips/screen_defs.h>
50:
51: #define MOUSE_INCREMENTAL 0x52 /* R */
52: #define MOUSE_PROMPTED 0x44 /* D */
53: #define MOUSE_REQ_POSITION 0x50 /* P */
54: #define MOUSE_SELFTEST 0x54 /* T */
55: #define MOUSE_RESERVED_FUNC 0x5a /* Z, param byte follows */
56:
57: #define TABLET_SAMPLE_55 0x4b /* K */ /* in reps/sec */
58: #define TABLET_SAMPLE_72 0x4c /* L */
59: #define TABLET_SAMPLE_120 0x4d /* M */
60: #define TABLET_9600 0x42 /* B */
61:
62: #define TYPE_MOUSE 0x2
63: #define TYPE_TABLET 0x4
64:
65: #define START_REPORT 0x80
66:
67: typedef union {
68: struct {
69: unsigned char r : 1, m : 1, l : 1, sy : 1, sx : 1;
70: unsigned char xpos;
71: unsigned char ypos;
72: } ms;
73: struct {
74: unsigned char pr : 1, buttons : 4;
75: unsigned char xlo, xhi;
76: unsigned char ylo, yhi;
77: } tb;
78: unsigned char raw[1];
79: } mouse_report_t;
80:
81:
82: /*
83: * Mouse state
84: */
85: struct mouse_softc {
86: user_info_t *up;
87: mouse_report_t report;
88: unsigned char rep_bytes;
89: unsigned char rep_ptr;
90: unsigned char prev_buttons;
91: unsigned char flags;
92: #define MS_TABLET 0x1
93: #define MS_MOVING 0x2
94: char screen_unit;
95: char sl_unit;
96: } mouse_softc_data[NLK];
97:
98: typedef struct mouse_softc *mouse_softc_t;
99:
100: mouse_softc_t mouse_softc[NLK];
101:
102:
103: mouse_notify_mapped(
104: int unit,
105: int screen_unit,
106: user_info_t *up)
107: {
108: mouse_softc_t ms = &mouse_softc_data[unit];
109:
110: ms->up = up;
111: ms->screen_unit = screen_unit;
112: }
113:
114: /*
115: * Autoconfiguration
116: */
117: mouse_probe(
118: int unit)
119: {
120: mouse_softc[unit] = &mouse_softc_data[unit];
121: }
122:
123: mouse_attach(
124: int unit,
125: int sl_unit)
126: {
127: int messg[4];
128: spl_t s;
129: mouse_softc_t ms;
130:
131: ms = mouse_softc[unit];
132: ms->sl_unit = sl_unit;
133:
134: s = spltty();
135: (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_SELFTEST);
136: delay(1);
137: messg[0] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
138: messg[1] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
139: messg[2] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
140: messg[3] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
141:
142: delay(100000); /* spec says less than 500 msecs */
143: (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_INCREMENTAL);
144: splx(s);
145:
146: ms->rep_bytes = 3;/* mouse */
147: if (messg[2] | messg[3]) {
148: printf(" bad pointer [%x %x %x %x] ",
149: messg[0], messg[1], messg[2], messg[3]);
150: if (messg[2] >= 0x20) printf("fatal ");
151: if (messg[2] == 0x3e) printf("RAM/ROM");
152: if (messg[2] == 0x3d) printf("button(s) %x", messg[3] & 0x1f);
153: } else {
154: int rev = messg[0] & 0xf;
155: int loc = (messg[1] & 0xf0) >> 4;
156: int tag = (messg[1] & 0xf);
157: printf("( %s rev. %x.%x )",
158: (tag == TYPE_MOUSE) ? "mouse" : "tablet",
159: rev, loc);
160: if (tag == TYPE_TABLET) {
161: ms->flags = MS_TABLET;
162: ms->rep_bytes = 5;
163: }
164: }
165: }
166:
167: /*
168: * Process a character from the mouse
169: */
170: mouse_input(
171: int unit,
172: register unsigned short data)
173: {
174: mouse_softc_t ms = mouse_softc[unit];
175: register char flg, but;
176:
177: data &= 0xff;
178:
179: /* sanity: might miss a byte sometimes */
180: if (data & START_REPORT)
181: ms->rep_ptr = 0;
182:
183: /* add byte to report */
184: ms->report.raw[ms->rep_ptr++] = data;
185:
186: /* does this mean the mouse is moving */
187: if (data && ((data & START_REPORT) == 0))
188: ms->flags |= MS_MOVING;
189:
190: /* Report complete ? */
191: if (ms->rep_ptr != ms->rep_bytes)
192: return;
193: ms->rep_ptr = 0;
194:
195: ssaver_bump(ms->screen_unit);
196:
197: /* check for mouse moved */
198: flg = ms->flags;
199: if (flg & MS_MOVING) {
200: ms->flags = flg & ~MS_MOVING;
201: mouse_motion_event(ms, flg);
202: }
203:
204: /* check for button pressed */
205: if (but = ms->prev_buttons ^ ms->report.raw[0]) {
206: mouse_button_event(ms, flg, but);
207: ms->prev_buttons = ms->report.raw[0];
208: }
209: }
210:
211: /*
212: * The mouse/puck moved.
213: * Find how much and post an event
214: */
215: mouse_motion_event(
216: mouse_softc_t ms,
217: int flg)
218: {
219: register int x, y;
220:
221: if (flg & MS_TABLET) {
222:
223: flg = DEV_TABLET;
224:
225: x = (ms->report.tb.xhi << 8) | ms->report.tb.xlo;
226: y = (ms->report.tb.yhi << 8) | ms->report.tb.ylo;
227:
228: } else {
229:
230: flg = DEV_MOUSE;
231:
232: x = ms->report.ms.xpos;
233: if (!ms->report.ms.sx) /* ??? */
234: x = -x;
235:
236: y = ms->report.ms.ypos;
237: if (ms->report.ms.sy)
238: y = -y;
239:
240: }
241:
242: screen_motion_event(ms->screen_unit, flg, x, y);
243: }
244:
245: /*
246: * A mouse/puck button was pressed/released.
247: * Find which one and post an event
248: */
249: mouse_button_event(
250: mouse_softc_t ms,
251: int flg,
252: int bmask)
253: {
254: register unsigned int buttons, i;
255: int key, type;
256:
257: buttons = ms->report.raw[0];
258: if (flg & MS_TABLET) {
259: /* check each one of the four buttons */
260: for (i = 0; i < 4; i += 1) {
261: if ((bmask & (2<<i)) == 0)
262: continue;/* did not change */
263: type = (buttons & (2<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP;
264: key = i;
265:
266: screen_keypress_event( ms->screen_unit,
267: DEV_TABLET, key, type);
268: }
269: } else {
270: ms->up->mouse_buttons = buttons & 0x7;
271: /* check each one of the three buttons */
272: for (i = 0; i < 3; i += 1) {
273: if ((bmask & (1<<i)) == 0)
274: continue;/* did not change */
275: type = (buttons & (1<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP;
276:
277: if (i & 1)
278: key = KEY_MIDDLE_BUTTON;
279: else if ((i & 2) == 0)
280: key = KEY_RIGHT_BUTTON;
281: else
282: key = KEY_LEFT_BUTTON;
283:
284: screen_keypress_event( ms->screen_unit,
285: DEV_MOUSE, key, type);
286: }
287: }
288: }
289:
290: /*
291: * Generate escape sequences for position reporting
292: * These are the same as xterm's.
293: * Prefix:
294: * ESC [ M button down
295: * ESC [ N button up
296: * Body:
297: * BUTTON COL ROW
298: * Button:
299: * 0 <-> left, 1 <-> middle, 2 <-> right
300: * All body values are offset by the ascii SPACE character
301: */
302: #define ESC '\033'
303: #define SPACE ' '
304:
305: mouse_report_position(
306: int unit,
307: int col,
308: int row,
309: int key,
310: int type)
311: {
312: cons_input(SCREEN_LINE_KEYBOARD, ESC, 0);
313: cons_input(SCREEN_LINE_KEYBOARD, '[', 0);
314: cons_input(SCREEN_LINE_KEYBOARD, (type==EVT_BUTTON_DOWN) ? 'M':'N', 0);
315:
316: cons_input(SCREEN_LINE_KEYBOARD, (key - 1) + SPACE, 0);/* quick remapping */
317: cons_input(SCREEN_LINE_KEYBOARD, SPACE + col + 2, 0);
318: cons_input(SCREEN_LINE_KEYBOARD, SPACE + row + 1, 0);
319: }
320:
321: #endif NLK > 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.