|
|
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:
1.1.1.4 ! root 104: void mouseintr();
1.1 root 105: void mouse_enqueue();
106: int mouse_baud = BCNT1200;
107:
108: boolean_t mouse_char_cmd = FALSE; /* mouse response is to cmd */
109: boolean_t mouse_char_wanted = FALSE; /* want mouse response */
1.1.1.4 ! root 110: int mouse_char_index; /* mouse response */
1.1 root 111:
112:
113: /*
114: * init_mouse_hw - initialize the serial port.
115: */
1.1.1.4 ! root 116: void
1.1 root 117: init_mouse_hw(unit, mode)
118: {
1.1.1.4 ! root 119: unsigned short base_addr = cominfo[unit]->address;
1.1 root 120:
121: outb(base_addr + RIE, 0);
122: outb(base_addr + RLC, LCDLAB);
123: outb(base_addr + RDLSB, mouse_baud & 0xff);
124: outb(base_addr + RDMSB, (mouse_baud >> 8) & 0xff);
125: outb(base_addr + RLC, mode);
126: outb(base_addr + RMC, MCDTR | MCRTS | MCOUT2);
127: outb(base_addr + RIE, IERD | IELS);
128: }
129:
130:
131: /*
132: * mouseopen - Verify that the request is read-only, initialize,
133: * and remember process group leader.
134: */
135: /*
136: * Low 3 bits of minor are the com port #.
137: * The high 5 bits of minor are the mouse type
138: */
139: #define MOUSE_SYSTEM_MOUSE 0
140: #define MICROSOFT_MOUSE 1
141: #define IBM_MOUSE 2
142: #define NO_MOUSE 3
143: #define LOGITECH_TRACKMAN 4
144: #define MICROSOFT_MOUSE7 5
145: static int mouse_type;
146: static int mousebufsize;
147: static int mousebufindex = 0;
148: int track_man[10];
149:
150: /*ARGSUSED*/
1.1.1.4 ! root 151: int
1.1 root 152: mouseopen(dev, flags)
153: dev_t dev;
154: int flags;
155: {
156: if (mouse_in_use)
1.1.1.4 ! root 157: return (D_ALREADY_OPEN);
1.1 root 158: mouse_in_use = TRUE; /* locking? */
159: kdq_reset(&mouse_queue);
160: lastbuttons = MOUSE_ALL_UP;
161:
162: switch (mouse_type = ((minor(dev) & 0xf8) >> 3)) {
163: case MICROSOFT_MOUSE7:
164: mousebufsize = 3;
165: serial_mouse_open(dev);
166: init_mouse_hw(dev&7, LC7);
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 root 201: serial_mouse_open(dev)
1.1.1.4 ! root 202: dev_t dev;
1.1 root 203: {
204: int unit = minor(dev) & 0x7;
205: int mouse_pic = cominfo[unit]->sysdep1;
206:
207: spl_t s = splhi(); /* disable interrupts */
208:
209: oldvect = ivect[mouse_pic];
210: ivect[mouse_pic] = mouseintr;
211:
212: oldunit = iunit[mouse_pic];
213: iunit[mouse_pic] = unit;
214:
215: /* XXX other arrays to init? */
216: splx(s); /* XXX - should come after init? */
217: }
218:
219: int mouse_packets = 0;
1.1.1.4 ! root 220:
! 221: void
1.1 root 222: kd_mouse_open(dev, mouse_pic)
1.1.1.4 ! root 223: dev_t dev;
! 224: int mouse_pic;
1.1 root 225: {
226: spl_t s = splhi(); /* disable interrupts */
1.1.1.4 ! root 227: extern void kdintr();
1.1 root 228:
229: oldvect = ivect[mouse_pic];
230: ivect[mouse_pic] = kdintr;
231: oldspl = intpri[mouse_pic];
232: intpri[mouse_pic] = SPL6;
233: form_pic_mask();
234: splx(s);
235: }
236:
237: /*
1.1.1.3 root 238: * mouseclose - Disable interrupts on the serial port, reset driver flags,
1.1 root 239: * and restore the serial port interrupt vector.
240: */
1.1.1.4 ! root 241: void
1.1 root 242: mouseclose(dev, flags)
1.1.1.4 ! root 243: dev_t dev;
! 244: int flags;
1.1 root 245: {
246: switch (mouse_type) {
247: case MICROSOFT_MOUSE:
248: case MICROSOFT_MOUSE7:
249: case MOUSE_SYSTEM_MOUSE:
250: case LOGITECH_TRACKMAN:
1.1.1.4 ! root 251: serial_mouse_close(dev, flags);
1.1 root 252: break;
253: case IBM_MOUSE:
254: ibm_ps2_mouse_close(dev);
255: kd_mouse_close(dev, 12);
256: {int i = 20000; for (;i--;); }
257: kd_mouse_drain();
258: break;
259: case NO_MOUSE:
260: break;
261: }
262:
263: kdq_reset(&mouse_queue); /* paranoia */
264: mouse_in_use = FALSE;
265: }
266:
267: /*ARGSUSED*/
1.1.1.4 ! root 268: void
1.1 root 269: serial_mouse_close(dev, flags)
270: dev_t dev;
271: int flags;
272: {
273: spl_t o_pri = splhi(); /* mutex with open() */
274: int unit = minor(dev) & 0x7;
275: int mouse_pic = cominfo[unit]->sysdep1;
1.1.1.4 ! root 276: unsigned short base_addr = cominfo[unit]->address;
1.1 root 277:
278: assert(ivect[mouse_pic] == mouseintr);
279: outb(base_addr + RIE, 0); /* disable serial port */
280: outb(base_addr + RMC, 0); /* no rts */
281: ivect[mouse_pic] = oldvect;
282: iunit[mouse_pic] = oldunit;
283:
284: (void)splx(o_pri);
285: }
286:
1.1.1.4 ! root 287: void
1.1 root 288: kd_mouse_close(dev, mouse_pic)
1.1.1.4 ! root 289: dev_t dev;
! 290: int mouse_pic;
1.1 root 291: {
292: spl_t s = splhi();
293:
294: ivect[mouse_pic] = oldvect;
295: intpri[mouse_pic] = oldspl;
296: form_pic_mask();
297: splx(s);
298: }
299:
1.1.1.2 root 300: io_return_t mousegetstat(dev, flavor, data, count)
301: dev_t dev;
302: int flavor;
303: int * data; /* pointer to OUT array */
304: unsigned int *count; /* OUT */
305: {
306: switch (flavor) {
307: case DEV_GET_SIZE:
308: data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
309: data[DEV_GET_SIZE_RECORD_SIZE] = sizeof(kd_event);
310: *count = DEV_GET_SIZE_COUNT;
311: break;
312: default:
313: return D_INVALID_OPERATION;
314: }
315: return D_SUCCESS;
316: }
317:
1.1 root 318:
319: /*
320: * mouseread - dequeue and return any queued events.
321: */
322: boolean_t mouse_read_done(); /* forward */
323:
1.1.1.4 ! root 324: int
1.1 root 325: mouseread(dev, ior)
326: dev_t dev;
327: register io_req_t ior;
328: {
329: register int err, count;
330: register spl_t s;
331:
1.1.1.2 root 332: /* Check if IO_COUNT is a multiple of the record size. */
333: if (ior->io_count % sizeof(kd_event) != 0)
334: return D_INVALID_SIZE;
335:
1.1 root 336: err = device_read_alloc(ior, (vm_size_t)ior->io_count);
337: if (err != KERN_SUCCESS)
338: return (err);
339:
340: s = SPLKD();
341: if (kdq_empty(&mouse_queue)) {
342: if (ior->io_mode & D_NOWAIT) {
343: splx(s);
344: return (D_WOULD_BLOCK);
345: }
346: ior->io_done = mouse_read_done;
347: enqueue_tail(&mouse_read_queue, (queue_entry_t)ior);
348: splx(s);
349: return (D_IO_QUEUED);
350: }
351: count = 0;
352: while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
353: register kd_event *ev;
354:
355: ev = kdq_get(&mouse_queue);
356: *(kd_event *)(&ior->io_data[count]) = *ev;
357: count += sizeof(kd_event);
358: }
359: splx(s);
360: ior->io_residual = ior->io_count - count;
361: return (D_SUCCESS);
362: }
363:
364: boolean_t mouse_read_done(ior)
365: register io_req_t ior;
366: {
367: register int count;
368: register spl_t s;
369:
370: s = SPLKD();
371: if (kdq_empty(&mouse_queue)) {
372: ior->io_done = mouse_read_done;
373: enqueue_tail(&mouse_read_queue, (queue_entry_t)ior);
374: splx(s);
375: return (FALSE);
376: }
377:
378: count = 0;
379: while (!kdq_empty(&mouse_queue) && count < ior->io_count) {
380: register kd_event *ev;
381:
382: ev = kdq_get(&mouse_queue);
383: *(kd_event *)(&ior->io_data[count]) = *ev;
384: count += sizeof(kd_event);
385: }
386: splx(s);
387:
388: ior->io_residual = ior->io_count - count;
389: ds_read_done(ior);
390:
391: return (TRUE);
392: }
393:
394:
395:
396: /*
397: * mouseintr - Get a byte and pass it up for handling. Called at SPLKD.
398: */
1.1.1.4 ! root 399: void
1.1 root 400: mouseintr(unit)
401: {
1.1.1.4 ! root 402: unsigned short base_addr = cominfo[unit]->address;
1.1 root 403: unsigned char id, ls;
404:
405: /* get reason for interrupt and line status */
406: id = inb(base_addr + RID);
407: ls = inb(base_addr + RLS);
408:
409: /* handle status changes */
410: if (id == IDLS) {
411: if (ls & LSDR) {
412: inb(base_addr + RDAT); /* flush bad character */
413: }
414: return; /* ignore status change */
415: }
416:
417: if (id & IDRD) {
418: mouse_handle_byte((u_char)(inb(base_addr + RDAT) & 0xff));
419: }
420: }
421:
422:
423: /*
424: * handle_byte - Accumulate bytes until we have an entire packet.
425: * If the mouse has moved or any of the buttons have changed state (up
426: * or down), enqueue the corresponding events.
427: * Called at SPLKD.
428: * XXX - magic numbers.
429: */
430: int show_mouse_byte = 0;
431: /*
1.1.1.3 root 432: 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 433: X down; middle down; X up; middle up 50 0 0; 50 0 0 22; 40 0 0 22; 40 0 0 2
434: *
435: * The trick here is that all the while the middle button is down you get 4 byte
436: * packets with the last byte 0x22. When the middle button goes up you get a
437: * last packet with 0x02.
438: */
439: int lastgitech = 0x40; /* figure whether the first 3 bytes imply */
440: /* its time to expect a fourth */
441: int fourthgitech = 0; /* look for the 4th byte; we must process it */
442: int middlegitech = 0; /* what should the middle button be */
443:
444: #define MOUSEBUFSIZE 5 /* num bytes def'd by protocol */
445: static u_char mousebuf[MOUSEBUFSIZE]; /* 5-byte packet from mouse */
446:
1.1.1.4 ! root 447: void
1.1 root 448: mouse_handle_byte(ch)
449: u_char ch;
450: {
451: if (show_mouse_byte) {
452: printf("%x(%c) ", ch, ch);
453: }
454:
455: if (mouse_char_cmd) {
456: /*
457: * Mouse character is response to command
458: */
1.1.1.4 ! root 459: if (mousebufindex < mousebufsize)
! 460: mousebuf[mousebufindex++] = ch;
1.1 root 461: if (mouse_char_wanted) {
462: mouse_char_wanted = FALSE;
1.1.1.4 ! root 463: wakeup((vm_offset_t)&mousebuf);
1.1 root 464: }
465: return;
466: }
467:
468: if (mousebufindex == 0) {
469: switch (mouse_type) {
470: case MICROSOFT_MOUSE7:
471: if ((ch & 0x40) != 0x40)
472: return;
473: break;
474: case MICROSOFT_MOUSE:
475: if ((ch & 0xc0) != 0xc0)
476: return;
477: break;
478: case MOUSE_SYSTEM_MOUSE:
479: if ((ch & 0xf8) != 0x80)
480: return;
481: break;
482: case LOGITECH_TRACKMAN:
483: if (fourthgitech == 1) {
484: fourthgitech = 0;
485: if (ch & 0xf0)
486: middlegitech = 0x4;
487: else
488: middlegitech = 0x0;
489: mouse_packet_microsoft_mouse(mousebuf);
490: return;
491: } else if ((ch & 0xc0) != 0x40)
492: return;
493: break;
494: case IBM_MOUSE:
495: break;
496: }
497: }
498:
499: mousebuf[mousebufindex++] = ch;
500: if (mousebufindex < mousebufsize)
501: return;
1.1.1.3 root 502:
1.1 root 503: /* got a packet */
504: mousebufindex = 0;
505:
506: switch (mouse_type) {
507: case MICROSOFT_MOUSE7:
508: case MICROSOFT_MOUSE:
509: mouse_packet_microsoft_mouse(mousebuf);
510: break;
511: case MOUSE_SYSTEM_MOUSE:
512: mouse_packet_mouse_system_mouse(mousebuf);
513: break;
514: case LOGITECH_TRACKMAN:
515: if ( mousebuf[1] || mousebuf[2] ||
516: mousebuf[0] != lastgitech) {
517: mouse_packet_microsoft_mouse(mousebuf);
518: lastgitech = mousebuf[0] & 0xf0;
519: } else {
520: fourthgitech = 1;
521: }
522: break;
523: case IBM_MOUSE:
524: mouse_packet_ibm_ps2_mouse(mousebuf);
525: break;
526: }
527: }
528:
1.1.1.4 ! root 529: void
1.1 root 530: mouse_packet_mouse_system_mouse(mousebuf)
531: u_char mousebuf[MOUSEBUFSIZE];
532: {
533: u_char buttons, buttonchanges;
534: struct mouse_motion moved;
535:
536: buttons = mousebuf[0] & 0x7; /* get current state of buttons */
537: buttonchanges = buttons ^ lastbuttons;
538: moved.mm_deltaX = (char)mousebuf[1] + (char)mousebuf[3];
539: moved.mm_deltaY = (char)mousebuf[2] + (char)mousebuf[4];
540:
541: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
542: mouse_moved(moved);
543:
544: if (buttonchanges != 0) {
545: lastbuttons = buttons;
546: if (buttonchanges & 1)
547: mouse_button(MOUSE_RIGHT, buttons & 1);
548: if (buttonchanges & 2)
549: mouse_button(MOUSE_MIDDLE, (buttons & 2) >> 1);
550: if (buttonchanges & 4)
551: mouse_button(MOUSE_LEFT, (buttons & 4) >> 2);
552: }
553: }
554:
555: /* same as above for microsoft mouse */
556: /*
557: * 3 byte microsoft format used
558: *
559: * 7 6 5 4 3 2 1 0
560: * 1 1 L R Y7 Y6 X7 X6
561: * 1 0 X5 X4 X3 X3 X1 X0
562: * 1 0 Y5 Y4 Y3 Y2 Y1 Y0
563: *
564: */
1.1.1.4 ! root 565: void
1.1 root 566: mouse_packet_microsoft_mouse(mousebuf)
567: u_char mousebuf[MOUSEBUFSIZE];
568: {
569: u_char buttons, buttonchanges;
570: struct mouse_motion moved;
571:
572: buttons = ((mousebuf[0] & 0x30) >> 4);
573: buttons |= middlegitech;
574: /* get current state of buttons */
575: #ifdef gross_hack
576: if (buttons == 0x03) /* both buttons down */
577: buttons = 0x04;
578: #endif /* gross_hack */
579: buttons = (~buttons) & 0x07; /* convert to not pressed */
580:
581: buttonchanges = buttons ^ lastbuttons;
582: moved.mm_deltaX = ((mousebuf[0] & 0x03) << 6) | (mousebuf[1] & 0x3F);
583: moved.mm_deltaY = ((mousebuf[0] & 0x0c) << 4) | (mousebuf[2] & 0x3F);
584: if (moved.mm_deltaX & 0x80) /* negative, in fact */
585: moved.mm_deltaX = moved.mm_deltaX - 0x100;
586: if (moved.mm_deltaY & 0x80) /* negative, in fact */
587: moved.mm_deltaY = moved.mm_deltaY - 0x100;
588: /* and finally the Y orientation is different for the microsoft mouse */
589: moved.mm_deltaY = -moved.mm_deltaY;
590:
591: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
592: mouse_moved(moved);
593:
594: if (buttonchanges != 0) {
595: lastbuttons = buttons;
596: if (buttonchanges & 1)
597: mouse_button(MOUSE_RIGHT, (buttons & 1) ?
598: MOUSE_UP : MOUSE_DOWN);
599: if (buttonchanges & 2)
600: mouse_button(MOUSE_LEFT, (buttons & 2) ?
601: MOUSE_UP : MOUSE_DOWN);
602: if (buttonchanges & 4)
603: mouse_button(MOUSE_MIDDLE, (buttons & 4) ?
604: MOUSE_UP : MOUSE_DOWN);
605: }
606: }
607:
608: /*
609: * AUX device (PS2) open/close
610: */
611:
612: /*
613: * Write character to mouse. Called at spltty.
614: */
615: void kd_mouse_write(
616: unsigned char ch)
617: {
618: while (inb(K_STATUS) & K_IBUF_FUL)
619: continue; /* wait for 'input' port empty */
620: outb(K_CMD, 0xd4); /* send next character to mouse */
621:
622: while (inb(K_STATUS) & K_IBUF_FUL)
623: continue; /* wait for 'input' port empty */
624: outb(K_RDWR, ch); /* send command to mouse */
625: }
626:
627: /*
628: * Read next character from mouse, waiting for interrupt
629: * to deliver it. Called at spltty.
630: */
631: int kd_mouse_read(void)
632: {
633: int ch;
634:
1.1.1.4 ! root 635: if (mouse_char_index >= mousebufsize)
! 636: return -1;
! 637:
! 638: while (mousebufindex <= mouse_char_index) {
1.1 root 639: mouse_char_wanted = TRUE;
1.1.1.4 ! root 640: assert_wait((event_t) &mousebuf, FALSE);
1.1 root 641: thread_block((void (*)()) 0);
642: }
643:
1.1.1.4 ! root 644: ch = mousebuf[mouse_char_index++];
1.1 root 645:
646: return ch;
647: }
648:
1.1.1.4 ! root 649: /*
! 650: * Prepare buffer for receiving next packet from mouse.
! 651: */
! 652: void kd_mouse_read_reset(void)
! 653: {
! 654: mousebufindex = 0;
! 655: mouse_char_index = 0;
! 656: }
! 657:
! 658: void
1.1 root 659: ibm_ps2_mouse_open(dev)
1.1.1.4 ! root 660: dev_t dev;
1.1 root 661: {
662: spl_t s = spltty();
663:
664: lastbuttons = 0;
665: mouse_char_cmd = TRUE; /* responses are to commands */
666:
667: kd_sendcmd(0xa8); /* enable mouse in kbd */
668:
669: kd_cmdreg_write(0x47); /* allow mouse interrupts */
670: /* magic number for ibm? */
671:
1.1.1.4 ! root 672: kd_mouse_read_reset();
1.1 root 673: kd_mouse_write(0xff); /* reset mouse */
674: if (kd_mouse_read() != 0xfa) {
675: splx(s);
676: return; /* need ACK */
677: }
678:
679: (void) kd_mouse_read(); /* discard 2-character mouse ID */
680: (void) kd_mouse_read();
681:
1.1.1.4 ! root 682: kd_mouse_read_reset();
1.1 root 683: kd_mouse_write(0xea); /* set stream mode */
684: if (kd_mouse_read() != 0xfa) {
685: splx(s);
686: return; /* need ACK */
687: }
688:
1.1.1.4 ! root 689: kd_mouse_read_reset();
1.1 root 690: kd_mouse_write(0xf4); /* enable */
691: if (kd_mouse_read() != 0xfa) {
692: splx(s);
693: return; /* need ACK */
694: }
695:
1.1.1.4 ! root 696: kd_mouse_read_reset();
1.1 root 697: mouse_char_cmd = FALSE; /* now we get mouse packets */
698:
699: splx(s);
700: }
701:
1.1.1.4 ! root 702: void
1.1 root 703: ibm_ps2_mouse_close(dev)
1.1.1.4 ! root 704: dev_t dev;
1.1 root 705: {
706: spl_t s = spltty();
707:
708: mouse_char_cmd = TRUE; /* responses are to commands */
709:
1.1.1.4 ! root 710: kd_mouse_read_reset();
1.1 root 711: kd_mouse_write(0xff); /* reset mouse */
712: if (kd_mouse_read() == 0xfa) {
713: /* got ACK: discard 2-char mouse ID */
714: (void) kd_mouse_read();
715: (void) kd_mouse_read();
716: }
717:
718: kd_sendcmd(0xa7); /* disable mouse in kbd */
719: kd_cmdreg_write(0x65); /* disallow mouse interrupts */
720: /* magic number for ibm? */
721:
722: splx(s);
723: }
724:
725: /*
726: * 3 byte ibm ps2 format used
727: *
728: * 7 6 5 4 3 2 1 0
729: * YO XO YS XS 1 M R L
730: * X7 X6 X5 X4 X3 X3 X1 X0
731: * Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
732: *
733: */
1.1.1.4 ! root 734: void
1.1 root 735: mouse_packet_ibm_ps2_mouse(mousebuf)
736: u_char mousebuf[MOUSEBUFSIZE];
737: {
738: u_char buttons, buttonchanges;
739: struct mouse_motion moved;
740:
741: buttons = mousebuf[0] & 0x7; /* get current state of buttons */
742: buttonchanges = buttons ^ lastbuttons;
743: moved.mm_deltaX = ((mousebuf[0]&0x10) ? 0xffffff00 : 0 ) | (u_char)mousebuf[1];
744: moved.mm_deltaY = ((mousebuf[0]&0x20) ? 0xffffff00 : 0 ) | (u_char)mousebuf[2];
745: if (mouse_packets) {
746: printf("(%x:%x:%x)", mousebuf[0], mousebuf[1], mousebuf[2]);
747: return;
748: }
749:
750: if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
751: mouse_moved(moved);
752:
753: if (buttonchanges != 0) {
754: lastbuttons = buttons;
755: if (buttonchanges & 1)
756: mouse_button(MOUSE_LEFT, !(buttons & 1));
757: if (buttonchanges & 2)
758: mouse_button(MOUSE_RIGHT, !((buttons & 2) >> 1));
759: if (buttonchanges & 4)
760: mouse_button(MOUSE_MIDDLE, !((buttons & 4) >> 2));
761: }
762: }
763:
764: /*
765: * Enqueue a mouse-motion event. Called at SPLKD.
766: */
1.1.1.4 ! root 767: void
1.1 root 768: mouse_moved(where)
769: struct mouse_motion where;
770: {
771: kd_event ev;
772:
773: ev.type = MOUSE_MOTION;
774: ev.time = time;
775: ev.value.mmotion = where;
776: mouse_enqueue(&ev);
777: }
778:
779:
780: /*
781: * Enqueue an event for mouse button press or release. Called at SPLKD.
782: */
1.1.1.4 ! root 783: void
1.1 root 784: mouse_button(which, direction)
785: kev_type which;
786: u_char direction;
787: {
788: kd_event ev;
789:
790: ev.type = which;
791: ev.time = time;
792: ev.value.up = (direction == MOUSE_UP) ? TRUE : FALSE;
793: mouse_enqueue(&ev);
794: }
795:
796:
797: /*
798: * mouse_enqueue - enqueue an event and wake up selecting processes, if
799: * any. Called at SPLKD.
800: */
801:
802: void
803: mouse_enqueue(ev)
804: kd_event *ev;
805: {
806: if (kdq_full(&mouse_queue))
807: printf("mouse: queue full\n");
808: else
809: kdq_put(&mouse_queue, ev);
810:
811: {
812: register io_req_t ior;
813: while ((ior = (io_req_t)dequeue_head(&mouse_read_queue)) != 0)
814: iodone(ior);
815: }
816: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.