diff options
Diffstat (limited to 'chips/mouse.c')
-rw-r--r-- | chips/mouse.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/chips/mouse.c b/chips/mouse.c new file mode 100644 index 00000000..85a27447 --- /dev/null +++ b/chips/mouse.c @@ -0,0 +1,321 @@ +/* + * Mach Operating System + * Copyright (c) 1992-1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: mouse.c + * Author: Alessandro Forin, Carnegie Mellon University + * Date: 9/90 + * + * Driver code for Digital's mouse AND tablet + */ + +/* + * XXX This should be rewritten to support other + * XXX sorts of mices and tablets. But for now + * XXX I have none to play with. Sorry about that. + */ + +#include <lk.h> /* one mouse per lk201 */ +#if NLK > 0 + +#include <mach/std_types.h> +#include <machine/machspl.h> /* spl definitions */ +#include <sys/time.h> +#include <kern/time_out.h> + +#include <chips/serial_defs.h> +#include <chips/screen_defs.h> + +#define MOUSE_INCREMENTAL 0x52 /* R */ +#define MOUSE_PROMPTED 0x44 /* D */ +#define MOUSE_REQ_POSITION 0x50 /* P */ +#define MOUSE_SELFTEST 0x54 /* T */ +#define MOUSE_RESERVED_FUNC 0x5a /* Z, param byte follows */ + +#define TABLET_SAMPLE_55 0x4b /* K */ /* in reps/sec */ +#define TABLET_SAMPLE_72 0x4c /* L */ +#define TABLET_SAMPLE_120 0x4d /* M */ +#define TABLET_9600 0x42 /* B */ + +#define TYPE_MOUSE 0x2 +#define TYPE_TABLET 0x4 + +#define START_REPORT 0x80 + +typedef union { + struct { + unsigned char r : 1, m : 1, l : 1, sy : 1, sx : 1; + unsigned char xpos; + unsigned char ypos; + } ms; + struct { + unsigned char pr : 1, buttons : 4; + unsigned char xlo, xhi; + unsigned char ylo, yhi; + } tb; + unsigned char raw[1]; +} mouse_report_t; + + +/* + * Mouse state + */ +struct mouse_softc { + user_info_t *up; + mouse_report_t report; + unsigned char rep_bytes; + unsigned char rep_ptr; + unsigned char prev_buttons; + unsigned char flags; +#define MS_TABLET 0x1 +#define MS_MOVING 0x2 + char screen_unit; + char sl_unit; +} mouse_softc_data[NLK]; + +typedef struct mouse_softc *mouse_softc_t; + +mouse_softc_t mouse_softc[NLK]; + + +mouse_notify_mapped( + int unit, + int screen_unit, + user_info_t *up) +{ + mouse_softc_t ms = &mouse_softc_data[unit]; + + ms->up = up; + ms->screen_unit = screen_unit; +} + +/* + * Autoconfiguration + */ +mouse_probe( + int unit) +{ + mouse_softc[unit] = &mouse_softc_data[unit]; +} + +mouse_attach( + int unit, + int sl_unit) +{ + int messg[4]; + spl_t s; + mouse_softc_t ms; + + ms = mouse_softc[unit]; + ms->sl_unit = sl_unit; + + s = spltty(); + (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_SELFTEST); + delay(1); + messg[0] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE); + messg[1] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE); + messg[2] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE); + messg[3] = (*console_getc)(sl_unit, SCREEN_LINE_POINTER, TRUE, TRUE); + + delay(100000); /* spec says less than 500 msecs */ + (*console_putc)(sl_unit, SCREEN_LINE_POINTER, MOUSE_INCREMENTAL); + splx(s); + + ms->rep_bytes = 3;/* mouse */ + if (messg[2] | messg[3]) { + printf(" bad pointer [%x %x %x %x] ", + messg[0], messg[1], messg[2], messg[3]); + if (messg[2] >= 0x20) printf("fatal "); + if (messg[2] == 0x3e) printf("RAM/ROM"); + if (messg[2] == 0x3d) printf("button(s) %x", messg[3] & 0x1f); + } else { + int rev = messg[0] & 0xf; + int loc = (messg[1] & 0xf0) >> 4; + int tag = (messg[1] & 0xf); + printf("( %s rev. %x.%x )", + (tag == TYPE_MOUSE) ? "mouse" : "tablet", + rev, loc); + if (tag == TYPE_TABLET) { + ms->flags = MS_TABLET; + ms->rep_bytes = 5; + } + } +} + +/* + * Process a character from the mouse + */ +mouse_input( + int unit, + register unsigned short data) +{ + mouse_softc_t ms = mouse_softc[unit]; + register char flg, but; + + data &= 0xff; + + /* sanity: might miss a byte sometimes */ + if (data & START_REPORT) + ms->rep_ptr = 0; + + /* add byte to report */ + ms->report.raw[ms->rep_ptr++] = data; + + /* does this mean the mouse is moving */ + if (data && ((data & START_REPORT) == 0)) + ms->flags |= MS_MOVING; + + /* Report complete ? */ + if (ms->rep_ptr != ms->rep_bytes) + return; + ms->rep_ptr = 0; + + ssaver_bump(ms->screen_unit); + + /* check for mouse moved */ + flg = ms->flags; + if (flg & MS_MOVING) { + ms->flags = flg & ~MS_MOVING; + mouse_motion_event(ms, flg); + } + + /* check for button pressed */ + if (but = ms->prev_buttons ^ ms->report.raw[0]) { + mouse_button_event(ms, flg, but); + ms->prev_buttons = ms->report.raw[0]; + } +} + +/* + * The mouse/puck moved. + * Find how much and post an event + */ +mouse_motion_event( + mouse_softc_t ms, + int flg) +{ + register int x, y; + + if (flg & MS_TABLET) { + + flg = DEV_TABLET; + + x = (ms->report.tb.xhi << 8) | ms->report.tb.xlo; + y = (ms->report.tb.yhi << 8) | ms->report.tb.ylo; + + } else { + + flg = DEV_MOUSE; + + x = ms->report.ms.xpos; + if (!ms->report.ms.sx) /* ??? */ + x = -x; + + y = ms->report.ms.ypos; + if (ms->report.ms.sy) + y = -y; + + } + + screen_motion_event(ms->screen_unit, flg, x, y); +} + +/* + * A mouse/puck button was pressed/released. + * Find which one and post an event + */ +mouse_button_event( + mouse_softc_t ms, + int flg, + int bmask) +{ + register unsigned int buttons, i; + int key, type; + + buttons = ms->report.raw[0]; + if (flg & MS_TABLET) { + /* check each one of the four buttons */ + for (i = 0; i < 4; i += 1) { + if ((bmask & (2<<i)) == 0) + continue;/* did not change */ + type = (buttons & (2<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP; + key = i; + + screen_keypress_event( ms->screen_unit, + DEV_TABLET, key, type); + } + } else { + ms->up->mouse_buttons = buttons & 0x7; + /* check each one of the three buttons */ + for (i = 0; i < 3; i += 1) { + if ((bmask & (1<<i)) == 0) + continue;/* did not change */ + type = (buttons & (1<<i)) ? EVT_BUTTON_DOWN : EVT_BUTTON_UP; + + if (i & 1) + key = KEY_MIDDLE_BUTTON; + else if ((i & 2) == 0) + key = KEY_RIGHT_BUTTON; + else + key = KEY_LEFT_BUTTON; + + screen_keypress_event( ms->screen_unit, + DEV_MOUSE, key, type); + } + } +} + +/* + * Generate escape sequences for position reporting + * These are the same as xterm's. + * Prefix: + * ESC [ M button down + * ESC [ N button up + * Body: + * BUTTON COL ROW + * Button: + * 0 <-> left, 1 <-> middle, 2 <-> right + * All body values are offset by the ascii SPACE character + */ +#define ESC '\033' +#define SPACE ' ' + +mouse_report_position( + int unit, + int col, + int row, + int key, + int type) +{ + cons_input(SCREEN_LINE_KEYBOARD, ESC, 0); + cons_input(SCREEN_LINE_KEYBOARD, '[', 0); + cons_input(SCREEN_LINE_KEYBOARD, (type==EVT_BUTTON_DOWN) ? 'M':'N', 0); + + cons_input(SCREEN_LINE_KEYBOARD, (key - 1) + SPACE, 0);/* quick remapping */ + cons_input(SCREEN_LINE_KEYBOARD, SPACE + col + 2, 0); + cons_input(SCREEN_LINE_KEYBOARD, SPACE + row + 1, 0); +} + +#endif NLK > 0 |