Added a spin-delay at start of pndnotifyd so in theory it will wait until a user...
authorskeezix <skeezix@flotsam-vm.(none)>
Sat, 19 Dec 2009 03:27:35 +0000 (22:27 -0500)
committerskeezix <skeezix@flotsam-vm.(none)>
Sat, 19 Dec 2009 03:27:35 +0000 (22:27 -0500)
extended evmapperd to not spam-execute script (configurable minimum separation time between runs)
extended evmapperd to pass the hold-time of key to script as first argument (argv[1], since argv[0] is job name)

apps/pndevmapperd.c
apps/pndnotifyd.c
deployment/etc/pandora/conf/eventmap
include/pnd_utility.h
lib/pnd_utility.c
testdata/conf/eventmap [new file with mode: 0644]
testdata/menuicons/jeff.sample.3.png [new file with mode: 0644]

index 7475903..90e6627 100644 (file)
@@ -13,6 +13,7 @@
 #include <sys/stat.h>  // for umask
 #include <fcntl.h> // for open(2)
 #include <errno.h> // for errno
+#include <time.h> // for time(2)
 
 #include <linux/input.h> // for keys
 //#include "../../kernel-rip/input.h" // for keys
@@ -29,6 +30,7 @@
 // daemon and logging
 //
 unsigned char g_daemon_mode = 0;
