From: skeezix Date: Sat, 19 Dec 2009 03:27:35 +0000 (-0500) Subject: Added a spin-delay at start of pndnotifyd so in theory it will wait until a user... X-Git-Tag: Release-2010-05/1~141^2 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be702b1f9e9ee66517144d40141cca3b1139a7bd;p=pandora-libraries.git Added a spin-delay at start of pndnotifyd so in theory it will wait until a user logs in; this possibly could solve the problem where sometimes pndnotifyd doesn't emit .desktops 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) --- diff --git a/apps/pndevmapperd.c b/apps/pndevmapperd.c index 7475903..90e6627 100644 --- a/apps/pndevmapperd.c +++ b/apps/pndevmapperd.c @@ -13,6 +13,7 @@ #include // for umask #include // for open(2) #include // for errno +#include // for time(2) #include // 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 diff --git a/apps/pndnotifyd.c b/apps/pndnotifyd.c index f41e842..66bd43d 100644 --- a/apps/pndnotifyd.c +++ b/apps/pndnotifyd.c @@ -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 */ diff --git a/deployment/etc/pandora/conf/eventmap b/deployment/etc/pandora/conf/eventmap index 83a8fee..5908728 100644 --- a/deployment/etc/pandora/conf/eventmap +++ b/deployment/etc/pandora/conf/eventmap @@ -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 diff --git a/include/pnd_utility.h b/include/pnd_utility.h index a9638ce..62af5af 100644 --- a/include/pnd_utility.h +++ b/include/pnd_utility.h @@ -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 ); diff --git a/lib/pnd_utility.c b/lib/pnd_utility.c index b7e146f..b9cf22d 100644 --- a/lib/pnd_utility.c +++ b/lib/pnd_utility.c @@ -15,6 +15,46 @@ #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 index 0000000..ed1aaac --- /dev/null +++ b/testdata/conf/eventmap @@ -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 index 0000000..140a393 Binary files /dev/null and b/testdata/menuicons/jeff.sample.3.png differ