summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSascha Hlusiak <saschahlusiak@arcor.de>2009-03-19 21:13:13 +0100
committerSascha Hlusiak <saschahlusiak@arcor.de>2009-03-19 21:13:13 +0100
commit7af61c78fd48ea9cc2442fb55570ba0d9f37f8c8 (patch)
tree5bd52e15882109f2b852b1999221136d1b3adb8d /src
parentbc430cc2aacdcda45ddc38d457b84ff040be6a8c (diff)
parent4b9aafd82bf78e86b2b2ddc78c37d73ccc7c25d5 (diff)
Merge branch 'pwm'
Diffstat (limited to 'src')
-rw-r--r--src/backend_bsd.c3
-rw-r--r--src/backend_evdev.c4
-rw-r--r--src/backend_joystick.c4
-rw-r--r--src/jstk.c24
-rw-r--r--src/jstk.h4
-rw-r--r--src/jstk_axis.c167
-rw-r--r--src/jstk_axis.h1
7 files changed, 183 insertions, 24 deletions
diff --git a/src/backend_bsd.c b/src/backend_bsd.c
index 60401b1..71f4168 100644
--- a/src/backend_bsd.c
+++ b/src/backend_bsd.c
@@ -267,7 +267,6 @@ jstkReadData_bsd(JoystickDevPtr joystick,
- bsddata->axis_item[j].logical_minimum);
if (abs(d) < joystick->axis[j].deadzone) d = 0;
if (d != joystick->axis[j].value) {
- joystick->axis[j].oldvalue = joystick->axis[j].value;
joystick->axis[j].value = d;
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = j;
@@ -286,14 +285,12 @@ jstkReadData_bsd(JoystickDevPtr joystick,
d = hid_get_data(bsddata->data_buf, &bsddata->hat_item[j])
- bsddata->hat_item[j].logical_minimum;
if (joystick->axis[a].value != v1_data[d]) {
- joystick->axis[a].oldvalue = joystick->axis[a].value;
joystick->axis[a].value = v1_data[d];
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = a;
return 2;
}
if (joystick->axis[a+1].value != v2_data[d]) {
- joystick->axis[a+1].oldvalue = joystick->axis[a+1].value;
joystick->axis[a+1].value = v2_data[d];
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = a+1;
diff --git a/src/backend_evdev.c b/src/backend_evdev.c
index d03efce..de061d3 100644
--- a/src/backend_evdev.c
+++ b/src/backend_evdev.c
@@ -281,15 +281,11 @@ jstkReadData_evdev(JoystickDevPtr joystick,
if (abs(value) < joystick->axis[axis->number].deadzone) {
/* We only want one event when in deadzone */
if (joystick->axis[axis->number].value != 0) {
- joystick->axis[axis->number].oldvalue =
- joystick->axis[axis->number].value;
joystick->axis[axis->number].value = 0;
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = axis->number;
}
}else{
- joystick->axis[axis->number].oldvalue =
- joystick->axis[axis->number].value;
joystick->axis[axis->number].value = value;
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = axis->number;
diff --git a/src/backend_joystick.c b/src/backend_joystick.c
index d8a0c3c..b69f932 100644
--- a/src/backend_joystick.c
+++ b/src/backend_joystick.c
@@ -193,15 +193,11 @@ jstkReadData_joystick(JoystickDevPtr joystick,
if (abs(js.value) < joystick->axis[js.number].deadzone) {
/* We only want one event when in deadzone */
if (joystick->axis[js.number].value != 0) {
- joystick->axis[js.number].oldvalue =
- joystick->axis[js.number].value;
joystick->axis[js.number].value = 0;
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = js.number;
}
}else{
- joystick->axis[js.number].oldvalue =
- joystick->axis[js.number].value;
joystick->axis[js.number].value = js.value;
if (event != NULL) *event = EVENT_AXIS;
if (number != NULL) *number = js.number;
diff --git a/src/jstk.c b/src/jstk.c
index c747b40..26f7a47 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -283,20 +283,9 @@ jstkReadProc(LocalDevicePtr local)
case JSTK_MAPPING_KEY: if (priv->keys_enabled == TRUE) {
if (priv->axis[number].type == JSTK_TYPE_ACCELERATED) {
- if ((priv->axis[number].value > 0) !=
- (priv->axis[number].oldvalue > 0))
- jstkGenerateKeys(priv->keyboard_device,
- priv->axis[number].keys_high,
- (priv->axis[number].value > 0) ? 1:0);
-
- if ((priv->axis[number].value < 0) !=
- (priv->axis[number].oldvalue < 0))
- jstkGenerateKeys(priv->keyboard_device,
- priv->axis[number].keys_low,
- (priv->axis[number].value < 0) ? 1:0);
+ jstkHandlePWMAxis(local, number);
} else if (priv->axis[number].type == JSTK_TYPE_BYVALUE) {
- if (priv->keys_enabled == TRUE)
- jstkStartAxisTimer(local, number);
+ jstkStartAxisTimer(local, number);
}
break;
}
@@ -449,6 +438,12 @@ jstkDeviceControlProc(DeviceIntPtr pJstk,
priv->timerrunning = FALSE;
TimerCancel(priv->timer);
}
+ for (i = 0; i < MAXAXES; i++)
+ if (priv->axis[i].timerrunning)
+ {
+ priv->axis[i].timerrunning = FALSE;
+ TimerCancel(priv->axis[i].timer);
+ }
if (local->fd >= 0)
RemoveEnabledDevice(local->fd);
@@ -552,6 +547,9 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
priv->axis[i].amplify = 1.0f;
priv->axis[i].valuator = -1;
priv->axis[i].subpixel = 0.0f;
+ priv->axis[i].timer = NULL;
+ priv->axis[i].timerrunning = FALSE;
+ priv->axis[i].key_isdown = 0;
for (j=0; j<MAXKEYSPERBUTTON; j++)
priv->axis[i].keys_low[j] = priv->axis[i].keys_high[j] = 0;
}
diff --git a/src/jstk.h b/src/jstk.h
index 694ae45..1d97937 100644
--- a/src/jstk.h
+++ b/src/jstk.h
@@ -81,7 +81,11 @@ typedef struct _AXIS {
float previousposition; /* TYPE_ABSOLUTE */
float amplify;
float subpixel; /* Pending subpixel movement */
+
KEYSCANCODES keys_low, keys_high; /* MAPPING_KEY */
+ int key_isdown;
+ OsTimerPtr timer;
+ Bool timerrunning;
} AXIS;
typedef struct _BUTTON {
diff --git a/src/jstk_axis.c b/src/jstk_axis.c
index 7e59e97..b314122 100644
--- a/src/jstk_axis.c
+++ b/src/jstk_axis.c
@@ -384,3 +384,170 @@ jstkHandleAbsoluteAxis(LocalDevicePtr device, int number)
xf86PostMotionEvent(device->dev, 0, 0, 2, x, y);
}
}
+
+
+
+
+
+/***********************************************************************
+ *
+ * jstkPWMAxisTimer --
+ *
+ * The timer that will generate Key events.
+ * The deflection of the axis will control the PERCENT OF TIME the key is
+ * down, not the amount of impulses.
+ * Return 0, when timer can be stopped.
+ *
+ ***********************************************************************
+ */
+static CARD32
+jstkPWMAxisTimer(OsTimerPtr timer,
+ CARD32 atime,
+ pointer arg)
+{
+ DeviceIntPtr device = (DeviceIntPtr)arg;
+ JoystickDevPtr priv = (JoystickDevPtr)XI_PRIVATE(device);
+
+ int sigstate, i;
+ int nexttimer;
+
+ nexttimer = 0;
+
+ sigstate = xf86BlockSIGIO();
+
+ for (i=0; i<MAXAXES; i++)
+ if (priv->axis[i].timer == timer) /* The timer handles only one axis! Find it. */
+ {
+ AXIS *axis;
+ axis = &priv->axis[i];
+
+ DBG(8, ErrorF("PWM Axis %d value %d (old %d)\n", i, axis->value, axis->oldvalue));
+
+ /* Force key_high down if centered */
+ if ((axis->value <= 0) &&
+ (axis->oldvalue > 0) &&
+ (axis->key_isdown))
+ {
+ DBG(7, ErrorF("PWM Axis %d jumped over. Forcing keys_high up.\n", i));
+ jstkGenerateKeys(priv->keyboard_device,
+ axis->keys_high,
+ 0);
+ axis->key_isdown = 0;
+ }
+
+ /* Force key_low down if centered */
+ if ((axis->value >= 0) &&
+ (axis->oldvalue < 0) &&
+ (axis->key_isdown))
+ {
+ DBG(7, ErrorF("PWM Axis %d jumped over. Forcing keys_low up.\n", i));
+ jstkGenerateKeys(priv->keyboard_device,
+ axis->keys_low,
+ 0);
+ axis->key_isdown = 0;
+ }
+
+ if (axis->value == 0)
+ nexttimer = 0;
+ else {
+ float time_on, time_off;
+ float scale;
+ KEYSCANCODES *keys;
+
+ if (axis->value < 0)
+ keys = &axis->keys_low;
+ else keys = &axis->keys_high;
+
+ /* Calculate next timer */
+ time_on = (float)(abs(axis->value) - axis->deadzone) / 32768.0;
+ time_on *= (32768.0f / (float)(32768 - axis->deadzone));
+
+ time_off = 1.0f - time_on;
+
+ time_on += 0.01f; /* Ugly but ensures we don't divide by 0 */
+ time_off += 0.01f;
+
+ /* Scale both durations, so the smaller always is 50ms */
+ scale = 50.0f * axis->amplify;
+
+ if (time_on < time_off)
+ scale /= time_on;
+ else scale /= time_off;
+
+ time_on *= scale;
+ time_off *= scale;
+
+
+ if (time_off > 600.0f) {
+ /* Might as well just have it down forever */
+ DBG(7, ErrorF("PWM Axis %d up time too long (%.0fms). Forcing up)\n", i, time_off));
+ if (axis->key_isdown == 1) {
+ axis->key_isdown = 0;
+ jstkGenerateKeys(priv->keyboard_device,
+ *keys,
+ axis->key_isdown);
+ }
+ nexttimer = 0;
+ } else if (time_on > 600.0f) {
+ /* Might as well just have it up forever */
+ DBG(7, ErrorF("PWM Axis %d down time too long (%.0fms). Forcing down)\n", i, time_on));
+ if (axis->key_isdown == 0) {
+ axis->key_isdown = 1;
+ jstkGenerateKeys(priv->keyboard_device,
+ *keys,
+ axis->key_isdown);
+ }
+ nexttimer = 0;
+ } else {
+ /* Flip key state */
+ axis->key_isdown = 1 - axis->key_isdown;
+ jstkGenerateKeys(priv->keyboard_device,
+ *keys,
+ axis->key_isdown);
+
+ DBG(7, ErrorF("PWM Axis %d state=%d (%.0fms down, %.0fms up).\n", i, axis->key_isdown, time_on, time_off));
+
+ nexttimer = axis->key_isdown ? (int)time_on : (int)time_off;
+ }
+ }
+
+ if (nexttimer == 0) { /* No next timer, stop */
+ axis->timerrunning = FALSE;
+
+ DBG(2, ErrorF("Stopping PWM Axis %d Timer\n", i));
+ }
+ axis->oldvalue = axis->value;
+ break;
+ }
+
+ xf86UnblockSIGIO (sigstate);
+ return nexttimer;
+}
+
+
+/***********************************************************************
+ *
+ * jstkStartAxisTimer --
+ *
+ * Starts the timer for the movement.
+ * Will already prepare for moving one pixel, for "tipping" the stick
+ *
+ ***********************************************************************
+ */
+void
+jstkHandlePWMAxis(LocalDevicePtr device, int number)
+{
+ JoystickDevPtr priv = device->private;
+ if (priv->axis[number].timerrunning) return;
+
+ priv->axis[number].timerrunning = TRUE;
+
+ DBG(2, ErrorF("Starting PWM Axis Timer (triggered by axis %d, value %d)\n",
+ number, priv->axis[number].value));
+ priv->axis[number].timer = TimerSet(
+ priv->axis[number].timer,
+ 0, /* Relative */
+ 1, /* What about NOW? */
+ jstkPWMAxisTimer,
+ device->dev);
+}
diff --git a/src/jstk_axis.h b/src/jstk_axis.h
index e759f39..028c65f 100644
--- a/src/jstk_axis.h
+++ b/src/jstk_axis.h
@@ -27,5 +27,6 @@
void jstkStartAxisTimer(LocalDevicePtr device, int number);
void jstkStartButtonAxisTimer(LocalDevicePtr device, int number);
void jstkHandleAbsoluteAxis(LocalDevicePtr device, int number);
+void jstkHandlePWMAxis(LocalDevicePtr device, int number);
#endif