diff options
Diffstat (limited to 'kcontrol/joystick/joywidget.cpp')
| -rw-r--r-- | kcontrol/joystick/joywidget.cpp | 379 | 
1 files changed, 379 insertions, 0 deletions
| 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" | 
