summaryrefslogtreecommitdiff
path: root/chips/mouse.c
diff options
context:
space:
mode:
authorThomas Bushnell <thomas@gnu.org>1997-02-25 21:28:37 +0000
committerThomas Bushnell <thomas@gnu.org>1997-02-25 21:28:37 +0000
commitf07a4c844da9f0ecae5bbee1ab94be56505f26f7 (patch)
tree12b07c7e578fc1a5f53dbfde2632408491ff2a70 /chips/mouse.c
Initial source
Diffstat (limited to 'chips/mouse.c')
-rw-r--r--chips/mouse.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/chips/mouse.c b/chips/mouse.c
new file mode 100644
index 0000000..85a2744
--- /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