foreach++, globals--, const& params++, new--, uninit mem usage--, mem leaks-- (still a lot to go)

This commit is contained in:
Mathias Panzenböck
2014-02-16 00:37:54 +01:00
parent 683fa64f01
commit 904a843b93
17 changed files with 213 additions and 208 deletions

View File

@ -15,13 +15,11 @@ Axis::Axis( int i, QObject *parent ) : QObject(parent) {
gradient = false; gradient = false;
toDefault(); toDefault();
tick = 0; tick = 0;
timer = new QTimer(this);
} }
Axis::~Axis() { Axis::~Axis() {
release(); release();
delete timer;
} }
bool Axis::read( QTextStream &stream ) { bool Axis::read( QTextStream &stream ) {
@ -210,8 +208,8 @@ void Axis::jsevent( int value ) {
if (gradient) { if (gradient) {
duration = 0; duration = 0;
release(); release();
timer->stop(); timer.stop();
disconnect(timer, SIGNAL(timeout()), 0, 0); disconnect(&timer, SIGNAL(timeout()), 0, 0);
tick = 0; tick = 0;
} }
} }
@ -220,8 +218,8 @@ void Axis::jsevent( int value ) {
isOn = true; isOn = true;
if (gradient) { if (gradient) {
duration = (abs(state) * FREQ) / JOYMAX; duration = (abs(state) * FREQ) / JOYMAX;
connect(timer, SIGNAL(timeout()), this, SLOT(timerCalled())); connect(&timer, SIGNAL(timeout()), this, SLOT(timerCalled()));
timer->start(MSEC); timer.start(MSEC);
} }
} }
//otherwise, state doesn't change! Don't touch it. //otherwise, state doesn't change! Don't touch it.

View File

@ -41,7 +41,7 @@ class Axis : public QObject {
void toDefault(); void toDefault();
//True iff currently at defaults //True iff currently at defaults
bool isDefault(); bool isDefault();
QString getName() { return "Axis " + QString::number(index+1);}; QString getName() { return QString("Axis %1").arg(index+1);}
//true iff the given value is in the dead zone for this axis. //true iff the given value is in the dead zone for this axis.
bool inDeadZone( int val ); bool inDeadZone( int val );
//a descriptive string used as a label for the button representing this axis //a descriptive string used as a label for the button representing this axis
@ -95,7 +95,7 @@ class Axis : public QObject {
//note, the key is still clicked at the same pace no matter what, //note, the key is still clicked at the same pace no matter what,
//this just decides how long it stays down each cycle. //this just decides how long it stays down each cycle.
int duration; int duration;
QTimer *timer; QTimer timer;
public slots: public slots:
void timerCalled(); void timerCalled();
}; };

View File

