|
|
1.1.1.3 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.3 root 5: *
1.1 root 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.
1.1.1.3 root 11: *
1.1 root 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.
1.1.1.3 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.3 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.3 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /* **********************************************************************
27: File: kd_mouse.c
28: Description: mouse driver as part of keyboard/display driver
29:
30: $ Header: $
31:
32: Copyright Ing. C. Olivetti & C. S.p.A. 1989.
33: All rights reserved.
34: ********************************************************************** */
35: /*
36: Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
37: Cupertino, California.
38:
39: All Rights Reserved
40:
41: Permission to use, copy, modify, and distribute this software and
42: its documentation for any purpose and without fee is hereby
43: granted, provided that the above copyright notice appears in all
44: copies and that both the copyright notice and this permission notice
45: appear in supporting documentation, and that the name of Olivetti
46: not be used in advertising or publicity pertaining to distribution
47: of the software without specific, written prior permission.
48:
49: OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
50: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
51: IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
52: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
53: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
54: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
55: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
56: */
57:
58: /*
59: * Hacked up support for serial mouse connected to COM1, using Mouse
60: * Systems 5-byte protocol at 1200 baud. This should work for
61: * Mouse Systems, SummaMouse, and Logitek C7 mice.
62: *
63: * The interface provided by /dev/mouse is a series of events as
64: * described in i386at/kd.h.
65: */
66:
67: #include <mach/boolean.h>
68: #include <sys/types.h>
1.1.1.4 root 69: #include <kern/printf.h>
70: #include <device/ds_routines.h>
71: #include <device/device_types.h>
1.1 root 72: #include <device/io_req.h>
1.1.1.4 root 73: #include <device/subrs.h>
1.1 root 74: #include <i386/ipl.h>
1.1.1.4 root 75: #include <i386/pic.h>
76: #include <i386/pio.h>
1.1 root 77: #include <chips/busses.h>
1.1.1.4 root 78: #include <i386at/com.h>
1.1 root 79: #include <i386at/kd.h>
80: #include <i386at/kd_queue.h>
81: #include <i386at/i8250.h>
82:
1.1.1.4 root 83: #include "kd_mouse.h"
84:
85: static void (*oldvect)(); /* old interrupt vector */
1.1 root 86: static int oldunit;
87: static spl_t oldspl;
88: extern struct bus_device *cominfo[];
89:
90: kd_event_queue mouse_queue; /* queue of mouse events */
91: boolean_t mouse_in_use = FALSE;
92: queue_head_t mouse_read_queue = { &mouse_read_queue, &mouse_read_queue };
1.1.1.4 root 93:
1.1 root 94:
95: /*
96: * The state of the 3 buttons is encoded in the low-order 3 bits (both
97: * here and in other variables in the driver).
98: */
99: u_char lastbuttons; /* previous state of mouse buttons */
100: #define MOUSE_UP 1
101: #define MOUSE_DOWN 0
102: #define MOUSE_ALL_UP 0x7
103:
104: int mouse_baud = BCNT1200;
105:
106: boolean_t mouse_char_cmd = FALSE; /* mouse response is to cmd */
107: boolean_t mouse_char_wanted = FALSE; /* want mouse response */
1.1.1.4 root 108: int mouse_char_index; /* mouse response */
1.1 root 109:
110:
111: /*
112: * init_mouse_hw - initialize the serial port.
113: */
1.1.1.4 root 114: void
1.1.1.5 ! root 115: init_mouse_hw(dev_t unit, int mode)
1.1 root 116: {
1.1.1.4 root 117: unsigned short base_addr = cominfo[unit]->address;
1.1 root 118:
119: outb(base_addr + RIE, 0);
120: outb(base_addr + RLC, LCDLAB);
121: outb(base_addr + RDLSB, mouse_baud & 0xff);
122: outb(base_addr + RDMSB, (mouse_baud >> 8) & 0xff);
123: outb(base_addr + RLC, mode);
124: outb(base_addr + RMC, MCDTR | MCRTS | MCOUT2);
125: outb(base_addr + RIE, IERD | IELS);
126: }
127:
128:
129: /*
130: * mouseopen - Verify that the request is read-only, initialize,
131: * and remember process group leader.
132: */
133: /*
134: * Low 3 bits of minor are the com port #.
135: * The high 5 bits of minor are the mouse type
136: */
137: #define MOUSE_SYSTEM_MOUSE 0
138: #define MICROSOFT_MOUSE 1
139: #define IBM_MOUSE 2
140: #define NO_MOUSE 3
141: #define LOGITECH_TRACKMAN 4
142: #define MICROSOFT_MOUSE7 5
143: static int mouse_type;
144: static int mousebufsize;
145: static int mousebufindex = 0;
146: int track_man[10];
147:
148: /*ARGSUSED*/
1.1.1.4 root 149: int
1.1.1.5 ! root 150: mouseopen(dev, flags, ior)
1.1 root 151: dev_t dev;
152: int flags;
1.1.1.5 ! root 153: io_req_t ior;
1.1 root 154: {
155: if (mouse_in_use)
1.1.1.4 root 156: return (D_ALREADY_OPEN);
1.1 root 157: mouse_in_use = TRUE; /* locking? */
158: kdq_reset(&mouse_queue);
159: lastbuttons = MOUSE_ALL_UP;
160:
161: switch (mouse_type = ((minor(dev) & 0xf8) >> 3)) {
162: case MICROSOFT_MOUSE7:
163: mousebufsize = 3;
164: serial_mouse_open(dev);
165: init_mouse_hw(dev&7, LC7);
1.1.1.5 ! root 166: break;
1.1 root 167: case MICROSOFT_MOUSE:
168: mousebufsize = 3;
169: serial_mouse_open(dev);
170: init_mouse_hw(dev&7, LC8);
171: break;
172: case MOUSE_SYSTEM_MOUSE:
173: mousebufsize = 5;
174: serial_mouse_open(dev);
175: init_mouse_hw(dev&7, LC8);
176: break;
177: case LOGITECH_TRACKMAN:
178: mousebufsize = 3;
179: serial_mouse_open(dev);
180: init_mouse_hw(dev&7, LC7);
181: track_man[0] = comgetc(dev&7);
182: track_man[1] = comgetc(dev&7);
1.1.1.3 root 183: if (track_man[0] != 0x4d &&
1.1 root 184: track_man[1] != 0x33) {
185: printf("LOGITECH_TRACKMAN: NOT M3");
186: }
187: break;
188: case IBM_MOUSE:
189: mousebufsize = 3;
190: kd_mouse_open(dev, 12);
191: ibm_ps2_mouse_open(dev);
192: break;
193: case NO_MOUSE:
194: break;
195: }
196: mousebufindex = 0;
197: return(0);
198: }
199:
1.1.1.4 root 200: void
1.1.1.5 ! root 201: serial_mouse_open(dev_t dev)
1.1 root 202: {
203: int unit = minor(dev) & 0x7;
204: int mouse_pic = cominfo[unit]->sysdep1;
205:
206: spl_t s = splhi(); /* disable interrupts */
207:
208: oldvect = ivect[mouse_pic];
209: ivect[mouse_pic] = mouseintr;
210:
211: oldunit = iunit[mouse_pic];
212: iunit[mouse_pic] = unit;
213:
214: /* XXX other arrays to init? */
215: splx(s); /* XXX - should come after init? */
216: }
217:
218: int mouse_packets = 0;
1.1.1.4 root 219:
220: void
1.1.1.5 ! root 221: kd_mouse_open(
! 222: dev_t dev,
! 223: int mouse_pic)
1.1 root 224: {
225: spl_t s = splhi(); /* disable interrupts */
226:
227: oldvect = ivect[mouse_pic];
228: ivect[mouse_pic] = kdintr;
229: oldspl = intpri[mouse_pic];
230: intpri[mouse_pic] = SPL6;
231: form_pic_mask();
232: splx(s);
233: }
234:
235: /*
1.1.1.3 root 236: * mouseclose - Disable interrupts on the serial port, reset driver flags,
1.1 root 237: * and restore the serial port interrupt vector.
238: */
1.1.1.4 root 239: void
1.1.1.5 ! root 240: mouseclose(
! 241: dev_t dev,
! 242: int flags)
1.1 root 243: {
244: switch (mouse_type) {
245: case MICROSOFT_MOUSE:
246: case MICROSOFT_MOUSE7:
247: case MOUSE_SYSTEM_MOUSE:
248: case LOGITECH_TRACKMAN:
1.1.1.4 root 249: serial_mouse_close(dev, flags);
1.1 root 250: break;
251: case IBM_MOUSE:
252: ibm_ps2_mouse_close(dev);
253: kd_mouse_close(dev, 12);
254: {int i = 20000; for (;i--;); }
255: kd_mouse_drain();
256: break;
257: case NO_MOUSE:
258: break;
259: }
260:
261: kdq_reset(&mouse_queue); /* paranoia */
262: mouse_in_use = FALSE;
263: }
264:
265: /*ARGSUSED*/
1.1.1.4 root 266: void
1.1.1.5 ! root 267: serial_mouse_close(
! 268: dev_t dev,
! 269: int flags)
1.1 root 270: {
271: spl_t o_pri = splhi(); /* mutex with open() */
272: int unit = minor(dev) & 0x7;
273: int mouse_pic = cominfo[unit]->sysdep1;
1.1.1.4 root 274: unsigned short base_addr = cominfo[unit]->address;
1.1 root 275:
276: assert(ivect[mouse_pic] == mouseintr);
277: outb(base_addr + RIE, 0); /* disable serial port */
278: outb(base_addr + RMC, 0); /* no rts */
279: ivect[mouse_pic] = oldvect;
280: iunit[mouse_pic] = oldunit;
281:
282: (void)splx(o_pri);
283: }
284:
1.1.1.4 root 285: void
1.1.1.5 ! root 286: kd_mouse_close(
! 287: dev_t dev,
! 288: int mouse_pic)
1.1 root 289: {
290: spl_t s = splhi();
291:
292: ivect[mouse_pic] = oldvect;
293: intpri[mouse_pic] = oldspl;
294: form_pic_mask();
295: splx(s);
296: }
297:
1.1.1.5 ! root 298: io_return_t mousegetstat(
! 299: dev_t dev,
! 300: int flavor,
! 301: int * data, /* pointer to OUT array */
! 302: unsigned int *count) /* OUT */
1.1.1.2 root 303: {
304: switch (flavor) {
305: case DEV_GET_SIZE:
306: data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
307: data[DEV_GET_SIZE_RECORD_SIZE] = sizeof(kd_event);
308: *count = DEV_GET_SIZE_COUNT;
309: break;
310: default:
311: return D_INVALID_OPERATION;
312: }
313: return D_SUCCESS;
314: }
315:
1.1 root 316:
317: /*
318: * mouseread - dequeue and return any queued events.
319: */
1.1.1.4 root 320: int
1.1.1.5 ! root 321: mouseread(
! 322: dev_t dev,
! 323: io_req_t ior)
1.1 root 324: {
1.1.1.5 ! root 325: int err, count;
! 326: spl_t s;
1.1 root 327:
1.1.1.2 root 328: /* Check if IO_COUNT is a multiple of the record size. */
329: if (ior->io_count % sizeof(kd_event) != 0)
330: return D_INVALID_SIZE;
331:
1.1 root 332: err = device_read_alloc(ior, (vm_size_t)ior->io_count);
333: if (err != KERN_SUCCESS)
334: return (err);
335:
336: s = SPLKD();
337: if (kdq_empty(&mouse_queue)) {
338: if (ior->io_mode & D_NOWAIT) {
339: splx(s);
340: return (D_WOULD_BLOCK);
341: }
342: ior->io_done = mouse_read_done;
343: enqueue_tail(&mouse_read_queue, (queue_entry_t)ior);
344: splx(s);
345: return (D_IO_QUEUED);
346: }
347: count = 0;
348: while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
1.1.1.5 ! root 349: kd_event *ev;
1.1 root 350:
351: ev = kdq_get(&mouse_queue);
352: *(kd_event *)(&ior->io_data[count]) = *ev;
353: count += sizeof(kd_event);
354: }
355: splx(s);
356: ior->io_residual = ior->io_count - count;
357: return (D_SUCCESS);
358: }
359:
1.1.1.5 ! root 360: boolean_t mouse_read_done(io_req_t ior)
1.1 root 361: {
1.1.1.5 ! root 362: int count;
! 363: spl_t s;
1.1 root 364:
365: s = SPLKD();
366: if (kdq_empty(&mouse_queue)) {
367: ior->io_done = mouse_read_done;
368: enqueue_tail(&mouse_read_queue, (queue_entry_t)ior);
369: splx(s);
370: return (FALSE);
371: }
372:
373: count = 0;
374: while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
1.1.1.5 ! root 375: kd_event *ev;
1.1 root 376:
377: ev = kdq_get(&mouse_queue);
378: *(kd_event *)(&ior->io_data[count]) = *ev;
379: count += sizeof(kd_event);
380: }
381: splx(s);
382:
383: ior->io_residual = ior->io_count - count;
384: ds_read_done(ior);
385:
386: return (TRUE);
387: }
388:
389:
390:
391: /*
392: * mouseintr - Get a byte and pass it up for handling. Called at SPLKD.
393: */
1.1.1.4 root 394: void
1.1.1.5 ! root 395: mouseintr(int unit)
1.1 root 396: {
1.1.1.4 root 397: unsigned short base_addr = cominfo[unit]->address;
1.1 root 398: unsigned char id, ls;
399:
400: /* get reason for interrupt and line status */
401: id = inb(base_addr + RID);
402: ls = inb(base_addr + RLS);
403:
404: /* handle status changes */
405: if (id == IDLS) {
406: if (ls & LSDR) {
407: inb(base_addr + RDAT); /* flush bad character */
408: }
409: return; /* ignore status change */
410: }
411:
412: if (id & IDRD) {
413: mouse_handle_byte((u_char)(inb(base_addr + RDAT) & 0xff));
414: }
415: }
416:
417:
418: /*
419: * handle_byte - Accumulate bytes until we have an entire packet.
420: * If the mouse has moved or any of the buttons have changed state (up
421: * or down), enqueue the corresponding events.
422: * Called at SPLKD.
423: * XXX - magic numbers.
424: */
425: int show_mouse_byte = 0;
426: /*
1.1.1.3 root 427: X down; middle down; middle up; X up 50 0 0; 50 0 0 22; 50 0 0 02; 40 0 0
1.1 root 428: X down; middle down; X up; middle up 50 0 0; 50 0 0 22; 40 0 0 22; 40 0 0 2
429: *
430: * The trick here is that all the while the middle button is down you get 4 byte
431: * packets with the last byte 0x22. When the middle button goes up you get a
432: * last packet with 0x02.
433: */
434: int lastgitech = 0x40; /* figure whether the first 3 bytes imply */
435: /* its time to expect a fourth */
436: int fourthgitech = 0; /* look for the 4th byte; we must process it */
437: int middlegitech = 0; /* what should the middle button be */
438:
439: #define MOUSEBUFSIZE 5 /* num bytes def'd by protocol */
440: static u_char mousebuf[MOUSEBUFSIZE]; /* 5-byte packet from mouse */
441:
1.1.1.4 root 442: void
1.1.1.5 ! root 443: mouse_handle_byte(u_char ch)
1.1 root 444: {
445: if (show_mouse_byte) {
446: printf("%x(%c) ", ch, ch);
447: }
448:
449: if (mouse_char_cmd) {
450: /*
451: * Mouse character is response to command
452: */
1.1.1.4 root 453: if (mousebufindex < mousebufsize)
454: mousebuf[mousebufindex++] = ch;
1.1 root 455: if (mouse_char_wanted) {
456: mouse_char_wanted = FALSE;
1.1.1.4 root 457: wakeup((vm_offset_t)&mousebuf);
1.1 root 458: }
459: return;
460: }
461:
462: if (mousebufindex == 0) {
463: switch (mouse_type) {
464: case MICROSOFT_MOUSE7:
465: if ((ch & 0x40) != 0x40)
466: return;
467: break;
468: case MICROSOFT_MOUSE:
469: if ((ch & 0xc0) != 0xc0)
470: return;
471: break;
472: case MOUSE_SYSTEM_MOUSE:
473: if ((ch & 0xf8) != 0x80)
474: return;
475: break;
476: case LOGITECH_TRACKMAN:
477: if (fourthgitech == 1) {
478: fourthgitech = 0;
479: if (ch & 0xf0)
480: middlegitech = 0x4;
481: else
482: middlegitech = 0x0;
483: mouse_packet_microsoft_mouse(mousebuf);
484: return;
485: } else if ((ch & 0xc0) != 0x40)
486: return;
487: break;
488: case IBM_MOUSE:
489: break;
490: }
491: }
492:
493: mousebuf[mousebufindex++] = ch;
494: if (mousebufindex < mousebufsize)
495: return;
1.1.1.3 root 496:
1.1 root 497: /* got a packet */
498: mousebufindex = 0;
499:
500: switch (mouse_type) {
501: case MICROSOFT_MOUSE7:
502: case MICROSOFT_MOUSE:
503: mouse_packet_microsoft_mouse(mousebuf);
504: break;
505: case MOUSE_SYSTEM_MOUSE:
506: mouse_packet_mouse_system_mouse(mousebuf);
507: break;
508: case LOGITECH_TRACKMAN:
509: if ( mousebuf[1] || mousebuf[2] ||
510: mousebuf[0] != lastgitech) {
511: mouse_packet_microsoft_mouse(mousebuf);
512: lastgitech = mousebuf[0] & 0xf0;
513: } else {
514: fourthgitech = 1;
515: }
516: break;
517: case IBM_MOUSE:
518: mouse_packet_ibm_ps2_mouse(mousebuf);
519: break;
520: }
521: }
522:
1.1.1.4 root 523: void
1.1.1.5 ! root 524: mouse_packet_mouse_system_mouse(u_char mousebuf[MOUSEBUFSIZE])
1.1 root 525: {
526: u_char buttons, buttonchanges;
527: struct mouse_motion moved;
528:
529: buttons = mousebuf[0] & 0x7; /* get current state of buttons */
530: buttonchanges = buttons ^ lastbuttons;
531: moved.mm_deltaX = (char)mousebuf[1] + (char)mousebuf[3];
532: moved.mm_deltaY = (char)mousebuf[2] + (char)mousebuf[4];
533:
534: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
535: mouse_moved(moved);
536:
537: if (buttonchanges != 0) {
538: lastbuttons = buttons;
539: if (buttonchanges & 1)
540: mouse_button(MOUSE_RIGHT, buttons & 1);
541: if (buttonchanges & 2)
542: mouse_button(MOUSE_MIDDLE, (buttons & 2) >> 1);
543: if (buttonchanges & 4)
544: mouse_button(MOUSE_LEFT, (buttons & 4) >> 2);
545: }
546: }
547:
548: /* same as above for microsoft mouse */
549: /*
550: * 3 byte microsoft format used
551: *
552: * 7 6 5 4 3 2 1 0
553: * 1 1 L R Y7 Y6 X7 X6
554: * 1 0 X5 X4 X3 X3 X1 X0
555: * 1 0 Y5 Y4 Y3 Y2 Y1 Y0
556: *
557: */
1.1.1.4 root 558: void
1.1.1.5 ! root 559: mouse_packet_microsoft_mouse(u_char mousebuf[MOUSEBUFSIZE])
1.1 root 560: {
561: u_char buttons, buttonchanges;
562: struct mouse_motion moved;
563:
564: buttons = ((mousebuf[0] & 0x30) >> 4);
565: buttons |= middlegitech;
566: /* get current state of buttons */
567: #ifdef gross_hack
568: if (buttons == 0x03) /* both buttons down */
569: buttons = 0x04;
570: #endif /* gross_hack */
571: buttons = (~buttons) & 0x07; /* convert to not pressed */
572:
573: buttonchanges = buttons ^ lastbuttons;
574: moved.mm_deltaX = ((mousebuf[0] & 0x03) << 6) | (mousebuf[1] & 0x3F);
575: moved.mm_deltaY = ((mousebuf[0] & 0x0c) << 4) | (mousebuf[2] & 0x3F);
576: if (moved.mm_deltaX & 0x80) /* negative, in fact */
577: moved.mm_deltaX = moved.mm_deltaX - 0x100;
578: if (moved.mm_deltaY & 0x80) /* negative, in fact */
579: moved.mm_deltaY = moved.mm_deltaY - 0x100;
580: /* and finally the Y orientation is different for the microsoft mouse */
581: moved.mm_deltaY = -moved.mm_deltaY;
582:
583: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
584: mouse_moved(moved);
585:
586: if (buttonchanges != 0) {
587: lastbuttons = buttons;
588: if (buttonchanges & 1)
589: mouse_button(MOUSE_RIGHT, (buttons & 1) ?
590: MOUSE_UP : MOUSE_DOWN);
591: if (buttonchanges & 2)
592: mouse_button(MOUSE_LEFT, (buttons & 2) ?
593: MOUSE_UP : MOUSE_DOWN);
594: if (buttonchanges & 4)
595: mouse_button(MOUSE_MIDDLE, (buttons & 4) ?
596: MOUSE_UP : MOUSE_DOWN);
597: }
598: }
599:
600: /*
601: * AUX device (PS2) open/close
602: */
603:
604: /*
605: * Write character to mouse. Called at spltty.
606: */
607: void kd_mouse_write(
608: unsigned char ch)
609: {
610: while (inb(K_STATUS) & K_IBUF_FUL)
611: continue; /* wait for 'input' port empty */
612: outb(K_CMD, 0xd4); /* send next character to mouse */
613:
614: while (inb(K_STATUS) & K_IBUF_FUL)
615: continue; /* wait for 'input' port empty */
616: outb(K_RDWR, ch); /* send command to mouse */
617: }
618:
619: /*
620: * Read next character from mouse, waiting for interrupt
621: * to deliver it. Called at spltty.
622: */
623: int kd_mouse_read(void)
624: {
625: int ch;
626:
1.1.1.4 root 627: if (mouse_char_index >= mousebufsize)
628: return -1;
629:
630: while (mousebufindex <= mouse_char_index) {
1.1 root 631: mouse_char_wanted = TRUE;
1.1.1.4 root 632: assert_wait((event_t) &mousebuf, FALSE);
1.1 root 633: thread_block((void (*)()) 0);
634: }
635:
1.1.1.4 root 636: ch = mousebuf[mouse_char_index++];
1.1 root 637:
638: return ch;
639: }
640:
1.1.1.4 root 641: /*
642: * Prepare buffer for receiving next packet from mouse.
643: */
644: void kd_mouse_read_reset(void)
645: {
646: mousebufindex = 0;
647: mouse_char_index = 0;
648: }
649:
650: void
1.1.1.5 ! root 651: ibm_ps2_mouse_open(dev_t dev)
1.1 root 652: {
653: spl_t s = spltty();
654:
655: lastbuttons = 0;
656: mouse_char_cmd = TRUE; /* responses are to commands */
657:
658: kd_sendcmd(0xa8); /* enable mouse in kbd */
659:
660: kd_cmdreg_write(0x47); /* allow mouse interrupts */
661: /* magic number for ibm? */
662:
1.1.1.4 root 663: kd_mouse_read_reset();
1.1 root 664: kd_mouse_write(0xff); /* reset mouse */
665: if (kd_mouse_read() != 0xfa) {
666: splx(s);
667: return; /* need ACK */
668: }
669:
670: (void) kd_mouse_read(); /* discard 2-character mouse ID */
671: (void) kd_mouse_read();
672:
1.1.1.4 root 673: kd_mouse_read_reset();
1.1 root 674: kd_mouse_write(0xea); /* set stream mode */
675: if (kd_mouse_read() != 0xfa) {
676: splx(s);
677: return; /* need ACK */
678: }
679:
1.1.1.4 root 680: kd_mouse_read_reset();
1.1 root 681: kd_mouse_write(0xf4); /* enable */
682: if (kd_mouse_read() != 0xfa) {
683: splx(s);
684: return; /* need ACK */
685: }
686:
1.1.1.4 root 687: kd_mouse_read_reset();
1.1 root 688: mouse_char_cmd = FALSE; /* now we get mouse packets */
689:
690: splx(s);
691: }
692:
1.1.1.4 root 693: void
1.1.1.5 ! root 694: ibm_ps2_mouse_close(dev_t dev)
1.1 root 695: {
696: spl_t s = spltty();
697:
698: mouse_char_cmd = TRUE; /* responses are to commands */
699:
1.1.1.4 root 700: kd_mouse_read_reset();
1.1 root 701: kd_mouse_write(0xff); /* reset mouse */
702: if (kd_mouse_read() == 0xfa) {
703: /* got ACK: discard 2-char mouse ID */
704: (void) kd_mouse_read();
705: (void) kd_mouse_read();
706: }
707:
708: kd_sendcmd(0xa7); /* disable mouse in kbd */
709: kd_cmdreg_write(0x65); /* disallow mouse interrupts */
710: /* magic number for ibm? */
711:
712: splx(s);
713: }
714:
715: /*
716: * 3 byte ibm ps2 format used
717: *
718: * 7 6 5 4 3 2 1 0
719: * YO XO YS XS 1 M R L
720: * X7 X6 X5 X4 X3 X3 X1 X0
721: * Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
722: *
723: */
1.1.1.4 root 724: void
1.1.1.5 ! root 725: mouse_packet_ibm_ps2_mouse(u_char mousebuf[MOUSEBUFSIZE])
1.1 root 726: {
727: u_char buttons, buttonchanges;
728: struct mouse_motion moved;
729:
730: buttons = mousebuf[0] & 0x7; /* get current state of buttons */
731: buttonchanges = buttons ^ lastbuttons;
732: moved.mm_deltaX = ((mousebuf[0]&0x10) ? 0xffffff00 : 0 ) | (u_char)mousebuf[1];
733: moved.mm_deltaY = ((mousebuf[0]&0x20) ? 0xffffff00 : 0 ) | (u_char)mousebuf[2];
734: if (mouse_packets) {
735: printf("(%x:%x:%x)", mousebuf[0], mousebuf[1], mousebuf[2]);
736: return;
737: }
738:
739: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
740: mouse_moved(moved);
741:
742: if (buttonchanges != 0) {
743: lastbuttons = buttons;
744: if (buttonchanges & 1)
745: mouse_button(MOUSE_LEFT, !(buttons & 1));
746: if (buttonchanges & 2)
747: mouse_button(MOUSE_RIGHT, !((buttons & 2) >> 1));
748: if (buttonchanges & 4)
749: mouse_button(MOUSE_MIDDLE, !((buttons & 4) >> 2));
750: }
751: }
752:
753: /*
754: * Enqueue a mouse-motion event. Called at SPLKD.
755: */
1.1.1.4 root 756: void
1.1.1.5 ! root 757: mouse_moved(struct mouse_motion where)
1.1 root 758: {
759: kd_event ev;
760:
761: ev.type = MOUSE_MOTION;
762: ev.time = time;
763: ev.value.mmotion = where;
764: mouse_enqueue(&ev);
765: }
766:
767: /*
768: * Enqueue an event for mouse button press or release. Called at SPLKD.
769: */
1.1.1.4 root 770: void
1.1.1.5 ! root 771: mouse_button(
! 772: kev_type which,
! 773: u_char direction)
1.1 root 774: {
775: kd_event ev;
776:
777: ev.type = which;
778: ev.time = time;
779: ev.value.up = (direction == MOUSE_UP) ? TRUE : FALSE;
780: mouse_enqueue(&ev);
781: }
782:
783: /*
784: * mouse_enqueue - enqueue an event and wake up selecting processes, if
785: * any. Called at SPLKD.
786: */
787:
788: void
1.1.1.5 ! root 789: mouse_enqueue(kd_event *ev)
1.1 root 790: {
791: if (kdq_full(&mouse_queue))
1.1.1.5 ! root 792: printf_once("mouse: queue full\n");
1.1 root 793: else
794: kdq_put(&mouse_queue, ev);
795:
796: {
1.1.1.5 ! root 797: io_req_t ior;
1.1 root 798: while ((ior = (io_req_t)dequeue_head(&mouse_read_queue)) != 0)
799: iodone(ior);
800: }
801: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.