Make version 2 the main jinput version

This commit is contained in:
endolf 2006-04-29 22:29:27 +00:00
parent 4c91a4eb44
commit 559c008a02
149 changed files with 13218 additions and 10800 deletions

View file

@ -1,72 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#if !defined(eventInterface_Device_h)
#define eventInterface_Device_h
/**
* Simple abstract device class
*
* @author Jeremy Booth (jeremy@newdawnsoftware.com)
*/
class Device {
private:
public:
/** Maximum name length for a device */
const static int MAX_NAME_LENGTH = 256;
/** Return the number of relative axes for this device */
virtual int getNumberRelAxes() = 0;
/** Return the number ofr absolute axes for this device */
virtual int getNumberAbsAxes() = 0;
/** Return the number of buttons for this device */
virtual int getNumberButtons() = 0;
/** Get the name of this device */
virtual const char *getName() = 0;
/** get teh bus type */
virtual int getBusType() = 0;
virtual int getVendorID() = 0;
virtual int getProductID() = 0;
virtual int getVersion() = 0;
/** Get the supported axes/button maps */
virtual void getSupportedRelAxes(int supportedAxis[]) = 0;
virtual void getSupportedAbsAxes(int supportedAxis[]) = 0;
virtual void getSupportedButtons(int supportedButtons[]) = 0;
/** poll it */
virtual int poll() = 0;
/** get the data */
virtual void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]) = 0;
/** Get axis details */
virtual int getAbsAxisMinimum(int axisNumber) = 0;
virtual int getAbsAxisMaximum(int axisNumber) = 0;
virtual int getAbsAxisFuzz(int axisNumber) = 0;
virtual bool getFFEnabled() = 0;
virtual void rumble(float force) = 0;
virtual void cleanup() = 0;
};
#endif //eventInterface_Device_h

View file