+unsigned int g_minimum_separation = 1;
 
 typedef enum {
   pndn_debug = 0,
@@ -41,10 +43,19 @@ typedef enum {
 // event-to-sh mapping
 //
 typedef struct {
+
+  /* template information
+   */
   unsigned char key_p; // 1 if its a key, otherwise an event
   int keycode;         // scancode for the key in question
   char *script;        // script to invoke
   //unsigned int hold_min; // minimum hold-time to trigger
+
+  /* state
+   */
+  time_t last_trigger_time;
+  time_t keydown_time;
+
 } evmap_t;
 
 #define MAXEVENTS 255
@@ -164,7 +175,7 @@ int main ( int argc, char *argv[] ) {
        g_evmap [ g_evmap_max ].key_p = 1;
        g_evmap [ g_evmap_max ].keycode = p -> keycode;
        g_evmap [ g_evmap_max ].script = n;
-       pnd_log ( pndn_debug, "Registered key %s [%d] to script %s\n", p -> keyname, p -> keycode, (char*) n );
+       pnd_log ( pndn_rem, "Registered key %s [%d] to script %s\n", p -> keyname, p -> keycode, (char*) n );
        g_evmap_max++;
       } else {
        pnd_log ( pndn_warning, "WARNING! Key '%s' is not handled by pndevmapperd yet! Skipping.", k );
@@ -173,6 +184,9 @@ int main ( int argc, char *argv[] ) {
     } else if ( strncmp ( k, "events.", 7 ) == 0 ) {
       k += 7;
 
+    } else if ( strncmp ( k, "pndevmapperd.", 7 ) == 0 ) {
+      // not consumed here, skip silently
+
     } else {
       // uhhh
       pnd_log ( pndn_warning, "Unknown config key '%s'; skipping.\n", k );
@@ -186,6 +200,11 @@ int main ( int argc, char *argv[] ) {
     pnd_log ( pndn_rem, "config file causes loglevel to change to %u", pnd_log_get_filter() );
   }
 
+  if ( pnd_conf_get_as_int ( evmaph, "pndevmapperd.minimum_separation" ) != PND_CONF_BADNUM ) {
+    g_minimum_separation = pnd_conf_get_as_int ( evmaph, "pndevmapperd.minimum_separation" );
+    pnd_log ( pndn_rem, "config file causes minimum_separation to change to %u", g_minimum_separation );
+  }
+
   /* do we have anything to do?
    */
   if ( ! g_evmap_max ) {
@@ -220,9 +239,12 @@ int main ( int argc, char *argv[] ) {
 
     if ( strcmp ( name, "omap_twl4030keypad" ) == 0 ) {
       fds [ 0 ] = fd;
-    } else if (strcmp(name, "gpio-keys") == 0) {
+    } else if ( strcmp ( name, "gpio-keys" ) == 0) {
       fds [ 1 ] = fd;
+    } else if ( strcmp ( name, "AT Translated Set 2 keyboard" ) == 0) { // for vmware, my dev environment
+      fds [ 0 ] = fd;
     } else {
+      pnd_log ( pndn_rem, "Ignoring unknown device '%s'\n", name );
       close ( fd );
       continue;
     }
@@ -302,7 +324,7 @@ int main ( int argc, char *argv[] ) {
        }
 
       } else {
-       pnd_log ( pndn_warning, "WARNING: Unexpected event type %i received\n", ev[i].type );
+       pnd_log ( pndn_debug, "DEBUG: Unexpected event type %i received\n", ev[i].type );
        continue;
       }
 
@@ -324,31 +346,55 @@ int main ( int argc, char *argv[] ) {
 void dispatch_key ( int keycode, int val ) {
   unsigned int i;
 
-  while ( i < g_evmap_max ) {
+  // val decodes as:
+  // 1 - down (pressed)
+  // 2 - down again (hold)
+  // 0 - up (released)
+
+  for ( i = 0; i < g_evmap_max; i++ ) {
 
     if ( ( g_evmap [ i ].key_p ) &&
-        ( g_evmap [ i ].keycode == keycode ) )
+        ( g_evmap [ i ].keycode == keycode ) &&
+        ( g_evmap [ i ].script ) )
     {
 
-      if ( g_evmap [ i ].script ) {
-       int x;
+      // is this a keydown or a keyup?
+      if ( val == 1 ) {
+       // keydown
+       g_evmap [ i ].keydown_time = time ( NULL );
 
-       if ( ( x = fork() ) < 0 ) {
-         pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
-         exit ( -3 );
-       }
+      } else if ( val == 0 ) {
+       // keyup
 
-       if ( x == 0 ) {
-         pnd_log ( pndn_debug, "REM: Invoking %s\n", g_evmap [ i ].script );
-         execl ( g_evmap [ i ].script, g_evmap [ i ].script, (char*)NULL );
-         pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", g_evmap [ i ].script );
-         exit ( -4 );
+       char holdtime [ 128 ];
+       sprintf ( holdtime, "%d", (int)( time(NULL) - g_evmap [ i ].keydown_time ) );
+
+       if ( time ( NULL ) - g_evmap [ i ].last_trigger_time >= g_minimum_separation ) {
+         int x;
+
+         g_evmap [ i ].last_trigger_time = time ( NULL );
+
+         pnd_log ( pndn_rem, "Will attempt to invoke: %s %s\n", g_evmap [ i ].script, holdtime );
+
+         if ( ( x = fork() ) < 0 ) {
+           pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
+           exit ( -3 );
+         }
+
+         if ( x == 0 ) {
+           execl ( g_evmap [ i ].script, g_evmap [ i ].script, holdtime, (char*)NULL );
+           pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", g_evmap [ i ].script );
+           exit ( -4 );
+         }
+
+       } else {
+         pnd_log ( pndn_rem, "Skipping invokation.. falls within minimum_separation threshold\n" );
        }
 
-      }
+      } // key up or down?
 
       return;
-    }
+    } // found matching event for keycode
 
   } // while
 
index f41e842..66bd43d 100644 (file)
@@ -151,6 +151,19 @@ int main ( int argc, char *argv[] ) {
     
   } // set up daemon
 
+  // wait for a user to be logged in - we should probably get hupped when a user logs in, so we can handle
+  // log-out and back in again, with SDs popping in and out between..
+  pnd_log ( pndn_rem, "Checking to see if a user is logged in\n" );
+  char tmp_username [ 128 ];
+  while ( 1 ) {
+    if ( pnd_check_login ( tmp_username, 127 ) ) {
+      break;
+    }
+    pnd_log ( pndn_debug, "  No one logged in yet .. spinning.\n" );
+    sleep ( 2 );
+  } // spin
+  pnd_log ( pndn_rem, "Looks like user '%s' is in, continue.\n", tmp_username );
+
   /* parse configs
    */
 
index 83a8fee..5908728 100644 (file)
@@ -12,3 +12,4 @@ lid-open      foo
 [pndevmapperd]
 # logging level 0 means to include debug; level 1 (regular), 2 (warnings), 3 (errors)
 loglevel       1
+minimum_separation     1       # 1 second minimum between a single event repeating
index a9638ce..62af5af 100644 (file)
@@ -6,6 +6,12 @@
 extern "C" {
 #endif
 
+// expand_tilde() will only function correctly if a user is actually logged in; perhaps you
+// want to spin until it looks like someone has in fact done so. (most devices will likely
+// have auto-login, but its not instantaneous!)
+//  r_username is optional; if present, will receive a copy of username
+unsigned char pnd_check_login ( char *r_username, unsigned int maxlen );
+
 // given a malloc'd pointer to a string, expand ~ to $HOME as often as it is found, returning a
 // new string; the old string is destroyed in the process, or returned as-is.
 char *pnd_expand_tilde ( char *freeable_buffer );
index b7e146f..b9cf22d 100644 (file)
 #include "pnd_pndfiles.h"
 #include "pnd_discovery.h"
 
+unsigned char pnd_check_login ( char *r_username, unsigned int maxlen ) {
+  FILE *f;
+  struct utmp b;
+  struct passwd *pw;
+
+  f = fopen ( "/var/run/utmp", "r" );
+
+  if ( f ) {
+
+    while ( fread ( &b, sizeof(struct utmp), 1, f ) == 1 ) {
+
+      if ( b.ut_type == USER_PROCESS ) {
+
+       // ut_user contains the username ..
+       // now we need to find the path to that account.
+       while ( ( pw = getpwent() ) ) {
+
+         if ( strcmp ( pw -> pw_name, b.ut_user ) == 0 ) {
+
+           if ( r_username ) {
+             strncpy ( r_username, b.ut_user, maxlen );
+           }
+
+           fclose ( f );
+           return ( 1 );
+         } // passwd entry matches the utmp entry
+
+       } // while iteratin across passwd entries
+       endpwent();
+
+      } // utmp entry is for a user login
+
+    } // while
+
+    fclose ( f );
+  } // opened?
+
+  return ( 0 );
+}
+
 // a generalized variable-substitution routine might be nice; for now we need a quick tilde one,
 // so here goes. Brute force ftw!
 char *pnd_expand_tilde ( char *freeable_buffer ) {
diff --git a/testdata/conf/eventmap b/testdata/conf/eventmap
new file mode 100644 (file)
index 0000000..ed1aaac
--- /dev/null
@@ -0,0 +1,15 @@
+
+# Open Pandora
+# Event-to-shscript map configuration
+
+[keys]
+a /usr/pandora/scripts/op_menu
+
+[events]
+lid-close      bar
+lid-open       foo
+
+[pndevmapperd]
+# logging level 0 means to include debug; level 1 (regular), 2 (warnings), 3 (errors)
+loglevel       1
+minimum_separation     1       # 1 second minimum between a single event repeating
diff --git a/testdata/menuicons/jeff.sample.3.png b/testdata/menuicons/jeff.sample.3.png
new file mode 100644 (file)
index 0000000..140a393
Binary files /dev/null and b/testdata/menuicons/jeff.sample.3.png differ