mirror of
https://github.com/shadowfacts/jinput-arm64.git
synced 2026-04-21 06:14:11 +00:00
Make version 2 the main jinput version
This commit is contained in:
parent
4c91a4eb44
commit
559c008a02
149 changed files with 13218 additions and 10800 deletions
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
257
plugins/linux/src/native/net_java_games_input_LinuxEventDevice.c
Normal file
257
plugins/linux/src/native/net_java_games_input_LinuxEventDevice.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue