From 1ef6081c1f731e959c41ef7a0da32009e4280acc Mon Sep 17 00:00:00 2001 From: endolf Date: Sun, 29 Oct 2006 15:57:42 +0000 Subject: [PATCH] First commit of the wintab plugin --- plugins/wintab/build.xml | 76 +++++++ .../games/input/WinTabButtonComponent.java | 29 +++ .../net/java/games/input/WinTabComponent.java | 195 ++++++++++++++++++ .../net/java/games/input/WinTabContext.java | 74 +++++++ .../games/input/WinTabCursorComponent.java | 28 +++ .../net/java/games/input/WinTabDevice.java | 131 ++++++++++++ .../games/input/WinTabEnvironmentPlugin.java | 69 +++++++ .../net/java/games/input/WinTabPacket.java | 11 + plugins/wintab/src/native/build.xml | 70 +++++++ .../net_java_games_input_WinTabContext.c | 85 ++++++++ .../net_java_games_input_WinTabDevice.c | 107 ++++++++++ 11 files changed, 875 insertions(+) create mode 100644 plugins/wintab/build.xml create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabButtonComponent.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabComponent.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabContext.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabCursorComponent.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabDevice.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabEnvironmentPlugin.java create mode 100644 plugins/wintab/src/java/net/java/games/input/WinTabPacket.java create mode 100644 plugins/wintab/src/native/build.xml create mode 100644 plugins/wintab/src/native/net_java_games_input_WinTabContext.c create mode 100644 plugins/wintab/src/native/net_java_games_input_WinTabDevice.c diff --git a/plugins/wintab/build.xml b/plugins/wintab/build.xml new file mode 100644 index 0000000..cc36299 --- /dev/null +++ b/plugins/wintab/build.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/wintab/src/java/net/java/games/input/WinTabButtonComponent.java b/plugins/wintab/src/java/net/java/games/input/WinTabButtonComponent.java new file mode 100644 index 0000000..ff6f425 --- /dev/null +++ b/plugins/wintab/src/java/net/java/games/input/WinTabButtonComponent.java @@ -0,0 +1,29 @@ +package net.java.games.input; + +import net.java.games.input.Component.Identifier; + +public class WinTabButtonComponent extends WinTabComponent { + + private int index; + + protected WinTabButtonComponent(WinTabContext context, int parentDevice, String name, Identifier id, int index) { + super(context, parentDevice, name, id); + this.index = index; + } + + public Event processPacket(WinTabPacket packet) { + Event newEvent = null; + + float newValue = ((packet.PK_BUTTONS & (int)Math.pow(2, index))>0) ? 1.0f : 0.0f; + if(newValue!=getPollData()) { + lastKnownValue = newValue; + + //Generate an event + newEvent = new Event(); + newEvent.set(this, newValue, packet.PK_TIME*1000); + return newEvent; + } + + return newEvent; + } +} diff --git a/plugins/wintab/src/java/net/java/games/input/WinTabComponent.java b/plugins/wintab/src/java/net/java/games/input/WinTabComponent.java new file mode 100644 index 0000000..91ae205 --- /dev/null +++ b/plugins/wintab/src/java/net/java/games/input/WinTabComponent.java @@ -0,0 +1,195 @@ +package net.java.games.input; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.java.games.input.Component.Identifier; + +public class WinTabComponent extends AbstractComponent { + + public final static int XAxis = 1; + public final static int YAxis = 2; + public final static int ZAxis = 3; + public final static int NPressureAxis = 4; + public final static int TPressureAxis = 5; + public final static int OrientationAxis = 6; + public final static int RotationAxis = 7; + + private int parentDevice; + private int min; + private int max; + private WinTabContext context; + protected float lastKnownValue; + private boolean analog; + + protected WinTabComponent(WinTabContext context, int parentDevice, String name, Identifier id, int min, int max) { + super(name, id); + this.parentDevice = parentDevice; + this.min = min; + this.max = max; + this.context = context; + analog = true; + } + + protected WinTabComponent(WinTabContext context, int parentDevice, String name, Identifier id) { + super(name, id); + this.parentDevice = parentDevice; + this.min = 0; + this.max = 1; + this.context = context; + analog = false; + } + + protected float poll() throws IOException { + return lastKnownValue; + } + + public boolean isAnalog() { + return analog; + } + + public boolean isRelative() { + // All axis are absolute + return false; + } + + public static List createComponents(WinTabContext context, int parentDevice, int axisId, int[] axisRanges) { + List components = new ArrayList(); + Identifier id; + switch(axisId) { + case XAxis: + id = Identifier.Axis.X; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + break; + case YAxis: + id = Identifier.Axis.Y; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + break; + case ZAxis: + id = Identifier.Axis.Z; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + break; + case NPressureAxis: + id = Identifier.Axis.X_FORCE; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + break; + case TPressureAxis: + id = Identifier.Axis.Y_FORCE; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + break; + case OrientationAxis: + id = Identifier.Axis.RX; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + id = Identifier.Axis.RY; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[2], axisRanges[3])); + id = Identifier.Axis.RZ; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[4], axisRanges[5])); + break; + case RotationAxis: + id = Identifier.Axis.RX; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[0], axisRanges[1])); + id = Identifier.Axis.RY; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[2], axisRanges[3])); + id = Identifier.Axis.RZ; + components.add(new WinTabComponent(context, parentDevice, id.getName(), id, axisRanges[4], axisRanges[5])); + break; + } + + return components; + } + + public static Collection createButtons(WinTabContext context, int deviceIndex, int numberOfButtons) { + List buttons = new ArrayList(); + Identifier id; + + for(int i=0;i0) { + Event ourEvent = (Event)eventList.remove(0); + event.set(ourEvent); + return true; + } else { + return false; + } + } + + protected void pollDevice() throws IOException { + // Get the data off the native queue. + context.processEvents(); + + super.pollDevice(); + } + + public Type getType() { + return Type.TRACKPAD; + } + + public void processPacket(WinTabPacket packet) { + Component[] components = getComponents(); + for(int i=0;i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/wintab/src/native/net_java_games_input_WinTabContext.c b/plugins/wintab/src/native/net_java_games_input_WinTabContext.c new file mode 100644 index 0000000..10863f9 --- /dev/null +++ b/plugins/wintab/src/native/net_java_games_input_WinTabContext.c @@ -0,0 +1,85 @@ +#include +#include + +#include +#include "net_java_games_input_WinTabContext.h" +#include +//#define PACKETDATA ( PK_X | PK_Y | PK_Z | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ROTATION | PK_ORIENTATION | PK_CURSOR ) +#define PACKETDATA ( PK_TIME | PK_X | PK_Y | PK_Z | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR ) +#define PACKETMODE 0 +#include +#include + +#define MAX_PACKETS 20 + +JNIEXPORT jlong JNICALL Java_net_java_games_input_WinTabContext_nOpen(JNIEnv *env, jclass unused, jlong hWnd_long) { + LOGCONTEXT context; + HWND hWnd = (HWND)(INT_PTR)hWnd_long; + HCTX hCtx = NULL; + + /* get default region */ + WTInfo(WTI_DEFCONTEXT, 0, &context); + + wsprintf(context.lcName, "JInput Digitizing"); + context.lcPktData = PACKETDATA; + context.lcPktMode = PACKETMODE; + context.lcMoveMask = PACKETDATA; + context.lcBtnUpMask = context.lcBtnDnMask; + + /* open the region */ + hCtx = WTOpen(hWnd, &context, TRUE); + + return (jlong)(intptr_t)hCtx; +} + +JNIEXPORT void JNICALL Java_net_java_games_input_WinTabContext_nClose(JNIEnv *env, jclass unused, jlong hCtx_long) { + WTClose((HCTX)(INT_PTR)hCtx_long); +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_WinTabContext_nGetNumberOfSupportedDevices(JNIEnv *env, jclass unused) { + int numDevices; + WTInfo(WTI_INTERFACE, IFC_NDEVICES, &numDevices); + return numDevices; +} + +JNIEXPORT jobjectArray JNICALL Java_net_java_games_input_WinTabContext_nGetPackets(JNIEnv *env, jclass unused, jlong hCtx_long) { + + jobjectArray retval; + int i=0; + PACKET packets[MAX_PACKETS]; + int numberRead = WTPacketsGet((HCTX)(INT_PTR)hCtx_long, MAX_PACKETS, packets); + jclass winTabPacketClass = (*env)->FindClass(env, "net/java/games/input/WinTabPacket"); + jfieldID packetTimeField = (*env)->GetFieldID(env, winTabPacketClass, "PK_TIME", "J"); + jfieldID packetXAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_X", "I"); + jfieldID packetYAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_Y", "I"); + jfieldID packetZAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_Z", "I"); + jfieldID packetButtonsField = (*env)->GetFieldID(env, winTabPacketClass, "PK_BUTTONS", "I"); + jfieldID packetNPressureAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_NORMAL_PRESSURE", "I"); + jfieldID packetTPressureAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_TANGENT_PRESSURE", "I"); + jfieldID packetCursorField = (*env)->GetFieldID(env, winTabPacketClass, "PK_CURSOR", "I"); + jfieldID packetOrientationAltAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_ORIENTATION_ALT", "I"); + jfieldID packetOrientationAzAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_ORIENTATION_AZ", "I"); + jfieldID packetOrientationTwistAxisField = (*env)->GetFieldID(env, winTabPacketClass, "PK_ORIENTATION_TWIST", "I"); + jobject prototypePacket = newJObject(env, "net/java/games/input/WinTabPacket", "()V"); + + retval = (*env)->NewObjectArray(env, numberRead, winTabPacketClass, NULL); + for(i=0;iSetLongField(env, tempPacket, packetTimeField, packets[i].pkTime); + (*env)->SetIntField(env, tempPacket, packetXAxisField, packets[i].pkX); + (*env)->SetIntField(env, tempPacket, packetYAxisField, packets[i].pkY); + (*env)->SetIntField(env, tempPacket, packetZAxisField, packets[i].pkZ); + (*env)->SetIntField(env, tempPacket, packetButtonsField, packets[i].pkButtons); + (*env)->SetIntField(env, tempPacket, packetNPressureAxisField, packets[i].pkNormalPressure); + (*env)->SetIntField(env, tempPacket, packetTPressureAxisField, packets[i].pkTangentPressure); + (*env)->SetIntField(env, tempPacket, packetCursorField, packets[i].pkCursor); + (*env)->SetIntField(env, tempPacket, packetOrientationAltAxisField, packets[i].pkOrientation.orAzimuth); + (*env)->SetIntField(env, tempPacket, packetOrientationAzAxisField, packets[i].pkOrientation.orAltitude); + (*env)->SetIntField(env, tempPacket, packetOrientationTwistAxisField, packets[i].pkOrientation.orTwist); + + (*env)->SetObjectArrayElement(env, retval, i, tempPacket); + } + + return retval; +} diff --git a/plugins/wintab/src/native/net_java_games_input_WinTabDevice.c b/plugins/wintab/src/native/net_java_games_input_WinTabDevice.c new file mode 100644 index 0000000..45f202e --- /dev/null +++ b/plugins/wintab/src/native/net_java_games_input_WinTabDevice.c @@ -0,0 +1,107 @@ +#include +#include + +#include +#include "net_java_games_input_WinTabDevice.h" +#include "net_java_games_input_WinTabComponent.h" +#include "util.h" +#include +#include +#define PACKETDATA ( PK_X | PK_Y | PK_Z | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR ) +#define PACKETMODE 0 +#include + +JNIEXPORT jstring JNICALL Java_net_java_games_input_WinTabDevice_nGetName(JNIEnv *env, jclass unused, jint deviceIndex) { + char name[50]; + WTInfo(WTI_DEVICES + deviceIndex, DVC_NAME, name); + return (*env)->NewStringUTF(env, name); +} + +JNIEXPORT jintArray JNICALL Java_net_java_games_input_WinTabDevice_nGetAxisDetails(JNIEnv *env, jclass unused, jint deviceIndex, jint axisId) { + UINT type; + AXIS threeAxisArray[3]; + AXIS axis; + long threeAxisData[6]; + long axisData[2]; + int res; + jintArray retVal = NULL; + + if(axisId==net_java_games_input_WinTabComponent_XAxis) type = DVC_X; + else if(axisId==net_java_games_input_WinTabComponent_YAxis) type = DVC_Y; + else if(axisId==net_java_games_input_WinTabComponent_ZAxis) type = DVC_Z; + else if(axisId==net_java_games_input_WinTabComponent_NPressureAxis) type = DVC_NPRESSURE; + else if(axisId==net_java_games_input_WinTabComponent_TPressureAxis) type = DVC_TPRESSURE; + else if(axisId==net_java_games_input_WinTabComponent_OrientationAxis) type = DVC_ORIENTATION; + else if(axisId==net_java_games_input_WinTabComponent_RotationAxis) type = DVC_ROTATION; + + if(axisId==net_java_games_input_WinTabComponent_RotationAxis || axisId==net_java_games_input_WinTabComponent_OrientationAxis) { + res = WTInfo(WTI_DEVICES + deviceIndex, type, &threeAxisArray); + if(res!=0) { + threeAxisData[0] = threeAxisArray[0].axMin; + threeAxisData[1] = threeAxisArray[0].axMax; + threeAxisData[2] = threeAxisArray[1].axMin; + threeAxisData[3] = threeAxisArray[1].axMax; + threeAxisData[4] = threeAxisArray[2].axMin; + threeAxisData[5] = threeAxisArray[2].axMax; + retVal = (*env)->NewIntArray(env, 6); + (*env)->SetIntArrayRegion(env, retVal, 0, 6, threeAxisData); + } + } else { + res = WTInfo(WTI_DEVICES + deviceIndex, type, &axis); + if(res!=0) { + axisData[0] = axis.axMin; + axisData[1] = axis.axMax; + retVal = (*env)->NewIntArray(env, 2); + (*env)->SetIntArrayRegion(env, retVal, 0, 2, axisData); + } + } + + if(retVal==NULL) { + retVal = (*env)->NewIntArray(env, 0); + } + + return retVal; +} + +JNIEXPORT jobjectArray JNICALL Java_net_java_games_input_WinTabDevice_nGetCursorNames(JNIEnv *env, jclass unused, jint deviceId) { + int numberCursorTypes; + int firstCursorType; + char name[50]; + int i; + jclass stringClass = (*env)->FindClass(env, "java/lang/String"); + jstring nameString; + jobjectArray retval; + + WTInfo(WTI_DEVICES + deviceId, DVC_NCSRTYPES, &numberCursorTypes); + WTInfo(WTI_DEVICES + deviceId, DVC_FIRSTCSR, &firstCursorType); + + retval = (*env)->NewObjectArray(env, numberCursorTypes, stringClass, NULL); + + for(i=0;iNewStringUTF(env, name); + (*env)->SetObjectArrayElement(env, retval, i-firstCursorType, nameString); + } + + return retval; +} + +JNIEXPORT jint JNICALL Java_net_java_games_input_WinTabDevice_nGetMaxButtonCount(JNIEnv *env, jclass unused, jint deviceId) { + int numberCursorTypes; + int firstCursorType; + byte buttonCount; + int i; + byte retval=0; + + WTInfo(WTI_DEVICES + deviceId, DVC_NCSRTYPES, &numberCursorTypes); + WTInfo(WTI_DEVICES + deviceId, DVC_FIRSTCSR, &firstCursorType); + + for(i=0;iretval) { + retval = buttonCount; + } + } + + return (jint)retval; +}