@ -1,481 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include "eventInterfaceTypes.h"
#include "EventDevice.h"
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <linux/input.h>
#include <malloc.h>
#include <errno.h>
#include "logger.h"
EventDevice::EventDevice(char *deviceFileName) {
char tempName[Device::MAX_NAME_LENGTH-1] = "Unknown";
int i;
fd = open(deviceFileName, O_RDWR | O_NONBLOCK);
if(fd<0) {
char errorMessage[512];
sprintf(errorMessage, "Error opening device %s read/write, Force Feedback disabled for this device\n", deviceFileName);
perror(errorMessage);
fd = open(deviceFileName, O_RDONLY | O_NONBLOCK);
if(fd<0) {
/*char errorMessage[512];
sprintf(errorMessage, "Error opening device %s\n", deviceFileName);
perror(errorMessage);*/
inited = 0;
return;
}
} else {
if(ioctl(fd, EVIOCGBIT(EV_FF, sizeof(uint8_t) * 16), ff_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
if(getBit(FF_RUMBLE, ff_bitmask)==1) {
ffSupported = 1;
//LOG_TRACE("Force feedback supported for %s\n", deviceFileName);
int n_effects = 0;
if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
char errorMessage[512];
sprintf(errorMessage, "Failed to get number of effects for device %s\n", deviceFileName);
perror(errorMessage);
}
LOG_TRACE("Device %s supports %d simultanious effects\n", deviceFileName, n_effects);
effect_playing = false;
effect.type=FF_RUMBLE;
effect.id=-1;
effect.u.rumble.strong_magnitude = (int)(0x8000);
effect.u.rumble.weak_magnitude = (int)(0xc000);
effect.replay.length = 5000;
effect.replay.delay = 0;
LOG_TRACE("Uploading effect %d\n", effect.id);
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
perror("Upload effect");
}
LOG_TRACE("Uploaded effect %d\n", effect.id);
} else {
ffSupported = 0;
LOG_TRACE("Force feedback not supported for %s %d\n", deviceFileName, getBit(FF_RUMBLE, ff_bitmask));
}
}
if(ioctl(fd, EVIOCGNAME(sizeof(tempName)), tempName) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
int namelength=strlen(tempName);
name = (char *)malloc(namelength+1);
strncpy(name,tempName, namelength+1);
LOG_TRACE("Device name for device file %s is %s\n", deviceFileName, name);
uint8_t evtype_bitmask[EV_MAX/8 + 1];
memset(evtype_bitmask, 0, sizeof(evtype_bitmask));
if(ioctl(fd, EVIOCGBIT(0, EV_MAX), evtype_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
struct input_devinfo deviceInfo;
if(ioctl(fd, EVIOCGID, &deviceInfo) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
bustype = deviceInfo.bustype;
vendor = deviceInfo.vendor;
product = deviceInfo.product;
version = deviceInfo.version;
numButtons = -1;
numAbsAxes = -1;
numRelAxes = -1;
if(!(getBit(EV_KEY, evtype_bitmask))) {
numButtons = 0;
}
if(!(getBit(EV_REL, evtype_bitmask))) {
numRelAxes = 0;
}
if(!(getBit(EV_ABS, evtype_bitmask))) {
numAbsAxes = 0;
}
if(!getBit(EV_FF, evtype_bitmask)) {
ffSupported = 0;
}
if(numButtons < 0) {
// This device supports keys, deal with it.
if(ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
for(i=0;i<KEY_MAX;i++) {
buttonLookup[i]=-1;
}
short tempSupportedButtons[KEY_MAX];
numButtons = 0;
for(i=0;i<KEY_MAX;i++) {
if(getBit(i,key_bitmask)) {
tempSupportedButtons[numButtons] = i;
numButtons++;
}
}
supportedButtons = (short *)malloc(numButtons * sizeof(short));
buttonData = (uint8_t *)malloc(numButtons * sizeof(uint8_t));
for(i=0;i<numButtons;i++) {
buttonData[i] = 0;
supportedButtons[i] = tempSupportedButtons[i];
buttonLookup[supportedButtons[i]] = i;
}
}
if(numRelAxes < 0) {
// This device supports axes, deal with it.
if(ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
for(i=0;i<REL_MAX;i++) {
relAxisLookup[i]=-1;
}
short tempSupportedAxes[REL_MAX];
numRelAxes=0;
for(i=0;i<REL_MAX;i++) {
if(getBit(i,rel_bitmask)) {
tempSupportedAxes[numRelAxes] = i;
numRelAxes++;
}
}
relAxesData = (int *)malloc(numRelAxes * sizeof(int));
supportedRelAxes = (short *)malloc(numRelAxes * sizeof(short));
for(i=0;i<numRelAxes;i++) {
relAxesData[i]=0;
supportedRelAxes[i] = tempSupportedAxes[i];
relAxisLookup[supportedRelAxes[i]] = i;
}
}
if(numAbsAxes < 0) {
if(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
for(i=0;i<ABS_MAX;i++) {
absAxisLookup[i] = -1;
}
short tempSupportedAxes[ABS_MAX];
numAbsAxes=0;
for(i=0;i<ABS_MAX;i++) {
if(getBit(i,abs_bitmask)) {
tempSupportedAxes[numAbsAxes] = i;
numAbsAxes++;
}
}
absAxesData = (int *)malloc(numAbsAxes * sizeof(int));
supportedAbsAxes = (short *)malloc(numAbsAxes * sizeof(short));
for(i=0;i<numAbsAxes;i++) {
supportedAbsAxes[i] = tempSupportedAxes[i];
absAxisLookup[supportedAbsAxes[i]] = i;
}
abs_features = (struct input_absinfo *)malloc(numAbsAxes * sizeof(struct input_absinfo));
for(i=0;i<numAbsAxes;i++) {
if(ioctl(fd, EVIOCGABS(supportedAbsAxes[i]), &(abs_features[i]))) {
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
absAxesData[i] = abs_features[i].value;
}
}
inited = 1;
}
int EventDevice::isValidDevice() {
return inited;
}
int EventDevice::getNumberRelAxes(){
if(inited!=1) return -1;
return numRelAxes;
}
int EventDevice::getNumberAbsAxes(){
if(inited!=1) return -1;
return numAbsAxes;
}
int EventDevice::getNumberButtons(){
if(inited!=1) return -1;
return numButtons;
}
const char *EventDevice::getName(){
LOG_TRACE("EventDevice::getName()\n");
return name;
}
int EventDevice::getBusType(){
if(inited!=1) return -1;
return bustype;
}
int EventDevice::getVendorID(){
if(inited!=1) return -1;
return vendor;
}
int EventDevice::getProductID(){
if(inited!=1) return -1;
return product;
}
int EventDevice::getVersion(){
if(inited!=1) return -1;
return version;
}
void EventDevice::getSupportedRelAxes(int supportedAxis[]){
int i;
if(inited!=1) return;
for(i=0;i<numRelAxes; i++) {
(supportedAxis)[i] = supportedRelAxes[i];
}
}
void EventDevice::getSupportedAbsAxes(int supportedAxis[]){
int i;
if(inited!=1) return;
for(i=0;i<numAbsAxes; i++) {
(supportedAxis)[i] = supportedAbsAxes[i];
}
}
void EventDevice::getSupportedButtons(int supportedButtons[]){
int i;
if(inited!=1) return;
for(i=0;i<numButtons; i++) {
(supportedButtons)[i] = this->supportedButtons[i];
}
}
/**
* A return value of -1 means error, 0 means ok, but no change
* a return of >0 means the data for this device has changed
*/
int EventDevice::poll(){
size_t read_bytes;
struct input_event events[64];
int dataChanged=0;
if(inited!=1) return -1;
// first thing to do is reset all relative axis as mice never seem to do it
int i;
for(i=0;i<numRelAxes;i++){
if(relAxesData[i]!=0) {
dataChanged=1;
relAxesData[i]=0;
}
}
read_bytes = read(fd, events, sizeof(struct input_event) * 64);
if(read_bytes == 0) {
// no sweat, just return;
return 0;
}
if(read_bytes == -1) {
if(errno == EAGAIN) {
// No worries, we are in non blocking and noting is ready
return 0;
} else {
perror("Error reading events: ");
return -1;
}
}
if (read_bytes < (int) sizeof(struct input_event)) {
perror("Error reading events: ");
return -1;
}
int numEventsRead = (int) (read_bytes / sizeof(struct input_event));
for(i=0;i<numEventsRead;i++) {
switch(events[i].type) {
case EV_SYN:
case EV_MSC:
// not sure what to do with it, ignore for now -- JPK
break;
case EV_KEY: {
dataChanged = 1;
int buttonIndex = buttonLookup[events[i].code];
buttonData[buttonIndex] = events[i].value;
//printf("button %d translates to button %d on this device\n", events[i].code, buttonIndex);
break;
}
case EV_REL: {
dataChanged = 1;
int axisIndex = relAxisLookup[events[i].code];
relAxesData[axisIndex] += events[i].value;
//printf("rel axis %d translates to rel axis %d on this device\n", events[i].code, axisIndex);
break;
}
case EV_ABS: {
dataChanged = 1;
int axisIndex = absAxisLookup[events[i].code];
absAxesData[axisIndex] = events[i].value;
//printf("abs axis %d translates to abs axis %d on this device\n", events[i].code, axisIndex);
break;
}
case EV_LED:
// reveiced for things like numlock led change
break;
default:
fprintf(stderr, "Received event of type 0x%02X from %s, which I wasn't expecting, please report it to jinput forum at www.javagaming.org\n", events[i].type, name);
}
}
return dataChanged;
}
void EventDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){
int i;
if(inited!=1) return;
for(i=0;i<numRelAxes;i++) {
(relAxesData)[i] = this->relAxesData[i];
}
for(i=0;i<numAbsAxes;i++) {
(absAxesData)[i] = this->absAxesData[i];
}
for(i=0;i<numButtons;i++) {
(buttonData)[i] = this->buttonData[i];
}
}
int EventDevice::getAbsAxisMinimum(int axisNumber) {
return abs_features[axisNumber].minimum;
}
int EventDevice::getAbsAxisMaximum(int axisNumber) {
return abs_features[axisNumber].maximum;
}
int EventDevice::getAbsAxisFuzz(int axisNumber) {
return abs_features[axisNumber].fuzz;
}
bool EventDevice::getFFEnabled() {
if(ffSupported==1) {
//LOG_TRACE("FF is supported for %s\n", getName());
return true;
}
//LOG_TRACE("FF is not supported for %s\n", getName());
return false;
}
void EventDevice::rumble(float force) {
if(force>1) force=1;
if(force<-1) force=-1;
//LOG_TRACE("Rumbling at %d%%, (shh, pretend)\n", (int)(force*100));
if(effect_playing==true) {
stop.type=EV_FF;
stop.code = effect.id;
stop.value=0;
LOG_TRACE("Stopping effect %d\n", stop.code);
if (write(fd, (const void*) &stop, sizeof(stop)) == -1) {
perror("Failed to stop effect");
} else {
effect_playing=false;
}
}
if(force>0.666666) {
effect.u.rumble.strong_magnitude = (int)(0x8000*force);
effect.u.rumble.weak_magnitude = (int)(0xc000*force);
} else if(force>0.3333333) {
effect.u.rumble.strong_magnitude = (int)(0x8000*force);
effect.u.rumble.weak_magnitude = (int)(0xc000*0);
} else {
effect.u.rumble.strong_magnitude = (int)(0x8000*0);
effect.u.rumble.weak_magnitude = (int)(0xc000*force);
}
LOG_TRACE("Uploading effect %d\n", effect.id);
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
perror("Upload effect");
}
LOG_TRACE("Uploaded effect %d\n", effect.id);
if(effect_playing==false && force!=0) {
play.type = EV_FF;
play.code=effect.id;
play.value=1;
LOG_TRACE("Playing effect %d\n", play.code);
if (write(fd, (const void*) &play, sizeof(play)) == -1) {
perror("Failed to play effect");
} else {
effect_playing=true;
}
}
}
void EventDevice::cleanup() {
char message[512];
sprintf(message, "Closing device %s\n", name);
LOG_TRACE(message);
close(fd);
}

View file

@ -1,92 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#if !defined(eventInterface_eventDevice_h)
#define eventInterface_eventDevice_h
#include <stdint.h>
#include <linux/input.h>
#include "eventInterfaceTypes.h"
#include "Device.h"
class EventDevice : public Device {
private:
int fd;
int inited;
char *name;
int numButtons;
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
short *supportedRelAxes;
short *supportedAbsAxes;
short *supportedButtons;
int *relAxesData;
int *absAxesData;
uint8_t *buttonData;
int ffSupported;
int numRelAxes;
int numAbsAxes;
uint8_t evtype_bitmask[EV_MAX/8 + 1];
uint8_t key_bitmask[KEY_MAX/8 + 1];
uint8_t rel_bitmask[REL_MAX/8 + 1];
uint8_t abs_bitmask[ABS_MAX/8 + 1];
uint8_t ff_bitmask[16];
struct input_absinfo *abs_features;
int absAxisLookup[ABS_MAX];
int relAxisLookup[REL_MAX];
int buttonLookup[KEY_MAX];
struct ff_effect effect;
struct input_event play, stop;
bool effect_playing;
public:
EventDevice(char *deviceFilename);
int getNumberRelAxes();
int getNumberAbsAxes();
int getNumberButtons();
const char *getName();
int getBusType();
int getVendorID();
int getProductID();
int getVersion();
void getSupportedRelAxes(int supportedAxis[]);
void getSupportedAbsAxes(int supportedAxis[]);
void getSupportedButtons(int supportedButtons[]);
int poll();
void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]);
int getAbsAxisMinimum(int axisNumber);
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
int isValidDevice();
bool getFFEnabled();
void rumble(float force);
void cleanup();
};
#endif //eventInterface_eventDevice_h

View file

@ -1,200 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include "eventInterfaceTypes.h"
#include "JoystickDevice.h"
#include <stdio.h>
#include <linux/input.h>
#include <linux/joystick.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include "logger.h"
JoystickDevice::JoystickDevice(char *deviceFileName) {
char tempName[Device::MAX_NAME_LENGTH-1] = "Unknown";
int i;
LOG_TRACE("Trying to open %s\n", deviceFileName);
fd = open(deviceFileName, O_RDONLY | O_NONBLOCK);
/*if(fd<0) {
char errorMessage[512];
sprintf(errorMessage, "Error opening device %s\n", deviceFileName);
perror(errorMessage);
}*/
if(fd>0){
LOG_TRACE("Opened %s, trying to get device name\n", deviceFileName);
if(ioctl(fd, JSIOCGNAME(sizeof(tempName)), tempName) < 0) {
LOG_TRACE("Failed to get device name for %s\n", deviceFileName);
char errorMessage[512];
sprintf(errorMessage, "Error reading device %s\n", deviceFileName);
perror(errorMessage);
}
int namelength=strlen(tempName);
name = (char *)malloc(namelength+1);
strncpy(name,tempName, namelength+1);
char tempNumButtons;
char tempNumAxes;
LOG_TRACE("Getting button and axes information for %s\n", deviceFileName);
ioctl (fd, JSIOCGBUTTONS, &tempNumButtons);
ioctl (fd, JSIOCGAXES, &tempNumAxes);
numButtons = tempNumButtons;
numAbsAxes = tempNumAxes;
//fprintf(stderr, "Got joystick %s with %d buttons and %d axes\n", tempName, numButtons, numAbsAxes);
//buttonData = (uint8_t *)malloc(numButtons * sizeof(uint8_t));
buttonData = new uint8_t[numButtons];
//absAxesData = (int *)malloc(numAbsAxes * sizeof(int));
absAxesData = new int[numAbsAxes];
LOG_TRACE("Initialisation of %s completed\n", deviceFileName);
inited = 1;
} else {
LOG_TRACE("Failed to open device %s\n", deviceFileName);
inited = 0;
}
}
int JoystickDevice::isValidDevice() {
return inited;
}
int JoystickDevice::getNumberRelAxes(){
if(inited!=1) return -1;
return 0;
}
int JoystickDevice::getNumberAbsAxes(){
if(inited!=1) return -1;
return numAbsAxes;
}
int JoystickDevice::getNumberButtons(){
if(inited!=1) return -1;
return numButtons;
}
const char *JoystickDevice::getName(){
return name;
}
int JoystickDevice::getBusType(){
if(inited!=1) return -1;
return 0;
}
int JoystickDevice::getVendorID(){
if(inited!=1) return -1;
return 0;
}
int JoystickDevice::getProductID(){
if(inited!=1) return -1;
return 0;
}
int JoystickDevice::getVersion(){
if(inited!=1) return -1;
return 0;
}
void JoystickDevice::getSupportedRelAxes(int supportedAxis[]){
}
void JoystickDevice::getSupportedAbsAxes(int supportedAxis[]){
}
void JoystickDevice::getSupportedButtons(int supportedButtons[]){
}
/**
* A return value of -1 means error, 0 means ok, but no change
* a return of >0 means the data for this device has changed
*/
int JoystickDevice::poll(){
struct js_event event;
int numEvents = 0;
while(read(fd, &event, sizeof event) > 0) {
numEvents++;
event.type &= ~JS_EVENT_INIT;
if(event.type == JS_EVENT_BUTTON) {
buttonData[event.number] = event.value;
} else if(event.type == JS_EVENT_AXIS) {
absAxesData[event.number] = event.value;
}
}
// EAGAIN is returned when the queue is empty
if(errno != EAGAIN) {
printf("Something went wrong getting an event\n");
}
return numEvents;
}
void JoystickDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){
int i;
if(inited!=1) return;
for(i=0;i<numAbsAxes;i++) {
(absAxesData)[i] = this->absAxesData[i];
}
for(i=0;i<numButtons;i++) {
(buttonData)[i] = this->buttonData[i];
}
}
int JoystickDevice::getAbsAxisMinimum(int axisNumber) {
return -32767;
}
int JoystickDevice::getAbsAxisMaximum(int axisNumber) {
return 32767;
}
int JoystickDevice::getAbsAxisFuzz(int axisNumber) {
return 0;
}
bool JoystickDevice::getFFEnabled() {
return false;
}
void JoystickDevice::rumble(float force) {
return;
}
void JoystickDevice::cleanup() {
close(fd);
}

View file

@ -1,70 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#ifndef JoystickDevice_h
#define JoystickDevice_h
#include <stdint.h>
#include <linux/input.h>
#include "eventInterfaceTypes.h"
#include "Device.h"
class JoystickDevice : public Device {
private:
int fd;
int inited;
char *name;
int numButtons;
int *absAxesData;
uint8_t *buttonData;
int numAbsAxes;
public:
JoystickDevice(char *deviceFilename);
int getNumberRelAxes();
int getNumberAbsAxes();
int getNumberButtons();
const char *getName();
int getBusType();
int getVendorID();
int getProductID();
int getVersion();
void getSupportedRelAxes(int supportedAxis[]);
void getSupportedAbsAxes(int supportedAxis[]);
void getSupportedButtons(int supportedButtons[]);
int poll();
void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]);
int getAbsAxisMinimum(int axisNumber);
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
int isValidDevice();
bool getFFEnabled();
void rumble(float force);
void cleanup();
};
#endif //eventInterface_eventDevice_h

View file

@ -1,134 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include "eventInterfaceTypes.h"
#include "JoystickDevice.h"
#include "MixedDevice.h"
#include <stdio.h>
#include <linux/input.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
MixedDevice::MixedDevice(JoystickDevice *jsDevice, EventDevice *evDevice) {
joystickDevice = jsDevice;
eventDevice = evDevice;
}
int MixedDevice::getNumberRelAxes(){
eventDevice->getNumberRelAxes();
}
int MixedDevice::getNumberAbsAxes(){
return eventDevice->getNumberAbsAxes();
}
int MixedDevice::getNumberButtons(){
return eventDevice->getNumberButtons();
}
const char *MixedDevice::getName(){
return eventDevice->getName();
}
int MixedDevice::getBusType(){
return eventDevice->getBusType();
}
int MixedDevice::getVendorID(){
return eventDevice->getVendorID();
}
int MixedDevice::getProductID(){
return eventDevice->getProductID();
}
int MixedDevice::getVersion(){
return eventDevice->getVersion();
}
void MixedDevice::getSupportedRelAxes(int supportedAxis[]){
return eventDevice->getSupportedRelAxes(supportedAxis);
}
void MixedDevice::getSupportedAbsAxes(int supportedAxis[]){
return eventDevice->getSupportedAbsAxes(supportedAxis);
}
void MixedDevice::getSupportedButtons(int supportedButtons[]){
return eventDevice->getSupportedButtons(supportedButtons);
}
/**
* A return value of -1 means error, 0 means ok, but no change
* a return of >0 means the data for this device has changed
*/
int MixedDevice::poll(){
eventDevice->poll();
return joystickDevice->poll();
}
void MixedDevice::getPolledData(int relAxesData[], int absAxesData[], int buttonData[]){
int i;
joystickDevice->getPolledData(new int[joystickDevice->getNumberRelAxes()], absAxesData, new int[joystickDevice->getNumberButtons()]);
eventDevice->getPolledData(relAxesData, new int[eventDevice->getNumberAbsAxes()], buttonData);
}
int MixedDevice::getAbsAxisMinimum(int axisNumber) {
return joystickDevice->getAbsAxisMinimum(axisNumber);
}
int MixedDevice::getAbsAxisMaximum(int axisNumber) {
return joystickDevice->getAbsAxisMaximum(axisNumber);
}
int MixedDevice::getAbsAxisFuzz(int axisNumber) {
return joystickDevice->getAbsAxisFuzz(axisNumber);
}
bool MixedDevice::getFFEnabled() {
return eventDevice->getFFEnabled();
}
void MixedDevice::rumble(float force) {
eventDevice->rumble(force);
}
void MixedDevice::cleanup() {
if(joystickDevice!=0 && eventDevice!=0) {
joystickDevice->cleanup();
eventDevice->cleanup();
free(joystickDevice);
free(eventDevice);
joystickDevice=0;
eventDevice=0;
}
}

View file

@ -1,70 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#ifndef MixedDevice_h
#define MixedDevice_h
#include <stdint.h>
#include <linux/input.h>
#include "eventInterfaceTypes.h"
#include "Device.h"
#include "EventDevice.h"
#include "JoystickDevice.h"
#include "MixedDevice.h"
class MixedDevice : public Device {
private:
JoystickDevice *joystickDevice;
EventDevice *eventDevice;
public:
MixedDevice(JoystickDevice *joystickDevice, EventDevice *eventDevice);
int getNumberRelAxes();
int getNumberAbsAxes();
int getNumberButtons();
const char *getName();
int getBusType();
int getVendorID();
int getProductID();
int getVersion();
void getSupportedRelAxes(int supportedAxis[]);
void getSupportedAbsAxes(int supportedAxis[]);
void getSupportedButtons(int supportedButtons[]);
void getSupportedRelAxes(short supportedAxis[]);
void getSupportedAbsAxes(short supportedAxis[]);
void getSupportedButtons(short supportedButtons[]);
int poll();
void getPolledData(int relAxesData[], int absAxesData[], int buttonData[]);
int getAbsAxisMinimum(int axisNumber);
int getAbsAxisMaximum(int axisNumber);
int getAbsAxisFuzz(int axisNumber);
bool getFFEnabled();
void rumble(float force);
void cleanup();
};
#endif //eventInterface_eventDevice_h

View file

@ -6,50 +6,43 @@
<!-- The idea is that both Ant and NetBeans have to know what the package root is -->
<!-- for the classes in your application. -->
<project name="JInput Linux port, Native code" basedir="." default="compileNativeJinputLib">
<!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! -->
<!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. -->
<property name="libname" value="libjinput-linux.so"/>
<target name="init">
<!-- You can set up any variables you want used throughout the script here. -->
<!-- property name="hello" value="world"/-->
<!-- To use e.g. Jikes, uncomment this line. -->
<!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) -->
<!-- <property name="build.compiler" value="jikes"/> -->
<!-- You might like to set up some overridable paths, etc.: -->
<!-- <property name="mylib" value="../lib/mylib.jar"/> -->
<mkdir dir="build"/>
<mkdir dir="apidoc"/>
</target>
<target name="createNativeDefinitions.java" depends="init">
<exec dir="." executable="./getDefinitions" os="Linux" output="../java/net/java/games/input/NativeDefinitions.java">
<arg line="/usr/include/linux/input.h"/>
</exec>
</target>
</target>
<target name="createJNIHeaders" depends="init">
<javah>
<classpath>
<pathelement path="."/>
<pathelement location="jinput.jar"/>
</classpath>
<class name="net.java.games.input.LinuxDevice"/>
<class name="net.java.games.input.LinuxEnvironmentPlugin"/>
<class name="net.java.games.input.LinuxKeyboard"/>
</javah>
</target>
<target name="compileNativeEventLib" depends="init">
<exec dir="." executable="g++" os="Linux">
<arg line="--shared -DLOGTRACE -o libeventInterface.so eventInterface.cpp EventDevice.cpp"/>
</exec>
</target>
<target depends="init" name="createNativeDefinitions.java">
<exec dir="." executable="gawk" os="Linux" output="../java/net/java/games/input/NativeDefinitions.java">
<arg line="-f"/>
<arg line="getDefinitions"/>
<arg line="/usr/include/linux/input.h"/>
</exec>
</target>
<target name="clean">
<delete>
<fileset dir="." includes="*.o"/>
<fileset file="${libname}"/>
</delete>
</target>
<target name="compileNativeJinputLib" depends="init">
<exec dir="." executable="g++" os="Linux">
<arg line="-I${java.home}/include -I${java.home}/include/linux -I${java.home}/../include -I${java.home}/../include/linux --shared -DLOGTRACE -o libjinput-linux.so jinput.cpp eventInterface.cpp EventDevice.cpp joystickInterface.cpp JoystickDevice.cpp MixedDevice.cpp"/>
</exec>
<apply dir="." executable="cc" os="Linux" dest="." skipemptyfilesets="true" failonerror="true">
<arg line="-O2 -Wall -c -fPIC"/>
<arg value="-I${java.home}/include"/>
<arg value="-I${java.home}/include/linux"/>
<arg value="-I../../../common/src/native"/>
<mapper type="glob" from="*.c" to="*.o"/>
<fileset dir="." includes="*.c"/>
<fileset dir="../../../common/src/native" includes="*.c"/>
</apply>
<apply dir="." parallel="true" executable="cc" os="Linux" failonerror="true">
<arg line="-shared -O2 -Wall -o ${libname}"/>
<fileset dir="." includes="*.o"/>
</apply>
<apply dir="." parallel="true" executable="strip" os="Linux" failonerror="true">
<fileset file="${libname}"/>
</apply>
</target>
</project>

