[Patch] Xpad Keyboard emulation
Richard Osborne <[email protected]> Mon, 18 Jul 2005 12:49:50 +0100
| Newsgroups | gmane.linux.ports.xbox.devel |
|---|---|
| Message-ID | <[email protected]> |
A while ago gary ng altered the xpad module to allow keyboard emulation for use with his HD Cloning tools (http://www.geocities.com/bononochimpanzee/). This allows the directions on the xpad to be mapped to the cursor keys and the 'A' button to be mapped to enter. While this clearly isn't enough for general text entry it is enough to navigate through a dialog based menu system. I was looking for something similar and so contacted him and obtained his patch for this. I've since spoken to a couple of people who have also been interested in this so I thought I'd post it here. The attached diff is generated against the 2.4.31 kernel. Richard
xpad-keyboard.diff
(text/x-patch, 4.3 KB)
Index: kernel/drivers/usb/xpad-core.c
===================================================================
RCS file: /cvsroot/xbox-linux/kernel/drivers/usb/xpad-core.c,v
retrieving revision 1.18
diff -u -r1.18 xpad-core.c
--- kernel/drivers/usb/xpad-core.c 12 Mar 2005 20:05:41 -0000 1.18
+++ kernel/drivers/usb/xpad-core.c 13 Jul 2005 14:50:00 -0000
@@ -100,7 +100,7 @@
BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* analogue buttons */
BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
BTN_0, BTN_1, BTN_2, BTN_3, /* d-pad as buttons */
- -1 /* terminating entry */
+ KEY_DOWN,KEY_UP,KEY_LEFT,KEY_RIGHT,KEY_ENTER,KEY_ESC,KEY_SPACE, /* keyboard simulation */
};
/* these have no analogue inputs and only 10 buttons */
@@ -109,7 +109,7 @@
BTN_START, BTN_BACK, /* start/back */
BTN_0, BTN_1, BTN_2, BTN_3, /* directions, LEFT/RIGHT is mouse
* so we cannot use those! */
- -1 /* terminating entry */
+ KEY_DOWN,KEY_UP,KEY_LEFT,KEY_RIGHT,KEY_ENTER,KEY_ESC,KEY_SPACE, /* keyboard simulation */
};
static signed short xpad_abs[] = {
@@ -291,6 +291,11 @@
remove_proc_entry( proc_name, xpad_procdir_units );
}
+static int keyboard = 101;
+
+MODULE_PARM( keyboard, "i" );
+MODULE_PARM_DESC( keyboard, "set to zero to de-activate keyboard support on insmod (default 101)" );
+
/*********************** the actual xpad functions ********************/
/**
* xpad_process_packet
@@ -306,21 +311,44 @@
struct input_dev *dev = &xpad->dev;
/* digital pad: bits (3 2 1 0) (right left down up) */
- input_report_key(dev, BTN_0, (data[2] & 0x01));
- input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
- input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
- input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);
-
- /* start/back buttons and stick press left/right */
- input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
- input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
+ if (keyboard) {
+ input_report_key(dev, KEY_RIGHT, (data[2] & 0x08) >> 3);
+ input_report_key(dev, KEY_LEFT, (data[2] & 0x04) >> 2);
+ input_report_key(dev, KEY_DOWN, (data[2] & 0x02) >> 1);
+ input_report_key(dev, KEY_UP, (data[2] & 0x01));
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_0, (data[2] & 0x01));
+ input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
+ input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
+ input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);
+ }
+
+ /* start and back buttons */
+ if (keyboard%100 == 2) {
+ input_report_key(dev, KEY_ENTER, (data[2] & 0x10) >> 4);
+ input_report_key(dev, KEY_ESC, (data[2] & 0x20) >> 5);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
+ input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
+ }
/* buttons A, B, X, Y digital mode */
- input_report_key(dev, BTN_A, data[4]);
- input_report_key(dev, BTN_B, data[5]);
- input_report_key(dev, BTN_X, data[6]);
- input_report_key(dev, BTN_Y, data[7]);
-
+ if (keyboard%100 == 1 || keyboard%100 > 3) {
+ input_report_key(dev, KEY_ENTER, data[4]);
+ input_report_key(dev, KEY_ESC, data[5]);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_A, data[4]);
+ input_report_key(dev, BTN_B, data[5]);
+ }
+
+ if (keyboard%100 == 3) {
+ input_report_key(dev, KEY_ENTER, data[6]);
+ input_report_key(dev, KEY_ESC, data[7]);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_X, data[6]);
+ input_report_key(dev, BTN_Y, data[7]);
+ }
+
if (xpad->isMat)
return;
@@ -342,7 +370,9 @@
/* stick press left/right */
input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
+ if (keyboard) input_report_key(dev, KEY_SPACE, (data[2] & 0x40) >> 6);
input_report_key(dev, BTN_THUMBR, data[2] >> 7);
+ if (keyboard) input_report_key(dev, KEY_SPACE, data[2] >> 7);
/* buttons A, B, X, Y analogue mode */
input_report_abs(dev, ABS_HAT1X, data[4]);
@@ -351,11 +381,11 @@
input_report_abs(dev, ABS_HAT3X, data[7]);
/* button C (black) digital/analogue mode */
- input_report_key(dev, BTN_C, data[8]);
+ if (keyboard < 100) input_report_key(dev, BTN_C, data[8]);
input_report_abs(dev, ABS_HAT2X, data[8]);
/* button Z (white) digital/analogue mode */
- input_report_key(dev, BTN_Z, data[9]);
+ if (keyboard < 100) input_report_key(dev, BTN_Z, data[9]);
input_report_abs(dev, ABS_HAT3Y, data[9]);
/* process input data for mouse event generation */