FreeBSD/Linux Kernel Cross Reference
sys/chips/mouse.c
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 Software.Distribution@CS.CMU.EDU
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 * HISTORY
28 * $Log: mouse.c,v $
29 * Revision 2.17 93/05/15 19:37:24 mrt
30 * machparam.h -> machspl.h
31 *
32 * Revision 2.16 93/05/10 20:08:23 rvb
33 * No more sys/types.h
34 * [93/05/06 09:55:04 af]
35 *
36 * Revision 2.15 93/02/05 08:05:50 danner
37 * Flamingo, protos, 64bit.
38 * [93/02/04 01:38:40 af]
39 *
40 * Proper spl typing.
41 * [92/11/30 af]
42 *
43 * Revision 2.14 92/03/05 17:08:25 rpd
44 * Moved scale & thresholding code up in screen.c
45 * This rids of all but one use of the user_info_t.
46 * [92/03/05 af]
47 *
48 * Revision 2.13 92/02/25 14:18:54 elf
49 * Delay modifications from af.
50 * [92/02/24 danner]
51 *
52 * Revision 2.12 92/02/19 16:46:03 elf
53 * Removed kmin hack.
54 * [92/02/10 17:16:53 af]
55 *
56 * Revision 2.11 91/08/24 11:52:32 af
57 * The hack for 3mins was screwing up everyone else.
58 * [91/08/02 af]
59 * Spl for 3min, more uniformity, temporary hack for bug
60 * still at large on 3min, generic console linkage.
61 * [91/08/02 02:33:05 af]
62 *
63 * Revision 2.10 91/06/25 20:54:24 rpd
64 * Tweaks to make gcc happy.
65 * [91/06/25 rpd]
66 *
67 * Revision 2.9 91/06/19 11:54:02 rvb
68 * File moved here from mips/PMAX since it tries to be generic;
69 * it is used on the PMAX and the Vax3100.
70 * [91/06/04 rvb]
71 *
72 * Revision 2.8 91/05/14 17:25:06 mrt
73 * Correcting copyright
74 *
75 * Revision 2.7 91/05/13 06:04:09 af
76 * Generate escape sequences for mouse cursor motion, same as
77 * xterm. Needs some more trim work.
78 * [91/05/12 16:08:19 af]
79 *
80 * Revision 2.6 91/02/14 14:35:02 mrt
81 * Sanity check so that we will never loose synch if the serial line
82 * drops characters.
83 * [91/02/12 12:57:21 af]
84 *
85 * Mouse events are now accounted for by the screenm saver.
86 * [91/01/04 15:35:30 af]
87 *
88 * Revision 2.5 91/02/05 17:43:01 mrt
89 * Added author notices
90 * [91/02/04 11:15:43 mrt]
91 *
92 * Changed to use new Mach copyright
93 * [91/02/02 12:14:27 mrt]
94 *
95 * Revision 2.4 91/01/08 15:48:04 rpd
96 * Mouse events are now accounted for by the screen saver.
97 * [91/01/04 15:35:30 af]
98 *
99 * Revision 2.3 90/12/05 23:33:11 af
100 *
101 *
102 * Revision 2.1.1.1 90/11/01 03:45:03 af
103 * Created, from the DEC specs:
104 * "VCB02 Video Subsystem Technical Manual"
105 * DEC Educational Services, AZ-GLGAB-MN, February 1986
106 * [90/09/03 af]
107 */
108 /*
109 * File: mouse.c
110 * Author: Alessandro Forin, Carnegie Mellon University
111 * Date: 9/90
112 *
113 * Driver code for Digital's mouse AND tablet
114 */
115
116 /*
117 * XXX This should be rewritten to support other
118 * XXX sorts of mices and tablets. But for now
119 * XXX I have none to play with. Sorry about that.
120 */
121
122 #include <lk.h> /* one mouse per lk201 */
123 #if NLK > 0
124
125 #include <mach/std_types.h>
126 #include <machine/machspl.h> /* spl definitions */
127 #include <sys/time.h>
128 #include <kern/time_out.h>
129
130 #include <chips/serial_defs.h>
131 #include <chips/screen_defs.h>
132
133 #define MOUSE_INCREMENTAL 0x52 /* R */
134 #define MOUSE_PROMPTED 0x44 /* D */
135 #define MOUSE_REQ_POSITION 0x50 /* P */
136 #define MOUSE_SELFTEST 0x54 /* T */
137 #define MOUSE_RESERVED_FUNC 0x5a /* Z, param byte follows */
138
139 #define TABLET_SAMPLE_55 0x4b /* K */ /* in reps/sec */
140 #define TABLET_SAMPLE_72 0x4c /* L */
141 #define TABLET_SAMPLE_120 0x4d /* M */
142 #define TABLET_9600 0x42 /* B */
143
144 #define TYPE_MOUSE 0x2
145 #define TYPE_TABLET 0x4
146
147 #define START_REPORT 0x80
148
149 typedef union {
150 struct {
151 unsigned char r : 1, m : 1, l : 1, sy : 1, sx : 1;
152 unsigned char xpos;
153 unsigned char ypos;
154 } ms;
155 struct {
156 unsigned char pr : 1, buttons : 4;
157 unsigned char xlo, xhi;
158 unsigned char ylo, yhi;
159 } tb;
160 unsigned char raw[1];
161 } mouse_report_t;
162
163
164 /*
165 * Mouse state
166 */
167 struct mouse_softc {
168 user_info_t *up;
169 mouse_report_t report;
170 unsigned char rep_bytes;
171 unsigned char rep_ptr;
172 unsigned char prev_buttons;
173 unsigned char flags;
174 #define MS_TABLET 0x1
175 #define MS_MOVING 0x2
176 char screen_unit;
177 char sl_unit;
178 } mouse_softc_data[NLK];
179
180 typedef struct mouse_softc *mouse_softc_t;
181
182 mouse_softc_t mouse_softc[NLK];
183
184
185 mouse_notify_mapped(
186 int unit,
187 int screen_unit,
188 user_info_t *up)
189 {
190 mouse_softc_t ms = &mouse_softc_data[unit];
191
192 ms->up = up;
193 ms->screen_unit = screen_unit;
194 }
195
196 /*
197 * Autoconfiguration
198 */
199 mouse_probe(
200 int unit)
201 {
202 mouse_softc[unit] = &mouse_softc_data[unit];
203 }
204
205 mouse_attach(
206 int unit,
207 int sl_unit)
208 {
209 int messg[4];
210 spl_t s;
211 mouse_softc_t ms;
212
213 ms = mouse_softc[unit];
214 ms->sl_unit = sl_unit;
215
216 s = spltty();
217 (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_SELFTEST);
218 delay(1);
219 messg[0] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
220 messg[1] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
221 messg[2] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
222 messg[3] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE);
223
224 delay(100000); /* spec says less than 500 msecs */
225 (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_INCREMENTAL);
226 splx(s);
227
228 ms->rep_bytes = 3;/* mouse */
229 if (messg[2] | messg[3]) {
230 printf(" bad pointer [%x %x %x %x] ",
231 messg[0], messg[1], messg[2], messg[3]);
232 if (messg[2] >= 0x20) printf("fatal ");
233 if (messg[2] == 0x3e) printf("RAM/ROM");
234 if (messg[2] == 0x3d) printf("button(s) %x", messg[3] & 0x1f);
235 } else {
236 int rev = messg[0] & 0xf;
237 int loc = (messg[1] & 0xf0) >> 4;
238 int tag = (messg[1] & 0xf);
239 printf("( %s rev. %x.%x )",
240 (tag == TYPE_MOUSE) ? "mouse" : "tablet",
241 rev, loc);
242 if (tag == TYPE_TABLET) {
243 ms->flags = MS_TABLET;
244 ms->rep_bytes = 5;
245 }
246 }
247 }
248
249 /*
250 * Process a character from the mouse
251 */
252 mouse_input(
253 int unit,
254 register unsigned short data)
255 {
256 mouse_softc_t ms = mouse_softc[unit];
257 register char flg, but;
258
259 data &= 0xff;
260
261 /* sanity: might miss a byte sometimes */
262 if (data & START_REPORT)
263 ms->rep_ptr = 0;
264
265 /* add byte to report */
266 ms->report.raw[ms->rep_ptr++] = data;
267
268 /* does this mean the mouse is moving */
269 if (data && ((data & START_REPORT) == 0))
270 ms->flags |= MS_MOVING;
271
272 /* Report complete ? */
273 if (ms->rep_ptr != ms->rep_bytes)
274 return;
275 ms->rep_ptr = 0;
276
277 ssaver_bump(ms->screen_unit);
278
279 /* check for mouse moved */
280 flg = ms->flags;
281 if (flg & MS_MOVING) {
282 ms->flags = flg & ~MS_MOVING;
283 mouse_motion_event(ms, flg);
284 }
285
286 /* check for button pressed */
287 if (but = ms->prev_buttons ^ ms->report.raw[0]) {
288 mouse_button_event(ms, flg, but);
289 ms->prev_buttons = ms->report.raw[0];
290 }
291 }
292
293 /*
294 * The mouse/puck moved.
295 * Find how much and post an event
296 */
297 mouse_motion_event(
298 mouse_softc_t ms,
299 int flg)
300 {
301 register int x, y;
302
303 if (flg & MS_TABLET) {
304
305 flg = DEV_TABLET;
306
307 x = (ms->report.tb.xhi << 8) | ms->report.tb.xlo;
308 y = (ms->report.tb.yhi << 8) | ms->report.tb.ylo;
309
310 } else {
311
312 flg = DEV_MOUSE;
313
314 x = ms->report.ms.xpos;
315 if (!ms->report.ms.sx) /* ??? */
316 x = -x;
317
318 y = ms->report.ms.ypos;
319 if (ms->report.ms.sy)
320 y = -y;
321
322 }
323
324 screen_motion_event(ms->screen_unit, flg, x, y);
325 }
326
327 /*
328 * A mouse/puck button was pressed/released.
329 * Find which one and post an event
330 */
331 mouse_button_event(
332 mouse_softc_t ms,
333 int flg,
334 int bmask)
335 {
336 register unsigned int buttons, i;
337 int key, type;
338
339 buttons = ms->report.raw[0];
340 if (flg & MS_TABLET) {
341 /* check each one of the four buttons */
342 for (i = 0; i < 4; i += 1) {
343 if ((bmask & (2<<i)) == 0)
344 continue;/* did not change */
345 type = (buttons & (2<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP;
346 key = i;
347
348 screen_keypress_event( ms->screen_unit,
349 DEV_TABLET, key, type);
350 }
351 } else {
352 ms->up->mouse_buttons = buttons & 0x7;
353 /* check each one of the three buttons */
354 for (i = 0; i < 3; i += 1) {
355 if ((bmask & (1<<i)) == 0)
356 continue;/* did not change */
357 type = (buttons & (1<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP;
358
359 if (i & 1)
360 key = KEY_MIDDLE_BUTTON;
361 else if ((i & 2) == 0)
362 key = KEY_RIGHT_BUTTON;
363 else
364 key = KEY_LEFT_BUTTON;
365
366 screen_keypress_event( ms->screen_unit,
367 DEV_MOUSE, key, type);
368 }
369 }
370 }
371
372 /*
373 * Generate escape sequences for position reporting
374 * These are the same as xterm's.
375 * Prefix:
376 * ESC [ M button down
377 * ESC [ N button up
378 * Body:
379 * BUTTON COL ROW
380 * Button:
381 * 0 <-> left, 1 <-> middle, 2 <-> right
382 * All body values are offset by the ascii SPACE character
383 */
384 #define ESC '\033'
385 #define SPACE ' '
386
387 mouse_report_position(
388 int unit,
389 int col,
390 int row,
391 int key,
392 int type)
393 {
394 cons_input(SCREEN_LINE_KEYBOARD, ESC, 0);
395 cons_input(SCREEN_LINE_KEYBOARD, '[', 0);
396 cons_input(SCREEN_LINE_KEYBOARD, (type==EVT_BUTTON_DOWN) ? 'M':'N', 0);
397
398 cons_input(SCREEN_LINE_KEYBOARD, (key - 1) + SPACE, 0);/* quick remapping */
399 cons_input(SCREEN_LINE_KEYBOARD, SPACE + col + 2, 0);
400 cons_input(SCREEN_LINE_KEYBOARD, SPACE + row + 1, 0);
401 }
402
403 #endif NLK > 0
Cache object: f78ff0714bf5e8da32b29dcd8ace8c79
|