mirror of
https://github.com/workinghard/jslisten.git
synced 2025-12-14 03:12:09 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce02867664 | |||
|
|
3efe5ec332 | ||
| 1dce82f003 |
123
README.md
123
README.md
@@ -7,14 +7,13 @@
|
||||
4. [Configuration](#configuration)
|
||||
5. [Known limitations](#known-limitations)
|
||||
6. [Multiple key combinations](#multiple-key-combinations)
|
||||
7. [Version Updates](UPDATES.md)
|
||||
|
||||
## Overview
|
||||
|
||||
This program listens in the background for gamepad inputs. If a special button combination is getting pressed,
|
||||
the provided command line will be invoked. It runs a command once defined buttons were pressed. It was developed for Raspbian and PS3 wireless controller but should work everywhere with `udev` and [joystick](https://sourceforge.net/projects/linuxconsole/) support.
|
||||
This program listen in the background for gamepad inputs. If a special button combination is getting pressed,
|
||||
the provided command line will be invoked. It runs a command once defined buttons were pressed. It was developed for Raspbian and PS3 wireless controller but should work everywhere with udev and [joystick](https://sourceforge.net/projects/linuxconsole/) support.
|
||||
|
||||
### Example Use Case
|
||||
## Usage
|
||||
|
||||
I have a Raspberry Pi. The installed operation system is raspbian. The Kodi package runs pretty well as a media center. The remote control is an App on a smartphone. So no other controller is needed.
|
||||
|
||||
@@ -26,78 +25,59 @@ In my configuration Kodi runs as default. Media center is still the primary usag
|
||||
|
||||
After searching the internet, I found nothing really interesting. Kodi addon will not work because gamepad support is still missing. EmulationStation addon might work but than ... Kodi solution will be missing. So I had to go one level up to the OS. But even here I found nothing really easy to setup or working. So I decided to write this program. It runs as a daemon in the background and listening in nonblocking mode to /dev/input/js* devices. To make it hotplug capable, it's monitoring the udev signals if no device is present.
|
||||
|
||||
<b>Update 12/22/2018:</b>
|
||||
If you have many different /dev/inputs, you can pass it as an arguement at the startup:
|
||||
|
||||
```jslisten --device /dev/input/js0```
|
||||
|
||||
** jslisten will also default to listen to the first device found if the defined device is not found.
|
||||
|
||||
<b>Update 02/12/2019:</b>
|
||||
Changed the default service user to "pi" in jslisten.service
|
||||
|
||||
Use user root only if it's really required.
|
||||
|
||||
<b>Update 02/16/2019:</b>
|
||||
Added a different mode to easier trigger scripts.
|
||||
|
||||
When started with `--mode plain` (the default) the program behaves as used. This is fine if you need the button combination once in a while.
|
||||
|
||||
However if you want to activate a script a few times in a short time, lets say to adjust your audio volume or if you have a led stripe installed in your arcade and want to adjust the brightness, then
|
||||
the `--mode hold` comes in handy.
|
||||
|
||||
When started with `--mode hold` and you have at least two buttons defined to enter an action, then you hold down the first one, while tipping the second one. If you have three buttons defined you can
|
||||
hold the second two and then just tip the third. In a four button set you will have to hold the first three.
|
||||
|
||||
As soon as you release any but the last button (according to the order in the `jslisten.cfg`) you will have to press the all buttons again.
|
||||
|
||||
So the difference to the plain mode is that once you have entered the engaged/elevated state with a three button set for example, you hold down the first two and can quickly trigger the action by
|
||||
pressing the third. In plain mode you would have to press all three buttons over again to do audio or brightness adjustment.
|
||||
|
||||
Also added `--help` for the command line for a brief summary of options.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Quick Install
|
||||
|
||||
```
|
||||
cd /tmp
|
||||
git clone https://github.com/workinghard/jslisten.git
|
||||
cd jslisten
|
||||
|
||||
echo "Building jslisten binary"
|
||||
make
|
||||
|
||||
echo "Moving jslisten binary to executable path"
|
||||
sudo mkdir -p /opt/bin
|
||||
sudo cp bin/jslisten /opt/bin/jslisten
|
||||
|
||||
echo "Copying default config; you will need to modify this file for your use case."
|
||||
cp /etc/jslisten.cfg ~/.jslisten
|
||||
|
||||
echo "Adding jslisten support at boot"
|
||||
sudo cp utils/jslisten.service /etc/systemd/system
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start jslisten.service
|
||||
sudo systemctl enable jslisten
|
||||
```
|
||||
|
||||
You will need to modify your `~/.jslisten` config file based on your own requirements.
|
||||
|
||||
### Step by step
|
||||
|
||||
Following example for Raspbian. Should work for many other distributions almost the same way.
|
||||
|
||||
#### Setting up the service
|
||||
|
||||
- run `make` to create the binary
|
||||
- Place the binary in `/opt/bin`
|
||||
- If you change the folder, please update the init script
|
||||
- Copy the configuration script `cp etc/jslisten.cfg /etc/jslisten.cfg`
|
||||
- This can either live in `/etc/jslisten.cfg` or as `~/.jslisten`
|
||||
- Modify the configuration script to your needs
|
||||
- See configuration walkthrough below
|
||||
|
||||
#### Testing
|
||||
- At this point you should have a runable version of `jslisten` that is configured for your use case.
|
||||
- you can test it by running `jslisten --device /dev/input/js[*]`
|
||||
- where `[*]` is your deviceID (ie `/dev/input/js0`)
|
||||
- Once you get it running manually, you can set it to start at boot
|
||||
|
||||
#### Start at boot
|
||||
- Copy the service script `sudo cp utils/jslisten.service /etc/systemd/system`
|
||||
- make any changes to the `ExecStart` to change joystick devices (defaults to `/dev/input/js0`)
|
||||
- Update the systemd daemon `sudo systemctl daemon-reload`
|
||||
- Make it start at boot `sudo systemctl enable jslisten`
|
||||
- You can start and stop the service via
|
||||
- Start: `sudo systemctl start jslisten.service`
|
||||
- Stop: `sudo systemctl stop jslisten.service`
|
||||
- Status: `sudo systemctl status jslisten.service`
|
||||
* run "# make" to create the binary
|
||||
* Place the binary to "/opt/bin" (if you change the folder, please update your init script)
|
||||
* Copy the configuration script to /etc/jslisten.cfg
|
||||
* Modify the configuration script to your needs
|
||||
* Copy the service script "utils/jslisten.service" to "/etc/systemd/system"
|
||||
* Update the systemd daemon: "# systemctl daemon-reload"
|
||||
* Start the daemon "# systemctl start jslisten.service"
|
||||
* Make it start at boot "# systemctl enable jslisten"
|
||||
|
||||
## Configuration
|
||||
|
||||
- I assume your joystick setup is already done and you can see activation with `jstest /dev/input/js0`
|
||||
- There are many tutorials out there and you should not proceed if this doesn't work for you!
|
||||
- Think which button combination will work for your gamepad. You can configure up to 4 button combination. In my case i picked `Left Shoulder` + `Right Shoulder` + `SELECT`. I'm pretty sure I will not need to press this buttons at the same time for any games.
|
||||
- Get the number ID's for this buttons with `jstest` (or any other similar program)
|
||||
- Edit the configuration file (either `/etc/jslisten.cfg` or `~/.jslisten`) and maintain the button ID's and the program which you want to run.
|
||||
- Make sure this script/program can handle multiple simultanios calls! Even if the daemon will wait till this program ends, you never know... And we like to press key combinations many times, if something doesn't work immediately...
|
||||
|
||||
### Example Config
|
||||
|
||||
Note that it calls a custom shell script `/opt/bin/modeSwitcher.sh`. You will need to define something like this for your use case.
|
||||
* I assume your joystick setup is already done and you can see with "jstest /dev/input/js0" nice looking key strokes coming up. There are many tutorials out there and you should not proceed if this doesn't work for you!
|
||||
* Run ./jslisten once to create ~/.jslisten config file or copy utils/jslisten.cfg to /etc
|
||||
* Think which button combination will work for your gamepad. You can configure up to 4 button combination. In my case i picked "Left Shoulder" + "Right Shoulder" + SELECT. I'm pretty sure i will not need to press this buttons at the same time for any games.
|
||||
* Get the number ID's for this buttons with jstest (or any other similar program)
|
||||
* Edit the configuration file (either /etc/jslisten.cfg or ~/.jslisten) and maintain the button ID's and the program which you want to run.
|
||||
* Make sure this script/program can handle multiple simultanios calls! Even if the daemon will wait till this program ends, you never know... And we like to press key combinations many times, if something doesn't work immediately...
|
||||
|
||||
Here is my config example:
|
||||
```
|
||||
[Generic]
|
||||
program="/opt/bin/modeSwitcher.sh"
|
||||
@@ -109,13 +89,12 @@ button4=
|
||||
|
||||
## Known limitations
|
||||
|
||||
- Kodi and X11 are blocking `/dev/input/*` events. For X11 you can add an exception in `/usr/share/X11/xorg.conf.d/10-quirks.conf` but Kodi is ... nasty ... As long as they don't implement a nice unified unput support, my workaround is to revoke the kodi group rights to the input devices. :(
|
||||
- If you experience any issues, feel free to use `--loglevel debug` option when starting the binary (either manually or adding to the `systemctl` [reference above] call) and check syslog.
|
||||
* Kodi and X11 are blocking /dev/input/* events. For X11 you can add an exception in /usr/share/X11/xorg.conf.d/10-quirks.conf but Kodi is ... nasty ... As long as they don't implement a nice
|
||||
unified unput support, my workaround is to revoke the kodi group rights to the input devices. :(
|
||||
* If you experience any issues, feel free to use '--loglevel debug' option and check syslog.
|
||||
|
||||
## Multiple key combinations
|
||||
|
||||
You can have different key sets to run different programs:
|
||||
|
||||
```
|
||||
[Generic]
|
||||
program="/opt/bin/modeSwitcher.sh"
|
||||
|
||||
32
UPDATES.md
32
UPDATES.md
@@ -1,32 +0,0 @@
|
||||
## Update 12/22/2018
|
||||
|
||||
If you have many different /dev/inputs, you can pass it as an arguement at the startup:
|
||||
|
||||
```jslisten --device /dev/input/js0```
|
||||
|
||||
** jslisten will also default to listen to the first device found if the defined device is not found.
|
||||
|
||||
## Update 02/12/2019
|
||||
|
||||
Changed the default service user to "pi" in jslisten.service
|
||||
|
||||
Use user root only if it's really required.
|
||||
|
||||
## Update 02/16/2019
|
||||
|
||||
Added a different mode to easier trigger scripts.
|
||||
|
||||
When started with `--mode plain` (the default) the program behaves as used. This is fine if you need the button combination once in a while.
|
||||
|
||||
However if you want to activate a script a few times in a short time, lets say to adjust your audio volume or if you have a led stripe installed in your arcade and want to adjust the brightness, then
|
||||
the `--mode hold` comes in handy.
|
||||
|
||||
When started with `--mode hold` and you have at least two buttons defined to enter an action, then you hold down the first one, while tipping the second one. If you have three buttons defined you can
|
||||
hold the second two and then just tip the third. In a four button set you will have to hold the first three.
|
||||
|
||||
As soon as you release any but the last button (according to the order in the `jslisten.cfg`) you will have to press the all buttons again.
|
||||
|
||||
So the difference to the plain mode is that once you have entered the engaged/elevated state with a three button set for example, you hold down the first two and can quickly trigger the action by
|
||||
pressing the third. In plain mode you would have to press all three buttons over again to do audio or brightness adjustment.
|
||||
|
||||
Also added `--help` for the command line for a brief summary of options.
|
||||
BIN
bin/jslisten
BIN
bin/jslisten
Binary file not shown.
203
src/jslisten.c
203
src/jslisten.c
@@ -47,7 +47,7 @@
|
||||
// Some static stuff
|
||||
//---------------------------------
|
||||
#define sizearray(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define BUTTON_DEFINED_RANGE -2147483647 // sizeof(long)
|
||||
#define BUTTON_UNSET -1
|
||||
#define true 0
|
||||
#define false 1
|
||||
|
||||
@@ -69,23 +69,24 @@ char myDevPath[NAME_LENGTH];
|
||||
int joyFD;
|
||||
struct KeySet {
|
||||
// Set Default unassigned
|
||||
long button1;
|
||||
int button1Active;
|
||||
long button2;
|
||||
int button2Active;
|
||||
long button3;
|
||||
int button3Active;
|
||||
long button4;
|
||||
int button4Active;
|
||||
int activeButtons;
|
||||
int isTriggered;
|
||||
char swFilename[100];
|
||||
long delay;
|
||||
long button1;
|
||||
unsigned long button1Active;
|
||||
long button2;
|
||||
unsigned long button2Active;
|
||||
long button3;
|
||||
unsigned long button3Active;
|
||||
long button4;
|
||||
unsigned long button4Active;
|
||||
int hotKeyCount;
|
||||
int isTriggered;
|
||||
};
|
||||
|
||||
struct KeySet myKeys[MAX_HOTKEYS];
|
||||
|
||||
int numHotkeys = 0;
|
||||
//int buttonActive = 0;
|
||||
int delayedSection = -1;
|
||||
int hotKeyCombos = 0;
|
||||
int logLevel = LOG_INFO;
|
||||
|
||||
// recognized values for --loglevel
|
||||
@@ -107,12 +108,32 @@ static struct option long_options[] = {
|
||||
typedef enum {PLAIN, HOLD} mode_type;
|
||||
mode_type mode = PLAIN;
|
||||
|
||||
unsigned long getMicrotime(){
|
||||
struct timeval currentTime;
|
||||
gettimeofday(¤tTime, NULL);
|
||||
return currentTime.tv_sec * (int)1e6 + currentTime.tv_usec;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Reset the keys
|
||||
//---------------------------------------------
|
||||
void resetHotkeys() {
|
||||
syslog(LOG_DEBUG, "Reseting Keys");
|
||||
for (int i=0; i<hotKeyCombos; i++) {
|
||||
myKeys[i].button1Active = 0;
|
||||
myKeys[i].button2Active = 0;
|
||||
myKeys[i].button3Active = 0;
|
||||
myKeys[i].button4Active = 0;
|
||||
myKeys[i].isTriggered = false;
|
||||
}
|
||||
delayedSection = -1;
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
// Check if the button was assigned
|
||||
//---------------------------------
|
||||
int buttonDefined(int val) {
|
||||
if ( val > BUTTON_DEFINED_RANGE ) {
|
||||
if ( val > BUTTON_UNSET ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -168,49 +189,61 @@ void readConfig(void) {
|
||||
|
||||
/* section/key enumeration */
|
||||
for (s = 0; ini_getsection(s, section, sizearray(section), iniFile) > 0; s++) {
|
||||
if ( numHotkeys < MAX_HOTKEYS ) {
|
||||
if ( hotKeyCombos < MAX_HOTKEYS ) {
|
||||
for (k = 0; ini_getkey(section, k, str, sizearray(str), iniFile) > 0; k++) {
|
||||
if ( strncmp("program", str, 7) == 0 ) { // Key found
|
||||
n = ini_gets(section, str, "dummy", myKeys[numHotkeys].swFilename, sizearray(myKeys[numHotkeys].swFilename), iniFile);
|
||||
if ( n > 5 && strncmp("dummy", myKeys[numHotkeys].swFilename, 5) != 0 ) { // Value is not empty
|
||||
syslog(LOG_INFO, "Filename: %s\n", myKeys[numHotkeys].swFilename);
|
||||
|
||||
if ( strncmp("program", str, 7) == 0 ) {
|
||||
n = ini_gets(section, str, "dummy", myKeys[hotKeyCombos].swFilename, sizearray(myKeys[hotKeyCombos].swFilename), iniFile);
|
||||
if ( n > 5 && strncmp("dummy", myKeys[hotKeyCombos].swFilename, 5) != 0 ) { // Value is not empty
|
||||
syslog(LOG_INFO, "Filename: %s\n", myKeys[hotKeyCombos].swFilename);
|
||||
}
|
||||
}
|
||||
if ( strncmp("button1", str, 7) == 0 ) { // Key found
|
||||
l = ini_getl(section, str, BUTTON_DEFINED_RANGE, iniFile);
|
||||
|
||||
if ( strncmp("delay", str, 5) == 0 ) {
|
||||
l = ini_getl(section, str, 0, iniFile);
|
||||
syslog(LOG_INFO, "Delay: %ld\n", l);
|
||||
myKeys[hotKeyCombos].delay = l * 1000000;
|
||||
}
|
||||
|
||||
|
||||
if ( strncmp("button1", str, 7) == 0 ) {
|
||||
l = ini_getl(section, str, BUTTON_UNSET, iniFile);
|
||||
if ( buttonDefined(l) == true ) { // Value is not empty
|
||||
syslog(LOG_INFO, "button1: %ld\n", l);
|
||||
myKeys[numHotkeys].button1 = l;
|
||||
myKeys[numHotkeys].activeButtons++;
|
||||
myKeys[hotKeyCombos].button1 = l;
|
||||
myKeys[hotKeyCombos].hotKeyCount++;
|
||||
}
|
||||
}
|
||||
if ( strncmp("button2", str, 7) == 0 ) { // Key found
|
||||
l = ini_getl(section, str, BUTTON_DEFINED_RANGE, iniFile);
|
||||
|
||||
if ( strncmp("button2", str, 7) == 0 ) {
|
||||
l = ini_getl(section, str, BUTTON_UNSET, iniFile);
|
||||
if ( buttonDefined(l) == true ) { // Value is not empty
|
||||
syslog(LOG_INFO, "button2: %ld\n", l);
|
||||
myKeys[numHotkeys].button2 = l;
|
||||
myKeys[numHotkeys].activeButtons++;
|
||||
myKeys[hotKeyCombos].button2 = l;
|
||||
myKeys[hotKeyCombos].hotKeyCount++;
|
||||
}
|
||||
}
|
||||
if ( strncmp("button3", str, 7) == 0 ) { // Key found
|
||||
l = ini_getl(section, str, BUTTON_DEFINED_RANGE, iniFile);
|
||||
|
||||
if ( strncmp("button3", str, 7) == 0 ) {
|
||||
l = ini_getl(section, str, BUTTON_UNSET, iniFile);
|
||||
if ( buttonDefined(l) == true ) { // Value is not empty
|
||||
syslog(LOG_INFO, "button3: %ld\n", l);
|
||||
myKeys[numHotkeys].button3 = l;
|
||||
myKeys[numHotkeys].activeButtons++;
|
||||
myKeys[hotKeyCombos].button3 = l;
|
||||
myKeys[hotKeyCombos].hotKeyCount++;
|
||||
}
|
||||
}
|
||||
if ( strncmp("button4", str, 7) == 0 ) { // Key found
|
||||
l = ini_getl(section, str, BUTTON_DEFINED_RANGE, iniFile);
|
||||
|
||||
if ( strncmp("button4", str, 7) == 0 ) {
|
||||
l = ini_getl(section, str, BUTTON_UNSET, iniFile);
|
||||
if ( buttonDefined(l) == true ) { // Value is not empty
|
||||
syslog(LOG_INFO, "button4: %ld\n", l);
|
||||
myKeys[numHotkeys].button4 = l;
|
||||
myKeys[numHotkeys].activeButtons++;
|
||||
myKeys[hotKeyCombos].button4 = l;
|
||||
myKeys[hotKeyCombos].hotKeyCount++;
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
}
|
||||
numHotkeys++; // Remember how many sections we have
|
||||
hotKeyCombos++; // Remember how many sections we have
|
||||
} /* for */
|
||||
}
|
||||
|
||||
@@ -219,7 +252,7 @@ void readConfig(void) {
|
||||
//---------------------------------------------
|
||||
int checkConfig(void) {
|
||||
int rc=0;
|
||||
for (int i=0; i<numHotkeys; i++) {
|
||||
for (int i=0; i<hotKeyCombos; i++) {
|
||||
if ( sizearray(myKeys[i].swFilename) < 3 ) { // no program make no sense
|
||||
syslog(LOG_ERR, "err: no valid filename provided in section %d. Please check ini file\n", i);
|
||||
rc = 1;
|
||||
@@ -229,7 +262,7 @@ int checkConfig(void) {
|
||||
rc = 1;
|
||||
}
|
||||
syslog(LOG_INFO, "Active assigned buttons in section %d: ", i);
|
||||
syslog(LOG_INFO, "%d\n", myKeys[i].activeButtons);
|
||||
syslog(LOG_INFO, "%d\n", myKeys[i].hotKeyCount);
|
||||
|
||||
}
|
||||
return rc;
|
||||
@@ -241,38 +274,65 @@ int checkConfig(void) {
|
||||
int checkButtonPressed(struct js_event js) {
|
||||
int section = -1;
|
||||
int i;
|
||||
|
||||
// Update the button press in all key combinations
|
||||
for (i=0; i<numHotkeys; i++) {
|
||||
syslog(LOG_DEBUG, "Checking button state");
|
||||
for (i=0; i<hotKeyCombos; i++) {
|
||||
if ( js.number == myKeys[i].button1 ) {
|
||||
myKeys[i].button1Active = js.value;
|
||||
if (js.value == 1) {
|
||||
if ( myKeys[i].button1Active == 0 ) { myKeys[i].button1Active = getMicrotime(); }
|
||||
} else {
|
||||
myKeys[i].button1Active = 0;
|
||||
if (i == delayedSection) { delayedSection = -1; }
|
||||
}
|
||||
} else if ( js.number == myKeys[i].button2 ) {
|
||||
myKeys[i].button2Active = js.value;
|
||||
if (js.value == 1) {
|
||||
if ( myKeys[i].button2Active == 0 ) { myKeys[i].button2Active = getMicrotime(); }
|
||||
} else { myKeys[i].button2Active = 0; }
|
||||
} else if ( js.number == myKeys[i].button3 ) {
|
||||
myKeys[i].button3Active = js.value;
|
||||
if (js.value == 1) {
|
||||
if ( myKeys[i].button3Active == 0 ) { myKeys[i].button3Active = getMicrotime(); }
|
||||
} else { myKeys[i].button3Active = 0; }
|
||||
} else if ( js.number == myKeys[i].button4 ) {
|
||||
myKeys[i].button4Active = js.value;
|
||||
if (js.value == 1) {
|
||||
if ( myKeys[i].button4Active == 0 ) { myKeys[i].button4Active = getMicrotime(); }
|
||||
} else { myKeys[i].button4Active = 0; }
|
||||
}
|
||||
}
|
||||
|
||||
// Analyse combinations
|
||||
for (i=0; i<numHotkeys; i++) {
|
||||
switch (myKeys[i].activeButtons) {
|
||||
for (i=0; i<hotKeyCombos; i++) {
|
||||
switch (myKeys[i].hotKeyCount) {
|
||||
case 1:
|
||||
if ( myKeys[i].button1Active == 1 ) { myKeys[i].isTriggered = 1; section = i; }
|
||||
if ( myKeys[i].button1Active > 0 ) {
|
||||
unsigned long hold_time = getMicrotime() - myKeys[i].button1Active;
|
||||
syslog(LOG_DEBUG, "Delayed: %ld\n", hold_time);
|
||||
if (myKeys[i].delay == 0 || hold_time >= myKeys[i].delay) {
|
||||
myKeys[i].isTriggered = 1;
|
||||
section = i;
|
||||
delayedSection = -1;
|
||||
} else {
|
||||
delayedSection = myKeys[i].delay > 0 ? 1 : delayedSection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ( myKeys[i].button1Active == 1 && myKeys[i].button2Active == 1 ) {
|
||||
myKeys[i].isTriggered = 1; section = i;
|
||||
if ( myKeys[i].button1Active > 0 && myKeys[i].button2Active > 0 ) {
|
||||
myKeys[i].isTriggered = 1;
|
||||
section = i;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if ( myKeys[i].button1Active == 1 && myKeys[i].button2Active == 1 && myKeys[i].button3Active == 1 ) {
|
||||
myKeys[i].isTriggered = 1; section = i;
|
||||
if ( myKeys[i].button1Active > 0 && myKeys[i].button2Active > 0 && myKeys[i].button3Active > 0 ) {
|
||||
myKeys[i].isTriggered = 1;
|
||||
section = i;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ( myKeys[i].button1Active == 1 && myKeys[i].button2Active == 1 && myKeys[i].button3Active == 1 && myKeys[i].button4Active == 1) {
|
||||
myKeys[i].isTriggered = 1; section = i;
|
||||
if ( myKeys[i].button1Active > 0 && myKeys[i].button2Active > 0
|
||||
&& myKeys[i].button3Active > 0 && myKeys[i].button4Active > 0 ) {
|
||||
myKeys[i].isTriggered = 1;
|
||||
section = i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -280,19 +340,6 @@ int checkButtonPressed(struct js_event js) {
|
||||
return section;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Reset the keys
|
||||
//---------------------------------------------
|
||||
void resetHotkeys() {
|
||||
for (int i=0; i<numHotkeys; i++) {
|
||||
myKeys[i].button1Active = 0;
|
||||
myKeys[i].button2Active = 0;
|
||||
myKeys[i].button3Active = 0;
|
||||
myKeys[i].button4Active = 0;
|
||||
myKeys[i].isTriggered = false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Get the input device
|
||||
//---------------------------------------------
|
||||
@@ -462,7 +509,7 @@ void listenJoy (void) {
|
||||
// returns 0 if any of the n-1 is still pressed
|
||||
//---------------------------------------------
|
||||
int button_held(int js_btn_number, int button_set_idx) {
|
||||
int activeKeys = myKeys[button_set_idx].activeButtons - 1;
|
||||
int activeKeys = myKeys[button_set_idx].hotKeyCount - 1;
|
||||
switch (activeKeys) {
|
||||
case 1:
|
||||
return js_btn_number == myKeys[button_set_idx].button1;
|
||||
@@ -545,12 +592,13 @@ int bindJoy(void) {
|
||||
|
||||
// Non-blocking reading
|
||||
struct js_event js;
|
||||
int needTrigger;
|
||||
int triggerSection;
|
||||
int lastTriggeredSet = -1;
|
||||
fcntl(joyFD, F_SETFL, O_NONBLOCK);
|
||||
|
||||
while (1) {
|
||||
while (read(joyFD, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
|
||||
while (read(joyFD, &js, sizeof(struct js_event)) == sizeof(struct js_event) || delayedSection >= 0) {
|
||||
syslog(LOG_DEBUG, "Button Event");
|
||||
if (js.type == JS_EVENT_BUTTON) {
|
||||
syslog(LOG_DEBUG, "Event: type %d, time %d, number %d, value %d\n",
|
||||
js.type, js.time, js.number, js.value);
|
||||
@@ -558,15 +606,16 @@ int bindJoy(void) {
|
||||
resetHotkeys();
|
||||
lastTriggeredSet = -1;
|
||||
}
|
||||
needTrigger = checkButtonPressed(js);
|
||||
if ( needTrigger > -1 ) { // We have found one key section
|
||||
triggerSection = checkButtonPressed(js);
|
||||
if ( triggerSection > -1 ) {
|
||||
// We have found one key section
|
||||
if (mode == HOLD) {
|
||||
// set to "engaged" mode (lastTriggeredSet > -1) and "fire" command once
|
||||
lastTriggeredSet = needTrigger;
|
||||
lastTriggeredSet = triggerSection;
|
||||
}
|
||||
syslog(LOG_INFO, "Swtching mode. ...\n");
|
||||
// call external program
|
||||
int rc = system(myKeys[needTrigger].swFilename);
|
||||
int rc = system(myKeys[triggerSection].swFilename);
|
||||
if ( rc == 0 ) {
|
||||
syslog(LOG_INFO, "Call succesfull\n");
|
||||
} else {
|
||||
@@ -672,15 +721,15 @@ void parse_command_line(int argc, char* argv[]) {
|
||||
//---------------------------------------------
|
||||
void init_button_keysets() {
|
||||
for (int i=0; i<MAX_HOTKEYS; i++) {
|
||||
myKeys[i].button1 = BUTTON_DEFINED_RANGE;
|
||||
myKeys[i].button1 = BUTTON_UNSET;
|
||||
myKeys[i].button1Active = 0;
|
||||
myKeys[i].button2 = BUTTON_DEFINED_RANGE;
|
||||
myKeys[i].button2 = BUTTON_UNSET;
|
||||
myKeys[i].button2Active = 0;
|
||||
myKeys[i].button3 = BUTTON_DEFINED_RANGE;
|
||||
myKeys[i].button3 = BUTTON_UNSET;
|
||||
myKeys[i].button3Active = 0;
|
||||
myKeys[i].button4 = BUTTON_DEFINED_RANGE;
|
||||
myKeys[i].button4 = BUTTON_UNSET;
|
||||
myKeys[i].button4Active = 0;
|
||||
myKeys[i].activeButtons = 0;
|
||||
myKeys[i].hotKeyCount = 0;
|
||||
myKeys[i].isTriggered = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user