View file

@ -1,147 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include <sys/dir.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/input.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include "Device.h"
#include "EventDevice.h"
#include "logger.h"
int evNumDevices;
int eventInterfaceVersion;
Device **evDeviceList;
int evInited = 0;
int evFileFilter(const struct direct *entry) {
if (strncmp(entry->d_name, "event", 5) == 0) {
return 1;
}
return 0;
}
int evGetDeviceFiles(char ***filenames) {
struct direct **files;
int num_files, i;
char dirName[] = {"/dev/input"};
num_files = scandir(dirName, &files, &evFileFilter, alphasort);
*filenames = (char **)malloc(num_files * sizeof(char *));
for(i=0;i<num_files;i++) {
char *filename = files[i]->d_name;
char *fullFileName;
fullFileName = (char *)malloc((strlen(dirName) + 1 + strlen(filename) + 1));
sprintf(fullFileName, "%s/%s", dirName, filename);
(*filenames)[i] = fullFileName;
}
return num_files;
}
int evInit() {
int fd=-1;
int i;
char **deviceFileNames;
int numDeviceFiles;
numDeviceFiles = evGetDeviceFiles(&deviceFileNames);
if(numDeviceFiles<0) {
return -1;
}
if ((fd = open(deviceFileNames[0], O_RDONLY)) <0) {
evNumDevices=0;
evInited=1;
return 0;
}
if (ioctl(fd, EVIOCGVERSION, &eventInterfaceVersion)) {
close(fd);
evNumDevices=0;
evInited=1;
return 0;
}
if(fd>=0) {close(fd);}
Device *tempDeviceList[numDeviceFiles];
evNumDevices = 0;
for(i=0;i<numDeviceFiles;i++) {
EventDevice *tempDevice = new EventDevice(deviceFileNames[i]);
if(tempDevice->isValidDevice()==1) {
tempDeviceList[i] = tempDevice;
evNumDevices++;
} else {
tempDeviceList[i] = NULL;
}
}
int highDeviceCountNumber = i;
int evTempDeviceCount = 0;
// Now we know for certain which devices are open, we can take notes
evDeviceList = (Device **)malloc(evNumDevices * sizeof(Device *));
for(i=0;i<evNumDevices;i++) {
while(tempDeviceList[evTempDeviceCount] == NULL) {
evTempDeviceCount++;
}
evDeviceList[i] = tempDeviceList[evTempDeviceCount];
LOG_TRACE("Copied temp event device %d to event device %d\n", evTempDeviceCount, i);
evTempDeviceCount++;
}
evInited=1;
return 0;
}
int evGetEventInterfaceVersionNumber() {
return eventInterfaceVersion;
}
int evGetNumberDevices() {
if(evInited) {
return evNumDevices;
}
return -1;
}
void evGetDevices(Device **theirDeviceList) {
int i;
for(i=0;i<evNumDevices;i++) {
theirDeviceList[i] = evDeviceList[i];
}
}

