171 lines
4.4 KiB
C++
171 lines
4.4 KiB
C++
#include <QX11Info>
|
|
#include "button.h"
|
|
#include "event.h"
|
|
|
|
Button::Button( int i, QObject *parent ) : QObject(parent) {
|
|
index = i;
|
|
isButtonPressed = false;
|
|
isDown = false;
|
|
rapidfire = false;
|
|
toDefault();
|
|
tick = 0;
|
|
}
|
|
|
|
Button::~Button() {
|
|
release();
|
|
}
|
|
|
|
bool Button::read( QTextStream &stream ) {
|
|
// at this point, toDefault() has just been called.
|
|
|
|
//read in a line of text and break it into words
|
|
QString input = stream.readLine().toLower();
|
|
QRegExp regex("[\\s,]+");
|
|
QStringList words = input.split(regex);
|
|
|
|
//used to assure correct conversion of QStrings -> ints
|
|
bool ok;
|
|
//used to receive converted ints from QStrings.
|
|
int val;
|
|
|
|
//go through every word on the line describing this button.
|
|
for ( QStringList::Iterator it = words.begin(); it != words.end(); ++it ) {
|
|
if (*it == "mouse") {
|
|
++it;
|
|
if (it == words.end()) return false;
|
|
val = (*it).toInt(&ok);
|
|
if (ok && val >= 0 && val <= MAXKEY) {
|
|
useMouse = true;
|
|
keycode = val;
|
|
}
|
|
else return false;
|
|
}
|
|
else if (*it == "key") {
|
|
++it;
|
|
if (it == words.end()) return false;
|
|
val = (*it).toInt(&ok);
|
|
if (ok && val >= 0 && val <= MAXKEY) {
|
|
useMouse = false;
|
|
keycode = val;
|
|
}
|
|
else return false;
|
|
}
|
|
else if (*it == "rapidfire") {
|
|
rapidfire = true;
|
|
}
|
|
else if (*it == "sticky") {
|
|
sticky = true;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Button::write( QTextStream &stream ) {
|
|
stream << "\t" << getName() << ": ";
|
|
if (rapidfire) stream << "rapidfire, ";
|
|
if (sticky) stream << "sticky, ";
|
|
stream << (useMouse ? "mouse " : "key ") << keycode << "\n";
|
|
}
|
|
|
|
void Button::release() {
|
|
if (isDown) {
|
|
click(false);
|
|
isDown = true;
|
|
}
|
|
}
|
|
|
|
void Button::jsevent( int value ) {
|
|
bool newval = (value == 1);
|
|
if (sticky) {
|
|
//the state of a sticky key only changes on button press, not button release.
|
|
if (value == 1) {
|
|
isButtonPressed = !isButtonPressed;
|
|
}
|
|
else return;
|
|
}
|
|
//if the received event indicates a change in state,
|
|
else if (newval != isButtonPressed) {
|
|
isButtonPressed = newval; //change state
|
|
if (isButtonPressed && rapidfire) {
|
|
tick = 0;
|
|
connect(&timer, SIGNAL(timeout()), this, SLOT(timerCalled()));
|
|
timer.start(MSEC);
|
|
}
|
|
if (!isButtonPressed && rapidfire) {
|
|
timer.stop();
|
|
disconnect(&timer, SIGNAL(timeout()), 0, 0);
|
|
if(isDown) {
|
|
click(false);
|
|
}
|
|
tick = 0;
|
|
}
|
|
}
|
|
//otherwise... we don't care. This shouldn't happen.
|
|
else return;
|
|
//if rapidfire is on, then timer() will do its job. Otherwise we must
|
|
//manually triger the key event.
|
|
if (!rapidfire) {
|
|
click(isButtonPressed);
|
|
}
|
|
}
|
|
|
|
void Button::toDefault() {
|
|
rapidfire = false;
|
|
sticky = false;
|
|
useMouse = false;
|
|
keycode = 0;
|
|
timer.stop();
|
|
}
|
|
|
|
bool Button::isDefault() {
|
|
return (rapidfire == false) &&
|
|
(sticky == false) &&
|
|
(useMouse == false) &&
|
|
(keycode == 0);
|
|
}
|
|
|
|
QString Button::status() {
|
|
if (useMouse) {
|
|
return QString("%1 : Mouse %2").arg(getName()).arg(keycode);
|
|
}
|
|
else {
|
|
return QString("%1 : %2").arg(getName(), ktos(keycode));
|
|
}
|
|
}
|
|
|
|
void Button::setKey( bool mouse, int value ) {
|
|
useMouse = mouse;
|
|
keycode = value;
|
|
}
|
|
|
|
void Button::timerTick( int tick ) {
|
|
if (isButtonPressed) {
|
|
//originally I just clicked true and then false right after, but this
|
|
//was not recognized by some programs. I need a delay in between.
|
|
if (tick % FREQ == 0) {
|
|
click(true);
|
|
}
|
|
if (tick % FREQ == FREQ / 2) {
|
|
click(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Button::click( bool press ) {
|
|
if (isDown == press) return;
|
|
isDown = press;
|
|
xevent click;
|
|
//determine which of the four possible events we're sending.
|
|
if (press) click.type = useMouse?BPRESS:KPRESS;
|
|
else click.type = useMouse?BREL:KREL;
|
|
//set up the event,
|
|
click.value1 = keycode;
|
|
click.value2 = 0;
|
|
//and send it.
|
|
sendevent( QX11Info::display(), click );
|
|
}
|
|
|
|
void Button::timerCalled() {
|
|
timerTick(++tick);
|
|
}
|