summaryrefslogtreecommitdiffstats
path: root/kcontrol/joystick
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/joystick')
-rw-r--r--kcontrol/joystick/Makefile.am17
-rw-r--r--kcontrol/joystick/caldialog.cpp193
-rw-r--r--kcontrol/joystick/caldialog.h54
-rw-r--r--kcontrol/joystick/configure.in.in7
-rw-r--r--kcontrol/joystick/joydevice.cpp397
-rw-r--r--kcontrol/joystick/joydevice.h110
-rw-r--r--kcontrol/joystick/joystick.cpp123
-rw-r--r--kcontrol/joystick/joystick.desktop177
-rw-r--r--kcontrol/joystick/joystick.h42
-rw-r--r--kcontrol/joystick/joywidget.cpp379
-rw-r--r--kcontrol/joystick/joywidget.h79
-rw-r--r--kcontrol/joystick/poswidget.cpp138
-rw-r--r--kcontrol/joystick/poswidget.h55
13 files changed, 1771 insertions, 0 deletions
diff --git a/kcontrol/joystick/Makefile.am b/kcontrol/joystick/Makefile.am
new file mode 100644
index 000000000..269dec101
--- /dev/null
+++ b/kcontrol/joystick/Makefile.am
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = $(all_includes)
+METASOURCES = AUTO
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = kcm_joystick.la
+
+kcm_joystick_la_SOURCES = joystick.cpp joywidget.cpp poswidget.cpp joydevice.cpp caldialog.cpp
+kcm_joystick_la_LIBADD = $(LIB_KDEUI)
+kcm_joystick_la_LDFLAGS = -module -avoid-version $(all_libraries) -no-undefined
+
+xdg_apps_DATA = joystick.desktop
+
+messages:
+ $(XGETTEXT) *.cpp -o $(podir)/joystick.pot
+
+noinst_HEADERS = joywidget.h joywidget.h poswidget.h joydevice.h caldialog.h
+
diff --git a/kcontrol/joystick/caldialog.cpp b/kcontrol/joystick/caldialog.cpp
new file mode 100644
index 000000000..f8340d03c
--- /dev/null
+++ b/kcontrol/joystick/caldialog.cpp
@@ -0,0 +1,193 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "caldialog.h"
+#include "joydevice.h"
+
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qapplication.h>
+#include <qvbox.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+//--------------------------------------------------------------
+
+CalDialog::CalDialog(QWidget *parent, JoyDevice *joy)
+ : KDialogBase(parent, "calibrateDialog", true,
+ i18n("Calibration"),
+ KDialogBase::Cancel|KDialogBase::User1, KDialogBase::User1, true, KGuiItem(i18n("Next"))),
+ joydev(joy)
+{
+ QVBox *main = makeVBoxMainWidget();
+
+ text = new QLabel(main);
+ text->setMinimumHeight(200);
+ valueLbl = new QLabel(main);
+}
+
+//--------------------------------------------------------------
+
+void CalDialog::calibrate()
+{
+ text->setText(i18n("Please wait a moment to calculate the precision"));
+ setResult(-1);
+ show();
+
+ // calibrate precision (which min,max delivers the joystick in its center position)
+ // get values through the normal idle procedure
+ QTimer ti;
+ ti.start(2000, true); // single shot in 2 seconds
+
+ // normally I'd like to hide the 'Next' button in this step,
+ // but it does not work - which means: in the steps after the first,
+ // the 'Next' button does not have the focus (to be the default button)
+
+ do
+ {
+ qApp->processEvents(2000);
+ }
+ while ( ti.isActive() && (result() != QDialog::Rejected) );
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ joydev->calcPrecision();
+
+ int i, lastVal;
+ int min[2], center[2], max[2];
+ QString hint;
+
+ for (i = 0; i < joydev->numAxes(); i++)
+ {
+ if ( i == 0 )
+ hint = i18n("(usually X)");
+ else if ( i == 1 )
+ hint = i18n("(usually Y)");
+ else
+ hint = "";
+
+ // minimum position
+ text->setText(i18n("<qt>Calibration is about to check the value range your device delivers.<br><br>"
+ "Please move <b>axis %1 %2</b> on your device to the <b>minimum</b> position.<br><br>"
+ "Press any button on the device or click on the 'Next' button "
+ "to continue with the next step.</qt>").arg(i+1).arg(hint));
+ waitButton(i, true, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ joydev->resetMinMax(i, lastVal);
+ if ( result() != -2 ) waitButton(i, false, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ min[0] = joydev->axisMin(i);
+ min[1] = joydev->axisMax(i);
+
+ // center position
+ text->setText(i18n("<qt>Calibration is about to check the value range your device delivers.<br><br>"
+ "Please move <b>axis %1 %2</b> on your device to the <b>center</b> position.<br><br>"
+ "Press any button on the device or click on the 'Next' button "
+ "to continue with the next step.</qt>").arg(i+1).arg(hint));
+ waitButton(i, true, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ joydev->resetMinMax(i, lastVal);
+ if ( result() != -2 ) waitButton(i, false, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ center[0] = joydev->axisMin(i);
+ center[1] = joydev->axisMax(i);
+
+ // maximum position
+ text->setText(i18n("<qt>Calibration is about to check the value range your device delivers.<br><br>"
+ "Please move <b>axis %1 %2</b> on your device to the <b>maximum</b> position.<br><br>"
+ "Press any button on the device or click on the 'Next' button "
+ "to continue with the next step.</qt>").arg(i+1).arg(hint));
+ waitButton(i, true, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ joydev->resetMinMax(i, lastVal);
+ if ( result() != -2 ) waitButton(i, false, lastVal);
+
+ if ( result() == QDialog::Rejected ) return; // user cancelled the dialog
+
+ max[0] = joydev->axisMin(i);
+ max[1] = joydev->axisMax(i);
+
+ joydev->calcCorrection(i, min, center, max);
+ }
+
+ JoyDevice::ErrorCode ret = joydev->applyCalibration();
+
+ if ( ret != JoyDevice::SUCCESS )
+ {
+ KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error"));
+ reject();
+ }
+
+ KMessageBox::information(this, i18n("You have successfully calibrated your device"), i18n("Calibration Success"));
+ accept();
+}
+
+//--------------------------------------------------------------
+
+void CalDialog::waitButton(int axis, bool press, int &lastVal)
+{
+ JoyDevice::EventType type;
+ int number, value;
+ bool button = false;
+ lastVal = 0;
+
+ setResult(-1);
+ // loop until the user presses a button on the device or on the dialog
+ do
+ {
+ qApp->processEvents(100);
+
+ if ( joydev->getEvent(type, number, value) )
+ {
+ button = ( (type == JoyDevice::BUTTON) && (press ? (value == 1) : (value == 0)) );
+
+ if ( (type == JoyDevice::AXIS) && (number == axis) )
+ valueLbl->setText(i18n("Value Axis %1: %2").arg(axis+1).arg(lastVal = value));
+ }
+ }
+ while ( !button && (result() == -1) );
+}
+
+//--------------------------------------------------------------
+// Next button
+
+void CalDialog::slotUser1()
+{
+ setResult(-2);
+}
+
+//--------------------------------------------------------------
+
+#include "caldialog.moc"
+
+//--------------------------------------------------------------
diff --git a/kcontrol/joystick/caldialog.h b/kcontrol/joystick/caldialog.h
new file mode 100644
index 000000000..678a0a2d1
--- /dev/null
+++ b/kcontrol/joystick/caldialog.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _CALDIALOG_H_
+#define _CALDIALOG_H_
+
+#include <kdialogbase.h>
+
+class QLabel;
+
+class JoyDevice;
+
+// the dialog which tells the user all steps to calibrate the device
+
+class CalDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ CalDialog(QWidget *parent, JoyDevice *joy);
+
+ void calibrate();
+
+ private:
+ void waitButton(int axis, bool press, int &lastVal);
+
+ private slots:
+ virtual void slotUser1();
+
+ private:
+ JoyDevice *joydev;
+
+ QLabel *text;
+ QLabel *valueLbl;
+};
+
+#endif
diff --git a/kcontrol/joystick/configure.in.in b/kcontrol/joystick/configure.in.in
new file mode 100644
index 000000000..a76ab434a
--- /dev/null
+++ b/kcontrol/joystick/configure.in.in
@@ -0,0 +1,7 @@
+case "$host" in
+ *-*-linux*)
+ FOUND_LINUX=yes
+ ;;
+esac
+
+AM_CONDITIONAL(include_kcontrol_joystick, test "$FOUND_LINUX" = "yes")
diff --git a/kcontrol/joystick/joydevice.cpp b/kcontrol/joystick/joydevice.cpp
new file mode 100644
index 000000000..2c1a16ce7
--- /dev/null
+++ b/kcontrol/joystick/joydevice.cpp
@@ -0,0 +1,397 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "joydevice.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <math.h>
+
+//--------------------------------------------------------------
+
+JoyDevice::JoyDevice(const QString &devicefile)
+ : devName(devicefile), joyFd(-1), buttons(0), axes(0),
+ amin(0), amax(0), corr(0), origCorr(0)
+{
+}
+
+//--------------------------------------------------------------
+
+QString JoyDevice::errText(ErrorCode code) const
+{
+ switch ( code )
+ {
+ case SUCCESS: return "";
+
+ case OPEN_FAILED:
+ {
+ return i18n("The given device %1 could not be opened: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case NO_JOYSTICK:
+ {
+ return i18n("The given device %1 is not a joystick.").arg(devName);
+ }
+
+ case ERR_GET_VERSION:
+ {
+ return i18n("Could not get kernel driver version for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case WRONG_VERSION:
+ {
+ int version = 0;
+ int fd = ::open(devName.latin1(), O_RDONLY);
+ if ( fd != -1 )
+ {
+ ::ioctl(fd, JSIOCGVERSION, &version);
+ ::close(fd);
+ }
+
+ return i18n("The current running kernel driver version (%1.%2.%3) is not the one this module was compiled for (%4.%5.%6).")
+ .arg(version >> 16).arg((version >> 8) & 0xFF).arg(version & 0xFF)
+ .arg(JS_VERSION >> 16).arg((JS_VERSION >> 8) & 0xFF).arg(JS_VERSION & 0xFF);
+ }
+
+ case ERR_GET_BUTTONS:
+ {
+ return i18n("Could not get number of buttons for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case ERR_GET_AXES:
+ {
+ return i18n("Could not get number of axes for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case ERR_GET_CORR:
+ {
+ return i18n("Could not get calibration values for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case ERR_RESTORE_CORR:
+ {
+ return i18n("Could not restore calibration values for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case ERR_INIT_CAL:
+ {
+ return i18n("Could not initialize calibration values for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ case ERR_APPLY_CAL:
+ {
+ return i18n("Could not apply calibration values for joystick device %1: %2")
+ .arg(devName).arg(strerror(errno));
+ }
+
+ default: return i18n("internal error - code %1 unknown").arg(int(code));
+ }
+}
+
+//--------------------------------------------------------------
+
+JoyDevice::ErrorCode JoyDevice::open()
+{
+ if ( joyFd != -1 ) return JoyDevice::SUCCESS; // already open
+
+ int fd = ::open(devName.latin1(), O_RDONLY);
+
+ if ( fd == -1 )
+ return JoyDevice::OPEN_FAILED;
+
+ // we could open the devicefile, now check if a joystick is attached
+ char name[128];
+
+ if ( ::ioctl(fd, JSIOCGNAME(sizeof(name)), &name) == -1 )
+ {
+ ::close(fd);
+ return JoyDevice::NO_JOYSTICK;
+ }
+
+ // check the kernel driver version
+ int version;
+ if ( ::ioctl(fd, JSIOCGVERSION, &version) == -1 )
+ {
+ ::close(fd);
+ return JoyDevice::ERR_GET_VERSION;
+ }
+
+ if ( version != JS_VERSION )
+ {
+ ::close(fd);
+ return JoyDevice::WRONG_VERSION;
+ }
+
+ char bt = 0, ax = 0;
+ if ( ::ioctl(fd, JSIOCGBUTTONS, &bt) == -1 )
+ {
+ ::close(fd);
+ return JoyDevice::ERR_GET_BUTTONS;
+ }
+
+ if ( ::ioctl(fd, JSIOCGAXES, &ax) == -1 )
+ {
+ ::close(fd);
+ return JoyDevice::ERR_GET_AXES;
+ }
+
+ struct js_corr *oldCorr = new struct js_corr[ax];
+
+ if ( ::ioctl(fd, JSIOCGCORR, oldCorr) == -1 )
+ {
+ ::close(fd);
+ delete [] oldCorr;
+ return JoyDevice::ERR_GET_CORR;
+ }
+
+ descr = name;
+ joyFd = fd;
+ axes = ax;
+ buttons = bt;
+ origCorr = oldCorr;
+ corr = new struct js_corr[axes];
+
+ amin = new int[axes];
+ amax = new int[axes];
+
+ int i;
+
+ for (i = 0; i < axes; i++)
+ resetMinMax(i);
+
+ return JoyDevice::SUCCESS;
+}
+
+//--------------------------------------------------------------
+
+void JoyDevice::close()
+{
+ if ( joyFd == -1 ) return;
+
+ ::close(joyFd);
+
+ joyFd = -1;
+ descr = "";
+
+ delete [] amin;
+ delete [] amax;
+ amin = 0;
+ amax = 0;
+
+ delete [] corr;
+ corr = 0;
+ delete [] origCorr;
+ origCorr = 0;
+}
+
+//--------------------------------------------------------------
+
+int JoyDevice::axisMin(int axis) const
+{
+ if ( (axis < 0) || (axis >= axes) ) return 0;
+
+ return amin[axis];
+}
+
+//--------------------------------------------------------------
+
+int JoyDevice::axisMax(int axis) const
+{
+ if ( (axis < 0) || (axis >= axes) ) return 0;
+
+ return amax[axis];
+}
+
+//--------------------------------------------------------------
+
+JoyDevice::ErrorCode JoyDevice::initCalibration()
+{
+ if ( joyFd == -1 ) return JoyDevice::ERR_INIT_CAL;
+
+ int i;
+
+ // Reset all current correction values
+ for (i = 0; i < axes; i++)
+ {
+ corr[i].type = JS_CORR_NONE;
+ corr[i].prec = 0;
+ }
+
+ if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 )
+ return JoyDevice::ERR_INIT_CAL;
+
+ for (i = 0; i < axes; i++)
+ corr[i].type = JS_CORR_BROKEN;
+
+ return JoyDevice::SUCCESS;
+}
+
+//--------------------------------------------------------------
+
+JoyDevice::ErrorCode JoyDevice::applyCalibration()
+{
+ if ( joyFd == -1 ) return JoyDevice::ERR_APPLY_CAL;
+
+ if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 )
+ return JoyDevice::ERR_APPLY_CAL;
+
+ return JoyDevice::SUCCESS;
+}
+
+//--------------------------------------------------------------
+
+void JoyDevice::resetMinMax(int axis, int value)
+{
+ amin[axis] = value;
+ amax[axis] = value;
+}
+
+//--------------------------------------------------------------
+
+void JoyDevice::calcPrecision()
+{
+ if ( !corr ) return;
+
+ int i;
+
+ for (i = 0; i < axes; i++)
+ {
+ corr[i].prec = amax[i] - amin[i];
+ kdDebug() << "Precision for axis: " << i << ": " << corr[i].prec << endl;
+ }
+}
+
+//--------------------------------------------------------------
+
+JoyDevice::ErrorCode JoyDevice::restoreCorr()
+{
+ if ( joyFd == -1 ) return JoyDevice::SUCCESS;
+
+ if ( ::ioctl(joyFd, JSIOCSCORR, origCorr) == -1 )
+ return JoyDevice::ERR_RESTORE_CORR;
+ else
+ return JoyDevice::SUCCESS;
+}
+
+//--------------------------------------------------------------
+
+JoyDevice::~JoyDevice()
+{
+ close();
+}
+
+//--------------------------------------------------------------
+
+bool JoyDevice::getEvent(JoyDevice::EventType &type, int &number, int &value)
+{
+ number = value = 0;
+
+ int ret;
+
+ fd_set readSet;
+
+ FD_ZERO(&readSet);
+ FD_SET(joyFd, &readSet);
+
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+
+ ret = ::select(joyFd + 1, &readSet, 0, 0, &timeout);
+
+ if ( ret == 1 ) // got an event from the joystick
+ {
+ struct js_event e;
+
+ if ( ::read(joyFd, &e, sizeof(struct js_event)) == sizeof(struct js_event) )
+ {
+ if ( e.type & JS_EVENT_BUTTON )
+ {
+ type = JoyDevice::BUTTON;
+ value = e.value;
+ number = e.number;
+
+ return true;
+ }
+
+ if ( e.type & JS_EVENT_AXIS )
+ {
+ type = JoyDevice::AXIS;
+ value = e.value;
+ number = e.number;
+
+ // store min, max values
+ if ( e.value < amin[number] ) amin[number] = e.value;
+ if ( e.value > amax[number] ) amax[number] = e.value;
+
+ return true;
+ }
+ }
+ }
+
+ return false; // no event
+}
+
+//--------------------------------------------------------------
+
+void JoyDevice::calcCorrection(int axis, int *min, int *center, int *max)
+{
+ const int MIN = 0;
+ const int MAX = 1;
+
+ double a, b, c, d;
+
+ a = center[MIN]; // inputs.cmin[1];
+ b = center[MAX]; // inputs.cmax[1];
+ c = 32767.0 / (center[MIN] - min[MAX]); // (inputs.cmin[1] - inputs.cmax[0]);
+ d = 32767.0 / (max[MIN] - center[MAX]); // (inputs.cmin[2] - inputs.cmax[1]);
+
+ corr[axis].coef[0] = (int)rint(a);
+ corr[axis].coef[1] = (int)rint(b);
+ corr[axis].coef[2] = (int)rint(c*16384.0);
+ corr[axis].coef[3] = (int)rint(d*16384.0);
+
+ kdDebug() << "min min: " << min[0] << " max: " << min[1] << endl;
+ kdDebug() << "max min: " << max[0] << " max: " << max[1] << endl;
+ kdDebug() << "Correction values for axis: " << axis << ": "
+ << corr[axis].coef[0] << ", "
+ << corr[axis].coef[1] << ", "
+ << corr[axis].coef[2] << ", "
+ << corr[axis].coef[3] << endl;
+}
+
+//--------------------------------------------------------------
diff --git a/kcontrol/joystick/joydevice.h b/kcontrol/joystick/joydevice.h
new file mode 100644
index 000000000..b84464241
--- /dev/null
+++ b/kcontrol/joystick/joydevice.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _JOYDEVICE_H_
+#define _JOYDEVICE_H_
+
+#include <qstring.h>
+
+#include <sys/types.h>
+#undef __STRICT_ANSI__
+#include <linux/joystick.h>
+#define __STRICT_ANSI__
+
+// helper class which holds all current values, file descriptor, etc. for
+// one device
+class JoyDevice
+{
+ public:
+ enum ErrorCode
+ {
+ SUCCESS,
+ OPEN_FAILED,
+ NO_JOYSTICK,
+ WRONG_VERSION,
+ ERR_GET_VERSION,
+ ERR_GET_BUTTONS,
+ ERR_GET_AXES,
+ ERR_GET_CORR,
+ ERR_RESTORE_CORR,
+ ERR_INIT_CAL,
+ ERR_APPLY_CAL
+ };
+
+ enum EventType
+ {
+ BUTTON,
+ AXIS
+ };
+
+ // devicefile to use, e.g. "/dev/js0"
+ JoyDevice(const QString &devicefile);
+ ~JoyDevice();
+
+ // returns one of the error-codes from above
+ ErrorCode open();
+
+ // return descriptive error text for given error code
+ QString errText(ErrorCode code) const;
+
+ int fd() const { return joyFd; }
+ void close();
+ ErrorCode restoreCorr();
+
+ // return devicefilename from constructor
+ const QString &device() const { return devName; }
+
+ // descriptive text for this device read from the driver
+ QString text() const { return descr; }
+
+ int numButtons() const { return buttons; }
+ int numAxes() const { return axes; }
+ int axisMin(int axis) const;
+ int axisMax(int axis) const;
+
+ // read next event from device; returns true if there was an event during the short timeout
+ bool getEvent(JoyDevice::EventType &type, int &number, int &value);
+
+ // methods for calibration
+ ErrorCode initCalibration(); // must be called first
+ void calcPrecision();
+
+ void resetMinMax(int axis, int value = 0);
+
+ // calculate correction values
+ // min[2], center[2], max[2], index 0 == minimum, index 1 == maximum
+ void calcCorrection(int axis, int *min, int *center, int *max);
+ ErrorCode applyCalibration();
+
+ private:
+ QString devName; // device filename
+ QString descr; // descriptive text
+ int joyFd;
+
+ int buttons;
+ int axes;
+ int *amin; // axes min values
+ int *amax; // axes max values
+
+ struct js_corr *corr; // calibration values during the calib. steps
+ struct js_corr *origCorr; // original calibration correction values
+};
+
+#endif
diff --git a/kcontrol/joystick/joystick.cpp b/kcontrol/joystick/joystick.cpp
new file mode 100644
index 000000000..75115fcb7
--- /dev/null
+++ b/kcontrol/joystick/joystick.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kaboutdata.h>
+#include <kgenericfactory.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+#include "joystick.h"
+#include "joywidget.h"
+#include "joydevice.h"
+
+//---------------------------------------------------------------------------------------------
+
+typedef KGenericFactory<joystick, QWidget> JoystickFactory;
+K_EXPORT_COMPONENT_FACTORY(kcm_joystick, JoystickFactory("joystick"))
+
+extern "C"
+{
+ KDE_EXPORT bool test_joystick()
+ { /* Code stolen from JoyWidget::init() */
+ int i;
+ char dev[30];
+
+ for (i = 0; i < 5; i++) // check the first 5 devices
+ {
+ sprintf(dev, "/dev/js%d", i); // first look in /dev
+ JoyDevice *joy = new JoyDevice(dev);
+
+ if ( joy->open() != JoyDevice::SUCCESS )
+ {
+ delete joy;
+ sprintf(dev, "/dev/input/js%d", i); // then look in /dev/input
+ joy = new JoyDevice(dev);
+
+ if ( joy->open() != JoyDevice::SUCCESS )
+ {
+ delete joy;
+ continue; // try next number
+ }
+ }
+
+ return true; /* We have at least one joystick and should hence be shown */
+ }
+ return false;
+ }
+}
+
+//---------------------------------------------------------------------------------------------
+
+joystick::joystick(QWidget *parent, const char *name, const QStringList &)
+ : KCModule(JoystickFactory::instance(), parent, name)
+{
+ setAboutData( new KAboutData("kcmjoystick", I18N_NOOP("KDE Joystick Control Module"), "1.0",
+ I18N_NOOP("KDE Control Center Module to test Joysticks"),
+ KAboutData::License_GPL, "(c) 2004, Martin Koller",
+ 0, "m.koller@surfeu.at"));
+
+ setQuickHelp( i18n("<h1>Joystick</h1>"
+ "This module helps to check if your joystick is working correctly.<br>"
+ "If it delivers wrong values for the axes, you can try to solve this with "
+ "the calibration.<br>"
+ "This module tries to find all available joystick devices "
+ "by checking /dev/js[0-4] and /dev/input/js[0-4]<br>"
+ "If you have another device file, enter it in the combobox.<br>"
+ "The Buttons list shows the state of the buttons on your joystick, the Axes list "
+ "shows the current value for all axes.<br>"
+ "NOTE: the current Linux device driver (Kernel 2.4, 2.6) can only autodetect"
+ "<ul>"
+ "<li>2-axis, 4-button joystick</li>"
+ "<li>3-axis, 4-button joystick</li>"
+ "<li>4-axis, 4-button joystick</li>"
+ "<li>Saitek Cyborg 'digital' joysticks</li>"
+ "</ul>"
+ "(For details you can check your Linux source/Documentation/input/joystick.txt)"
+ ));
+
+ joyWidget = new JoyWidget(this);
+
+ setMinimumSize(joyWidget->minimumSize());
+
+ setButtons(KCModule::Default);
+}
+
+//---------------------------------------------------------------------------------------------
+
+void joystick::load()
+{
+ joyWidget->init();
+}
+
+//---------------------------------------------------------------------------------------------
+
+void joystick::defaults()
+{
+ joyWidget->resetCalibration();
+
+ emit changed(true);
+}
+
+//---------------------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------
+
+#include "joystick.moc"
diff --git a/kcontrol/joystick/joystick.desktop b/kcontrol/joystick/joystick.desktop
new file mode 100644
index 000000000..92166c544
--- /dev/null
+++ b/kcontrol/joystick/joystick.desktop
@@ -0,0 +1,177 @@
+[Desktop Entry]
+Comment=joystick - a kcontrol module to test joysticks
+Comment[af]=joystick - 'n beheer module om joysticks mee te toets
+Comment[be]=Модуль настаўлення джойстыка
+Comment[bg]=Настройване на джойстика
+Comment[bn]=joystick - জয়-স্টিক পরীক্ষা করার জন্য একটি নিয়ন্ত্রণ মডিউল
+Comment[bs]=joystick - KControl modul za testiranje džojstika
+Comment[ca]=Joystick - un mòdul de kcontrol per a provar palanques de control
+Comment[cs]=Ovládací modul pro testování joysticků
+Comment[csb]=joystick - mòduł Centróm kòntrolë dlô testowaniô joysticków
+Comment[cy]=joystick - modiwl kcontrol i brofi ffyn rheoli
+Comment[da]=joystick - et kcontrol modul til at test joystick
+Comment[de]=Joystick-Testmodul
+Comment[el]=χειριστήριο - ένα άρθρωμα ελέγχου χειριστηρίων
+Comment[eo]=stirstango - kontrola modulo por testi stirstangojn
+Comment[es]=joystick - un módulo de kcontrol para probar joysticks
+Comment[et]=juhtpult - KDE juhtimiskeskuse moodul juhtpultide testimiseks
+Comment[eu]=joystick - joystickak aztertzeko kontrol modulua
+Comment[fa]=اهرم کنترل - پیمانۀ kcontrol برای آزمایش اهرمهای کنترل
+Comment[fi]=peliohjain - KDE:n ohjauskeskuksen moduuli peliohjainta varten
+Comment[fr]=joystick - un module pour tester les joysticks
+Comment[fy]=joystick - in Konfiguraasjemodule foar it teste fan joysticks
+Comment[gl]=joystick - un módulo de kcontrol para probar joysticks
+Comment[he]=ג'ויסטיק - מודול לבדיקת ג'ויסטיקים
+Comment[hi]=जॉयस्टिक - जॉयस्टिक को जाँचने का एक के-कंट्रोल मॉड्यूल
+Comment[hr]=joystick - kcontrol modul za ispitivanje igraće palice
+Comment[hu]=Botkormányok tesztelése, kalibrálása
+Comment[is]=joystick - kcontrol stjórneining til að prófa stýripinna
+Comment[it]=joystick - un modulo di kcontrol per provare i joystick
+Comment[ja]=ジョイスティックをテストする kcontrol モジュール
+Comment[ka]=joystick - kcontrol მოდული ჯოისტიკის ტესტირებისთვის
+Comment[kk]=joystick - джойстикты сынау kcontrol модулі
+Comment[km]=យ៉យស្ទីក - ម៉ូឌុល kcontrol ដើម្បី​សាកល្បង​យ៉យស្ទីក
+Comment[ko]=joystick - 조이스틱을 테스트하기 위한 kcontrol 모듈
+Comment[lt]=valdymo svirtis - kcontrol modulis valdymo svirčių išbandymui
+Comment[lv]=kursorsvira - kkontroles modulis kursorsviru testēšanai
+Comment[mk]=joystick - модул на kcontrol за тестирање џојстици
+Comment[mt]=joystick - modulu ta' kcontrol biex tittestja joysticks
+Comment[nb]=Styrepinne – en kcontrolmodul for å prøve ut styrepinner
+Comment[nds]=joystick - Moduul för't Utproberen vun Joysticks
+Comment[ne]=जोयस्टिक - जोयस्टिक परीक्षण गर्ने के नियन्त्रण मोड्युल
+Comment[nl]=joystick - een configuratiemodule voor het testen van joysticks
+Comment[nn]=Styrespak – ein kontrollmodul for å prøva ut styrepinnar
+Comment[pa]=joystick - ਜਾਏਸਟਿੱਕ ਜਾਂਚ ਲਈ ਕੇਕੰਟਰੋਲ ਮੈਡੀਊਲ
+Comment[pl]=joystick - moduł Centrum sterowania do testowania joysticków
+Comment[pt]=joystick - um módulo do kcontrol para testar joysticks
+Comment[pt_BR]=joystick - um módulo de controle para testes de joysticks
+Comment[ro]=Un modul pentru testarea joystick-urilor
+Comment[ru]=joystick - модуль kcontrol для проверки джойстика
+Comment[rw]=Agakoreshamukino - igice cya k-igenzura mu gusuzuma udukoreshamikino
+Comment[se]=Stivrensággi – stivrenmoduvla mainna geahččala stivrensákkiid
+Comment[sk]=Ovládací modul pre test joysticku
+Comment[sl]=joystick - modul Nadzornega središča za preizkus igralnih palic
+Comment[sr]=џојстик - модул контролног центра за тестирање џојстика
+Comment[sr@Latn]=džojstik - modul kontrolnog centra za testiranje džojstika
+Comment[sv]=Styrspak: en inställningsmodul för att testa styrspakar
+Comment[ta]=இயக்கும் கருவி - கேகண்ட்ரோல் கூறு இயக்கும் கருவியை பரிசோதிக்கிறது
+Comment[tg]=ҷостик - модули kидора барои санҷиши ҷостикҳо
+Comment[th]=จอยสติก - โมดูลของศูนย์ควบคุม KDE สำหรับตรวจสอบจอยสติก
+Comment[tr]=oyun kumandası - oyun kumandalarını denemek için bir kcontrol modülü
+Comment[tt]=Joystik sınaw öçen kcontrol modulı
+Comment[uk]=Джойстик - модуль центру керування для тестування джойстиків
+Comment[uz]=Joystik uchun boshqaruv moduli
+Comment[uz@cyrillic]=Жойстик учун бошқарув модули
+Comment[vi]=cần điều khiển - một mô đun điều khiển KDE đêr kiểm tra cần lái
+Comment[wa]=djîsse di djeu - on module di kcontrol po sayî les djîsses di djeu
+Comment[zh_CN]=joystick - 测试游戏杆的 kcontrol 模块
+Comment[zh_TW]=搖桿 - 用來測試搖桿的 kcontrol 模組
+Exec=kcmshell joystick
+Keywords=joystick,gamepad
+Keywords[be]=Джойстык,joystick,gamepad
+Keywords[bg]=джойстик, игра, игри, управление, joystick, gamepad
+Keywords[bs]=joystick,gamepad,džojstik
+Keywords[csb]=joystick,gamepad,dżojstik
+Keywords[cy]=ffôn reoli,pad gêm
+Keywords[da]=joystick,spilleplade
+Keywords[de]=Joystick,Gamepad,Spiele
+Keywords[el]=χειριστήριο,χειριστήριο κονσόλας παιχνιδιών
+Keywords[eo]=stirstango,stirstangoj,ludotabuleto
+Keywords[et]=juhtpult,mängupult
+Keywords[fa]=اهرم کنترل، صفحه بازی
+Keywords[fi]=joystick,peliohjain
+Keywords[fr]=joystick,gamepad,manette de jeu
+Keywords[ga]=luamhán stiúrtha,ceap cluiche
+Keywords[he]=joystick,gamepad,ג'ויסטיק,גויסטיק
+Keywords[hi]=जॉयस्टिक,गेमपेड
+Keywords[hr]=joystick,gamepad,igraća palica,igraća konzola
+Keywords[hu]=botkormány,joystick,gamepad
+Keywords[is]=joystick,gamepad,stýripinni
+Keywords[ja]=joystick,gamepad,ジョイスティック,ゲームパッド
+Keywords[km]=យ៉យស្ទីក,បន្ទះ​ល្បែង
+Keywords[lt]=valdymo svirtis, joystick,gamepad
+Keywords[lv]=kursorsvira,spēļu pults
+Keywords[nb]=styrepinne,spillkontroll
+Keywords[ne]=जोयस्टिक, गेमप्याड
+Keywords[nn]=styrespak,spelkontroll
+Keywords[pa]=joystick,gamepad,ਜਾਏਸਟਿੱਕ
+Keywords[pl]=joystick,gamepad,dżojstik
+Keywords[pt_BR]=joystick,gamepad, jogos
+Keywords[rw]=agakoreshamukino, umwanyaumukino
+Keywords[se]=stivrensággi,speallanstivrran
+Keywords[sl]=joystick,gamepad,igralna palica,igralni plošček
+Keywords[sr]=joystick,gamepad,џојстик
+Keywords[sr@Latn]=joystick,gamepad,džojstik
+Keywords[sv]=styrspak,spelkonsol
+Keywords[ta]=இயக்கும் கருவி, விளையாட்டு பலகை
+Keywords[te]=జాయ్ స్టిక్, గేమ్ పాడ్
+Keywords[th]=จอยสติก,แป้นคุมเกม,gamepad
+Keywords[tr]=oyun çubuğu
+Keywords[uk]=джойстик,gamepad
+Keywords[uz]=joystik,geympad
+Keywords[uz@cyrillic]=жойстик,геймпад
+Keywords[vi]=cần điều khiển,bàn điều khiển trò chơi
+Keywords[wa]=joystick,gamepad,djîsse,djîsse di djeu
+Keywords[zh_CN]=joystick,gamepad,游戏杆,手柄
+Keywords[zh_TW]=joystick,gamepad,搖桿,遊戲台
+Name=Joystick
+Name[be]=Джойстык
+Name[bg]=Джойстик
+Name[bn]=জয়-স্টিক
+Name[br]=Lanker-c'hoari
+Name[ca]=Palanca de control
+Name[cy]=Ffôn reoli
+Name[el]=Χειριστήριο
+Name[eo]=Stirstango
+Name[et]=Juhtpult
+Name[fa]=اهرم کنترل
+Name[fi]=Peliohjain
+Name[ga]=Luamhán Stiúrtha
+Name[he]=ג'ויסטיק
+Name[hi]=जॉयस्टिक
+Name[hr]=Igraća palica
+Name[hu]=Botkormány
+Name[is]=Stýripinnar
+Name[ja]=ジョイスティック
+Name[ka]=ჯოისტიკი
+Name[kk]=Джойстик
+Name[km]=យ៉យស្ទីក
+Name[ko]=조이스틱
+Name[lo]=จอยสติ๊ก
+Name[lt]=Valdymo svirtis
+Name[lv]=Kursorsvira
+Name[ms]=Kayu Bidik
+Name[nb]=Styrepinne
+Name[ne]=जोयस्टिक
+Name[nn]=Styrespak
+Name[oc]=Palanca de jogs
+Name[pa]=ਜਾਏਸਟਿੱਕ
+Name[ru]=Джойстик
+Name[rw]=Agakoreshamukino
+Name[se]=Stivrensággi
+Name[sl]=Igralna palica
+Name[sr]=Џојстик
+Name[sr@Latn]=Džojstik
+Name[sv]=Styrspak
+Name[ta]=இயக்கு கருவி
+Name[te]=జాయ్ స్టిక్
+Name[th]=จอยสติก
+Name[tr]=Oyun Çubuğu
+Name[tt]=Joystik
+Name[uk]=Джойстик
+Name[uz]=Joystik
+Name[uz@cyrillic]=Жойстик
+Name[ven]=Thambo dzau tumanya na tshishumiswa
+Name[vi]=Cần điều khiển
+Name[wa]=Djîsse di djeu
+Name[xh]=Uvuyo
+Name[zh_CN]=游戏杆
+Name[zh_TW]=玩具
+Name[zu]=Induku yenjabulo
+Terminal=false
+Type=Application
+X-KDE-FactoryName=kcm_joystick
+X-KDE-Library=joystick
+X-KDE-Test-Module=true
+Icon=joystick
+Categories=Qt;KDE;X-KDE-settings-hardware;
diff --git a/kcontrol/joystick/joystick.h b/kcontrol/joystick/joystick.h
new file mode 100644
index 000000000..819a5f70d
--- /dev/null
+++ b/kcontrol/joystick/joystick.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _JOYSTICK_H_
+#define _JOYSTICK_H_
+
+#include <kcmodule.h>
+
+class JoyWidget;
+
+class joystick: public KCModule
+{
+ Q_OBJECT
+
+ public:
+ joystick(QWidget *parent = 0, const char *name = 0, const QStringList &list = QStringList());
+
+ virtual void load();
+ virtual void defaults();
+
+ private:
+ JoyWidget *joyWidget;
+};
+
+#endif
diff --git a/kcontrol/joystick/joywidget.cpp b/kcontrol/joystick/joywidget.cpp
new file mode 100644
index 000000000..a4d42e3f1
--- /dev/null
+++ b/kcontrol/joystick/joywidget.cpp
@@ -0,0 +1,379 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "joywidget.h"
+#include "joydevice.h"
+#include "poswidget.h"
+#include "caldialog.h"
+
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qtable.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qlistbox.h>
+#include <qcheckbox.h>
+#include <qtimer.h>
+#include <qfontmetrics.h>
+#include <qpushbutton.h>
+
+#include <klocale.h>
+#include <kdialog.h>
+#include <kmessagebox.h>
+#include <kiconloader.h>
+
+//--------------------------------------------------------------
+static QString PRESSED = I18N_NOOP("PRESSED");
+//--------------------------------------------------------------
+
+JoyWidget::JoyWidget(QWidget *parent, const char *name)
+ : QWidget(parent, name), idle(0), joydev(0)
+{
+ QVBox *mainVbox = new QVBox(parent);
+ mainVbox->setSpacing(KDialog::spacingHint());
+
+ // create area to show an icon + message if no joystick was detected
+ {
+ messageBox = new QHBox(mainVbox);
+ messageBox->setSpacing(KDialog::spacingHint());
+ QLabel *icon = new QLabel(messageBox);
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon("messagebox_warning", KIcon::NoGroup,
+ KIcon::SizeMedium, KIcon::DefaultState, 0, true));
+ icon->setFixedSize(icon->sizeHint());
+ message = new QLabel(messageBox);
+ messageBox->hide();
+ }
+
+ QHBox *devHbox = new QHBox(mainVbox);
+ new QLabel(i18n("Device:"), devHbox);
+ device = new QComboBox(true, devHbox);
+ device->setInsertionPolicy(QComboBox::NoInsertion);
+ connect(device, SIGNAL(activated(const QString &)), this, SLOT(deviceChanged(const QString &)));
+ devHbox->setStretchFactor(device, 3);
+
+ QHBox *hbox = new QHBox(mainVbox);
+ hbox->setSpacing(KDialog::spacingHint());
+
+ QVBox *vboxLeft = new QVBox(hbox);
+ vboxLeft->setSpacing(KDialog::spacingHint());
+
+ new QLabel(i18n("Position:"), vboxLeft);
+ xyPos = new PosWidget(vboxLeft);
+ trace = new QCheckBox(i18n("Show trace"), mainVbox);
+ connect(trace, SIGNAL(toggled(bool)), this, SLOT(traceChanged(bool)));
+
+ QVBox *vboxMid = new QVBox(hbox);
+ vboxMid->setSpacing(KDialog::spacingHint());
+
+ QVBox *vboxRight = new QVBox(hbox);
+ vboxRight->setSpacing(KDialog::spacingHint());
+
+ // calculate the column width we need
+ QFontMetrics fm(font());
+ int colWidth = QMAX(fm.width(PRESSED), fm.width("-32767")) + 10; // -32767 largest string
+
+ new QLabel(i18n("Buttons:"), vboxMid);
+ buttonTbl = new QTable(0, 1, vboxMid);
+ buttonTbl->setReadOnly(true);
+ buttonTbl->horizontalHeader()->setLabel(0, i18n("State"));
+ buttonTbl->horizontalHeader()->setClickEnabled(false);
+ buttonTbl->horizontalHeader()->setResizeEnabled(false);
+ buttonTbl->verticalHeader()->setClickEnabled(false);
+ buttonTbl->verticalHeader()->setResizeEnabled(false);
+ buttonTbl->setColumnWidth(0, colWidth);
+
+ new QLabel(i18n("Axes:"), vboxRight);
+ axesTbl = new QTable(0, 1, vboxRight);
+ axesTbl->setReadOnly(true);
+ axesTbl->horizontalHeader()->setLabel(0, i18n("Value"));
+ axesTbl->horizontalHeader()->setClickEnabled(false);
+ axesTbl->horizontalHeader()->setResizeEnabled(false);
+ axesTbl->verticalHeader()->setClickEnabled(false);
+ axesTbl->verticalHeader()->setResizeEnabled(false);
+ axesTbl->setColumnWidth(0, colWidth);
+
+ // calibrate button
+ calibrate = new QPushButton(i18n("Calibrate"), mainVbox);
+ connect(calibrate, SIGNAL(clicked()), this, SLOT(calibrateDevice()));
+ calibrate->setEnabled(false);
+
+ // set up a timer for idle processing of joystick events
+ idle = new QTimer(this);
+ connect(idle, SIGNAL(timeout()), this, SLOT(checkDevice()));
+
+ // check which devicefiles we have
+ init();
+
+ vboxLeft->adjustSize();
+ vboxMid->adjustSize();
+ vboxRight->adjustSize();
+ hbox->adjustSize();
+ mainVbox->adjustSize();
+
+ setMinimumSize(mainVbox->size());
+}
+
+//--------------------------------------------------------------
+
+JoyWidget::~JoyWidget()
+{
+ delete joydev;
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::init()
+{
+ // check which devicefiles we have
+ int i;
+ bool first = true;
+ char dev[30];
+
+ device->clear();
+ buttonTbl->setNumRows(0);
+ axesTbl->setNumRows(0);
+
+ for (i = 0; i < 5; i++) // check the first 5 devices
+ {
+ sprintf(dev, "/dev/js%d", i); // first look in /dev
+ JoyDevice *joy = new JoyDevice(dev);
+
+ if ( joy->open() != JoyDevice::SUCCESS )
+ {
+ delete joy;
+ sprintf(dev, "/dev/input/js%d", i); // then look in /dev/input
+ joy = new JoyDevice(dev);
+
+ if ( joy->open() != JoyDevice::SUCCESS )
+ {
+ delete joy;
+ continue; // try next number
+ }
+ }
+
+ // we found one
+
+ device->insertItem(QString("%1 (%2)").arg(joy->text()).arg(joy->device()));
+
+ // display values for first device
+ if ( first )
+ {
+ showDeviceProps(joy); // this sets the joy object into this->joydev
+ first = false;
+ }
+ else
+ delete joy;
+ }
+
+ /* KDE 4: Remove this check(and i18n) when all KCM wrappers properly test modules */
+ if ( device->count() == 0 )
+ {
+ messageBox->show();
+ message->setText(QString("<qt><b>%1</b></qt>").arg(
+ i18n("No joystick device automatically found on this computer.<br>"
+ "Checks were done in /dev/js[0-4] and /dev/input/js[0-4]<br>"
+ "If you know that there is one attached, please enter the correct device file.")));
+ }
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::traceChanged(bool state)
+{
+ xyPos->showTrace(state);
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::restoreCurrDev()
+{
+ if ( !joydev ) // no device open
+ {
+ device->setCurrentText("");
+ calibrate->setEnabled(false);
+ }
+ else
+ {
+ // try to find the current open device in the combobox list
+ QListBoxItem *item;
+ item = device->listBox()->findItem(joydev->device(), Qt::Contains);
+
+ if ( !item ) // the current open device is one the user entered (not in the list)
+ device->setCurrentText(joydev->device());
+ else
+ device->setCurrentText(item->text());
+ }
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::deviceChanged(const QString &dev)
+{
+ // find "/dev" in given string
+ int start, stop;
+ QString devName;
+
+ if ( (start = dev.find("/dev")) == -1 )
+ {
+ KMessageBox::sorry(this,
+ i18n("The given device name is invalid (does not contain /dev).\n"
+ "Please select a device from the list or\n"
+ "enter a device file, like /dev/js0."), i18n("Unknown Device"));
+
+ restoreCurrDev();
+ return;
+ }
+
+ if ( (stop = dev.find(")", start)) != -1 ) // seems to be text selected from our list
+ devName = dev.mid(start, stop - start);
+ else
+ devName = dev.mid(start);
+
+ if ( joydev && (devName == joydev->device()) ) return; // user selected the current device; ignore it
+
+ JoyDevice *joy = new JoyDevice(devName);
+ JoyDevice::ErrorCode ret = joy->open();
+
+ if ( ret != JoyDevice::SUCCESS )
+ {
+ KMessageBox::error(this, joy->errText(ret), i18n("Device Error"));
+
+ delete joy;
+ restoreCurrDev();
+ return;
+ }
+
+ showDeviceProps(joy);
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::showDeviceProps(JoyDevice *joy)
+{
+ joydev = joy;
+
+ buttonTbl->setNumRows(joydev->numButtons());
+
+ axesTbl->setNumRows(joydev->numAxes());
+ if ( joydev->numAxes() >= 2 )
+ {
+ axesTbl->verticalHeader()->setLabel(0, "1(x)");
+ axesTbl->verticalHeader()->setLabel(1, "2(y)");
+ }
+
+ calibrate->setEnabled(true);
+ idle->start(0);
+
+ // make both tables use the same space for header; this looks nicer
+ buttonTbl->setLeftMargin(QMAX(buttonTbl->verticalHeader()->width(),
+ axesTbl->verticalHeader()->width()));
+ axesTbl->setLeftMargin(buttonTbl->verticalHeader()->width());
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::checkDevice()
+{
+ if ( !joydev ) return; // no open device yet
+
+ JoyDevice::EventType type;
+ int number, value;
+
+ if ( !joydev->getEvent(type, number, value) )
+ return;
+
+ if ( type == JoyDevice::BUTTON )
+ {
+ if ( value == 0 ) // button release
+ buttonTbl->setText(number, 0, "-");
+ else
+ buttonTbl->setText(number, 0, PRESSED);
+ }
+
+ if ( type == JoyDevice::AXIS )
+ {
+ if ( number == 0 ) // x-axis
+ xyPos->changeX(value);
+
+ if ( number == 1 ) // y-axis
+ xyPos->changeY(value);
+
+ axesTbl->setText(number, 0, QString("%1").arg(int(value)));
+ }
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::calibrateDevice()
+{
+ if ( !joydev ) return; // just to be save
+
+ JoyDevice::ErrorCode ret = joydev->initCalibration();
+
+ if ( ret != JoyDevice::SUCCESS )
+ {
+ KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error"));
+ return;
+ }
+
+ if ( KMessageBox::messageBox(this, KMessageBox::Information,
+ i18n("<qt>Calibration is about to check the precision.<br><br>"
+ "<b>Please move all axes to their center position and then "
+ "do not touch the joystick anymore.</b><br><br>"
+ "Click OK to start the calibration.</qt>"),
+ i18n("Calibration"),
+ KStdGuiItem::ok(), KStdGuiItem::cancel()) != KMessageBox::Ok )
+ return;
+
+ idle->stop(); // stop the joystick event getting; this must be done inside the calibrate dialog
+
+ CalDialog dlg(this, joydev);
+ dlg.calibrate();
+
+ // user cancelled somewhere during calibration, therefore the device is in a bad state
+ if ( dlg.result() == QDialog::Rejected )
+ joydev->restoreCorr();
+
+ idle->start(0); // continue with event getting
+}
+
+//--------------------------------------------------------------
+
+void JoyWidget::resetCalibration()
+{
+ if ( !joydev ) return; // just to be save
+
+ JoyDevice::ErrorCode ret = joydev->restoreCorr();
+
+ if ( ret != JoyDevice::SUCCESS )
+ {
+ KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error"));
+ }
+ else
+ {
+ KMessageBox::information(this,
+ i18n("Restored all calibration values for joystick device %1.").arg(joydev->device()),
+ i18n("Calibration Success"));
+ }
+}
+
+//--------------------------------------------------------------
+
+#include "joywidget.moc"
diff --git a/kcontrol/joystick/joywidget.h b/kcontrol/joystick/joywidget.h
new file mode 100644
index 000000000..5f561c0e5
--- /dev/null
+++ b/kcontrol/joystick/joywidget.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _JOYWIDGET_H_
+#define _JOYWIDGET_H_
+
+#include <qwidget.h>
+
+class JoyDevice;
+
+class PosWidget;
+class QLabel;
+class QTable;
+class QTimer;
+class QComboBox;
+class QPushButton;
+class QCheckBox;
+class QHBox;
+
+// the widget which displays all buttons, values, etc.
+class JoyWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ JoyWidget(QWidget *parent = 0, const char *name = 0);
+
+ ~JoyWidget();
+
+ // initialize list of possible devices and open the first available
+ void init();
+
+ public slots:
+ // reset calibration values to their value when this KCM was started
+ void resetCalibration();
+
+ private slots:
+ void checkDevice();
+ void deviceChanged(const QString &dev);
+ void traceChanged(bool);
+ void calibrateDevice();
+
+ private:
+ void showDeviceProps(JoyDevice *joy); // fill widgets with given device parameters
+ void restoreCurrDev(); // restores the content of the combobox to reflect the current open device
+
+ private:
+ QHBox *messageBox;
+ QLabel *message; // in case of no device, show here a message rather than in a dialog
+ QComboBox *device;
+ PosWidget *xyPos;
+ QTable *buttonTbl;
+ QTable *axesTbl;
+ QCheckBox *trace;
+ QPushButton *calibrate;
+
+ QTimer *idle;
+
+ JoyDevice *joydev;
+};
+
+#endif
diff --git a/kcontrol/joystick/poswidget.cpp b/kcontrol/joystick/poswidget.cpp
new file mode 100644
index 000000000..54e619d7a
--- /dev/null
+++ b/kcontrol/joystick/poswidget.cpp
@@ -0,0 +1,138 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "poswidget.h"
+
+#include <qpainter.h>
+
+#define XY_WIDTH 220
+#define MARK_WIDTH 10
+
+//-----------------------------------------------------------------
+
+PosWidget::PosWidget(QWidget *parent, const char *name)
+ : QWidget(parent, name, WRepaintNoErase), x(0), y(0), trace(false)
+{
+ setMinimumSize(XY_WIDTH, XY_WIDTH);
+ setMaximumSize(XY_WIDTH, XY_WIDTH);
+ setPaletteBackgroundColor(Qt::white);
+}
+
+//-----------------------------------------------------------------
+
+void PosWidget::paintEvent(QPaintEvent *)
+{
+ QPainter paint(this);
+
+ paint.drawRect(0, 0, width(), height());
+ paint.setPen(Qt::gray);
+
+ // draw a center grid
+ paint.drawLine(XY_WIDTH/2, 1,
+ XY_WIDTH/2, XY_WIDTH - 2);
+
+ paint.drawLine(1, XY_WIDTH/2,
+ XY_WIDTH - 2, XY_WIDTH/2);
+
+ // draw the current position marker
+ paint.setPen(Qt::blue);
+
+ paint.drawLine(x - MARK_WIDTH/2, y - MARK_WIDTH/2,
+ x + MARK_WIDTH/2, y + MARK_WIDTH/2);
+
+ paint.drawLine(x - MARK_WIDTH/2, y + MARK_WIDTH/2,
+ x + MARK_WIDTH/2, y - MARK_WIDTH/2);
+}
+
+//-----------------------------------------------------------------
+
+void PosWidget::changeX(int newX)
+{
+ // transform coordinates from joystick to widget coordinates
+ newX = int((newX/65535.0)*XY_WIDTH + XY_WIDTH/2);
+
+ if ( x == newX ) return; // avoid unnecessary redraw
+
+ eraseOld();
+
+ x = newX;
+}
+
+//-----------------------------------------------------------------
+
+void PosWidget::changeY(int newY)
+{
+ // transform coordinates from joystick to widget coordinates
+ newY = int((newY/65535.0)*XY_WIDTH + XY_WIDTH/2);
+
+ if ( y == newY ) return; // avoid unnecessary redraw
+
+ eraseOld();
+
+ y = newY;
+}
+
+//-----------------------------------------------------------------
+
+void PosWidget::showTrace(bool t)
+{
+ trace = t;
+
+ if ( !trace )
+ {
+ erase();
+ update();
+ }
+}
+
+//-----------------------------------------------------------------
+
+void PosWidget::eraseOld()
+{
+ QPainter paint(this);
+
+ //paint.eraseRect(x - MARK_WIDTH/2, y - MARK_WIDTH/2, MARK_WIDTH + 1, MARK_WIDTH + 1);
+
+ // erase previous cross (don't use eraseRect() so that trace flags will be not destroyed so much)
+ paint.setPen(Qt::white);
+
+ paint.drawLine(x - MARK_WIDTH/2, y - MARK_WIDTH/2,
+ x + MARK_WIDTH/2, y + MARK_WIDTH/2);
+
+ paint.drawLine(x - MARK_WIDTH/2, y + MARK_WIDTH/2,
+ x + MARK_WIDTH/2, y - MARK_WIDTH/2);
+
+ if ( trace ) // show previous position with a smaller black cross
+ {
+ paint.setPen(Qt::black);
+
+ paint.drawLine(x - 2, y - 2,
+ x + 2, y + 2);
+
+ paint.drawLine(x - 2, y + 2,
+ x + 2, y - 2);
+ }
+
+ update();
+}
+
+//-----------------------------------------------------------------
+
+#include "poswidget.moc"
diff --git a/kcontrol/joystick/poswidget.h b/kcontrol/joystick/poswidget.h
new file mode 100644
index 000000000..9151da57f
--- /dev/null
+++ b/kcontrol/joystick/poswidget.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Martin Koller *
+ * m.koller@surfeu.at *
+ * This file is part of the KDE Control Center Module for Joysticks *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _POSWIDGET_H_
+#define _POSWIDGET_H_
+
+#include <qwidget.h>
+
+/**
+ Widget to display the joystick-selected (x,y) position
+*/
+class PosWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ PosWidget(QWidget *parent = 0, const char *name = 0);
+
+ void changeX(int x);
+ void changeY(int y);
+
+ // define if a trace of the moving joystick shall be displayed
+ // setting it to false will erase all previous marks from the widget
+ // NOTE: the traced positions are not stored and will be erased if the widget is covered/redisplayed
+ void showTrace(bool t);
+
+ protected:
+ virtual void paintEvent(QPaintEvent *);
+
+ private:
+ void eraseOld();
+
+ private:
+ int x, y;
+ bool trace;
+};
+
+#endif