@ -6,14 +6,12 @@ Button::Button( int i, QObject *parent ) : QObject(parent) {
isButtonPressed = false; isButtonPressed = false;
isDown = false; isDown = false;
rapidfire = false; rapidfire = false;
timer = new QTimer(this);
toDefault(); toDefault();
tick = 0; tick = 0;
} }
Button::~Button() { Button::~Button() {
release(); release();
//delete timer;
} }
bool Button::read( QTextStream &stream ) { bool Button::read( QTextStream &stream ) {
@ -37,7 +35,7 @@ bool Button::read( QTextStream &stream ) {
val = (*it).toInt(&ok); val = (*it).toInt(&ok);
if (ok && val >= 0 && val <= MAXKEY) { if (ok && val >= 0 && val <= MAXKEY) {
useMouse = true; useMouse = true;
mousecode = val; keycode = val;
} }
else return false; else return false;
} }
@ -65,12 +63,7 @@ void Button::write( QTextStream &stream ) {
stream << "\t" << getName() << ": "; stream << "\t" << getName() << ": ";
if (rapidfire) stream << "rapidfire, "; if (rapidfire) stream << "rapidfire, ";
if (sticky) stream << "sticky, "; if (sticky) stream << "sticky, ";
if (useMouse) { stream << (useMouse ? "mouse " : "key ") << keycode << "\n";
stream << "mouse " << mousecode << "\n";
}
else {
stream << "key " << keycode << "\n";
}
} }
void Button::release() { void Button::release() {
@ -94,12 +87,12 @@ void Button::jsevent( int value ) {
isButtonPressed = newval; //change state isButtonPressed = newval; //change state
if (isButtonPressed && rapidfire) { if (isButtonPressed && rapidfire) {
tick = 0; tick = 0;
connect(timer, SIGNAL(timeout()), this, SLOT(timerCalled())); connect(&timer, SIGNAL(timeout()), this, SLOT(timerCalled()));
timer->start(MSEC); timer.start(MSEC);
} }
if (!isButtonPressed && rapidfire) { if (!isButtonPressed && rapidfire) {
timer->stop(); timer.stop();
disconnect(timer, SIGNAL(timeout()), 0, 0); disconnect(&timer, SIGNAL(timeout()), 0, 0);
if(isDown) { if(isDown) {
click(false); click(false);
} }
@ -120,36 +113,28 @@ void Button::toDefault() {
sticky = false; sticky = false;
useMouse = false; useMouse = false;
keycode = 0; keycode = 0;
mousecode = 0; timer.stop();
timer->stop();
} }
bool Button::isDefault() { bool Button::isDefault() {
return (rapidfire == false) && return (rapidfire == false) &&
(sticky == false) && (sticky == false) &&
(useMouse == false) && (useMouse == false) &&
(keycode == 0) && (keycode == 0);
(mousecode == 0);
} }
QString Button::status() { QString Button::status() {
if (useMouse) { if (useMouse) {
return getName() + " : Mouse " + QString::number(mousecode); return QString("%1 : Mouse %2").arg(getName(), keycode);
} }
else { else {
return getName() + " : " + QString(ktos(keycode)); return QString("%1 : %2").arg(getName(), ktos(keycode));
} }
} }
void Button::setKey( bool mouse, int value ) { void Button::setKey( bool mouse, int value ) {
if (mouse) { useMouse = mouse;
mousecode = value; keycode = value;
useMouse = true;
}
else {
keycode = value;
useMouse = false;
}
} }
void Button::timerTick( int tick ) { void Button::timerTick( int tick ) {
@ -173,7 +158,7 @@ void Button::click( bool press ) {
if (press) click.type = useMouse?BPRESS:KPRESS; if (press) click.type = useMouse?BPRESS:KPRESS;
else click.type = useMouse?BREL:KREL; else click.type = useMouse?BREL:KREL;
//set up the event, //set up the event,
click.value1 = useMouse?mousecode:keycode; click.value1 = keycode;
click.value2 = 0; click.value2 = 0;
//and send it. //and send it.
sendevent( display, click ); sendevent( display, click );

View File

@ -29,7 +29,7 @@ class Button : public QObject {
//True iff is currently using default settings //True iff is currently using default settings
bool isDefault(); bool isDefault();
//returns a string representation of this button. //returns a string representation of this button.
QString getName() { return "Button " + QString::number(index+1);}; QString getName() { return QString("Button %1").arg(index+1); }
//a descriptive string used as a label for the button representing this axis //a descriptive string used as a label for the button representing this axis
QString status(); QString status();
//set the key code for this axis. Used by quickset. //set the key code for this axis. Used by quickset.
@ -50,9 +50,8 @@ class Button : public QObject {
bool rapidfire; bool rapidfire;
bool sticky; bool sticky;
bool useMouse; bool useMouse;
int keycode; int keycode;
int mousecode; //like keycode, only mousebutton ;) QTimer timer;
QTimer *timer;
public slots: public slots:
void timerCalled(); void timerCalled();
}; };

View File

@ -15,7 +15,7 @@ ButtonEdit::ButtonEdit(Button* butt)
v->setMargin(5); v->setMargin(5);
v->setSpacing(5); v->setSpacing(5);
BKKey = new KeyButton( button->getName(), button->useMouse?button->mousecode:button->keycode, this, true, button->useMouse); BKKey = new KeyButton( button->getName(), button->keycode, this, true, button->useMouse);
v->addWidget(BKKey); v->addWidget(BKKey);
QHBoxLayout* h = new QHBoxLayout(); QHBoxLayout* h = new QHBoxLayout();
@ -53,14 +53,8 @@ void ButtonEdit::accept() {
button->rapidfire = CRapid->isChecked(); button->rapidfire = CRapid->isChecked();
button->sticky = (CSticky->isChecked()); button->sticky = (CSticky->isChecked());
//if the user chose a mouse button... //if the user chose a mouse button...
if (BKKey->choseMouse()) { button->useMouse = BKKey->choseMouse();
button->useMouse = true; button->keycode = BKKey->getValue();
button->mousecode = BKKey->getValue();
}
else {
button->useMouse = false;
button->keycode = BKKey->getValue();
}
QDialog::accept(); QDialog::accept();
} }

View File

@ -1,5 +1,5 @@
#ifndef JCONST_H #ifndef QJOYPAD_CONSTANT_H
#define JCONST_H #define QJOYPAD_CONSTANT_H
//How many cycles there are per click. //How many cycles there are per click.
#define FREQ 10 #define FREQ 10

View File

@ -1,12 +1,12 @@
#ifndef JOY_ERROR_H #ifndef QJOYPAD_ERROR_H
#define JOY_ERROR_H #define QJOYPAD_ERROR_H
#include <qmessagebox.h> #include <qmessagebox.h>
#include <stdarg.h> #include <stdarg.h>
//a nice simple way of throwing up an error message if something goes wrong. //a nice simple way of throwing up an error message if something goes wrong.
inline void error(QString type, QString message ) { inline void error(const QString &type, const QString &message ) {
QMessageBox::warning(0,NAME" - " + type, QMessageBox::warning(0, QString("%1 - %2").arg(NAME, type),
message, QMessageBox::Ok, Qt::NoButton); message, QMessageBox::Ok, Qt::NoButton);
} }

View File

@ -13,13 +13,18 @@ JoyPad::JoyPad( int i, int dev ) {
//load data from the joystick device, if available. //load data from the joystick device, if available.
joydevFileHandle = NULL; joydevFileHandle = NULL;
if(dev > 0) { if(dev >= 0) {
debug_mesg("Valid file handle, setting up handlers and reading axis configs...\n"); debug_mesg("Valid file handle, setting up handlers and reading axis configs...\n");
resetToDev(dev); resetToDev(dev);
debug_mesg("done resetting and setting up device index %d\n", i); debug_mesg("done resetting and setting up device index %d\n", i);
char id[200]; char id[256];
ioctl(joydev, JSIOCGNAME(199), id); memset(id, 0, sizeof(id));
deviceId = id; if (ioctl(joydev, JSIOCGNAME(sizeof(id)), id) < 0) {
deviceId = "Unknown";
}
else {
deviceId = id;
}
} else { } else {
debug_mesg("This joypad does not have a valid file handle, not setting up event listeners\n"); debug_mesg("This joypad does not have a valid file handle, not setting up event listeners\n");
} }
@ -96,25 +101,25 @@ bool JoyPad::readConfig( QTextStream &stream ) {
toDefault(); toDefault();
QString word; QString word;
QChar dump; QChar ch = 0;
int num; int num = 0;
stream >> word; stream >> word;
while (word != NULL && word != "}") { while (!word.isNull() && word != "}") {
word = word.toLower(); word = word.toLower();
if (word == "button") { if (word == "button") {
stream >> num; stream >> num;
if (num > 0) { if (num > 0) {
stream >> dump; stream >> ch;
if (dump != ':') { if (ch != ':') {
error("Layout file error", "Expected ':', found '" + QString(dump) + "'."); error("Layout file error", QString("Expected ':', found '%1'.").arg(ch));
return false; return false;
} }
if (Buttons[num-1] == 0) { if (Buttons[num-1] == 0) {
Buttons.insert(num-1,new Button(num-1)); Buttons.insert(num-1,new Button(num-1));
} }
if (!Buttons[num-1]->read( stream )) { if (!Buttons[num-1]->read( stream )) {
error("Layout file error", "Error reading Button " + QString::number(num)); error("Layout file error", QString("Error reading Button %1").arg(num));
return false; return false;
} }
} }
@ -125,22 +130,22 @@ bool JoyPad::readConfig( QTextStream &stream ) {
else if (word == "axis") { else if (word == "axis") {
stream >> num; stream >> num;
if (num > 0) { if (num > 0) {
stream >> dump; stream >> ch;
if (dump != ':') { if (ch != ':') {
error("Layout file error", "Expected ':', found '" + QString(dump) + "'."); error("Layout file error", QString("Expected ':', found '%1'.").arg(ch));
return false; return false;
} }
if (Axes[num-1] == 0) { if (Axes[num-1] == 0) {
Axes.insert(num-1,new Axis(num-1)); Axes.insert(num-1,new Axis(num-1));
} }
if (!Axes[num-1]->read(stream)) { if (!Axes[num-1]->read(stream)) {
error("Layout file error", "Error reading Axis " + QString::number(num)); error("Layout file error", QString("Error reading Axis %1").arg(num));
return false; return false;
} }
} }
} }
else { else {
error( "Layout file error", "Error while reading layout. Unrecognized word: " + word ); error( "Layout file error", QString("Error while reading layout. Unrecognized word: %1").arg(word) );
return false; return false;
} }
stream >> word; stream >> word;

View File

@ -23,11 +23,11 @@
class JoyPadWidget; class JoyPadWidget;
//represents an actual joystick device //represents an actual joystick device
class JoyPad : public QObject{ class JoyPad : public QObject {
Q_OBJECT Q_OBJECT
friend class JoyPadWidget; friend class JoyPadWidget;
friend class QuickSet; friend class QuickSet;
public: public:
void setupJoyDeviceListener(int dev); void setupJoyDeviceListener(int dev);
JoyPad( int i, int dev ); JoyPad( int i, int dev );
//read from a stream //read from a stream
@ -47,9 +47,11 @@ class JoyPad : public QObject{
//read the dimensions on the real joystick and use them //read the dimensions on the real joystick and use them
void resetToDev( int dev ); void resetToDev( int dev );
//generates a name ("Joystick 1") //generates a name ("Joystick 1")
QString getName() { return QString("Joystick %1").arg(index+1);} QString getName() const { return QString("Joystick %1").arg(index+1);}
int getIndex() const { return index; }
private: private:
//it's just easier to have these publicly available. //it's just easier to have these publicly available.
int joydev; //the actual file descriptor to the joystick device int joydev; //the actual file descriptor to the joystick device
int axes; //the number of axes available on this device int axes; //the number of axes available on this device
@ -60,8 +62,7 @@ class JoyPad : public QObject{
//so that the joypad is always aware when it has a widget active. //so that the joypad is always aware when it has a widget active.
JoyPadWidget* widget(QWidget* parent, int i); JoyPadWidget* widget(QWidget* parent, int i);
//called when the joypad is no longer being edited. //called when the joypad is no longer being edited.
void releaseWidget(); void releaseWidget();
QString getId();
protected: protected:
//lookup axes and buttons. These are dictionaries to support //lookup axes and buttons. These are dictionaries to support
//layouts with different numbers of axes/buttons than the current //layouts with different numbers of axes/buttons than the current

View File

@ -8,41 +8,41 @@ JoyPadWidget::JoyPadWidget( JoyPad* jp, int i, QWidget* parent )
/* This was in below, no idea what it does :( ... /* This was in below, no idea what it does :( ...
* (joypad->axes+1)/2 +(joypad->buttons+1)/2 + 2 * (joypad->axes+1)/2 +(joypad->buttons+1)/2 + 2
*/ */
LMain = new QGridLayout(this); layoutMain = new QGridLayout(this);
LMain->setSpacing(5); layoutMain->setSpacing(5);
LMain->setMargin(5); layoutMain->setMargin(5);
flashcount = 0; flashcount = 0;
int insertCounter = 0; int insertCounter = 0;
quickset = NULL; quickset = NULL;
Axes = new AxisWidget*[joypad->axes]; foreach (Axis *axis, joypad->Axes) {
for (int i = 0; i < joypad->axes; i++) { AxisWidget *aw = new AxisWidget(axis,this);
Axes[i] = new AxisWidget(joypad->Axes[i],this); axes.append(aw);
connect( Axes[i], SIGNAL( flashed( bool ) ), this, SLOT( flash( bool ))); connect( aw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
LMain->addWidget(Axes[i], insertCounter / 2, insertCounter %2); layoutMain->addWidget(aw, insertCounter / 2, insertCounter %2);
insertCounter++; insertCounter++;
} }
Buttons = new ButtonWidget*[joypad->buttons]; foreach (Button *button, joypad->Buttons) {
for (int i = 0; i < joypad->buttons; i++) { ButtonWidget *bw = new ButtonWidget(button,this);
Buttons[i] = new ButtonWidget(joypad->Buttons[i],this); buttons.append(bw);
connect( Buttons[i], SIGNAL( flashed( bool ) ), this, SLOT( flash( bool ))); connect( bw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
LMain->addWidget(Buttons[i], insertCounter/2, insertCounter%2); layoutMain->addWidget(bw, insertCounter/2, insertCounter%2);
insertCounter++; insertCounter++;
} }
if(insertCounter % 2 == 1) { if (insertCounter % 2 == 1) {
insertCounter++; insertCounter ++;
} }
insertCounter+=2; insertCounter += 2;
BClear = new QPushButton("Clear", this); btnClear = new QPushButton("Clear", this);
connect(BClear, SIGNAL(clicked()), this, SLOT(clear())); connect(btnClear, SIGNAL(clicked()), this, SLOT(clear()));
LMain->addWidget(BClear, insertCounter / 2, insertCounter %2); layoutMain->addWidget(btnClear, insertCounter / 2, insertCounter %2);
insertCounter++; insertCounter++;
BAll = new QPushButton("Quick Set", this); btnAll = new QPushButton("Quick Set", this);
LMain->addWidget(BAll, insertCounter /2, insertCounter%2); layoutMain->addWidget(btnAll, insertCounter /2, insertCounter%2);
connect(BAll, SIGNAL(clicked()), this, SLOT(setAll())); connect(btnAll, SIGNAL(clicked()), this, SLOT(setAll()));
} }
JoyPadWidget::~JoyPadWidget() { JoyPadWidget::~JoyPadWidget() {
@ -63,11 +63,11 @@ void JoyPadWidget::flash( bool on ) {
} }
void JoyPadWidget::update() { void JoyPadWidget::update() {
for (int i = 0; i < joypad->axes; i++) { foreach (AxisWidget *axis, axes) {
Axes[i]->update(); axis->update();
} }
for (int i = 0; i < joypad->buttons; i++) { foreach (ButtonWidget *button, buttons) {
Buttons[i]->update(); button->update();
} }
} }
@ -79,7 +79,7 @@ void JoyPadWidget::clear() {
void JoyPadWidget::setAll() { void JoyPadWidget::setAll() {
//quickset is NULL if there is no quickset dialog, and a pointer to the //quickset is NULL if there is no quickset dialog, and a pointer to the
//dialog otherwise. This is so we can forward jsevents properly. //dialog otherwise. This is so we can forward jsevents properly.
quickset = new QuickSet(joypad); quickset = new QuickSet(joypad, this);
quickset->exec(); quickset->exec();
update(); update();
delete quickset; delete quickset;
@ -90,10 +90,10 @@ void JoyPadWidget::jsevent( js_event msg ) {
//notify the component this event applies to. this cannot generate anything //notify the component this event applies to. this cannot generate anything
//other than a flash :) //other than a flash :)
if (msg.type == JS_EVENT_AXIS) { if (msg.type == JS_EVENT_AXIS) {
Axes[msg.number]->jsevent(msg.value); if (msg.number < axes.count()) axes[msg.number]->jsevent(msg.value);
} }
else { else {
Buttons[msg.number]->jsevent(msg.value); if (msg.number < buttons.count()) buttons[msg.number]->jsevent(msg.value);
} }
//if we're doing quickset, it needs to know when we do something. //if we're doing quickset, it needs to know when we do something.
if (quickset != NULL) if (quickset != NULL)

View File

@ -4,6 +4,7 @@
//parts for the widget //parts for the widget
//Added by qt3to4: //Added by qt3to4:
#include <QList>
#include <linux/joystick.h> #include <linux/joystick.h>
#include "axisw.h" #include "axisw.h"
//this all relates to a JoyPad //this all relates to a JoyPad
@ -40,7 +41,7 @@ class JoyPadWidget : public QWidget {
//(either on or off) The int is the index of this widget so that this //(either on or off) The int is the index of this widget so that this
//signal can be directly connected to FlashRadioArray's flash(int) //signal can be directly connected to FlashRadioArray's flash(int)
void flashed(int); void flashed(int);
protected: private:
//the joypad this is linked to //the joypad this is linked to
JoyPad* joypad; JoyPad* joypad;
//the index of this widget IN THE WIDGET STACK! This is unique from //the index of this widget IN THE WIDGET STACK! This is unique from
@ -53,10 +54,10 @@ class JoyPadWidget : public QWidget {
int flashcount; int flashcount;
//the parts of the dialog //the parts of the dialog
QGridLayout *LMain; QGridLayout *layoutMain;
AxisWidget **Axes; QList<AxisWidget*> axes;
ButtonWidget **Buttons; QList<ButtonWidget*> buttons;
QPushButton *BClear, *BAll; QPushButton *btnClear, *btnAll;
//the quickset window, when we create it //the quickset window, when we create it
QuickSet* quickset; QuickSet* quickset;

View File

@ -2,26 +2,22 @@
#include <errno.h> #include <errno.h>
//initialize things and set up an icon :) //initialize things and set up an icon :)
LayoutManager::LayoutManager( bool useTrayIcon ) { LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QString &settingsDir ) : devdir(devdir), settingsDir(settingsDir), le(0) {
//no LayoutEdit yet.
le = NULL;
//prepare the popup first. //prepare the popup first.
Popup = new QMenu();
fillPopup(); fillPopup();
connect(Popup,SIGNAL(triggered(QAction*)),this, SLOT(trayMenu(QAction*))); connect(&trayMenuPopup,SIGNAL(triggered(QAction*)),this, SLOT(trayMenu(QAction*)));
//make a tray icon //make a tray icon
if (useTrayIcon) { if (useTrayIcon) {
QSystemTrayIcon *Tray = new QSystemTrayIcon(this); QSystemTrayIcon *tray = new QSystemTrayIcon(this);
Tray->setContextMenu(Popup); tray->setContextMenu(&trayMenuPopup);
Tray->setIcon(QIcon(ICON24)); tray->setIcon(QIcon(ICON24));
Tray->show(); tray->show();
connect(Tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClick(QSystemTrayIcon::ActivationReason))); connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClick(QSystemTrayIcon::ActivationReason)));
} }
//or make a floating icon //or make a floating icon
else { else {
FloatingIcon* Icon = new FloatingIcon(QPixmap(ICON64),Popup,0,"tray"); FloatingIcon* Icon = new FloatingIcon(QPixmap(ICON64),&trayMenuPopup,0,"tray");
connect(Icon, SIGNAL( clicked()), this, SLOT( iconClick())); connect(Icon, SIGNAL( clicked()), this, SLOT( iconClick()));
connect(Icon, SIGNAL( closed()), qApp, SLOT( quit())); connect(Icon, SIGNAL( closed()), qApp, SLOT( quit()));
Icon->show(); Icon->show();
@ -32,7 +28,7 @@ LayoutManager::LayoutManager( bool useTrayIcon ) {
} }
QString LayoutManager::getFileName( QString layoutname ) { QString LayoutManager::getFileName( QString layoutname ) {
return settingsDir + layoutname + ".lyt"; return QString("%1%2.lyt").arg(settingsDir, layoutname);
} }
bool LayoutManager::load(const QString& name) { bool LayoutManager::load(const QString& name) {
@ -65,42 +61,65 @@ bool LayoutManager::load(const QString& name) {
//start reading joypads! //start reading joypads!
QTextStream stream( &file ); QTextStream stream( &file );
QString input = stream.readLine().toLower(); bool okay = false;
QRegExp quoted("\"(.*)\""); int num = 0;
bool okay; QChar ch = 0;
int num; QString word;
while (!stream.atEnd()) {
stream >> word;
if (word.isNull())
break;
while (input != QString::null) {
QStringList words = input.split(" ");
//if this line is specifying a joystick //if this line is specifying a joystick
if (words[0] == "joystick") { if (word.compare(QLatin1String("joystick"), Qt::CaseInsensitive) == 0) {
num = words[1].toInt(&okay); stream >> word;
num = word.toInt(&okay);
//make sure the number of the joystick is valid //make sure the number of the joystick is valid
if (!okay || okay < 1) { if (!okay || num < 1) {
error( "Load error", "Error reading joystick definition. Expected: Joysyick 1 {"); error( "Load error", QString("Error reading joystick definition. Unexpected token \"%1\". Expected a positive number.").arg(word));
if (name != CurrentLayout) reload(); if (name != currentLayout) reload();
else clear(); else clear();
return false; return false;
} }
stream.skipWhiteSpace();
stream >> ch;
if (ch != QChar('{')) {
error( "Load error", QString("Error reading joystick definition. Unexpected character \"%1\". Expected '{'.").arg(ch));
if (name != currentLayout) reload();
else clear();
return false;
}
int index = num - 1;
//if there was no joypad defined for this index before, make it now! //if there was no joypad defined for this index before, make it now!
if (joypads[num-1] == 0) { if (joypads[index] == 0) {
joypads.insert(num-1, new JoyPad(num-1, 0)); joypads.insert(index, new JoyPad(index, -1));
} }
//try to read the joypad, report error on fail. //try to read the joypad, report error on fail.
if (!joypads[num-1]->readConfig(stream)) { if (!joypads[index]->readConfig(stream)) {
error( "Load error", "Error reading definition for joystick " + QString::number(num-1)); error( "Load error", QString("Error reading definition for joystick %1.").arg(index));
//if this was attempting to change to a new layout and it failed, //if this was attempting to change to a new layout and it failed,
//revert back to the old layout. //revert back to the old layout.
if (name != CurrentLayout) reload(); if (name != currentLayout) reload();
//to keep from going into an infinite loop, if there is no good //to keep from going into an infinite loop, if there is no good
//layout to fall back on, go to NL. //layout to fall back on, go to NL.
else clear(); else clear();
return false; return false;
} }
} }
//read a new line. else if (word == QLatin1String("#")) {
input = stream.readLine().toLower(); // ignore comment
stream.readLine();
}
else {
error("Load error", QString("Error reading joystick definition. Unexpected token \"%1\". Expected \"Joystick\".").arg(word));
if (name != currentLayout) reload();
else clear();
return false;
}
} }
//if loading succeeded, this is our new layout. //if loading succeeded, this is our new layout.
setLayoutName(name); setLayoutName(name);
return true; return true;
@ -115,7 +134,7 @@ bool LayoutManager::load() {
name = stream.readLine(); name = stream.readLine();
file.close(); file.close();
//if there was no name, don't load. //if there was no name, don't load.
if (name == "") { if (name.isEmpty()) {
return false; return false;
} }
//if there was a name, try to load it! Note, this will still return //if there was a name, try to load it! Note, this will still return
@ -127,7 +146,7 @@ bool LayoutManager::load() {
} }
bool LayoutManager::reload() { bool LayoutManager::reload() {
return load(CurrentLayout); return load(currentLayout);
} }
void LayoutManager::clear() { void LayoutManager::clear() {
@ -140,13 +159,13 @@ void LayoutManager::clear() {
} }
void LayoutManager::save() { void LayoutManager::save() {
if (CurrentLayout == NL) { if (currentLayout == NL) {
saveAs(); saveAs();
return; return;
} }
//get a filename //get a filename
QString filename = getFileName( CurrentLayout ); QString filename = getFileName( currentLayout );
QFile file(filename); QFile file(filename);
//if it's good, start writing the file //if it's good, start writing the file
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
@ -194,15 +213,15 @@ void LayoutManager::saveDefault() {
QFile file( settingsDir + "layout"); QFile file( settingsDir + "layout");
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
QTextStream stream(&file); QTextStream stream(&file);
stream << CurrentLayout; stream << currentLayout;
file.close(); file.close();
} }
} }
void LayoutManager::remove() { void LayoutManager::remove() {
if (CurrentLayout == NL) return; if (currentLayout == NL) return;
if (QMessageBox::warning( 0, NAME" - Delete layout?","Remove layout permanently from your hard drive?", "Yes", "No", 0, 0, 1 ) == 1) return; if (QMessageBox::warning( 0, NAME" - Delete layout?","Remove layout permanently from your hard drive?", "Yes", "No", 0, 0, 1 ) == 1) return;
QString filename = getFileName( CurrentLayout ); QString filename = getFileName( currentLayout );
if (!QFile(filename).remove()) { if (!QFile(filename).remove()) {
error("Remove error", "Could not remove file " + filename); error("Remove error", "Could not remove file " + filename);
} }
@ -214,12 +233,12 @@ void LayoutManager::remove() {
clear(); clear();
} }
QStringList LayoutManager::getLayoutNames() { QStringList LayoutManager::getLayoutNames() const {
//goes through the list of .lyt files and removes the file extensions ;) //goes through the list of .lyt files and removes the file extensions ;)
QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt")); QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt"));
for ( QStringList::Iterator it = result.begin(); it != result.end(); ++it ) { for (int i = 0; i < result.size(); ++ i) {
*it = (*it).left((*it).length() - 4); result[i] = result[i].left(result[i].length() - 4);
} }
//and, of course, there's always NL. //and, of course, there's always NL.
result.prepend(NL); result.prepend(NL);
@ -228,7 +247,7 @@ QStringList LayoutManager::getLayoutNames() {
} }
void LayoutManager::setLayoutName(QString name) { void LayoutManager::setLayoutName(QString name) {
CurrentLayout = name; currentLayout = name;
fillPopup(); fillPopup();
if (le != NULL) { if (le != NULL) {
@ -238,7 +257,7 @@ void LayoutManager::setLayoutName(QString name) {
void LayoutManager::iconClick() { void LayoutManager::iconClick() {
//don't show the dialog if there aren't any joystick devices plugged in //don't show the dialog if there aren't any joystick devices plugged in
if (available.count() == 0) { if (available.isEmpty()) {
error("No joystick devices available","No joystick devices are currently available to configure.\nPlease plug in a gaming device and select\n\"Update Joystick Devices\" from the popup menu."); error("No joystick devices available","No joystick devices are currently available to configure.\nPlease plug in a gaming device and select\n\"Update Joystick Devices\" from the popup menu.");
return; return;
} }
@ -247,7 +266,7 @@ void LayoutManager::iconClick() {
} }
//otherwise, make a new LayoutEdit dialog and show it. //otherwise, make a new LayoutEdit dialog and show it.
le = new LayoutEdit(this); le = new LayoutEdit(this);
le->setLayout(CurrentLayout); le->setLayout(currentLayout);
} }
void LayoutManager::trayClick(QSystemTrayIcon::ActivationReason reason) { void LayoutManager::trayClick(QSystemTrayIcon::ActivationReason reason) {
@ -259,7 +278,7 @@ void LayoutManager::trayClick(QSystemTrayIcon::ActivationReason reason) {
void LayoutManager::trayMenu(QAction *menuItemAction) { void LayoutManager::trayMenu(QAction *menuItemAction) {
//if they clicked on a Layout name, load it! //if they clicked on a Layout name, load it!
//note that the other options are handled with their own special functions //note that the other options are handled with their own special functions
if (Popup->actions().indexOf(menuItemAction) > 1 && menuItemAction->text() != "Quit" && if (trayMenuPopup.actions().indexOf(menuItemAction) > 1 && menuItemAction->text() != "Quit" &&
menuItemAction->text() != "Update lyaout list" && menuItemAction->text() != "Update lyaout list" &&
menuItemAction->text() != "Update joystick devices") { menuItemAction->text() != "Update joystick devices") {
load(menuItemAction->text()); load(menuItemAction->text());
@ -268,42 +287,40 @@ void LayoutManager::trayMenu(QAction *menuItemAction) {
void LayoutManager::fillPopup() { void LayoutManager::fillPopup() {
//start with an empty slate //start with an empty slate
Popup->clear(); trayMenuPopup.clear();
//make a list of joystick devices //make a list of joystick devices
QString devs = "Joysticks: "; QString devs = "Joysticks: ";
QHashIterator<int, JoyPad*> it( available ); foreach (JoyPad *joypad, available) {
while (it.hasNext()) devs += QString("%1 ").arg(joypad->getIndex() + 1);
{
it.next();
devs += QString::number(it.key() + 1) + " ";
} }
QAction *temp = Popup->addAction(devs);
Popup->addSeparator(/*temp*/); QAction *temp = trayMenuPopup.addAction(devs);
trayMenuPopup.addSeparator(/*temp*/);
//add in the Update options //add in the Update options
QAction *tempAdd = new QAction("Update layout list", this); QAction *tempAdd = new QAction("Update layout list", this);
connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(fillPopup())); connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(fillPopup()));
Popup->addAction(tempAdd); trayMenuPopup.addAction(tempAdd);
tempAdd = new QAction("Update joystick devices", this); tempAdd = new QAction("Update joystick devices", this);
connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(updateJoyDevs())); connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(updateJoyDevs()));
Popup->addAction(tempAdd); trayMenuPopup.addAction(tempAdd);
Popup->addSeparator(/*temp*/); trayMenuPopup.addSeparator(/*temp*/);
//then add all the layout names //then add all the layout names
QStringList names = getLayoutNames(); QStringList names = getLayoutNames();
for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) { foreach (const QString &name, names) {
temp = Popup->addAction(*it); temp = trayMenuPopup.addAction(name);
temp->setCheckable(true); temp->setCheckable(true);
//put a check by the current one ;) //put a check by the current one ;)
if (CurrentLayout == (*it)) { if (currentLayout == name) {
temp->setChecked(true); temp->setChecked(true);
} }
} }
Popup->addSeparator(); trayMenuPopup.addSeparator();
//and, at the end, quit! //and, at the end, quit!
Popup->addAction("Quit",qApp,SLOT(quit())); trayMenuPopup.addAction("Quit",qApp,SLOT(quit()));
} }
void LayoutManager::updateJoyDevs() { void LayoutManager::updateJoyDevs() {
@ -318,30 +335,31 @@ void LayoutManager::updateJoyDevs() {
available.clear(); available.clear();
//set all joydevs anew (create new JoyPad's if necesary) //set all joydevs anew (create new JoyPad's if necesary)
QDir DeviceDir(devdir); QDir deviceDir(devdir);
QStringList devices = DeviceDir.entryList(QStringList("js*"), QDir::System ); QStringList devices = deviceDir.entryList(QStringList("js*"), QDir::System);
QRegExp devicename(".*\\js(\\d+)"); QRegExp devicename(".*\\js(\\d+)");
int joydev; int joydev = 0;
int index; int index = 0;
//for every joystick device in the directory listing... //for every joystick device in the directory listing...
//(note, with devfs, only available devices are listed) //(note, with devfs, only available devices are listed)
for (QStringList::Iterator it = devices.begin(); it != devices.end(); ++it) { foreach (const QString &device, devices) {
debug_mesg("found a device file, %s\n", qPrintable(devdir + "/" + (*it))); QString devpath = QString("%1/%2").arg(devdir, device);
debug_mesg("found a device file, %s\n", qPrintable(devpath));
//try opening the device. //try opening the device.
joydev = open( qPrintable(devdir + "/" + (*it)), O_RDONLY | O_NONBLOCK); joydev = open( qPrintable(devpath), O_RDONLY | O_NONBLOCK);
//if it worked, then we have a live joystick! Make sure it's properly //if it worked, then we have a live joystick! Make sure it's properly
//setup. //setup.
if (joydev > 0) { if (joydev > 0) {
devicename.indexIn(*it); devicename.indexIn(device);
index = QString(devicename.cap(1)).toInt(); index = devicename.cap(1).toInt();
JoyPad* joypad; JoyPad* joypad = joypads[index];
//if we've never seen this device before, make a new one! //if we've never seen this device before, make a new one!
if (joypads[index] == 0) { if (joypad == 0) {
struct pollfd read_struct; struct pollfd read_struct;
read_struct.fd = joydev; read_struct.fd = joydev;
read_struct.events = POLLIN; read_struct.events = POLLIN;
char buf[10]; char buf[10];
while(poll(&read_struct, 1, 5)!=0) { while (poll(&read_struct, 1, 5) != 0) {
debug_mesg("reading junk data\n"); debug_mesg("reading junk data\n");
if (read(joydev, buf, 10) <= 0) break; if (read(joydev, buf, 10) <= 0) break;
} }
@ -350,15 +368,13 @@ void LayoutManager::updateJoyDevs() {
} }
else { else {
debug_mesg("found previously open joypad with index %d, ignoring", index); debug_mesg("found previously open joypad with index %d, ignoring", index);
joypad = joypads[index];
joypad->resetToDev(joydev); joypad->resetToDev(joydev);
} }
//make this joystick device available. //make this joystick device available.
available.insert(index,joypad); available.insert(index,joypad);
} }
else { else {
int errsv = errno; perror(qPrintable(devpath));
printf("error reading joypad dev device: %s\n", strerror(errsv));
} }
} }
//when it's all done, rebuild the popup menu so it displays the correct //when it's all done, rebuild the popup menu so it displays the correct

View File

@ -31,19 +31,15 @@
//for recognizing when the special empty layout is in use //for recognizing when the special empty layout is in use
#define NL "[NO LAYOUT]" #define NL "[NO LAYOUT]"
//where QJoyPad saves its settings!
const QString settingsDir(QDir::homePath() + "/.qjoypad3/");
extern QString devdir;
//handles loading, saving, and changing of layouts //handles loading, saving, and changing of layouts
class LayoutManager : public QObject { class LayoutManager : public QObject {
friend class LayoutEdit; friend class LayoutEdit;
Q_OBJECT Q_OBJECT
public: public:
LayoutManager( bool useTrayIcon); LayoutManager(bool useTrayIcon, const QString &devdir, const QString &settingsDir);
//produces a list of the names of all the available layout. //produces a list of the names of all the available layout.
QStringList getLayoutNames(); QStringList getLayoutNames() const;
void leWindowClosed(); void leWindowClosed();
public slots: public slots:
//load a layout with a given name //load a layout with a given name
@ -79,13 +75,16 @@ class LayoutManager : public QObject {
void setLayoutName(QString name); void setLayoutName(QString name);
//get the file name for a layout name //get the file name for a layout name
QString getFileName( QString layoutname ); QString getFileName( QString layoutname );
//the directory in wich the joystick devices are (e.g. "/dev/input")
QString devdir;
QString settingsDir;
//the layout that is currently in use //the layout that is currently in use
QString CurrentLayout; QString currentLayout;
//the popup menu from the tray/floating icon //the popup menu from the tray/floating icon
QMenu* Popup; QMenu trayMenuPopup;
//if there is a LayoutEdit open, this points to it. Otherwise, NULL. //if there is a LayoutEdit open, this points to it. Otherwise, NULL.
LayoutEdit* le; LayoutEdit* le;
}; };
#endif #endif

View File

@ -98,7 +98,7 @@ void LayoutEdit::updateLayoutList() {
CLayouts->clear(); CLayouts->clear();
QStringList layouts = lm->getLayoutNames(); QStringList layouts = lm->getLayoutNames();
CLayouts->insertItems(-1, layouts); CLayouts->insertItems(-1, layouts);
CLayouts->setCurrentIndex(layouts.indexOf(lm->CurrentLayout)); CLayouts->setCurrentIndex(layouts.indexOf(lm->currentLayout));
} }
void LayoutEdit::updateJoypadWidgets() { void LayoutEdit::updateJoypadWidgets() {

View File

@ -18,6 +18,7 @@
#include "error.h" #include "error.h"
#include <QX11Info> #include <QX11Info>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QPointer>
#include <getopt.h> #include <getopt.h>
//for making universally available variables //for making universally available variables
@ -25,15 +26,14 @@ QHash<int, JoyPad*> available; //to device.h
QHash<int, JoyPad*> joypads; //to device.h QHash<int, JoyPad*> joypads; //to device.h
//variables needed in various functions in this file //variables needed in various functions in this file
LayoutManager* lm = 0; QPointer<LayoutManager> layoutManagerPtr;
QString devdir = DEVDIR;
//signal handler for SIGIO //signal handler for SIGIO
//SIGIO means that a new layout should be loaded. It is saved in //SIGIO means that a new layout should be loaded. It is saved in
// ~/.qjoypad/layout, where the last used layout is put. // ~/.qjoypad/layout, where the last used layout is put.
void catchSIGIO( int sig ) void catchSIGIO( int sig )
{ {
lm->load(); if (layoutManagerPtr) layoutManagerPtr->load();
//remember to catch this signal again next time. //remember to catch this signal again next time.
signal( sig, catchSIGIO ); signal( sig, catchSIGIO );
} }
@ -44,7 +44,7 @@ void catchSIGIO( int sig )
//SIGUSR1 means that we should update the available joystick device list. //SIGUSR1 means that we should update the available joystick device list.
void catchSIGUSR1( int sig ) { void catchSIGUSR1( int sig ) {
//buildJoyDevices(); //buildJoyDevices();
lm->updateJoyDevs(); if (layoutManagerPtr) layoutManagerPtr->updateJoyDevs();
//remember to catch this signal again next time. //remember to catch this signal again next time.
signal( sig, catchSIGUSR1 ); signal( sig, catchSIGUSR1 );
} }
@ -67,9 +67,15 @@ int main( int argc, char **argv )
a.setQuitOnLastWindowClosed(false); a.setQuitOnLastWindowClosed(false);
//where QJoyPad saves its settings!
const QString settingsDir(QDir::homePath() + "/.qjoypad3/");
//where to look for settings. If it does not exist, it will be created //where to look for settings. If it does not exist, it will be created
QDir dir(settingsDir); QDir dir(settingsDir);
//the directory in wich the joystick devices are (e.g. "/dev/input")
QString devdir = DEVDIR;
//if there is no new directory and we can't make it, complain //if there is no new directory and we can't make it, complain
if (!dir.exists() && !dir.mkdir(settingsDir)) { if (!dir.exists() && !dir.mkdir(settingsDir)) {
printf("Couldn't create the QJoyPad save directory (%s)!", settingsDir.toStdString().c_str()); printf("Couldn't create the QJoyPad save directory (%s)!", settingsDir.toStdString().c_str());
@ -236,14 +242,15 @@ int main( int argc, char **argv )
//create a new LayoutManager with a tray icon / floating icon, depending //create a new LayoutManager with a tray icon / floating icon, depending
//on the user's request //on the user's request
lm = new LayoutManager(useTrayIcon); LayoutManager layoutManager(useTrayIcon,devdir,settingsDir);
layoutManagerPtr = &layoutManager;
//build the joystick device list for the first time, //build the joystick device list for the first time,
//buildJoyDevices(); //buildJoyDevices();
lm->updateJoyDevs(); layoutManager.updateJoyDevs();
//load the last used layout (Or the one given as a command-line argument) //load the last used layout (Or the one given as a command-line argument)
lm->load(); layoutManager.load();
//prepare the signal handlers //prepare the signal handlers
signal( SIGIO, catchSIGIO ); signal( SIGIO, catchSIGIO );
@ -254,7 +261,7 @@ int main( int argc, char **argv )
int result = a.exec(); int result = a.exec();
//when everything is done, save the current layout for next time... //when everything is done, save the current layout for next time...
lm->saveDefault(); layoutManager.saveDefault();
//remove the lock file... //remove the lock file...
pidFile.remove(); pidFile.remove();

View File

@ -2,8 +2,8 @@
#include "getkey.h" #include "getkey.h"
//build the dialog //build the dialog
QuickSet::QuickSet( JoyPad* jp) QuickSet::QuickSet( JoyPad* jp, QWidget *parent)
: QDialog() { : QDialog(parent) {
setting = false; setting = false;
joypad = jp; joypad = jp;
setWindowTitle("Set " + jp->getName()); setWindowTitle("Set " + jp->getName());

View File

@ -19,7 +19,7 @@ class JoyPad;
//a dialog to quickly set a key to a button //a dialog to quickly set a key to a button
class QuickSet : public QDialog { class QuickSet : public QDialog {
public: public:
QuickSet(JoyPad* jp); QuickSet(JoyPad* jp, QWidget *parent = 0);
//this needs to see js_events so it can capture them directly //this needs to see js_events so it can capture them directly
void jsevent( js_event msg ); void jsevent( js_event msg );
private: private: