globals--, fmt string fix, foreeach++, better names++, close fds, tray icon activates/closes

This commit is contained in:
Mathias Panzenböck
2014-02-16 04:37:11 +01:00
parent f2a566cc06
commit cfa17f8947
24 changed files with 208 additions and 206 deletions

View File

@ -1,3 +1,4 @@
#include <QX11Info>
#include "axis.h" #include "axis.h"
#include "event.h" #include "event.h"
#include "time.h" #include "time.h"
@ -423,5 +424,5 @@ void Axis::move( bool press ) {
} }
} }
//actually create the event //actually create the event
sendevent(display, e); sendevent(QX11Info::display(), e);
} }

View File

@ -2,7 +2,7 @@
AxisWidget::AxisWidget( Axis* a, QWidget* parent ) AxisWidget::AxisWidget( Axis* a, QWidget* parent )
: FlashButton( "",parent) { : FlashButton(QString::null, QString::null, parent) {
axis = a; axis = a;
ae = NULL; ae = NULL;
update(); update();

View File

@ -1,3 +1,4 @@
#include <QX11Info>
#include "button.h" #include "button.h"
#include "event.h" #include "event.h"
@ -125,7 +126,7 @@ bool Button::isDefault() {
QString Button::status() { QString Button::status() {
if (useMouse) { if (useMouse) {
return QString("%1 : Mouse %2").arg(getName(), keycode); return QString("%1 : Mouse %2").arg(getName()).arg(keycode);
} }
else { else {
return QString("%1 : %2").arg(getName(), ktos(keycode)); return QString("%1 : %2").arg(getName(), ktos(keycode));
@ -161,7 +162,7 @@ void Button::click( bool press ) {
click.value1 = keycode; click.value1 = keycode;
click.value2 = 0; click.value2 = 0;
//and send it. //and send it.
sendevent( display, click ); sendevent( QX11Info::display(), click );
} }
void Button::timerCalled() { void Button::timerCalled() {

View File

@ -2,7 +2,7 @@
ButtonWidget::ButtonWidget( Button* b, QWidget* parent ) ButtonWidget::ButtonWidget( Button* b, QWidget* parent )
: FlashButton( "", parent) { : FlashButton(QString::null, QString::null, parent) {
button = b; button = b;
update(); update();
on = false; on = false;

View File

@ -18,8 +18,6 @@ inline void debug_mesg(const char *fmt, ...) {
va_end(ap); va_end(ap);
} }
#else #else
inline void debug_mesg(...) { inline void debug_mesg(...) {}
return;
}
#endif #endif
#endif #endif

View File

@ -4,7 +4,7 @@
Display *display = 0; Display *display = 0;
//actually creates an XWindows event :) //actually creates an XWindows event :)
void sendevent( Display* display, xevent e ) { void sendevent(Display* display, const xevent &e ) {
if (e.value1 == 0 && e.value2 == 0) return; if (e.value1 == 0 && e.value2 == 0) return;
if (e.type == WARP) { if (e.type == WARP) {
XTestFakeRelativeMotionEvent(display, e.value1, e.value2, 0); XTestFakeRelativeMotionEvent(display, e.value1, e.value2, 0);

View File

@ -16,8 +16,6 @@ struct xevent {
int value2; //y int value2; //y
}; };
extern Display* display; void sendevent( Display* display, const xevent& e );
void sendevent( Display* display, xevent e );
#endif #endif

View File

@ -4,7 +4,7 @@
//Modified here (and in .h) to not have default arguments for 2 and 3. //Modified here (and in .h) to not have default arguments for 2 and 3.
//This caused an error with a development version of g++ on a Mandrake system //This caused an error with a development version of g++ on a Mandrake system
//in Sweden. //in Sweden.
FlashButton::FlashButton( QString text, QWidget* parent, QString name ) FlashButton::FlashButton( QString text, QString name, QWidget* parent )
:QPushButton( text, parent ) :QPushButton( text, parent )
{ {
this->setObjectName(name); this->setObjectName(name);
@ -47,41 +47,38 @@ FlashRadioArray::FlashRadioArray( const QStringList &names, bool horizontal, QWi
:QWidget( parent ) :QWidget( parent )
{ {
if (horizontal) { if (horizontal) {
LMain = new QHBoxLayout( this); mainLayout = new QHBoxLayout( this);
LMain->setMargin(5); mainLayout->setMargin(5);
LMain->setSpacing(5); mainLayout->setSpacing(5);
} else { } else {
LMain = new QVBoxLayout( this); mainLayout = new QVBoxLayout( this);
LMain->setMargin(5); mainLayout->setMargin(5);
LMain->setSpacing(5); mainLayout->setSpacing(5);
} }
// TODO: fix memleak
int count = names.size();
int i = 0;
Buttons = new FlashButton*[count];
foreach (const QString &name, names) { foreach (const QString &name, names) {
Buttons[i] = new FlashButton( name, this, "" ); FlashButton *button = new FlashButton( name, QString::null, this );
buttons.append(button);
//when any of the buttons is clicked, it calls the same function on this. //when any of the buttons is clicked, it calls the same function on this.
connect( Buttons[i], SIGNAL( clicked() ), this, SLOT( clicked() )); connect( button, SIGNAL( clicked() ), this, SLOT( clicked() ));
LMain->addWidget(Buttons[i]); mainLayout->addWidget(button);
++i;
} }
Count = count; state = 0;
State = 0; if (!buttons.isEmpty()) {
if (count > 0) { buttons[0]->setDown( true );
Buttons[0]->setDown( true );
} }
} }
int FlashRadioArray::getState() int FlashRadioArray::getState()
{ {
return State; return state;
} }
void FlashRadioArray::flash( int index ) void FlashRadioArray::flash( int index )
{ {
Buttons[index]->flash(); if (index < buttons.size()) {
buttons[index]->flash();
}
} }
void FlashRadioArray::clicked() void FlashRadioArray::clicked()
@ -89,15 +86,16 @@ void FlashRadioArray::clicked()
//go through each button. If it wasn't the button that was just clicked, //go through each button. If it wasn't the button that was just clicked,
//then make sure that it is up. If it WAS the button that was clicked, //then make sure that it is up. If it WAS the button that was clicked,
//remember that index as the new state. //remember that index as the new state.
for (int i = 0; i < Count; i++) int i = 0;
{ foreach (FlashButton *button, buttons) {
if ( Buttons[i] != sender() ) if ( button != sender() ) {
Buttons[i]->setDown( false ); button->setDown( false );
else
{
State = i;
Buttons[i]->setDown( true );
} }
else {
state = i;
button->setDown( true );
}
++ i;
} }
emit changed( State ); emit changed( state );
} }

View File

@ -30,7 +30,7 @@ class FlashButton : public QPushButton
{ {
Q_OBJECT Q_OBJECT
public: public:
FlashButton( QString text, QWidget* parent, QString name = "" ); FlashButton(QString text, QString name = "" , QWidget* parent = 0);
public slots: public slots:
//make the button turn blue if it was gray, or visa versa. //make the button turn blue if it was gray, or visa versa.
void flash(); void flash();
@ -51,7 +51,7 @@ class FlashRadioArray : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
FlashRadioArray( const QStringList &names, bool horizontal, QWidget* parent); FlashRadioArray( const QStringList &names, bool horizontal, QWidget* parent);
//returns an integer returning the currently selected button. //returns an integer returning the currently selected button.
//First button is 0. //First button is 0.
int getState(); int getState();
@ -64,15 +64,13 @@ class FlashRadioArray : public QWidget
signals: signals:
//happens when the state changes. The int is the new state. //happens when the state changes. The int is the new state.
void changed( int ); void changed( int );
private: private:
//how many buttons
int Count;
//which is currently down //which is currently down
int State; int state;
//the array of buttons //the array of buttons
FlashButton** Buttons; QList<FlashButton*> buttons;
//the main layout. //the main layout.
QBoxLayout* LMain; QBoxLayout* mainLayout;
}; };
#endif #endif

View File

@ -1,3 +1,4 @@
#include <QX11Info>
#include "getkey.h" #include "getkey.h"
GetKey::GetKey( QString button, bool m ) GetKey::GetKey( QString button, bool m )
@ -33,7 +34,7 @@ bool GetKey::x11Event( XEvent* e )
//On a key press, return the key and quit //On a key press, return the key and quit
//Ctrl+X == [No Key] //Ctrl+X == [No Key]
if (e->type == KeyRelease) { if (e->type == KeyRelease) {
if (XKeycodeToKeysym(display,e->xkey.keycode,0) == XK_x ) { if (XKeycodeToKeysym(QX11Info::display(),e->xkey.keycode,0) == XK_x ) {
if (e->xkey.state & ControlMask) done( 0 ); if (e->xkey.state & ControlMask) done( 0 );
else done( e->xkey.keycode ); else done( e->xkey.keycode );
} }

View File

@ -10,8 +10,6 @@
//The KeySym for "x" //The KeySym for "x"
#define XK_x 0x078 #define XK_x 0x078
extern Display *display;
//a keycode dialog box //a keycode dialog box
class GetKey : public QDialog { class GetKey : public QDialog {
Q_OBJECT Q_OBJECT

View File

@ -1,21 +1,24 @@
#include "unistd.h" #include <unistd.h>
#include "joypad.h"
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include<stdint.h> #include <stdint.h>
#include <poll.h> #include <poll.h>
#include <QApplication> #include <QApplication>
JoyPad::JoyPad( int i, int dev, QObject *parent ) : QObject(parent) { #include "joypad.h"
JoyPad::JoyPad( int i, int dev, QObject *parent )
: QObject(parent), joydev(-1), axisCount(0), buttonCount(0), jpw(0), readNotifier(0), errorNotifier(0) {
debug_mesg("Constructing the joypad device with index %d and fd %d\n", i, dev); debug_mesg("Constructing the joypad device with index %d and fd %d\n", i, dev);
//remember the index, //remember the index,
index = i; index = i;
//load data from the joystick device, if available. //load data from the joystick device, if available.
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); open(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[256]; char id[256];
memset(id, 0, sizeof(id)); memset(id, 0, sizeof(id));
@ -28,70 +31,96 @@ JoyPad::JoyPad( int i, int dev, QObject *parent ) : QObject(parent) {
} 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");
} }
//there is no JoyPadWidget yet.
jpw = NULL;
debug_mesg("Done constructing the joypad device %d\n", i); debug_mesg("Done constructing the joypad device %d\n", i);
} }
void JoyPad::resetToDev(int dev ) { JoyPad::~JoyPad() {
close();
}
void JoyPad::close() {
if (readNotifier) {
disconnect(readNotifier, 0, 0, 0);
readNotifier->blockSignals(true);
readNotifier->setEnabled(false);
delete readNotifier;
readNotifier = 0;
}
if (errorNotifier) {
disconnect(errorNotifier, 0, 0, 0);
errorNotifier->blockSignals(true);
errorNotifier->setEnabled(false);
delete errorNotifier;
errorNotifier = 0;
}
if (joydev >= 0) {
if (::close(joydev) != 0) {
debug_mesg("close(js%d %d): %s\n", index, joydev, strerror(errno));
}
joydev = -1;
}
}
void JoyPad::open(int dev) {
debug_mesg("resetting to dev\n"); debug_mesg("resetting to dev\n");
//remember the device file descriptor //remember the device file descriptor
close();
joydev = dev; joydev = dev;
//read in the number of axes / buttons //read in the number of axes / buttons
axes = 0; axisCount = 0;
ioctl (joydev, JSIOCGAXES, &axes); ioctl (joydev, JSIOCGAXES, &axisCount);
buttons = 0; buttonCount = 0;
ioctl (joydev, JSIOCGBUTTONS, &buttons); ioctl (joydev, JSIOCGBUTTONS, &buttonCount);
//make sure that we have the axes we need. //make sure that we have the axes we need.
//if one that we need doesn't yet exist, add it in. //if one that we need doesn't yet exist, add it in.
//Note: if the current layout has a key assigned to an axis that did not //Note: if the current layout has a key assigned to an axis that did not
//have a real joystick axis mapped to it, and this function suddenly brings //have a real joystick axis mapped to it, and this function suddenly brings
//that axis into use, the key assignment will not be lost because the axis //that axis into use, the key assignment will not be lost because the axis
//will already exist and no new axis will be created. //will already exist and no new axis will be created.
for (int i = 0; i < axes; i++) { for (int i = 0; i < axisCount; i++) {
if (Axes[i] == 0) Axes.insert(i, new Axis( i, this )); if (axes[i] == 0) axes.insert(i, new Axis( i, this ));
} }
for (int i = 0; i < buttons; i++) { for (int i = 0; i < buttonCount; i++) {
if (Buttons[i] == 0) Buttons.insert(i, new Button( i, this )); if (buttons[i] == 0) buttons.insert(i, new Button( i, this ));
} }
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;
} }
setupJoyDeviceListener(dev);
debug_mesg("done resetting to dev\n");
}
void JoyPad::setupJoyDeviceListener(int dev) {
debug_mesg("Setting up joyDeviceListeners\n"); debug_mesg("Setting up joyDeviceListeners\n");
joydevFileHandle = new QSocketNotifier(dev, QSocketNotifier::Read, this); readNotifier = new QSocketNotifier(joydev, QSocketNotifier::Read, this);
connect(joydevFileHandle, SIGNAL(activated(int)), this, SLOT(handleJoyEvents(int))); connect(readNotifier, SIGNAL(activated(int)), this, SLOT(handleJoyEvents()));
joydevFileException = new QSocketNotifier(dev, QSocketNotifier::Exception, this); errorNotifier = new QSocketNotifier(joydev, QSocketNotifier::Exception, this);
connect(joydevFileException, SIGNAL(activated(int)), this, SLOT(errorRead(int))); connect(errorNotifier, SIGNAL(activated(int)), this, SLOT(handleJoyEvents()));
debug_mesg("Done setting up joyDeviceListeners\n"); debug_mesg("Done setting up joyDeviceListeners\n");
debug_mesg("done resetting to dev\n");
} }
void JoyPad::toDefault() { void JoyPad::toDefault() {
//to reset the whole, reset all the parts. //to reset the whole, reset all the parts.
foreach (Axis *axis, Axes) { foreach (Axis *axis, axes) {
axis->toDefault(); axis->toDefault();
} }
foreach (Button *button, Buttons) { foreach (Button *button, buttons) {
button->toDefault(); button->toDefault();
} }
} }
bool JoyPad::isDefault() { bool JoyPad::isDefault() {
//if any of the parts are not at default, then the whole isn't either. //if any of the parts are not at default, then the whole isn't either.
foreach (Axis *axis, Axes) { foreach (Axis *axis, axes) {
if (!axis->isDefault()) return false; if (!axis->isDefault()) return false;
} }
foreach (Button *button, Buttons) { foreach (Button *button, buttons) {
if (!button->isDefault()) return false; if (!button->isDefault()) return false;
} }
return true; return true;
@ -115,10 +144,10 @@ bool JoyPad::readConfig( QTextStream &stream ) {
error("Layout file error", QString("Expected ':', found '%1'.").arg(ch)); 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", QString("Error reading Button %1").arg(num)); error("Layout file error", QString("Error reading Button %1").arg(num));
return false; return false;
} }
@ -135,10 +164,10 @@ bool JoyPad::readConfig( QTextStream &stream ) {
error("Layout file error", QString("Expected ':', found '%1'.").arg(ch)); 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", QString("Error reading Axis %1").arg(num)); error("Layout file error", QString("Error reading Axis %1").arg(num));
return false; return false;
} }
@ -155,12 +184,12 @@ bool JoyPad::readConfig( QTextStream &stream ) {
//only actually writes something if this JoyPad is NON DEFAULT. //only actually writes something if this JoyPad is NON DEFAULT.
void JoyPad::write( QTextStream &stream ) { void JoyPad::write( QTextStream &stream ) {
if (!Axes.empty() || !Buttons.empty()) { if (!axes.empty() || !buttons.empty()) {
stream << getName() << " {\n"; stream << getName() << " {\n";
foreach (Axis *axis, Axes) { foreach (Axis *axis, axes) {
axis->write(stream); axis->write(stream);
} }
foreach (Button *button, Buttons) { foreach (Button *button, buttons) {
button->write(stream); button->write(stream);
} }
stream << "}\n\n"; stream << "}\n\n";
@ -168,15 +197,15 @@ void JoyPad::write( QTextStream &stream ) {
} }
void JoyPad::release() { void JoyPad::release() {
foreach (Axis *axis, Axes) { foreach (Axis *axis, axes) {
axis->release(); axis->release();
} }
foreach (Button *button, Buttons) { foreach (Button *button, buttons) {
button->release(); button->release();
} }
} }
void JoyPad::jsevent( js_event msg ) { void JoyPad::jsevent(const js_event &msg) {
//if there is a JoyPadWidget around, ie, if the joypad is being edited //if there is a JoyPadWidget around, ie, if the joypad is being edited
if (jpw != NULL && hasFocus) { if (jpw != NULL && hasFocus) {
//tell the dialog there was an event. It will use this to flash //tell the dialog there was an event. It will use this to flash
@ -190,15 +219,18 @@ void JoyPad::jsevent( js_event msg ) {
//otherwise, lets create us a fake event! Pass on the event to whichever //otherwise, lets create us a fake event! Pass on the event to whichever
//Button or Axis was pressed and let them decide what to do with it. //Button or Axis was pressed and let them decide what to do with it.
if (msg.type & JS_EVENT_AXIS) { qulonglong type = msg.type & ~JS_EVENT_INIT;
if (type == JS_EVENT_AXIS) {
debug_mesg("DEBUG: passing on an axis event\n"); debug_mesg("DEBUG: passing on an axis event\n");
debug_mesg("DEBUG: %d %d\n", msg.number, msg.value); debug_mesg("DEBUG: %d %d\n", msg.number, msg.value);
Axes[msg.number]->jsevent(msg.value); Axis *axis = axes[msg.number];
if (axis) axis->jsevent(msg.value);
} }
else { else if (type == JS_EVENT_BUTTON) {
debug_mesg("DEBUG: passing on a button event\n"); debug_mesg("DEBUG: passing on a button event\n");
debug_mesg("DEBUG: %d %d\n", msg.number, msg.value); debug_mesg("DEBUG: %d %d\n", msg.number, msg.value);
Buttons[msg.number]->jsevent(msg.value); Button *button = buttons[msg.number];
if (button) button->jsevent(msg.value);
} }
} }
@ -208,15 +240,11 @@ JoyPadWidget* JoyPad::widget( QWidget* parent, int i) {
return jpw; return jpw;
} }
void JoyPad::handleJoyEvents(int fd) { void JoyPad::handleJoyEvents() {
Q_UNUSED(fd);
js_event msg; js_event msg;
int len; ssize_t len = read(joydev, &msg, sizeof(js_event));
len = read( joydev, &msg, sizeof(js_event));
//if there was a real event waiting, //if there was a real event waiting,
if (len == (int) sizeof(js_event)) { if (len == sizeof(js_event)) {
//pass that event on to the joypad! //pass that event on to the joypad!
jsevent(msg); jsevent(msg);
} }
@ -227,30 +255,10 @@ void JoyPad::releaseWidget() {
jpw = NULL; jpw = NULL;
} }
void JoyPad::unsetDev() { void JoyPad::errorRead() {
close(joydev); debug_mesg("There was an error reading off of the device with fd %d, disabling\n", joydev);
joydev = -1; close();
if(joydevFileHandle != NULL) { debug_mesg("Done disabling device with fd %d\n", joydev);
delete joydevFileHandle;
}
}
void JoyPad::errorRead(int fd) {
debug_mesg("There was an error reading off of the device with fd %d, disabling\n", fd);
joydevFileHandle->blockSignals(true);
joydevFileHandle->setEnabled(false);
close(joydev);
if(disconnect(joydevFileHandle , 0, 0, 0)) {
joydevFileHandle->deleteLater();
joydevFileHandle = NULL;
}
if(disconnect(joydevFileException, 0, 0, 0)) {
joydevFileException->setEnabled(false);
joydevFileException->deleteLater();
joydevFileException = NULL;
}
joydev = -1;
debug_mesg("Done disabling device with fd %d\n", fd);
} }
void JoyPad::focusChange(bool focusState) { void JoyPad::focusChange(bool focusState) {

View File

@ -28,8 +28,10 @@ class JoyPad : public QObject {
friend class JoyPadWidget; friend class JoyPadWidget;
friend class QuickSet; friend class QuickSet;
public: public:
void setupJoyDeviceListener(int dev);
JoyPad( int i, int dev, QObject* parent ); JoyPad( int i, int dev, QObject* parent );
~JoyPad();
// close file descriptor and socket notifier
void close();
//read from a stream //read from a stream
bool readConfig( QTextStream &stream ); bool readConfig( QTextStream &stream );
//write to a stream //write to a stream
@ -37,15 +39,13 @@ class JoyPad : public QObject {
//release any pushed buttons and return to a neutral state //release any pushed buttons and return to a neutral state
void release(); void release();
//handle an event from the joystick device this is associated with //handle an event from the joystick device this is associated with
void jsevent( js_event msg ); void jsevent( const js_event& msg );
//reset to default settings //reset to default settings
void toDefault(); void toDefault();
//true iff this is currently at default settings //true iff this is currently at default settings
bool isDefault(); bool isDefault();
//release the connection to the real joystick
void unsetDev();
//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 open( int dev );
//generates a name ("Joystick 1") //generates a name ("Joystick 1")
QString getName() const { return QString("Joystick %1").arg(index+1);} QString getName() const { return QString("Joystick %1").arg(index+1);}
int getIndex() const { return index; } int getIndex() const { return index; }
@ -54,8 +54,8 @@ class JoyPad : public QObject {
//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 char axisCount; //the number of axes available on this device
int buttons; //the number of buttons char buttonCount; //the number of buttons
public: public:
//request the joypad to make a JoyPadWidget. We create them this way //request the joypad to make a JoyPadWidget. We create them this way
@ -68,21 +68,21 @@ class JoyPad : public QObject {
//layouts with different numbers of axes/buttons than the current //layouts with different numbers of axes/buttons than the current
//devices. Note that with the current layout settings, the defined //devices. Note that with the current layout settings, the defined
//buttons that don't actually exist on the device may not be contiguous. //buttons that don't actually exist on the device may not be contiguous.
QHash<int, Axis*> Axes; QHash<int, Axis*> axes;
QHash<int, Button*> Buttons; QHash<int, Button*> buttons;
//the index of this device (devicenum) //the index of this device (devicenum)
int index; int index;
//the widget that edits this. Mainly I keep track of this to know if //the widget that edits this. Mainly I keep track of this to know if
//the joypad is currently being edited. //the joypad is currently being edited.
JoyPadWidget* jpw; JoyPadWidget* jpw;
QSocketNotifier *joydevFileHandle; QSocketNotifier *readNotifier;
QSocketNotifier *joydevFileException; QSocketNotifier *errorNotifier;
QString deviceId; QString deviceId;
bool hasFocus; bool hasFocus;
public slots: public slots:
void handleJoyEvents(int fd); void handleJoyEvents();
void errorRead(int fd); void errorRead();
void focusChange(bool windowHasFocus); void focusChange(bool windowHasFocus);
}; };

View File

@ -15,33 +15,32 @@ JoyPadWidget::JoyPadWidget( JoyPad* jp, int i, QWidget* parent )
int insertCounter = 0; int insertCounter = 0;
quickset = NULL; quickset = NULL;
foreach (Axis *axis, joypad->Axes) { foreach (Axis *axis, joypad->axes) {
AxisWidget *aw = new AxisWidget(axis,this); AxisWidget *aw = new AxisWidget(axis,this);
axes.append(aw); axes.append(aw);
connect( aw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool ))); connect( aw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
layoutMain->addWidget(aw, insertCounter / 2, insertCounter %2); layoutMain->addWidget(aw, insertCounter / 2, insertCounter % 2);
insertCounter++; insertCounter++;
} }
foreach (Button *button, joypad->Buttons) { foreach (Button *button, joypad->buttons) {
ButtonWidget *bw = new ButtonWidget(button,this); ButtonWidget *bw = new ButtonWidget(button,this);
buttons.append(bw); buttons.append(bw);
connect( bw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool ))); connect( bw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
layoutMain->addWidget(bw, 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;
btnClear = new QPushButton("Clear", this); btnClear = new QPushButton("Clear", this);
connect(btnClear, SIGNAL(clicked()), this, SLOT(clear())); connect(btnClear, SIGNAL(clicked()), this, SLOT(clear()));
layoutMain->addWidget(btnClear, insertCounter / 2, insertCounter %2); layoutMain->addWidget(btnClear, insertCounter / 2, insertCounter % 2);
insertCounter++; insertCounter++;
btnAll = new QPushButton("Quick Set", this); btnAll = new QPushButton("Quick Set", this);
layoutMain->addWidget(btnAll, insertCounter /2, insertCounter%2); layoutMain->addWidget(btnAll, insertCounter / 2, insertCounter % 2);
connect(btnAll, SIGNAL(clicked()), this, SLOT(setAll())); connect(btnAll, SIGNAL(clicked()), this, SLOT(setAll()));
} }
@ -86,16 +85,18 @@ void JoyPadWidget::setAll() {
quickset = NULL; quickset = NULL;
} }
void JoyPadWidget::jsevent( js_event msg ) { void JoyPadWidget::jsevent( const 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) { qulonglong type = msg.type & ~JS_EVENT_INIT;
if (type == JS_EVENT_AXIS) {
if (msg.number < axes.count()) axes[msg.number]->jsevent(msg.value); if (msg.number < axes.count()) axes[msg.number]->jsevent(msg.value);
} }
else { else if (type == JS_EVENT_BUTTON) {
if (msg.number < buttons.count()) 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) {
quickset->jsevent(msg); quickset->jsevent(msg);
}
} }

View File

@ -25,7 +25,7 @@ class JoyPadWidget : public QWidget {
JoyPadWidget( JoyPad* jp, int i, QWidget* parent); JoyPadWidget( JoyPad* jp, int i, QWidget* parent);
~JoyPadWidget(); ~JoyPadWidget();
//takes in an event and decides whether or not to flash anything //takes in an event and decides whether or not to flash anything
void jsevent( js_event msg ); void jsevent(const js_event &msg );
public slots: public slots:
//called whenever one of the subwidgets flashes... used to determine //called whenever one of the subwidgets flashes... used to determine
//when to emit the flashed() signal. //when to emit the flashed() signal.

View File

@ -1,3 +1,4 @@
#include <QX11Info>
#include "keycode.h" #include "keycode.h"
#include "getkey.h" #include "getkey.h"
@ -7,7 +8,7 @@ const QString ktos( int keycode )
if (keycode == 0) return "[NO KEY]"; if (keycode == 0) return "[NO KEY]";
QString xname = XKeysymToString(XKeycodeToKeysym(display, keycode,0)); QString xname = XKeysymToString(XKeycodeToKeysym(QX11Info::display(), keycode,0));
//this section of code converts standard X11 keynames into much nicer names //this section of code converts standard X11 keynames into much nicer names
//which are prettier, fit the dialogs better, and are more readily understandable. //which are prettier, fit the dialogs better, and are more readily understandable.

View File

@ -13,9 +13,6 @@
//Produce a string for any keycode //Produce a string for any keycode
const QString ktos( int keycode ); const QString ktos( int keycode );
//The X11 display, taken from main.cpp
extern Display* display;
//a button that requests a keycode from the user when clicked. //a button that requests a keycode from the user when clicked.
class KeyButton : public QPushButton { class KeyButton : public QPushButton {

View File

@ -17,16 +17,23 @@ LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QSt
} }
//or make a floating icon //or make a floating icon
else { else {
FloatingIcon* Icon = new FloatingIcon(QPixmap(ICON64),&trayMenuPopup,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();
} }
//no layout loaded at start. //no layout loaded at start.
setLayoutName(NL); setLayoutName(NL);
} }
LayoutManager::~LayoutManager() {
if (le) {
le->close();
le = 0;
}
}
QString LayoutManager::getFileName( QString layoutname ) { QString LayoutManager::getFileName( QString layoutname ) {
return QString("%1%2.lyt").arg(settingsDir, layoutname); return QString("%1%2.lyt").arg(settingsDir, layoutname);
} }
@ -204,7 +211,7 @@ void LayoutManager::saveAs() {
//add the new name to our lists //add the new name to our lists
fillPopup(); fillPopup();
if (le != NULL) { if (le) {
le->updateLayoutList(); le->updateLayoutList();
} }
} }
@ -227,7 +234,7 @@ void LayoutManager::remove() {
} }
fillPopup(); fillPopup();
if (le != NULL) { if (le) {
le->updateLayoutList(); le->updateLayoutList();
} }
clear(); clear();
@ -238,7 +245,8 @@ QStringList LayoutManager::getLayoutNames() const {
QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt")); QStringList result = QDir(settingsDir).entryList(QStringList("*.lyt"));
for (int i = 0; i < result.size(); ++ i) { for (int i = 0; i < result.size(); ++ i) {
result[i] = result[i].left(result[i].length() - 4); QString& name = result[i];
name.truncate(name.length() - 4);
} }
//and, of course, there's always NL. //and, of course, there's always NL.
result.prepend(NL); result.prepend(NL);
@ -250,7 +258,7 @@ void LayoutManager::setLayoutName(QString name) {
currentLayout = name; currentLayout = name;
fillPopup(); fillPopup();
if (le != NULL) { if (le) {
le->setLayout(name); le->setLayout(name);
} }
} }
@ -261,7 +269,13 @@ void LayoutManager::iconClick() {
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;
} }
if(le) { if (le) {
if (le->hasFocus()) {
le->close();
}
else {
le->raise();
}
return; return;
} }
//otherwise, make a new LayoutEdit dialog and show it. //otherwise, make a new LayoutEdit dialog and show it.
@ -328,7 +342,7 @@ void LayoutManager::updateJoyDevs() {
//reset all joydevs to sentinal value (-1) //reset all joydevs to sentinal value (-1)
foreach (JoyPad *joypad, joypads) { foreach (JoyPad *joypad, joypads) {
joypad->unsetDev(); joypad->close();
} }
//clear out the list of previously available joysticks //clear out the list of previously available joysticks
@ -338,8 +352,8 @@ void LayoutManager::updateJoyDevs() {
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 = 0; int joydev = -1;
int index = 0; int index = -1;
//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)
foreach (const QString &device, devices) { foreach (const QString &device, devices) {
@ -349,7 +363,7 @@ void LayoutManager::updateJoyDevs() {
joydev = open( qPrintable(devpath), 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(device); devicename.indexIn(device);
index = devicename.cap(1).toInt(); index = devicename.cap(1).toInt();
JoyPad* joypad = joypads[index]; JoyPad* joypad = joypads[index];
@ -368,7 +382,7 @@ 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->resetToDev(joydev); joypad->open(joydev);
} }
//make this joystick device available. //make this joystick device available.
available.insert(index,joypad); available.insert(index,joypad);
@ -385,7 +399,3 @@ void LayoutManager::updateJoyDevs() {
} }
debug_mesg("done updating joydevs\n"); debug_mesg("done updating joydevs\n");
} }
void LayoutManager::leWindowClosed() {
le=NULL;
}

View File

@ -13,6 +13,7 @@
#include <QMenu> #include <QMenu>
#include <QApplication> #include <QApplication>
#include <QDialog> #include <QDialog>
#include <QPointer>
#include <QInputDialog> #include <QInputDialog>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <poll.h> #include <poll.h>
@ -35,10 +36,10 @@ class LayoutManager : public QObject {
Q_OBJECT Q_OBJECT
public: public:
LayoutManager(bool useTrayIcon, const QString &devdir, const QString &settingsDir); LayoutManager(bool useTrayIcon, const QString &devdir, const QString &settingsDir);
~LayoutManager();
//produces a list of the names of all the available layout. //produces a list of the names of all the available layout.
QStringList getLayoutNames() const; QStringList getLayoutNames() const;
void leWindowClosed();
public slots: public slots:
//load a layout with a given name //load a layout with a given name
bool load(const QString& name); bool load(const QString& name);
@ -82,7 +83,7 @@ class LayoutManager : public QObject {
QMenu trayMenuPopup; 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; QPointer<LayoutEdit> le;
QHash<int, JoyPad*> available; QHash<int, JoyPad*> available;
QHash<int, JoyPad*> joypads; QHash<int, JoyPad*> joypads;

View File

@ -130,15 +130,10 @@ void LayoutEdit::updateJoypadWidgets() {
} }
} }
void LayoutEdit::closeEvent(QCloseEvent *event) {
lm->leWindowClosed();
event->accept();
}
void LayoutEdit::appFocusChanged(QWidget *old, QWidget *now) { void LayoutEdit::appFocusChanged(QWidget *old, QWidget *now) {
if(now!=NULL && old==NULL) { if (now != NULL && old == NULL) {
emit focusStateChanged(false); emit focusStateChanged(false);
} else if(old!=NULL && now==NULL) { } else if(old != NULL && now == NULL) {
emit focusStateChanged(true); emit focusStateChanged(true);
foreach (JoyPad *joypad, lm->available) { foreach (JoyPad *joypad, lm->available) {
debug_mesg("iterating and releasing\n"); debug_mesg("iterating and releasing\n");

View File

@ -16,7 +16,7 @@ class LayoutManager;
class LayoutEdit : public QWidget { class LayoutEdit : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
LayoutEdit( LayoutManager* l ); LayoutEdit( LayoutManager* l );
//swap to a new layout //swap to a new layout
void setLayout(QString layout); void setLayout(QString layout);
//update the list of available layouts //update the list of available layouts
@ -28,8 +28,7 @@ class LayoutEdit : public QWidget {
void appFocusChanged(QWidget *old, QWidget *now); void appFocusChanged(QWidget *old, QWidget *now);
protected: protected:
//the layout manager this represents //the layout manager this represents
LayoutManager* lm; LayoutManager* lm;
virtual void closeEvent(QCloseEvent *event);
//parts of the dialog: //parts of the dialog:
QVBoxLayout *mainLayout; QVBoxLayout *mainLayout;
QStackedWidget *padStack; QStackedWidget *padStack;

View File

@ -14,7 +14,6 @@
#include "event.h" #include "event.h"
//to produce errors! //to produce errors!
#include "error.h" #include "error.h"
#include <QX11Info>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QPointer> #include <QPointer>
#include <getopt.h> #include <getopt.h>
@ -57,8 +56,8 @@ int main( int argc, char **argv )
{ {
//create a new event loop. This will be captured by the QApplication //create a new event loop. This will be captured by the QApplication
//when it gets created //when it gets created
QApplication a( argc, argv ); QApplication app( argc, argv );
a.setQuitOnLastWindowClosed(false); app.setQuitOnLastWindowClosed(false);
//where QJoyPad saves its settings! //where QJoyPad saves its settings!
@ -231,9 +230,6 @@ int main( int argc, char **argv )
} }
} }
} }
//capture the current display for event.h
display = QX11Info::display();
//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
LayoutManager layoutManager(useTrayIcon,devdir,settingsDir); LayoutManager layoutManager(useTrayIcon,devdir,settingsDir);
@ -252,7 +248,7 @@ int main( int argc, char **argv )
// signal( SIGUSR2, catchSIGUSR2 ); // signal( SIGUSR2, catchSIGUSR2 );
//and run the program! //and run the program!
int result = a.exec(); int result = app.exec();
//when everything is done, save the current layout for next time... //when everything is done, save the current layout for next time...
layoutManager.saveDefault(); layoutManager.saveDefault();

View File

@ -19,14 +19,15 @@ QuickSet::QuickSet( JoyPad* jp, QWidget *parent)
connect( button, SIGNAL(clicked()), this, SLOT(accept())); connect( button, SIGNAL(clicked()), this, SLOT(accept()));
} }
void QuickSet::jsevent( js_event msg ) { void QuickSet::jsevent(const js_event &msg ) {
//ignore any joystick events if we're waiting for a keypress //ignore any joystick events if we're waiting for a keypress
if (setting) return; if (setting) return;
//if a button was pressed on the joystick //if a button was pressed on the joystick
if (msg.type == JS_EVENT_BUTTON) { qulonglong type = msg.type & ~JS_EVENT_INIT;
if (type == JS_EVENT_BUTTON) {
//capture that button. //capture that button.
Button* button = joypad->Buttons[msg.number]; Button* button = joypad->buttons[msg.number];
//go into setting mode and request a key/mousebutton //go into setting mode and request a key/mousebutton
setting = true; setting = true;
@ -41,16 +42,16 @@ void QuickSet::jsevent( js_event msg ) {
//otherwise, tell it to use a keycode. //otherwise, tell it to use a keycode.
button->setKey(false, code); button->setKey(false, code);
} }
else { else if (type == JS_EVENT_AXIS) {
//require a signal strength of at least 5000 to consider an axis moved. //require a signal strength of at least 5000 to consider an axis moved.
if (abs(msg.value) < 5000) return; if (abs(msg.value) < 5000) return;
//capture the axis that moved //capture the axis that moved
Axis* axis = joypad->Axes[msg.number]; Axis* axis = joypad->axes[msg.number];
//grab a keycode for that axis and that direction //grab a keycode for that axis and that direction
setting = true; setting = true;
int code = GetKey(axis->getName() + ", " + QString((msg.value > 0)?"positive":"negative"), false).exec(); int code = GetKey(QString("%1, %2").arg(axis->getName(), msg.value > 0 ? "positive" : "negative"), false).exec();
setting = false; setting = false;
//assign the key to the axis. //assign the key to the axis.

View File

@ -23,7 +23,7 @@ class QuickSet : public QDialog {
public: public:
QuickSet(JoyPad* jp, QWidget *parent = 0); 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( const js_event& msg );
private: private:
//the joypad that is being configured //the joypad that is being configured
JoyPad* joypad; JoyPad* joypad;