diff --git a/src/Makefile.am b/src/Makefile.am index 11c3702..ac4ea27 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,4 +30,5 @@ @DRIVER_NAME@_drv_la_SOURCES = jstk.c jstk.h \ linux_jstk.c linux_jstk.h \ - jstk_axis.c jstk_axis.h + jstk_axis.c jstk_axis.h \ + jstk_options.c jstk_options.h \ No newline at end of file diff --git a/src/jstk.c b/src/jstk.c index 9af24ac..ef73c65 100644 --- a/src/jstk.c +++ b/src/jstk.c @@ -45,6 +45,7 @@ #include "jstk.h" #include "linux_jstk.h" #include "jstk_axis.h" +#include "jstk_options.h" @@ -423,103 +424,24 @@ xf86JstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags) /* Process button mapping options */ for (i=0; ibuttons; i++) if (icommonOptions, p, NULL); if (s != NULL) { - char *param; - char *tmp; - int value; - param = xstrdup(s); - - for (tmp = param; *tmp; tmp++) *tmp = tolower(*tmp); - xf86Msg(X_CONFIG, "%s: Option \"mapbutton%d\" \"%s\"\n", - local->name, i+1, param); - if (strcmp(param, "none") == 0) { - priv->button[i].mapping = MAPPING_NONE; - } else if (sscanf(param, "button=%d", &value) == 1) { - priv->button[i].mapping = MAPPING_BUTTON; - priv->button[i].value = value; - } else { - xf86Msg(X_WARNING, "%s: not recognized parameter\n", - local->name); - } - xfree(param); + xf86Msg(X_CONFIG, "%s: Option \"mapbutton%d\" \"%s\"\n", + local->name, i+1, s); + jstkParseButtonOption(s, &priv->button[i], local->name); } } /* Process button mapping options */ for (i=0; iaxes; i++) if (icommonOptions, p, NULL); if (s != NULL) { - char *param; - char *tmp; - int value; - float fvalue; - param = xstrdup(s); - for (tmp = param; *tmp; tmp++) *tmp = tolower(*tmp); xf86Msg(X_CONFIG, "%s: Option \"mapaxis%d\" \"%s\"\n", - local->name, i+1, param); - - if ((s=strstr(param, "mode=")) != NULL) { - if (sscanf(s, "mode=%15s", p2) == 1) { - if (strcmp(p2, "relative") == 0) - priv->axis[i].type = TYPE_BYVALUE; - else if (strcmp(p2, "accelerated") == 0) - priv->axis[i].type = TYPE_ACCELERATED; - else if (strcmp(p2, "absolute") == 0) - priv->axis[i].type = TYPE_ABSOLUTE; - else { - xf86Msg(X_WARNING, "%s: \"%s\": error parsing mode.\n", - local->name, param); - } - }else xf86Msg(X_WARNING, "%s: \"%s\": error parsing mode.\n", - local->name, param); - } - - if ((s=strstr(param, "axis=")) != NULL) { - if (sscanf(s, "axis=%15s", p2) == 1) { - if (strcmp(p2, "x") == 0) - priv->axis[i].mapping = MAPPING_X; - else if (strcmp(p2, "y") == 0) - priv->axis[i].mapping = MAPPING_Y; - else if (strcmp(p2, "zx") == 0) - priv->axis[i].mapping = MAPPING_ZX; - else if (strcmp(p2, "zy") == 0) - priv->axis[i].mapping = MAPPING_ZY; - else { - xf86Msg(X_WARNING, "%s: error parsing axis.\n", - local->name); - } - }else xf86Msg(X_WARNING, "%s: error parsing axis.\n", - local->name); - } - - if ((s=strstr(param, "deadzone=")) != NULL ) { - if (sscanf(s, "deadzone=%d", &value) == 1) { - value = (value<0)?(-value):value; - if (value > 30000) - xf86Msg(X_WARNING, - "%s: deadzone of %d seems unreasonable. Ignored.\n", - local->name, value); - else priv->axis[i].deadzone = value; - }else xf86Msg(X_WARNING, "%s: error parsing deadzone.\n", - local->name); - } - if ((s=strstr(param, "amplify=")) != NULL ) { - if (sscanf(s, "amplify=%f", &fvalue) == 1) { - if ((fvalue > 10000)||(fvalue < -10000.0)) - xf86Msg(X_WARNING, - "%s: amplifier of %.3f seems unreasonable. Ignored.\n", - local->name, fvalue); - else priv->axis[i].amplify = fvalue; - }else xf86Msg(X_WARNING, "%s: error parsing amplifier.\n", - local->name); - } - - xfree(param); + local->name, i+1, s); + jstkParseAxisOption(s, &priv->axis[i], local->name); } } diff --git a/src/jstk_axis.c b/src/jstk_axis.c new file mode 100644 index 0000000..70967a8 --- /dev/null +++ b/src/jstk_axis.c @@ -0,0 +1,205 @@ +/* + * Copyright 2007 by Sascha Hlusiak. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sascha Hlusiak not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sascha Hlusiak makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SASCHA HLUSIAK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SASCHA HLUSIAK BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +// #include + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "jstk.h" +#include "jstk_axis.h" + + + +static CARD32 +jstkAxisTimer(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; iaxis[i].value != 0) { + float p1 = 1.0; + float p2 = 1.0; + float scale; + + nexttimer = 15; + + if (priv->axis[i].type == TYPE_BYVALUE) { + /* Calculate scale value, so we still get a range from 0 to 32768 */ + scale = (32768.0/(float)(32768 - priv->axis[i].deadzone)); + + p1 = ((pow((abs((float)priv->axis[i].value)-(float)priv->axis[i].deadzone)* + scale/1700.0, 3.5))+100.0)* + ((float)nexttimer/40000.0) * priv->axis[i].amplify; + p2 = ((pow((abs((float)priv->axis[i].value)-(float)priv->axis[i].deadzone)* + scale/1000.0, 2.5))+200.0)* + ((float)nexttimer/200000.0) * priv->axis[i].amplify; + + + } else if (priv->axis[i].type == TYPE_ACCELERATED) { + if (priv->axis[i].temp < 120.0) priv->axis[i].temp *= 1.2; + + p1 = (priv->axis[i].temp - 0.1) * (float)nexttimer / 180.0 * priv->axis[i].amplify; + p2 = p1 / 8.0; + } + if (priv->axis[i].value < 0) { + p1 *= -1.0; + p2 *= -1.0; + } + + + + switch (priv->axis[i].mapping) { + case MAPPING_X: + priv->x += p1; + break; + case MAPPING_Y: + priv->y += p1; + break; + case MAPPING_ZX: + priv->zx += p2; + break; + case MAPPING_ZY: + priv->zy += p2; + break; + default: + break; + } + } + + if (((int)priv->x != 0)||((int)priv->y != 0)) + xf86PostMotionEvent(device, 0, 0, 2, (int)priv->x, (int)priv->y); + priv->x = priv->x - (int)priv->x; + priv->y = priv->y - (int)priv->y; + + while (priv->zy >= 1.0) { + xf86PostButtonEvent(device, 0, 5, 1, 0, 0); + xf86PostButtonEvent(device, 0, 5, 0, 0, 0); + priv->zy-=1.0; + } + while (priv->zy <= -1.0) { + xf86PostButtonEvent(device, 0, 4, 1, 0, 0); + xf86PostButtonEvent(device, 0, 4, 0, 0, 0); + priv->zy+=1.0; + } + + while (priv->zx >= 1.0) { + xf86PostButtonEvent(device, 0, 7, 1, 0, 0); + xf86PostButtonEvent(device, 0, 7, 0, 0, 0); + priv->zx-=1.0; + } + while (priv->zx <= -1.0) { + xf86PostButtonEvent(device, 0, 6, 1, 0, 0); + xf86PostButtonEvent(device, 0, 6, 0, 0, 0); + priv->zx+=1.0; + } + + if (nexttimer == 0) { + priv->timerrunning = FALSE; + priv->x = 0.0; + priv->y = 0.0; + priv->zx = 0.0; + priv->zy = 0.0; + DBG(2, ErrorF("Stopping Timer\n")); + } + xf86UnblockSIGIO (sigstate); + return nexttimer; +} + +void +jstkStartAxisTimer(LocalDevicePtr device, int number) { + JoystickDevPtr priv = device->private; + + if (priv->timerrunning) return; + priv->timerrunning = TRUE; + + int pixel = 1; + if (priv->axis[number].value < 0) pixel = -1; + switch (priv->axis[number].mapping) { + case MAPPING_X: + priv->x += pixel; + break; + case MAPPING_Y: + priv->y += pixel; + break; + case MAPPING_ZX: + priv->zx += pixel; + break; + case MAPPING_ZY: + priv->zy += pixel; + break; + default: + break; + } + + DBG(2, ErrorF("Starting Timer\n")); + priv->timer = TimerSet( + priv->timer, + 0, /* Relative */ + 5, + jstkAxisTimer, + device->dev); +} + + + +void +jstkHandleAbsoluteAxis(LocalDevicePtr device, int number) { + JoystickDevPtr priv = device->private; + int x,y,i; + x = screenInfo.screens[0]->width / 2; + y = screenInfo.screens[0]->height / 2; + + for (i=0; iaxis[i].type == TYPE_ABSOLUTE)&&(priv->axis[i].value != 0)) + { + float rel; + rel = (priv->axis[i].value>0)? + (priv->axis[i].value - priv->axis[i].deadzone): + (priv->axis[i].value + priv->axis[i].deadzone); + rel = (rel)/(2.0*(float)(32768 - priv->axis[i].deadzone)) + 0.5; + + if (priv->axis[i].mapping == MAPPING_X) + x = rel * screenInfo.screens[0]->width; + if (priv->axis[i].mapping == MAPPING_Y) + y = rel * screenInfo.screens[0]->height; + } +/* DBG(2, ErrorF("Setting mouse to %dx%d\n",x,y));*/ + xf86PostMotionEvent(device->dev, 1, 0, 2, x, y); +} + + + + diff --git a/src/jstk_axis.h b/src/jstk_axis.h new file mode 100644 index 0000000..fb7f15d --- /dev/null +++ b/src/jstk_axis.h @@ -0,0 +1,31 @@ +/* + * Copyright 2007 by Sascha Hlusiak. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sascha Hlusiak not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sascha Hlusiak makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SASCHA HLUSIAK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SASCHA HLUSIAK BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef _XF86JSTK_AXIS_H_INCLUDED_ +#define _XF86JSTK_AXIS_H_INCLUDED_ + +void jstkStartAxisTimer(LocalDevicePtr device, int number); +void jstkHandleAbsoluteAxis(LocalDevicePtr device, int number); + + +#endif diff --git a/src/jstk_options.c b/src/jstk_options.c new file mode 100644 index 0000000..9c51177 --- /dev/null +++ b/src/jstk_options.c @@ -0,0 +1,136 @@ +/* + * Copyright 2007 by Sascha Hlusiak. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sascha Hlusiak not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sascha Hlusiak makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SASCHA HLUSIAK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SASCHA HLUSIAK BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include "jstk.h" +#include "jstk_options.h" + + +void +jstkParseButtonOption(const char* org, + struct BUTTON *button, + const char* name) { + char *param; + char *tmp; + int value; + char p[64]; + param = xstrdup(org); + + for (tmp = param; *tmp; tmp++) *tmp = tolower(*tmp); + + if (strcmp(param, "none") == 0) { + button->mapping = MAPPING_NONE; + } else if (sscanf(param, "button=%d", &value) == 1) { + button->mapping = MAPPING_BUTTON; + button->value = value; + } else if (sscanf(param, "axis=%15s", p) == 1) { + if (strcmp(p, "x") == 0) + button->mapping = MAPPING_X; + else if (strcmp(p, "y") == 0) + button->mapping = MAPPING_Y; + else if (strcmp(p, "zx") == 0) + button->mapping = MAPPING_ZX; + else if (strcmp(p, "zy") == 0) + button->mapping = MAPPING_ZY; + else { + xf86Msg(X_WARNING, "%s: error parsing axis.\n", + name); + } + } else { + xf86Msg(X_WARNING, "%s: error parsing button parameter.\n", + name); + } + xfree(param); +} + + +void +jstkParseAxisOption(const char* org, struct AXIS *axis, const char *name) { + char *param; + char *tmp; + int value; + float fvalue; + char p[64]; + param = xstrdup(org); + for (tmp = param; *tmp; tmp++) *tmp = tolower(*tmp); + + if ((tmp=strstr(param, "mode=")) != NULL) { + if (sscanf(tmp, "mode=%15s", p) == 1) { + p[15]='\0'; + if (strcmp(p, "relative") == 0) + axis->type = TYPE_BYVALUE; + else if (strcmp(p, "accelerated") == 0) + axis->type = TYPE_ACCELERATED; + else if (strcmp(p, "absolute") == 0) + axis->type = TYPE_ABSOLUTE; + else { + xf86Msg(X_WARNING, "%s: \"%s\": error parsing mode.\n", + name, param); + } + }else xf86Msg(X_WARNING, "%s: \"%s\": error parsing mode.\n", + name, param); + } + + if ((tmp=strstr(param, "axis=")) != NULL) { + if (sscanf(tmp, "axis=%15s", p) == 1) { + p[15]='\0'; + if (strcmp(p, "x") == 0) + axis->mapping = MAPPING_X; + else if (strcmp(p, "y") == 0) + axis->mapping = MAPPING_Y; + else if (strcmp(p, "zx") == 0) + axis->mapping = MAPPING_ZX; + else if (strcmp(p, "zy") == 0) + axis->mapping = MAPPING_ZY; + else { + xf86Msg(X_WARNING, "%s: error parsing axis.\n", + name); + } + }else xf86Msg(X_WARNING, "%s: error parsing axis.\n", + name); + } + + if ((tmp=strstr(param, "deadzone=")) != NULL ) { + if (sscanf(tmp, "deadzone=%d", &value) == 1) { + value = (value<0)?(-value):value; + if (value > 30000) + xf86Msg(X_WARNING, + "%s: deadzone of %d seems unreasonable. Ignored.\n", + name, value); + else axis->deadzone = value; + }else xf86Msg(X_WARNING, "%s: error parsing deadzone.\n", + name); + } + if ((tmp=strstr(param, "amplify=")) != NULL ) { + if (sscanf(tmp, "amplify=%f", &fvalue) == 1) { + if ((fvalue > 10000)||(fvalue < -10000.0)) + xf86Msg(X_WARNING, + "%s: amplifier of %.3f seems unreasonable. Ignored.\n", + name, fvalue); + else axis->amplify = fvalue; + }else xf86Msg(X_WARNING, "%s: error parsing amplifier.\n", + name); + } + + xfree(param); +} diff --git a/src/jstk_options.h b/src/jstk_options.h new file mode 100644 index 0000000..494da6b --- /dev/null +++ b/src/jstk_options.h @@ -0,0 +1,35 @@ +/* + * Copyright 2007 by Sascha Hlusiak. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sascha Hlusiak not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sascha Hlusiak makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SASCHA HLUSIAK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SASCHA HLUSIAK BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef __JSTK_OPTIONS_H_INCLUDED__ +#define __JSTK_OPTIONS_H_INCLUDED__ + + +void jstkParseButtonOption(const char* org, + struct BUTTON *button, + const char* name); +void jstkParseAxisOption(const char* org, + struct AXIS *axis, + const char* name); + +#endif