mirror of
https://github.com/X11Libre/xf86-input-joystick.git
synced 2026-04-14 11:54:23 +00:00
Added USB-HID backend for *BSD
Added checks for platform in configure.ac and Makefile.am
This commit is contained in:
18
configure.ac
18
configure.ac
@@ -62,6 +62,24 @@ AH_TOP([#include "xorg-server.h"])
|
||||
# AC_DEFINE(XKB,1,[Enable XKB support])
|
||||
#fi
|
||||
|
||||
case $host_os in
|
||||
linux*)
|
||||
IS_LINUX="yes"
|
||||
;;
|
||||
|
||||
freebsd* | kfreebsd-gnu* | netbsd* | openbsd*)
|
||||
IS_BSD="yes"
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Your operating system is not supported by the joystick driver.
|
||||
Contact xorg@lists.freedesktop.org if you are interested in
|
||||
porting it.])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(LINUX, [test "x$IS_LINUX" = xyes])
|
||||
AM_CONDITIONAL(BSD, [test "x$IS_BSD" = xyes])
|
||||
|
||||
AC_ARG_WITH(xorg-module-dir,
|
||||
AC_HELP_STRING([--with-xorg-module-dir=DIR],
|
||||
[Default xorg module directory [[default=$libdir/xorg/modules]]]),
|
||||
|
||||
@@ -28,7 +28,20 @@
|
||||
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
|
||||
@DRIVER_NAME@_drv_ladir = @inputdir@
|
||||
|
||||
@DRIVER_NAME@_drv_la_SOURCES = jstk.c jstk.h \
|
||||
linux_jstk.c linux_jstk.h \
|
||||
@DRIVER_NAME@_drv_la_SOURCES = jstk.c jstk.h jstk_hw.h \
|
||||
jstk_axis.c jstk_axis.h \
|
||||
jstk_options.c jstk_options.h
|
||||
|
||||
BSD_SRCS = bsd_jstk.c
|
||||
LINUX_SRCS = linux_jstk.c
|
||||
|
||||
if BSD
|
||||
@DRIVER_NAME@_drv_la_SOURCES += $(BSD_SRCS)
|
||||
@DRIVER_NAME@_drv_la_LDFLAGS += -lusbhid
|
||||
endif
|
||||
|
||||
if LINUX
|
||||
@DRIVER_NAME@_drv_la_SOURCES += $(LINUX_SRCS)
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(BSD_SRCS) $(LINUX_SRCS)
|
||||
|
||||
303
src/bsd_jstk.c
Normal file
303
src/bsd_jstk.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2007 by Sascha Hlusiak. <saschahlusiak@freedesktop.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Sascha Hlusiak not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Sascha Hlusiak makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* SASCHA HLUSIAK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL SASCHA HLUSIAK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xf86.h>
|
||||
#include <xf86_OSproc.h>
|
||||
|
||||
#include <usbhid.h>
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbhid.h>
|
||||
|
||||
#include "jstk.h"
|
||||
#include "jstk_hw.h"
|
||||
|
||||
|
||||
struct jstk_bsd_hid_data {
|
||||
int dlen;
|
||||
char *data_buf;
|
||||
struct hid_item axis_item[MAXAXES];
|
||||
struct hid_item button_item[MAXBUTTONS];
|
||||
struct hid_item hat_item[MAXAXES];
|
||||
int hats;
|
||||
int hotdata;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* jstkOpenDevice --
|
||||
*
|
||||
* Open and initialize a joystick device
|
||||
* Returns the filedescriptor, or -1 in case of error
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
int
|
||||
jstkOpenDevice(JoystickDevPtr joystick)
|
||||
{
|
||||
int cur_axis, cur_button;
|
||||
int is_joystick, report_id = 0;
|
||||
int got_something;
|
||||
struct hid_data *d;
|
||||
struct hid_item h;
|
||||
report_desc_t rd;
|
||||
struct jstk_bsd_hid_data *bsddata;
|
||||
|
||||
if ((joystick->fd = open(joystick->device, O_RDWR | O_NDELAY, 0)) < 0) {
|
||||
xf86Msg(X_ERROR, "Cannot open joystick '%s' (%s)\n", joystick->device,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
joystick->axes = 0;
|
||||
joystick->buttons = 0;
|
||||
|
||||
if ((rd = hid_get_report_desc(joystick->fd)) == 0)
|
||||
{
|
||||
xf86Msg(X_ERROR, "Joystick: hid_get_report_desc failed: %s\n",
|
||||
strerror(errno));
|
||||
close(joystick->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(joystick->fd, USB_GET_REPORT_ID, &report_id) < 0)
|
||||
{
|
||||
xf86Msg(X_ERROR, "Joystick: ioctl USB_GET_REPORT_ID failed: %s\n",
|
||||
strerror(errno));
|
||||
close(joystick->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsddata = (struct jstk_bsd_hid_data*) malloc(sizeof(struct jstk_bsd_hid_data));
|
||||
bsddata->dlen = hid_report_size(rd, hid_input, report_id);
|
||||
|
||||
if ((bsddata->data_buf = malloc(bsddata->dlen)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: couldn't malloc %d bytes\n", bsddata->dlen);
|
||||
hid_dispose_report_desc(rd);
|
||||
free(bsddata);
|
||||
close(joystick->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_joystick = 0;
|
||||
got_something = 0;
|
||||
cur_axis = 0;
|
||||
cur_button = 0;
|
||||
bsddata->hats = 0;
|
||||
|
||||
for (d = hid_start_parse(rd, 1 << hid_input, report_id);
|
||||
hid_get_item(d, &h); )
|
||||
{
|
||||
int usage, page;
|
||||
|
||||
page = HID_PAGE(h.usage);
|
||||
usage = HID_USAGE(h.usage);
|
||||
|
||||
/* This test is somewhat too simplistic, but this is how MicroSoft
|
||||
* does, so I guess it works for all joysticks/game pads. */
|
||||
is_joystick = is_joystick ||
|
||||
(h.kind == hid_collection &&
|
||||
page == HUP_GENERIC_DESKTOP &&
|
||||
(usage == HUG_JOYSTICK || usage == HUG_GAME_PAD));
|
||||
|
||||
if (h.kind != hid_input)
|
||||
continue;
|
||||
|
||||
if (!is_joystick)
|
||||
continue;
|
||||
|
||||
if (page == HUP_GENERIC_DESKTOP)
|
||||
{
|
||||
if (usage == HUG_HAT_SWITCH)
|
||||
{
|
||||
if ((bsddata->hats < MAXAXES) && (joystick->axes <= MAXAXES-2)) {
|
||||
got_something = 1;
|
||||
memcpy(&bsddata->hat_item[bsddata->hats],&h,sizeof(h));
|
||||
bsddata->hats++;
|
||||
joystick->axes += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (joystick->axes < MAXAXES) {
|
||||
got_something = 1;
|
||||
memcpy(&bsddata->axis_item[cur_axis],&h,sizeof(h));
|
||||
cur_axis++;
|
||||
joystick->axes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (page == HUP_BUTTON)
|
||||
{
|
||||
if (joystick->buttons < MAXBUTTONS) {
|
||||
got_something = 1;
|
||||
memcpy(&bsddata->button_item[cur_button], &h, sizeof(h));
|
||||
cur_button++;
|
||||
joystick->buttons++;
|
||||
}
|
||||
}
|
||||
}
|
||||
hid_end_parse(d);
|
||||
|
||||
if (!got_something)
|
||||
{
|
||||
free(bsddata->data_buf);
|
||||
xf86Msg(X_ERROR, "Joystick: Didn't find any usable axes.\n");
|
||||
free(bsddata);
|
||||
close(joystick->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsddata->hotdata = 0;
|
||||
joystick->devicedata = (void*) bsddata;
|
||||
xf86Msg(X_INFO, "Joystick: %d buttons, %d axes\n",
|
||||
joystick->axes, joystick->buttons);
|
||||
|
||||
return joystick->fd;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* jstkCloseDevice --
|
||||
*
|
||||
* close the handle.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
jstkCloseDevice(JoystickDevPtr joystick)
|
||||
{
|
||||
if ((joystick->fd >= 0)) {
|
||||
xf86CloseSerial(joystick->fd);
|
||||
joystick->fd = -1;
|
||||
}
|
||||
if (joystick->devicedata != NULL) {
|
||||
if ((((struct jstk_bsd_hid_data*)joystick->devicedata)->data_buf) != NULL)
|
||||
free(((struct jstk_bsd_hid_data*)joystick->devicedata)->data_buf);
|
||||
free(joystick->devicedata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* jstkReadData --
|
||||
*
|
||||
* Reads data from fd and stores it in the JoystickDevRec struct
|
||||
* fills in the type of event and the number of the button/axis
|
||||
* return 1 if success, 0 otherwise. Success does not neccessarily
|
||||
* mean that there is a new event waiting.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
int
|
||||
jstkReadData(JoystickDevPtr joystick,
|
||||
enum JOYSTICKEVENT *event,
|
||||
int *number)
|
||||
{
|
||||
int j,d;
|
||||
struct jstk_bsd_hid_data *bsddata = (struct jstk_bsd_hid_data*)(joystick->devicedata);
|
||||
|
||||
if (event != NULL) *event = EVENT_NONE;
|
||||
if (bsddata->hotdata == 0) {
|
||||
j= xf86ReadSerial(joystick->fd,
|
||||
bsddata->data_buf,
|
||||
bsddata->dlen
|
||||
);
|
||||
if (j != bsddata->dlen) {
|
||||
ErrorF("Read: %d byte! Should be %d\n",j,bsddata->dlen);
|
||||
return 0;
|
||||
}
|
||||
bsddata->hotdata = 1;
|
||||
}
|
||||
|
||||
for (j=0; j<joystick->axes - (bsddata->hats * 2); j++)
|
||||
{
|
||||
d = hid_get_data(bsddata->data_buf, &bsddata->axis_item[j]);
|
||||
d = d - (bsddata->axis_item[j].logical_maximum - bsddata->axis_item[j].logical_minimum) / 2;
|
||||
d = d * 65536 / (bsddata->axis_item[j].logical_maximum - bsddata->axis_item[j].logical_minimum);
|
||||
if (abs(d) < joystick->axis[j].deadzone) d = 0;
|
||||
if (d != joystick->axis[j].value) {
|
||||
joystick->axis[j].value = d;
|
||||
if (event != NULL) *event = EVENT_AXIS;
|
||||
if (number != NULL) *number = j;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<bsddata->hats; j++)
|
||||
{
|
||||
int a;
|
||||
int v1_data[9] = { 0, 32767, 32767, 32767, 0, -32768, -32768, -32768, 0 };
|
||||
int v2_data[9] = { -32768, -32768, 0, 32767, 32767, 32767, 0, -32767, 0 };
|
||||
a = j*2 + joystick->axes - bsddata->hats *2;
|
||||
d = hid_get_data(bsddata->data_buf, &bsddata->hat_item[j])
|
||||
- bsddata->hat_item[j].logical_minimum;
|
||||
if (joystick->axis[a].value != v1_data[d]) {
|
||||
joystick->axis[a].value = v1_data[d];
|
||||
if (event != NULL) *event = EVENT_AXIS;
|
||||
if (number != NULL) *number = a;
|
||||
return 2;
|
||||
}
|
||||
if (joystick->axis[a+1].value != v2_data[d]) {
|
||||
joystick->axis[a+1].value = v2_data[d];
|
||||
if (event != NULL) *event = EVENT_AXIS;
|
||||
if (number != NULL) *number = a+1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (j=0; j<joystick->buttons; j++)
|
||||
{
|
||||
d = hid_get_data(bsddata->data_buf, &bsddata->button_item[j]);
|
||||
if (((d == bsddata->button_item[j].logical_minimum)?0:1) != joystick->button[j].pressed) {
|
||||
joystick->button[j].pressed = (d == bsddata->button_item[j].logical_minimum)?0:1;
|
||||
if (event != NULL) *event = EVENT_BUTTON;
|
||||
if (number != NULL) *number = j;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
bsddata->hotdata = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ jstkReadProc(LocalDevicePtr local)
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (r == 2);
|
||||
} while (r == 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <xf86_OSproc.h>
|
||||
|
||||
#include "jstk.h"
|
||||
#include "linux_jstk.h"
|
||||
#include "jstk_hw.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
Reference in New Issue
Block a user