View file

@ -1,37 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#if !defined(eventInterface_h)
#define eventInterface_h
#include "Device.h"
int evGetEventInterfaceVersionNumber();
int evInit();
int evGetNumberDevices();
void evGetDevices(Device **deviceList);
#endif //eventInterface_h

View file

@ -1,27 +0,0 @@
#if !defined(eventInterfaceTypes_h)
#define eventInterfaceTypes_h
#include <linux/input.h>
#include <stdint.h>
#define getBit(bit, bitField) (bitField[bit/8] & (1 << (bit%8)))
struct input_devinfo {
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
};
/** removed for compatability with input.h --JPK
struct input_absinfo {
int value;
int minimum;
int maximum;
int fuzz;
int flat;
};
*/
#endif //eventInterfaceTypes_h

View file

@ -29,7 +29,7 @@ NR == 1 {
printf("package net.java.games.input;\n\n")
printf("\n");
printf("/**\n * This file is generated from %s please do not edit\n */\n", FILENAME);
printf("public class NativeDefinitions {\n")
printf("class NativeDefinitions {\n")
}
/#define ABS_/ {
printf(" public static final int %s = %s;\n", $2, $3)
@ -46,6 +46,15 @@ NR == 1 {
/#define BUS_/ {
printf(" public static final int %s = %s;\n", $2, $3)
}
/#define EV_/ {
printf(" public static final int %s = %s;\n", $2, $3)
}
/#define FF_/ {
printf(" public static final int %s = %s;\n", $2, $3)
}
/#define USAGE_/ {
printf(" public static final int %s = %s;\n", $2, $3)
}
END {
printf("}\n");
}

