patch-2.1.79 linux/drivers/macintosh/mac_keyb.c
Next file: linux/drivers/macintosh/macio-adb.c
Previous file: linux/drivers/macintosh/control.c
Back to the patch index
Back to the overall index
- Lines: 301
- Date:
Mon Jan 12 15:18:13 1998
- Orig file:
v2.1.78/linux/drivers/macintosh/mac_keyb.c
- Orig date:
Mon Aug 18 18:19:45 1997
diff -u --recursive --new-file v2.1.78/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
@@ -18,6 +18,7 @@
#include <asm/keyboard.h>
#include <asm/bitops.h>
+#include <asm/adb.h>
#include <asm/cuda.h>
#include <linux/kbd_kern.h>
@@ -27,15 +28,19 @@
#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
-unsigned char kbd_read_mask = 0; /* XXX */
-
static void kbd_repeat(unsigned long);
static struct timer_list repeat_timer = { NULL, NULL, 0, 0, kbd_repeat };
static int last_keycode;
-static void keyboard_input(unsigned char *, int, struct pt_regs *);
+static void keyboard_input(unsigned char *, int, struct pt_regs *, int);
static void input_keycode(int, int);
-static void leds_done(struct cuda_request *);
+static void leds_done(struct adb_request *);
+
+/* XXX: Hook for mouse driver */
+void (*adb_mouse_interrupt_hook) (char *, int);
+int adb_emulate_button2;
+int adb_emulate_button3;
+extern int console_loglevel;
extern struct kbd_struct kbd_table[];
@@ -75,14 +80,11 @@
if (!raw_mode) {
/*
* Convert R-shift/control/option to L version.
- * Remap keycode 0 (A) to the unused keycode 0x5a.
- * Other parts of the system assume 0 is not a valid keycode.
*/
switch (keycode) {
case 0x7b: keycode = 0x38; break; /* R-shift */
case 0x7c: keycode = 0x3a; break; /* R-option */
case 0x7d: keycode = 0x36; break; /* R-control */
- case 0: keycode = 0x5a; break; /* A */
}
}
*keycodep = keycode;
@@ -95,15 +97,15 @@
}
static void
-keyboard_input(unsigned char *data, int nb, struct pt_regs *regs)
+keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
{
/* first check this is from register 0 */
- if (nb != 5 || (data[2] & 3) != KEYB_KEYREG)
+ if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
return; /* ignore it */
kbd_pt_regs = regs;
- input_keycode(data[3], 0);
- if (!(data[4] == 0xff || (data[4] == 0x7f && data[3] == 0x7f)))
- input_keycode(data[4], 0);
+ input_keycode(data[1], 0);
+ if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
+ input_keycode(data[2], 0);
}
static void
@@ -114,10 +116,66 @@
kbd = kbd_table + fg_console;
up_flag = (keycode & 0x80);
- keycode &= 0x7f;
+ keycode &= 0x7f;
+
if (!repeat)
del_timer(&repeat_timer);
+ /*
+ * XXX: Add mouse button 2+3 fake codes here if mouse open.
+ * Keep track of 'button' states here as we only send
+ * single up/down events!
+ * Really messy; might need to check if keyboard is in
+ * VC_RAW mode.
+ * Might also want to know how many buttons need to be emulated.
+ * -> hide this as function in arch/m68k/mac ?
+ */
+ if (adb_mouse_interrupt_hook || console_loglevel == 10) {
+ unsigned char button, button2, button3, fake_event;
+ static unsigned char button2state=0, button3state=0; /* up */
+ /* faked ADB packet */
+ static char data[4] = { 0, 0x80, 0x80, 0x80 };
+
+ button = 0;
+ fake_event = 0;
+ switch (keycode) { /* which 'button' ? */
+ case 0x7c: /* R-option */
+ button2 = (!up_flag); /* new state */
+ if (button2 != button2state) /* change ? */
+ button = 2;
+ button2state = button2; /* save state */
+ fake_event = 2;
+ break;
+ case 0x7d: /* R-control */
+ button3 = (!up_flag); /* new state */
+ if (button3 != button3state) /* change ? */
+ button = 3;
+ button3state = button3; /* save state */
+ fake_event = 3;
+ break;
+ }
+ if (fake_event && console_loglevel >= 8)
+ printk("fake event: button2 %d button3 %d button %d\n",
+ button2state, button3state, button);
+ if (button) { /* there's been a button state change */
+ /* fake a mouse packet : send all bytes, change one! */
+ data[button] = (up_flag ? 0x80 : 0);
+ if (adb_mouse_interrupt_hook)
+ adb_mouse_interrupt_hook(data, -1);
+ else
+ printk("mouse_fake: data %x %x %x buttons %x \n",
+ data[1], data[2], data[3],
+ ~( (data[1] & 0x80 ? 0 : 4)
+ | (data[2] & 0x80 ? 0 : 1)
+ | (data[3] & 0x80 ? 0 : 2) )&7 );
+ }
+ /*
+ * XXX: testing mouse emulation ... don't process fake keys!
+ */
+ if (fake_event)
+ return;
+ }
+
if (kbd->kbdmode != VC_RAW) {
if (!up_flag && !dont_repeat[keycode]) {
last_keycode = keycode;
@@ -126,11 +184,23 @@
}
/*
- * XXX fix caps-lock behaviour by turning the key-up
- * transition into a key-down transition.
+ * adb kludge!! Imitate pc caps lock behaviour by
+ * generating an up/down event for each time caps
+ * is pressed/released. Also, makes sure that the
+ * LED are handled. atong@uiuc.edu
*/
- if (keycode == 0x39 && up_flag && vc_kbd_led(kbd, VC_CAPSLOCK))
- up_flag = 0;
+ switch (keycode) {
+ /*case 0xb9:*/
+ case 0x39:
+ handle_scancode(0x39);
+ handle_scancode(0xb9);
+ mark_bh(KEYBOARD_BH);
+ return;
+ case 0x47:
+ /*case 0xc7:*/
+ mark_bh(KEYBOARD_BH);
+ break;
+ }
}
handle_scancode(keycode + up_flag);
@@ -148,7 +218,7 @@
}
static void
-mouse_input(unsigned char *data, int nb, struct pt_regs *regs)
+mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
{
/* [ACA:23-Mar-97] Three button mouse support. This is designed to
function with MkLinux DR-2.1 style X servers. It only works with
@@ -230,6 +300,18 @@
*/
struct kbd_struct *kbd;
+ if (adb_mouse_interrupt_hook)
+ adb_mouse_interrupt_hook(data, nb);
+ else
+ if (console_loglevel == 10)
+ printk("mouse_input: data %x %x %x buttons %x dx %d dy %d \n",
+ data[1], data[2], data[3],
+ ~((data[1] & 0x80 ? 0 : 4)
+ | (data[2] & 0x80 ? 0 : 1)
+ | (data[3] & 0x80 ? 0 : 2))&7,
+ ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ),
+ ((data[1]&0x7f) < 64 ? -(data[1]&0x7f) : 128-(data[1]&0x7f) ) );
+
kbd = kbd_table + fg_console;
/* Only send mouse codes when keyboard is in raw mode. */
@@ -239,13 +321,13 @@
/* Send first button, second button and movement. */
put_queue( 0x7e );
- put_queue( data[3] );
- put_queue( data[4] );
+ put_queue( data[1] );
+ put_queue( data[2] );
/* [ACA: Are there any two-button ADB mice that use handler 1 or 2?] */
/* Store the button state. */
- uchButtonSecond = (data[4] & 0x80);
+ uchButtonSecond = (data[2] & 0x80);
/* Send second button. */
if (uchButtonSecond != uch_ButtonStateSecond) {
@@ -254,12 +336,12 @@
}
/* Macintosh 3-button mouse (handler 4). */
- if ((nb == 6) && (data[1] & 0x40)) {
+ if ((nb == 6) && autopoll /*?*/) {
static unsigned char uch_ButtonStateThird = 0;
unsigned char uchButtonThird;
/* Store the button state for speed. */
- uchButtonThird = (data[5] & 0x80);
+ uchButtonThird = (data[3] & 0x80);
/* Send third button. */
if (uchButtonThird != uch_ButtonStateThird) {
@@ -282,20 +364,20 @@
7, /* caps + num + scroll lock */
};
-static struct cuda_request led_request;
+static struct adb_request led_request;
static int leds_pending;
void mackbd_leds(unsigned char leds)
{
- if (led_request.got_reply) {
- cuda_request(&led_request, leds_done, 4, ADB_PACKET,
+ if (led_request.complete) {
+ adb_request(&led_request, leds_done, 0, 3,
ADB_WRITEREG(ADB_KEYBOARD, KEYB_LEDREG),
0xff, ~mac_ledmap[leds]);
} else
leds_pending = leds | 0x100;
}
-static void leds_done(struct cuda_request *req)
+static void leds_done(struct adb_request *req)
{
int leds;
@@ -308,36 +390,32 @@
void mackbd_init_hw(void)
{
- struct cuda_request req;
+ struct adb_request req;
+
+ /* initialize mouse interrupt hook */
+ adb_mouse_interrupt_hook = NULL;
+ /* assume broken mouse :-) - should be adjusted based on
+ * result of the mouse setup !! (or passed as kernel option) */
+ adb_emulate_button2 = 1;
+ adb_emulate_button3 = 1;
adb_register(ADB_KEYBOARD, keyboard_input);
adb_register(ADB_MOUSE, mouse_input);
- /* turn on ADB auto-polling in the CUDA */
- cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
- while (!req.got_reply)
- cuda_poll();
-
/* turn off all leds */
- cuda_request(&req, NULL, 4, ADB_PACKET,
- ADB_WRITEREG(ADB_KEYBOARD, KEYB_LEDREG), 0xff, 0xff);
- while (!req.got_reply)
- cuda_poll();
+ adb_request(&req, NULL, ADBREQ_SYNC, 3,
+ ADB_WRITEREG(ADB_KEYBOARD, KEYB_LEDREG), 0xff, 0xff);
/* get the keyboard to send separate codes for
left and right shift, control, option keys. */
- cuda_request(&req, NULL, 4, ADB_PACKET,
- ADB_WRITEREG(ADB_KEYBOARD, 3), 0, 3);
- while (!req.got_reply)
- cuda_poll();
+ adb_request(&req, NULL, ADBREQ_SYNC, 3,
+ ADB_WRITEREG(ADB_KEYBOARD, 3), 0, 3);
- led_request.got_reply = 1;
+ led_request.complete = 1;
/* Try to switch the mouse (id 3) to handler 4, for three-button
mode. (0x20 is Service Request Enable, 0x03 is Device ID). */
- cuda_request(&req, NULL, 4, ADB_PACKET,
- ADB_WRITEREG(ADB_MOUSE, 3), 0x23, 4 );
- while (!req.got_reply)
- cuda_poll();
+ adb_request(&req, NULL, ADBREQ_SYNC, 3,
+ ADB_WRITEREG(ADB_MOUSE, 3), 0x23, 4 );
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov