diff --git a/Makefile b/Makefile
index 0654937..26b61a2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS ?= -g -O2 -Wall
+CFLAGS ?= -g -O2 -Wall -std=c99
PROGRAMS = jslisten
diff --git a/README.md b/README.md
index 26495a1..a6b1426 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,9 @@ After searching the internet, I found nothing really interesting. Kodi addon wil
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/myinput/js0```
+```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
@@ -57,7 +59,7 @@ Also added `--help` for the command line for a brief summary of options.
## Installation
Following example for Raspbian. Should work for many other distributions almost the same way.
- * Use the precompiled binary in bin/ or run "# make" to create the binary
+ * 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
diff --git a/src/jslisten.c b/src/jslisten.c
index 41a65ee..c059d5f 100644
--- a/src/jslisten.c
+++ b/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 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 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= 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);
@@ -550,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 {
@@ -664,15 +721,15 @@ void parse_command_line(int argc, char* argv[]) {
//---------------------------------------------
void init_button_keysets() {
for (int i=0; i