View file

@ -1,357 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "net_java_games_input_JInputLibrary.h"
#include "Device.h"
#include "EventDevice.h"
#include "JoystickDevice.h"
#include "MixedDevice.h"
#include "eventInterface.h"
#include "joystickInterface.h"
#include "logger.h"
Device **jinputDeviceList;
int jinputNumDevices;
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeInit
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_nativeInit
(JNIEnv *, jclass) {
LOG_TRACE("Initing event interface\n");
if(evInit()!=0) {
fprintf(stderr, "Could not find any working event devices\n");
// return -1;
}
LOG_TRACE("Initing joystick interface\n");
if(jsInit()!=0) {
fprintf(stderr, "Could not find any working joystick devices\n");
// return -1;
}
LOG_TRACE("Getting the number of event devices\n");
int numEventDevices = evGetNumberDevices();
EventDevice *eventDevices[numEventDevices];
LOG_TRACE("Getting %d event devices\n", numEventDevices);
evGetDevices((Device **)eventDevices);
LOG_TRACE("Getting the number of joystick devices\n");
int numJoysticks = jsGetNumberDevices();
JoystickDevice *jsDevices[numJoysticks];
LOG_TRACE("Getting %d joystick devices\n", numJoysticks);
jsGetDevices((Device **)jsDevices);
int i;
int j;
int joystickPtr = 0;
jinputDeviceList = (Device **)malloc((numEventDevices + numJoysticks) * sizeof(Device *));
for(i=0;i<numEventDevices;i++) {
EventDevice *eventDevice = eventDevices[i];
int deviceCountCache = jinputNumDevices;
for(j=joystickPtr;j<numJoysticks;j++) {
JoystickDevice *jsDevice = jsDevices[j];
LOG_TRACE("Getting device information for event device %d and joystick %d\n", i, j);
if((jsDevice->getNumberButtons() == eventDevice->getNumberButtons()) && (jsDevice->getNumberAbsAxes() == (eventDevice->getNumberAbsAxes() + eventDevice->getNumberRelAxes()))) {
const char *jsName = jsDevice->getName();
const char *eventDeviceName = eventDevice->getName();
if(strcmp(jsName, eventDeviceName) == 0) {
// The current event device is the curre joystick device too
LOG_TRACE("Creating a mixed device with id %d, combining event device %d and joystick device %d\n", jinputNumDevices, i, j);
jinputDeviceList[jinputNumDevices] = new MixedDevice(jsDevice, eventDevice);
jsDevices[j] = NULL;
j++;
jinputNumDevices++;
joystickPtr = j;
j = numJoysticks;
}
}
/*if(jinputNumDevices == deviceCountCache) {
fprintf(stderr, "event device \"%s\" doesn't match js \"%s\"\n", eventDevice->getName(), jsDevice->getName());
fprintf(stderr, "event device has %d rel axes, %d abs axis and %d buttons\n", eventDevice->getNumberRelAxes(), eventDevice->getNumberAbsAxes(), eventDevice->getNumberButtons());
fprintf(stderr, "js device has %d axes and %d buttons\n", jsDevice->getNumberAbsAxes(), jsDevice->getNumberButtons());
} else {
fprintf(stderr, "event device %s did match js %s\n", eventDevice->getName(), jsDevice->getName());
}*/
}
if(jinputNumDevices == deviceCountCache) {
jinputDeviceList[jinputNumDevices] = eventDevice;
jinputNumDevices++;
}
}
for(i=0;i<numJoysticks;i++) {
if(jsDevices[i]!=NULL) {
LOG_TRACE("Copying joystick device %d to jinput device list %d\n", i, jinputNumDevices);
jinputDeviceList[jinputNumDevices] = jsDevices[i];
jinputNumDevices++;
}
}
return(0);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getDeviceName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_net_java_games_input_JInputLibrary_getDeviceName
(JNIEnv *env, jclass, jint deviceID) {
LOG_TRACE("Gettign device name for jinput device %d.\n", deviceID);
LOG_TRACE("jinput device %d is %d\n", deviceID, jinputDeviceList[deviceID]);
LOG_TRACE("Gettign device name for jinput device %d, (%s)\n", deviceID, jinputDeviceList[deviceID]->getName());
return env->NewStringUTF(jinputDeviceList[deviceID]->getName());
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumAbsAxes
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumAbsAxes
(JNIEnv *env, jclass, jint deviceID) {
LOG_TRACE("Gettign number of absolute axes for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberAbsAxes());
return jinputDeviceList[deviceID]->getNumberAbsAxes();
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumRelAxes
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumRelAxes
(JNIEnv *env, jclass, jint deviceID) {
LOG_TRACE("Gettign number of relative axes for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberRelAxes());
return jinputDeviceList[deviceID]->getNumberRelAxes();
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumButtons
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumButtons
(JNIEnv *, jclass, jint deviceID) {
LOG_TRACE("Gettign number of buttons for jinput device %d (%d)\n", deviceID, jinputDeviceList[deviceID]->getNumberButtons());
return jinputDeviceList[deviceID]->getNumberButtons();
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumberOfDevices
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumberOfDevices
(JNIEnv *, jclass) {
return jinputNumDevices;
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedAbsAxes
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedAbsAxes
(JNIEnv *env, jclass, jint deviceID, jintArray axesData) {
jint *axisReturns = env->GetIntArrayElements(axesData, 0);
LOG_TRACE("Getting suported absolute axes for jinput device %d\n", deviceID);
jinputDeviceList[deviceID]->getSupportedAbsAxes(axisReturns);
env->ReleaseIntArrayElements(axesData, axisReturns, 0);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedRelAxes
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedRelAxes
(JNIEnv *env, jclass, jint deviceID, jintArray axesData) {
jint *axisReturns = env->GetIntArrayElements(axesData, 0);
LOG_TRACE("Getting suported relative axes for jinput device %d\n", deviceID);
jinputDeviceList[deviceID]->getSupportedRelAxes(axisReturns);
env->ReleaseIntArrayElements(axesData, axisReturns, 0);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedButtons
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedButtons
(JNIEnv *env, jclass, jint deviceID, jintArray buttonData) {
jint *buttonDataElements = env->GetIntArrayElements(buttonData, 0);
LOG_TRACE("Getting supported buttons for jinput device %d\n", deviceID);
jinputDeviceList[deviceID]->getSupportedButtons(buttonDataElements);
env->ReleaseIntArrayElements(buttonData, buttonDataElements, 0);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: poll
* Signature: (I[I[I[I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_poll
(JNIEnv *env, jclass, jint deviceID, jintArray buttons, jintArray relAxes, jintArray absAxes) {
jint *buttonElements = env->GetIntArrayElements(buttons, 0);
jint *relAxesElements = env->GetIntArrayElements(relAxes, 0);
jint *absAxesElements = env->GetIntArrayElements(absAxes, 0);
LOG_POLL_TRACE("Polling jinput device %d\n", deviceID);
int retval = jinputDeviceList[deviceID]->poll();
LOG_POLL_TRACE("Getting polled data for device %d\n", deviceID);
jinputDeviceList[deviceID]->getPolledData(relAxesElements, absAxesElements, buttonElements);
env->ReleaseIntArrayElements(buttons, buttonElements, 0);
env->ReleaseIntArrayElements(relAxes, relAxesElements, 0);
env->ReleaseIntArrayElements(absAxes, absAxesElements, 0);
return retval;
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisFuzz
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisFuzz
(JNIEnv *, jclass, jint deviceID, jint axisID) {
LOG_TRACE("Getting fuzz data for axis %d on device %d\n", axisID, deviceID);
return jinputDeviceList[deviceID]->getAbsAxisFuzz(axisID);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisMaximum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMaximum
(JNIEnv *, jclass, jint deviceID, jint axisID) {
LOG_TRACE("Getting absolute axes maximum value data for axis %d on device %d\n", axisID, deviceID);
return jinputDeviceList[deviceID]->getAbsAxisMaximum(axisID);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisMinimum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMinimum
(JNIEnv *, jclass, jint deviceID, jint axisID) {
LOG_TRACE("Getting absolute axes minimum value data for axis %d on device %d\n", axisID, deviceID);
return jinputDeviceList[deviceID]->getAbsAxisMinimum(axisID);
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNativePortType
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNativePortType
(JNIEnv *, jclass, jint deviceID) {
LOG_TRACE("Getting bus type for device %d\n", deviceID);
return jinputDeviceList[deviceID]->getBusType();
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: getFFEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_net_java_games_input_JInputLibrary_getFFEnabled
(JNIEnv *, jclass, jint deviceID) {
LOG_TRACE("Getting FFEnabled status for device %d\n", deviceID);
if(jinputDeviceList[deviceID]->getFFEnabled()) {
//LOG_TRACE("jinput lib thinks device %d is ff enabled\n", deviceID);
return JNI_TRUE;
}
//LOG_TRACE("jinput lib thinks device %d is ff disabled\n", deviceID);
return JNI_FALSE;
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeRumble
* Signature: (IF)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeRumble
(JNIEnv *, jclass, jint deviceID, jfloat force) {
if(jinputDeviceList[deviceID]!=0) {
LOG_TRACE("Setting rumble on device %d to %d\n", deviceID, force);
jinputDeviceList[deviceID]->rumble(force);
}
}
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeCleanup
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeCleanup
(JNIEnv *, jclass, jint deviceID) {
if(jinputDeviceList[deviceID]!=0) {
LOG_TRACE("Cleaning up device %d\n", deviceID);
jinputDeviceList[deviceID]->cleanup();
free(jinputDeviceList[deviceID]);
jinputDeviceList[deviceID]=0;
}
}

View file

@ -1,160 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#include <sys/dir.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/joystick.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include "Device.h"
#include "JoystickDevice.h"
int jsNumDevices;
int joystickInterfaceVersion;
Device **jsDeviceList;
int jsInited = 0;
int jsFileFilter(const struct direct *entry) {
if (strncmp(entry->d_name, "js", 2) == 0) {
return 1;
}
return 0;
}
int jsGetDeviceFiles(char ***filenames) {
struct direct **files;
int num_files, i;
char dirName[12];
sprintf(dirName, "/dev/input");
num_files = scandir(dirName, &files, &jsFileFilter, alphasort);
if(num_files==0) {
sprintf(dirName, "/dev");
num_files = scandir(dirName, &files, &jsFileFilter, alphasort);
}
*filenames = (char **)malloc(num_files * sizeof(char *));
for(i=0;i<num_files;i++) {
char *filename = files[i]->d_name;
char *fullFileName;
fullFileName = (char *)malloc((strlen(dirName) + 1 + strlen(filename) + 1));
sprintf(fullFileName, "%s/%s", dirName, filename);
(*filenames)[i] = fullFileName;
}
return num_files;
}
int jsInit() {
int fd=-1;
int i;
char **deviceFileNames;
int numDeviceFiles;
numDeviceFiles = jsGetDeviceFiles(&deviceFileNames);
if(numDeviceFiles<0) {
return -1;
}
if(numDeviceFiles==0) {
jsNumDevices = 0;
jsInited=1;
return 0;
}
if ((fd = open(deviceFileNames[0], O_RDONLY)) <0) {
jsNumDevices = 0;
jsInited=1;
return 0;
}
if (ioctl(fd, JSIOCGVERSION, &joystickInterfaceVersion)) {
close(fd);
jsNumDevices = 0;
jsInited=1;
return 0;
}
if(fd>=0) {close(fd);}
Device *tempDeviceList[numDeviceFiles];
jsNumDevices = 0;
for(i=0;i<numDeviceFiles;i++) {
JoystickDevice *tempDevice = new JoystickDevice(deviceFileNames[i]);
// The device has a copy of the name, free the memory
free(deviceFileNames[i]);
if(tempDevice->isValidDevice()==1) {
tempDeviceList[i] = tempDevice;
jsNumDevices++;
}
}
int jsTempDeviceCount = 0;
// Now we know for certain which devices are open, we can take notes
jsDeviceList = (Device **)malloc(jsNumDevices * sizeof(Device *));
for(i=0;i<jsNumDevices;i++) {
while(tempDeviceList[jsTempDeviceCount] == NULL) {
jsTempDeviceCount++;
}
jsDeviceList[i] = tempDeviceList[jsTempDeviceCount];
//printf("Copied joystick %d to %d\n", jsTempDeviceCount, i);
jsTempDeviceCount++;
}
// Free the file names array, which should now be free anyway.
free(deviceFileNames);
jsInited=1;
return 0;
}
int jsGetJoystickInterfaceVersionNumber() {
return joystickInterfaceVersion;
}
int jsGetNumberDevices() {
if(jsInited) {
return jsNumDevices;
}
return -1;
}
void jsGetDevices(Device **theirDeviceList) {
int i;
for(i=0;i<jsNumDevices;i++) {
theirDeviceList[i] = jsDeviceList[i];
}
}

View file

@ -1,37 +0,0 @@
/**
* Copyright (C) 2003 Jeremy Booth (jeremy@newdawnsoftware.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution.
* The name of the author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*/
#if !defined(joystickInterface_h)
#define joystickInterface_h
#include "Device.h"
int jsGetJoystickInterfaceVersionNumber();
int jsInit();
int jsGetNumberDevices();
void jsGetDevices(Device **deviceList);
#endif //joystickInterface_h

View file

@ -1,11 +0,0 @@
#ifdef LOGTRACE
#define LOG_TRACE(args...) printf(args)
#else
#define LOG_TRACE(args...)
#endif
#ifdef LOGPOLLTRACE
#define LOG_POLL_TRACE(args...) LOG_TRACE(args...)
#else
#define LOG_POLL_TRACE(args...)
#endif

View file

@ -1,156 +0,0 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class net_java_games_input_JInputLibrary */
#ifndef _Included_net_java_games_input_JInputLibrary
#define _Included_net_java_games_input_JInputLibrary
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: inited */
/* Inaccessible static: workerThreadMonitor */
/* Inaccessible static: shutdown */
/* Inaccessible static: shutdownThreadMonitor */
/* Inaccessible static: cleanupDone */
/* Inaccessible static: rumbler */
/* Inaccessible static: force */
/*
* Class: net_java_games_input_JInputLibrary
* Method: getDeviceName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_net_java_games_input_JInputLibrary_getDeviceName
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumAbsAxes
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumAbsAxes
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumRelAxes
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumRelAxes
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumButtons
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumButtons
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeInit
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_nativeInit
(JNIEnv *, jclass);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNumberOfDevices
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNumberOfDevices
(JNIEnv *, jclass);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedAbsAxes
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedAbsAxes
(JNIEnv *, jclass, jint, jintArray);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedRelAxes
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedRelAxes
(JNIEnv *, jclass, jint, jintArray);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getSupportedButtons
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_getSupportedButtons
(JNIEnv *, jclass, jint, jintArray);
/*
* Class: net_java_games_input_JInputLibrary
* Method: poll
* Signature: (I[I[I[I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_poll
(JNIEnv *, jclass, jint, jintArray, jintArray, jintArray);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisFuzz
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisFuzz
(JNIEnv *, jclass, jint, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisMaximum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMaximum
(JNIEnv *, jclass, jint, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getAbsAxisMinimum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getAbsAxisMinimum
(JNIEnv *, jclass, jint, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getNativePortType
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_net_java_games_input_JInputLibrary_getNativePortType
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: getFFEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_net_java_games_input_JInputLibrary_getFFEnabled
(JNIEnv *, jclass, jint);
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeRumble
* Signature: (IF)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeRumble
(JNIEnv *, jclass, jint, jfloat);
/*
* Class: net_java_games_input_JInputLibrary
* Method: nativeCleanup
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_net_java_games_input_JInputLibrary_nativeCleanup
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,257 @@
/*
* %W% %E%
*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
/*****************************************************************************
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materails provided with the distribution.
*
* Neither the name Sun Microsystems, Inc. or the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for us in
* the design, construction, operation or maintenance of any nuclear facility
*
*****************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "util.h"
#include "net_java_games_input_LinuxEventDevice.h"
JNIEXPORT jlong JNICALL Java_net_java_games_input_LinuxEventDevice_nOpen(JNIEnv *env, jclass unused, jstring path, jboolean rw_flag) {
const char *path_str = (*env)->GetStringUTFChars(env, path, NULL);
if (path_str == NULL)
return -1;
int flags = rw_flag == JNI_TRUE ? O_RDWR : O_RDONLY;
flags = flags | O_NONBLOCK;
int fd = open(path_str, flags);
if (fd == -1)
throwIOException(env, "Failed to open device %s (%d)\n", path_str, errno);
(*env)->ReleaseStringUTFChars(env, path, path_str);
return fd;
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nClose(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
int result = close(fd);
if (result == -1)
throwIOException(env, "Failed to close device (%d)\n", errno);
}
JNIEXPORT jstring JNICALL Java_net_java_games_input_LinuxEventDevice_nGetName(JNIEnv *env, jclass unused, jlong fd_address) {
#define BUFFER_SIZE 1024
int fd = (int)fd_address;
char device_name[BUFFER_SIZE];
if (ioctl(fd, EVIOCGNAME(BUFFER_SIZE), device_name) == -1) {
throwIOException(env, "Failed to get device name (%d)\n", errno);
return NULL;
}
jstring jstr = (*env)->NewStringUTF(env, device_name);
return jstr;
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetKeyStates(JNIEnv *env, jclass unused, jlong fd_address, jbyteArray bits_array) {
int fd = (int)fd_address;
jsize len = (*env)->GetArrayLength(env, bits_array);
jbyte *bits = (*env)->GetByteArrayElements(env, bits_array, NULL);
if (bits == NULL)
return;
int res = ioctl(fd, EVIOCGKEY(len), bits);
(*env)->ReleaseByteArrayElements(env, bits_array, bits, 0);
if (res == -1)
throwIOException(env, "Failed to get device key states (%d)\n", errno);
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nGetVersion(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
int version;
if (ioctl(fd, EVIOCGVERSION, &version) == -1) {
throwIOException(env, "Failed to get device version (%d)\n", errno);
return -1;
}
return version;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nGetNumEffects(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
int num_effects;
if (ioctl(fd, EVIOCGEFFECTS, &num_effects) == -1) {
throwIOException(env, "Failed to get number of device effects (%d)\n", errno);
return -1;
}
return num_effects;
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetDeviceUsageBits(JNIEnv *env, jclass unused, jlong fd_address, jbyteArray usages_array) {
#if EV_VERSION >= 0x010001
int fd = (int)fd_address;
jsize len = (*env)->GetArrayLength(env, usages_array);
jbyte *usages = (*env)->GetByteArrayElements(env, usages_array, NULL);
if (usages == NULL)
return;
int res = ioctl(fd, EVIOCGUSAGE(len), usages);
(*env)->ReleaseByteArrayElements(env, usages_array, usages, 0);
if (res == -1)
throwIOException(env, "Failed to get device usages (%d)\n", errno);
#endif
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetBits(JNIEnv *env, jclass unused, jlong fd_address, jint evtype, jbyteArray bits_array) {
int fd = (int)fd_address;
jsize len = (*env)->GetArrayLength(env, bits_array);
jbyte *bits = (*env)->GetByteArrayElements(env, bits_array, NULL);
if (bits == NULL)
return;
int res = ioctl(fd, EVIOCGBIT(evtype, len), bits);
(*env)->ReleaseByteArrayElements(env, bits_array, bits, 0);
if (res == -1)
throwIOException(env, "Failed to get device bits (%d)\n", errno);
}
JNIEXPORT jobject JNICALL Java_net_java_games_input_LinuxEventDevice_nGetInputID(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
jclass input_id_class = (*env)->FindClass(env, "net/java/games/input/LinuxInputID");
if (input_id_class == NULL)
return NULL;
jmethodID input_id_constructor = (*env)->GetMethodID(env, input_id_class, "<init>", "(IIII)V");
if (input_id_constructor == NULL)
return NULL;
struct input_id id;
int result = ioctl(fd, EVIOCGID, &id);
if (result == -1) {
throwIOException(env, "Failed to get input id for device (%d)\n", errno);
return NULL;
}
return (*env)->NewObject(env, input_id_class, input_id_constructor, (jint)id.bustype, (jint)id.vendor, (jint)id.product, (jint)id.version);
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nGetAbsInfo(JNIEnv *env, jclass unused, jlong fd_address, jint abs_axis, jobject abs_info_return) {
int fd = (int)fd_address;
jclass abs_info_class = (*env)->GetObjectClass(env, abs_info_return);
if (abs_info_class == NULL)
return;
jmethodID abs_info_set = (*env)->GetMethodID(env, abs_info_class, "set", "(IIIII)V");
if (abs_info_set == NULL)
return;
struct input_absinfo abs_info;
int result = ioctl(fd, EVIOCGABS(abs_axis), &abs_info);
if (result == -1) {
throwIOException(env, "Failed to get abs info for axis (%d)\n", errno);
return;
}
(*env)->CallVoidMethod(env, abs_info_return, abs_info_set, (jint)abs_info.value, (jint)abs_info.minimum, (jint)abs_info.maximum, (jint)abs_info.fuzz, (jint)abs_info.flat);
}
JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxEventDevice_nGetNextEvent(JNIEnv *env, jclass unused, jlong fd_address, jobject linux_event_return) {
int fd = (int)fd_address;
jclass linux_event_class = (*env)->GetObjectClass(env, linux_event_return);
if (linux_event_class == NULL)
return JNI_FALSE;
jmethodID linux_event_set = (*env)->GetMethodID(env, linux_event_class, "set", "(JJIII)V");
if (linux_event_set == NULL)
return JNI_FALSE;
struct input_event event;
if (read(fd, &event, sizeof(struct input_event)) == -1) {
if (errno == EAGAIN)
return JNI_FALSE;
throwIOException(env, "Failed to read next device event (%d)\n", errno);
return JNI_FALSE;
}
(*env)->CallVoidMethod(env, linux_event_return, linux_event_set, (jlong)event.time.tv_sec, (jlong)event.time.tv_usec, (jint)event.type, (jint)event.code, (jint)event.value);
return JNI_TRUE;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nUploadRumbleEffect(JNIEnv *env, jclass unused, jlong fd_address, jint id, jint direction, jint trigger_button, jint trigger_interval, jint replay_length, jint replay_delay, jint strong_magnitude, jint weak_magnitude) {
int fd = (int)fd_address;
struct ff_effect effect;
effect.type = FF_RUMBLE;
effect.id = id;
effect.trigger.button = trigger_button;
effect.trigger.interval = trigger_interval;
effect.replay.length = replay_length;
effect.replay.delay = replay_delay;
effect.direction = direction;
effect.u.rumble.strong_magnitude = strong_magnitude;
effect.u.rumble.weak_magnitude = weak_magnitude;
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
throwIOException(env, "Failed to upload effect (%d)\n", errno);
return -1;
}
return effect.id;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxEventDevice_nUploadConstantEffect(JNIEnv *env, jclass unused, jlong fd_address, jint id, jint direction, jint trigger_button, jint trigger_interval, jint replay_length, jint replay_delay, jint constant_level, jint constant_env_attack_length, jint constant_env_attack_level, jint constant_env_fade_length, jint constant_env_fade_level) {
int fd = (int)fd_address;
struct ff_effect effect;
effect.type = FF_CONSTANT;
effect.id = id;
effect.trigger.button = trigger_button;
effect.trigger.interval = trigger_interval;
effect.replay.length = replay_length;
effect.replay.delay = replay_delay;
effect.direction = direction;
effect.u.constant.level = constant_level;
effect.u.constant.envelope.attack_length = constant_env_attack_length;
effect.u.constant.envelope.attack_level = constant_env_attack_level;
effect.u.constant.envelope.fade_length = constant_env_fade_length;
effect.u.constant.envelope.fade_level = constant_env_fade_level;
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
throwIOException(env, "Failed to upload effect (%d)\n", errno);
return -1;
}
return effect.id;
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nWriteEvent(JNIEnv *env, jclass unused, jlong fd_address, jint type, jint code, jint value) {
int fd = (int)fd_address;
struct input_event event;
event.type = type;
event.code = code;
event.value = value;
if (write(fd, &event, sizeof(event)) == -1) {
throwIOException(env, "Failed to write to device (%d)\n", errno);
}
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxEventDevice_nEraseEffect(JNIEnv *env, jclass unused, jlong fd_address, jint ff_id) {
int fd = (int)fd_address;
int ff_id_int = ff_id;
if (ioctl(fd, EVIOCRMFF, &ff_id_int) == -1)
throwIOException(env, "Failed to erase effect (%d)\n", errno);
}

View file

@ -0,0 +1,128 @@
/*
* %W% %E%
*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
/*****************************************************************************
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materails provided with the distribution.
*
* Neither the name Sun Microsystems, Inc. or the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
* A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for us in
* the design, construction, operation or maintenance of any nuclear facility
*
*****************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/joystick.h>
#include "util.h"
#include "net_java_games_input_LinuxJoystickDevice.h"
JNIEXPORT jlong JNICALL Java_net_java_games_input_LinuxJoystickDevice_nOpen(JNIEnv *env, jclass unused, jstring path) {
const char *path_str = (*env)->GetStringUTFChars(env, path, NULL);
if (path_str == NULL)
return -1;
int fd = open(path_str, O_RDONLY | O_NONBLOCK);
if (fd == -1)
throwIOException(env, "Failed to open device %s (%d)\n", path_str, errno);
(*env)->ReleaseStringUTFChars(env, path, path_str);
return fd;
}
JNIEXPORT void JNICALL Java_net_java_games_input_LinuxJoystickDevice_nClose(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
int result = close(fd);
if (result == -1)
throwIOException(env, "Failed to close device (%d)\n", errno);
}
JNIEXPORT jstring JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetName(JNIEnv *env, jclass unused, jlong fd_address) {
#define BUFFER_SIZE 1024
int fd = (int)fd_address;
char device_name[BUFFER_SIZE];
if (ioctl(fd, JSIOCGNAME(BUFFER_SIZE), device_name) == -1) {
throwIOException(env, "Failed to get device name (%d)\n", errno);
return NULL;
}
jstring jstr = (*env)->NewStringUTF(env, device_name);
return jstr;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetVersion(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
__u32 version;
if (ioctl(fd, JSIOCGVERSION, &version) == -1) {
throwIOException(env, "Failed to get device version (%d)\n", errno);
return -1;
}
return version;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNumButtons(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
__u8 num_buttons;
if (ioctl(fd, JSIOCGBUTTONS, &num_buttons) == -1) {
throwIOException(env, "Failed to get number of buttons (%d)\n", errno);
return -1;
}
return num_buttons;
}
JNIEXPORT jint JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNumAxes(JNIEnv *env, jclass unused, jlong fd_address) {
int fd = (int)fd_address;
__u8 num_axes;
if (ioctl(fd, JSIOCGAXES, &num_axes) == -1) {
throwIOException(env, "Failed to get number of buttons (%d)\n", errno);
return -1;
}
return num_axes;
}
JNIEXPORT jboolean JNICALL Java_net_java_games_input_LinuxJoystickDevice_nGetNextEvent(JNIEnv *env, jclass unused, jlong fd_address, jobject event_return) {
int fd = (int)fd_address;
jclass event_class = (*env)->GetObjectClass(env, event_return);
if (event_class == NULL)
return JNI_FALSE;
jmethodID event_set = (*env)->GetMethodID(env, event_class, "set", "(JIII)V");
if (event_set == NULL)
return JNI_FALSE;
struct js_event event;
if (read(fd, &event, sizeof(event)) == -1) {
if (errno == EAGAIN)
return JNI_FALSE;
throwIOException(env, "Failed to read next device event (%d)\n", errno);
return JNI_FALSE;
}
(*env)->CallVoidMethod(env, event_return, event_set, (jlong)event.time, (jint)event.value, (jint)event.type, (jint)event.number);
return JNI_TRUE;
}