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