add more spacing
[personal-kdebase.git] / workspace / kcontrol / hardware / joystick / joydevice.cpp
blobc23e18eb7d9c3707e13aaa6a1afb093cc18be7a3
1 /***************************************************************************
2 * Copyright (C) 2003 by Martin Koller *
3 * m.koller@surfeu.at *
4 * This file is part of the KDE Control Center Module for Joysticks *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 ***************************************************************************/
22 #include "joydevice.h"
24 #include <klocale.h>
25 #include <kdebug.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/select.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <sys/ioctl.h>
33 #include <sys/time.h>
34 #include <errno.h>
35 #include <math.h>
37 //--------------------------------------------------------------
39 JoyDevice::JoyDevice(const QString &devicefile)
40 : devName(devicefile), joyFd(-1), buttons(0), axes(0),
41 amin(0), amax(0), corr(0), origCorr(0)
45 //--------------------------------------------------------------
47 QString JoyDevice::errText(ErrorCode code) const
49 switch ( code )
51 case SUCCESS: return "";
53 case OPEN_FAILED:
55 return i18n("The given device %1 could not be opened: %2",
56 devName, strerror(errno));
59 case NO_JOYSTICK:
61 return i18n("The given device %1 is not a joystick.", devName);
64 case ERR_GET_VERSION:
66 return i18n("Could not get kernel driver version for joystick device %1: %2",
67 devName, strerror(errno));
70 case WRONG_VERSION:
72 int version = 0;
73 int fd = ::open(devName.toLatin1(), O_RDONLY);
74 if ( fd != -1 )
76 ::ioctl(fd, JSIOCGVERSION, &version);
77 ::close(fd);
80 KLocalizedString loc = ki18n("The current running kernel driver version (%1.%2.%3) is not the one this module was compiled for (%4.%5.%6).");
81 loc.subs(version >> 16);
82 loc.subs((version >> 8) & 0xFF);
83 loc.subs(version & 0xFF);
84 loc.subs(JS_VERSION >> 16);
85 loc.subs((JS_VERSION >> 8) & 0xFF);
86 loc.subs(JS_VERSION & 0xFF);
87 return loc.toString();
90 case ERR_GET_BUTTONS:
92 return i18n("Could not get number of buttons for joystick device %1: %2",
93 devName, strerror(errno));
96 case ERR_GET_AXES:
98 return i18n("Could not get number of axes for joystick device %1: %2",
99 devName, strerror(errno));
102 case ERR_GET_CORR:
104 return i18n("Could not get calibration values for joystick device %1: %2",
105 devName, strerror(errno));
108 case ERR_RESTORE_CORR:
110 return i18n("Could not restore calibration values for joystick device %1: %2",
111 devName, strerror(errno));
114 case ERR_INIT_CAL:
116 return i18n("Could not initialize calibration values for joystick device %1: %2",
117 devName, strerror(errno));
120 case ERR_APPLY_CAL:
122 return i18n("Could not apply calibration values for joystick device %1: %2",
123 devName, strerror(errno));
126 default: return i18n("internal error - code %1 unknown", int(code));
130 //--------------------------------------------------------------
132 JoyDevice::ErrorCode JoyDevice::open()
134 if ( joyFd != -1 ) return JoyDevice::SUCCESS; // already open
136 int fd = ::open(devName.toLatin1(), O_RDONLY);
138 if ( fd == -1 )
139 return JoyDevice::OPEN_FAILED;
141 // we could open the devicefile, now check if a joystick is attached
142 char name[128];
144 if ( ::ioctl(fd, JSIOCGNAME(sizeof(name)), &name) == -1 )
146 ::close(fd);
147 return JoyDevice::NO_JOYSTICK;
150 // check the kernel driver version
151 int version;
152 if ( ::ioctl(fd, JSIOCGVERSION, &version) == -1 )
154 ::close(fd);
155 return JoyDevice::ERR_GET_VERSION;
158 if ( version != JS_VERSION )
160 ::close(fd);
161 return JoyDevice::WRONG_VERSION;
164 char bt = 0, ax = 0;
165 if ( ::ioctl(fd, JSIOCGBUTTONS, &bt) == -1 )
167 ::close(fd);
168 return JoyDevice::ERR_GET_BUTTONS;
171 if ( ::ioctl(fd, JSIOCGAXES, &ax) == -1 )
173 ::close(fd);
174 return JoyDevice::ERR_GET_AXES;
177 struct js_corr *oldCorr = new struct js_corr[ax];
179 if ( ::ioctl(fd, JSIOCGCORR, oldCorr) == -1 )
181 ::close(fd);
182 delete [] oldCorr;
183 return JoyDevice::ERR_GET_CORR;
186 descr = name;
187 joyFd = fd;
188 axes = ax;
189 buttons = bt;
190 origCorr = oldCorr;
191 corr = new struct js_corr[axes];
193 amin = new int[axes];
194 amax = new int[axes];
196 int i;
198 for (i = 0; i < axes; i++)
199 resetMinMax(i);
201 return JoyDevice::SUCCESS;
204 //--------------------------------------------------------------
206 void JoyDevice::close()
208 if ( joyFd == -1 ) return;
210 ::close(joyFd);
212 joyFd = -1;
213 descr = "";
215 delete [] amin;
216 delete [] amax;
217 amin = 0;
218 amax = 0;
220 delete [] corr;
221 corr = 0;
222 delete [] origCorr;
223 origCorr = 0;
226 //--------------------------------------------------------------
228 int JoyDevice::axisMin(int axis) const
230 if ( (axis < 0) || (axis >= axes) ) return 0;
232 return amin[axis];
235 //--------------------------------------------------------------
237 int JoyDevice::axisMax(int axis) const
239 if ( (axis < 0) || (axis >= axes) ) return 0;
241 return amax[axis];
244 //--------------------------------------------------------------
246 JoyDevice::ErrorCode JoyDevice::initCalibration()
248 if ( joyFd == -1 ) return JoyDevice::ERR_INIT_CAL;
250 int i;
252 // Reset all current correction values
253 for (i = 0; i < axes; i++)
255 corr[i].type = JS_CORR_NONE;
256 corr[i].prec = 0;
259 if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 )
260 return JoyDevice::ERR_INIT_CAL;
262 for (i = 0; i < axes; i++)
263 corr[i].type = JS_CORR_BROKEN;
265 return JoyDevice::SUCCESS;
268 //--------------------------------------------------------------
270 JoyDevice::ErrorCode JoyDevice::applyCalibration()
272 if ( joyFd == -1 ) return JoyDevice::ERR_APPLY_CAL;
274 if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 )
275 return JoyDevice::ERR_APPLY_CAL;
277 return JoyDevice::SUCCESS;
280 //--------------------------------------------------------------
282 void JoyDevice::resetMinMax(int axis, int value)
284 amin[axis] = value;
285 amax[axis] = value;
288 //--------------------------------------------------------------
290 void JoyDevice::calcPrecision()
292 if ( !corr ) return;
294 int i;
296 for (i = 0; i < axes; i++)
298 corr[i].prec = amax[i] - amin[i];
299 kDebug() << "Precision for axis: " << i << ": " << corr[i].prec;
303 //--------------------------------------------------------------
305 JoyDevice::ErrorCode JoyDevice::restoreCorr()
307 if ( joyFd == -1 ) return JoyDevice::SUCCESS;
309 if ( ::ioctl(joyFd, JSIOCSCORR, origCorr) == -1 )
310 return JoyDevice::ERR_RESTORE_CORR;
311 else
312 return JoyDevice::SUCCESS;
315 //--------------------------------------------------------------
317 JoyDevice::~JoyDevice()
319 close();
322 //--------------------------------------------------------------
324 bool JoyDevice::getEvent(JoyDevice::EventType &type, int &number, int &value)
326 number = value = 0;
328 int ret;
330 fd_set readSet;
332 FD_ZERO(&readSet);
333 FD_SET(joyFd, &readSet);
335 struct timeval timeout;
336 timeout.tv_sec = 0;
337 timeout.tv_usec = 10000;
339 ret = ::select(joyFd + 1, &readSet, 0, 0, &timeout);
341 if ( ret == 1 ) // got an event from the joystick
343 struct js_event e;
345 if ( ::read(joyFd, &e, sizeof(struct js_event)) == sizeof(struct js_event) )
347 if ( e.type & JS_EVENT_BUTTON )
349 type = JoyDevice::BUTTON;
350 value = e.value;
351 number = e.number;
353 return true;
356 if ( e.type & JS_EVENT_AXIS )
358 type = JoyDevice::AXIS;
359 value = e.value;
360 number = e.number;
362 // store min, max values
363 if ( e.value < amin[number] ) amin[number] = e.value;
364 if ( e.value > amax[number] ) amax[number] = e.value;
366 return true;
371 return false; // no event
374 //--------------------------------------------------------------
376 void JoyDevice::calcCorrection(int axis, int *min, int *center, int *max)
378 const int MIN = 0;
379 const int MAX = 1;
381 double a, b, c, d;
383 a = center[MIN]; // inputs.cmin[1];
384 b = center[MAX]; // inputs.cmax[1];
385 c = 32767.0 / (center[MIN] - min[MAX]); // (inputs.cmin[1] - inputs.cmax[0]);
386 d = 32767.0 / (max[MIN] - center[MAX]); // (inputs.cmin[2] - inputs.cmax[1]);
388 corr[axis].coef[0] = (int)rint(a);
389 corr[axis].coef[1] = (int)rint(b);
390 corr[axis].coef[2] = (int)rint(c*16384.0);
391 corr[axis].coef[3] = (int)rint(d*16384.0);
393 kDebug() << "min min: " << min[0] << " max: " << min[1] ;
394 kDebug() << "max min: " << max[0] << " max: " << max[1] ;
395 kDebug() << "Correction values for axis: " << axis << ": "
396 << corr[axis].coef[0] << ", "
397 << corr[axis].coef[1] << ", "
398 << corr[axis].coef[2] << ", "
399 << corr[axis].coef[3] << endl;
402 //--------------------------------------------------------------