diff --git a/LCDd.conf b/LCDd.conf
index 0b66fcb..b22994e 100644
--- a/LCDd.conf
+++ b/LCDd.conf
@@ -452,11 +452,15 @@ Size=16x2
# Select the input device to use [default: /dev/js0]
Device=/dev/js0
-# Modify the axis mapa [default: EFGHIJKLMNOPQRST]
-#AxisMap=EFGHIJKLMNOPQRST
+# set the axis map
+Map_Axis1- = Left
+Map_Axis1+ = Right
+Map_Axis2- = Up
+Map_Axis2+ = Down
-# Modify the button map [default: BDACEFGHIJKLMNOP]
-#ButtonMap=BDACEFGHIJKLMNOP
+# set the button map
+Map_Button1 = Enter
+Map_Button2 = Escape
@@ -486,7 +490,6 @@ Device=/dev/ttyS1
# Keyname Function
# Normal context Menu context
# ------- -------------- ------------
-#
# PauseKey Pause/Continue Enter/select
# BackKey Back(Go to previous screen) Up/Left
# ForwardKey Forward(Go to next screen) Down/Right
diff --git a/docs/lcdproc-user/drivers/joy.docbook b/docs/lcdproc-user/drivers/joy.docbook
index 8136811..219a9e0 100644
--- a/docs/lcdproc-user/drivers/joy.docbook
+++ b/docs/lcdproc-user/drivers/joy.docbook
@@ -25,22 +25,57 @@ This section covers the joystick input driver for LCDd.
- AxisMap=
- MAP-LIST
+ Map_AxisNUM-=
+ KEY
-
- Modify the axis mapa [default: EFGHIJKLMNOPQRST]
-
+
+ Map_AxisNUM+=
+ KEY
+
+
+
+ Set the axis map.
+
+
+
+ NUM is an integer starting with 1
+ that represents each axis with the appendices + and
+ - determining the direction.
+ The exact numbering of the axes depends on the hardware used.
+
+
+
+ KEY can be one of the keys that LCDd recognizes
+ (Left, Right, Up,
+ Down, Enter or Escape)
+ or any other string that a client can parse.
+
+
- ButtonMap=
- MAP-LIST
+ Map_ButtonNUM=
+ KEY
-
- Modify the button map [default: BDACEFGHIJKLMNOP]
-
+
+
+ Set the button map.
+
+
+
+ NUM is an integer starting with 1
+ that represents each button. The exact numbering of the buttons depends on the
+ hardware used.
+
+
+
+ KEY can be one of the keys that LCDd recognizes
+ (Left, Right, Up,
+ Down, Enter or Escape)
+ or any other string that a client can parse.
+
+
diff --git a/server/drivers/joy.c b/server/drivers/joy.c
index 3471ff9..b91a44b 100644
--- a/server/drivers/joy.c
+++ b/server/drivers/joy.c
@@ -43,21 +43,21 @@
#define JOY_DEFAULT_AXISMAP "EFGHIJKLMNOPQRST"
#define JOY_DEFAULT_BUTTONMAP "BDACEFGHIJKLMNOP"
-int fd = -1;
-struct js_event js;
-char axes = 2;
-char buttons = 2;
-int jsversion = 0x000801;
-char jsname[JOY_NAMELENGTH] = "Unknown";
+typedef struct driver_private_data {
+ char device[256];
+ int fd;
-int *axis = NULL;
-int *button = NULL;
+ char axes;
+ char buttons;
+ int jsversion;
+ char jsname[JOY_NAMELENGTH];
+
+ char **axismap;
+ char **buttonmap;
+} PrivateData;
-// Configured for a Gravis Gamepad (2 axis, 4 button)
-char axismap[JOY_MAPSIZE+1] = JOY_DEFAULT_AXISMAP;
-char buttonmap[JOY_MAPSIZE+1] = JOY_DEFAULT_BUTTONMAP;
// Vars for the server core
MODULE_EXPORT char *api_version = API_VERSION;
@@ -72,54 +72,92 @@ MODULE_EXPORT char *symbol_prefix = "joy_";
MODULE_EXPORT int
joy_init (Driver *drvthis)
{
- char device[256];
+ PrivateData *p;
+ int i;
- /* Read config file */
+ /* Allocate and store private data */
+ p = (PrivateData *) calloc(1, sizeof(PrivateData));
+ if (p == NULL)
+ return -1;
+ if (drvthis->store_private_ptr(drvthis, p))
+ return -1;
+
+ /* initialize private data */
+ p->fd = -1;
+ p->axes = 2;
+ p->buttons = 2;
+ p->jsversion = 0;
+ strcpy(p->jsname, "Unknown");
+ p->axismap = NULL;
+ p->buttonmap = NULL;
+
+
+ /* Read config file (1st part) */
/* What device should be used */
- strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0,
- JOY_DEFAULT_DEVICE), sizeof(device));
- device[sizeof(device)-1] = '\0';
- report(RPT_INFO, "%s: using Device %s", drvthis->name, device);
+ strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0,
+ JOY_DEFAULT_DEVICE), sizeof(p->device));
+ p->device[sizeof(p->device)-1] = '\0';
+ report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device);
- /* How does the axis map look like */
- strncpy(axismap, drvthis->config_get_string(drvthis->name, "AxisMap", 0,
- JOY_DEFAULT_AXISMAP), sizeof(axismap));
- axismap[sizeof(axismap)-1] = '\0';
-
- /* How does the button map look like */
- strncpy(buttonmap, drvthis->config_get_string(drvthis->name, "ButtonMap", 0,
- JOY_DEFAULT_BUTTONMAP), sizeof(buttonmap));
- buttonmap[sizeof(buttonmap)-1] = '\0';
-
- /* End of config file parsing */
+ /* End of config file parsing (1st part) */
- if ((fd = open(device, O_RDONLY)) < 0) {
+ if ((p->fd = open(p->device, O_RDONLY)) < 0) {
report(RPT_ERR, "%s: open(%s) failed (%s)",
- drvthis->name, device, strerror(errno));
+ drvthis->name, p->device, strerror(errno));
return -1;
}
- fcntl(fd, F_SETFL, O_NONBLOCK);
- ioctl(fd, JSIOCGVERSION, &jsversion);
- ioctl(fd, JSIOCGAXES, &axes);
- ioctl(fd, JSIOCGBUTTONS, &buttons);
- ioctl(fd, JSIOCGNAME(JOY_NAMELENGTH), jsname);
+ /* init joystick, get values for buttons, exes, name, ... */
+ fcntl(p->fd, F_SETFL, O_NONBLOCK);
+ ioctl(p->fd, JSIOCGVERSION, &p->jsversion);
+ ioctl(p->fd, JSIOCGAXES, &p->axes);
+ ioctl(p->fd, JSIOCGBUTTONS, &p->buttons);
+ ioctl(p->fd, JSIOCGNAME(JOY_NAMELENGTH), p->jsname);
report(RPT_NOTICE, "%s: Joystick (%s) has %d axes and %d buttons. Driver version is %d.%d.%d",
- drvthis->name, jsname, axes, buttons,
- jsversion >> 16, (jsversion >> 8) & 0xff, jsversion & 0xff);
+ drvthis->name, p->jsname, p->axes, p->buttons,
+ p->jsversion >> 16, (p->jsversion >> 8) & 0xff, p->jsversion & 0xff);
- if ((axis = calloc(axes, sizeof (int))) == NULL) {
- report(RPT_ERR, "%s: could not allocate memory for axes", drvthis->name);
+ if ((p->axismap = calloc(2 * p->axes, sizeof(char *))) == NULL) {
+ report(RPT_ERR, "%s: cannot allocate memory for axes", drvthis->name);
return -1;
}
- if ((button = calloc(buttons, sizeof (char))) == NULL) {
- report(RPT_ERR, "%s: could not allocate memory for buttons", drvthis->name);
+ if ((p->buttonmap = calloc(p->buttons, sizeof(char *))) == NULL) {
+ report(RPT_ERR, "%s: cannot allocate memory for buttons", drvthis->name);
return -1;
}
+ /* Read config file (2nd part) */
+
+ for (i = 0; i < p->axes; i++) {
+ char mapkey[50];
+ char *mapval;
+
+ snprintf(mapkey, sizeof(mapkey), "Map_Axis%d-", i+1);
+ mapval = drvthis->config_get_string(drvthis->name, mapkey, 0, NULL);
+ if (mapval != NULL)
+ p->axismap[2*i] = strdup(mapval);
+
+ snprintf(mapkey, sizeof(mapkey), "Map_Axis%d+", i+1);
+ mapval = drvthis->config_get_string(drvthis->name, mapkey, 0, NULL);
+ if (mapval != NULL)
+ p->axismap[2*i + 1] = strdup(mapval);
+ }
+
+ for (i = 0; i < p->buttons; i++) {
+ char mapkey[50];
+ char *mapval;
+
+ snprintf(mapkey, sizeof(mapkey), "Map_Button%d", i+1);
+ mapval = drvthis->config_get_string(drvthis->name, mapkey, 0, NULL);
+ if (mapval != NULL)
+ p->buttonmap[i] = strdup(mapval);
+ }
+
+ /* End of config file parsing (2nd part) */
+
report(RPT_DEBUG, "%s: init() done", drvthis->name);
return 0;
@@ -128,69 +166,59 @@ joy_init (Driver *drvthis)
MODULE_EXPORT void
joy_close (Driver *drvthis)
{
- if (fd >= 0)
- close(fd);
+ PrivateData *p = drvthis->private_data;
+
+ if (p != NULL) {
+ if (p->fd >= 0)
+ close(p->fd);
- // Why do I have so much trouble getting memory freed without segfaults??
- // Use gdb and find out :) In preliminary testing, this seemed to work...
-
- if (axis != NULL)
- free(axis);
- if (button != NULL)
- free(button);
+ if (p->axismap != NULL)
+ free(p->axismap);
+ if (p->buttonmap != NULL)
+ free(p->buttonmap);
+ free(p);
+ }
+ drvthis->store_private_ptr(drvthis, NULL);
}
//////////////////////////////////////////////////////////////////////
// Tries to read a character from an input device...
//
-// Return 0 for "nothing available".
+// Return NULL0 for "nothing available".
//
-MODULE_EXPORT char
-joy_getkey (Driver *drvthis)
+MODULE_EXPORT const char *
+joy_get_key (Driver *drvthis)
{
- int i;
+ PrivateData *p = drvthis->private_data;
+ struct js_event js;
int err;
- if ((err = read(fd, &js, sizeof(struct js_event))) <= 0) {
- return 0;
- } else
- if (err != sizeof(struct js_event)) {
- report(RPT_ERR, "%s: error reading joystick input", drvthis->name);
- return 0;
- }
+ if ((err = read(p->fd, &js, sizeof(struct js_event))) <= 0) {
+ return NULL;
+ }
+ if (err != sizeof(struct js_event)) {
+ report(RPT_ERR, "%s: error reading joystick input", drvthis->name);
+ return NULL;
+ }
-// if (js.type & JS_EVENT_INIT) return 0;
+ //if (js.type & JS_EVENT_INIT)
+ // return NULL;
switch (js.type & ~JS_EVENT_INIT) {
case JS_EVENT_BUTTON:
- button[js.number] = js.value;
- break;
+ /* ignore button release */
+ if ((js.value == 0) || (js.number >= p->buttons))
+ return NULL;
+ return p->buttonmap[js.number];
case JS_EVENT_AXIS:
- axis[js.number] = js.value;
- break;
+ /* ignore noise */
+ if ((js.value > -20000) || (js.value < 20000)
+ || (js.number >= 2 * p->axes))
+ return NULL;
+ return p->axismap[js.number];
+ default:
+ return NULL;
}
-
- if (buttons) {
- //printf("Buttons: ");
- for (i = 0; i < buttons; i++)
- //printf("%2d:%s ", i, button[i] ? "on " : "off");
- if (button[i])
- return buttonmap[i];
- }
-
- if (axes) {
- //printf("Axes: ");
- for (i = 0; i < axes; i++) {
- //printf("%2d:%6d ", i, axis[i]);
- // Eliminate noise...
- if (axis[i] > 20000)
- return axismap[(2 * i) + 1];
- if (axis[i] < -20000)
- return axismap[(2 * i)];
- }
- }
-
- return 0;
}
diff --git a/server/drivers/joy.h b/server/drivers/joy.h
index 8a68944..e964ea0 100644
--- a/server/drivers/joy.h
+++ b/server/drivers/joy.h
@@ -6,6 +6,6 @@
MODULE_EXPORT int joy_init (Driver *drvthis);
MODULE_EXPORT void joy_close (Driver *drvthis);
-MODULE_EXPORT char joy_getkey (Driver *drvthis);
+MODULE_EXPORT const char *joy_get_key (Driver *drvthis);
#endif