New exec(disco-t) for more flexible pnd exec. PXML may specify appdata dirname, and...
authorskeezix <skeezix@flotsam-vm.(none)>
Fri, 26 Mar 2010 17:53:50 +0000 (13:53 -0400)
committerskeezix <skeezix@flotsam-vm.(none)>
Fri, 26 Mar 2010 17:53:50 +0000 (13:53 -0400)
15 files changed:
apps/pndevmapperd.c
artwork/PandoraLogo.png [new file with mode: 0644]
include/pnd_apps.h
include/pnd_device.h
include/pnd_discovery.h
include/pnd_pxml.h
include/pnd_pxml_names.h
lib/pnd_apps.c
lib/pnd_desktop.c
lib/pnd_device.c
lib/pnd_discovery.c
lib/pnd_pxml.c
lib/pnd_tinyxml.cpp
minimenu/TODO.txt
minimenu/mmui.c

index aa090c4..14bd6a3 100644 (file)
@@ -776,20 +776,28 @@ void sigalrm_handler ( int n ) {
 
   // first -- are we critical yet? if so, shut down!
   if ( batlevel <= b_shutdown && b_shutdown_script ) {
 
   // first -- are we critical yet? if so, shut down!
   if ( batlevel <= b_shutdown && b_shutdown_script ) {
-    int x;
+    int mamps = 0;
 
 
-    pnd_log ( pndn_error, "CRITICAL BATTERY LEVEL -- shutdown the system down! Invoke: %s\n", b_shutdown_script );
+    if ( pnd_device_get_charge_current ( &mamps ) && mamps > 100 ) {
+      // critical battery, but charging, so relax.
+    } else {
+      int x;
 
 
-    if ( ( x = fork() ) < 0 ) {
-      pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
-      exit ( -3 );
-    }
+      pnd_log ( pndn_error, "CRITICAL BATTERY LEVEL -- shutdown the system down! Invoke: %s\n",
+               b_shutdown_script );
 
 
-    if ( x == 0 ) {
-      execl ( b_shutdown_script, b_shutdown_script, (char*)NULL );
-      pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", b_shutdown_script );
-      exit ( -4 );
-    }
+      if ( ( x = fork() ) < 0 ) {
+       pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
+       exit ( -3 );
+      }
+
+      if ( x == 0 ) {
+       execl ( b_shutdown_script, b_shutdown_script, (char*)NULL );
+       pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", b_shutdown_script );
+       exit ( -4 );
+      }
+
+    } // charging
 
   }
 
 
   }
 
diff --git a/artwork/PandoraLogo.png b/artwork/PandoraLogo.png
new file mode 100644 (file)
index 0000000..289234e
Binary files /dev/null and b/artwork/PandoraLogo.png differ
index 5f8f12b..80b5aaf 100644 (file)
@@ -6,6 +6,9 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
+#include "pnd_container.h"
+#include "pnd_discovery.h"
+
 // default application searchpath (and key to look it up in config)
 #define PND_APPS_SEARCHPATH "/media/*/pandora/apps:/usr/pandora/apps"
 #define PND_APPS_KEY "autodiscovery.searchpath"
 // default application searchpath (and key to look it up in config)
 #define PND_APPS_SEARCHPATH "/media/*/pandora/apps:/usr/pandora/apps"
 #define PND_APPS_KEY "autodiscovery.searchpath"
@@ -69,6 +72,14 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
                              unsigned int clockspeed, unsigned int options );
 char *pnd_apps_exec_runline ( void ); // returns the cached pnd_run.sh line from last PND_EXEC_OPTION_NORUN
 
                              unsigned int clockspeed, unsigned int options );
 char *pnd_apps_exec_runline ( void ); // returns the cached pnd_run.sh line from last PND_EXEC_OPTION_NORUN
 
+// this is a superior version of pnd_apps_exec(), but avoiding breaking the pnd_apps_exec() API to
+// extend it.
+// - same option booleans
+// - 'reserved' should be NULL unless you know what to put there (depends on options)
+// - 'app' should be a return from discovery, or a populated disco-t struct
+// - 'pndrun' is a reference to a pnd_run.sh script, to avoid seeking it out every time
+unsigned char pnd_apps_exec_disco ( char *pndrun, pnd_disco_t *app, unsigned int options, void *reserved );
+
 // should you wish to know where an app will get mounted, call this function to obtain a guess. The
 // logic is wrapped up in pnd_run.sh, but in theory should be easily determined.
 
 // should you wish to know where an app will get mounted, call this function to obtain a guess. The
 // logic is wrapped up in pnd_run.sh, but in theory should be easily determined.
 
index f9a58a7..09437f7 100644 (file)
@@ -22,6 +22,7 @@ extern "C" {
 #define PND_DEVICE_NUB1 "/dev/input/js1"
 #define PND_DEVICE_NUB2 "/dev/input/js2"
 #define PND_DEVICE_BATTERY_GAUGE_PERC "/sys/class/power_supply/bq27500-0/capacity"
 #define PND_DEVICE_NUB1 "/dev/input/js1"
 #define PND_DEVICE_NUB2 "/dev/input/js2"
 #define PND_DEVICE_BATTERY_GAUGE_PERC "/sys/class/power_supply/bq27500-0/capacity"
+#define PND_DEVICE_CHARGE_CURRENT "/sys/class/power_supply/bq27500-0/current_now"
 
 #define PND_DEVICE_LED_CHARGER "/sys/class/leds/pandora::charger"
 #define PND_DEVICE_LED_POWER   "/sys/class/leds/pandora::power"
 
 #define PND_DEVICE_LED_CHARGER "/sys/class/leds/pandora::charger"
 #define PND_DEVICE_LED_POWER   "/sys/class/leds/pandora::power"
@@ -55,6 +56,7 @@ unsigned int pnd_device_get_clock ( void );
  * On error, returns -1
  */
 int pnd_device_get_battery_gauge_perc ( void );
  * On error, returns -1
  */
 int pnd_device_get_battery_gauge_perc ( void );
+unsigned char pnd_device_get_charge_current ( int *result ); // returns + - current; if charging, current is +ve.
 
 // LCD to set on/off
 
 
 // LCD to set on/off
 
index 33513d3..5f8734f 100644 (file)
@@ -56,6 +56,7 @@ typedef struct {
   char *title_en;
   char *desc_en;
   char *unique_id;
   char *title_en;
   char *desc_en;
   char *unique_id;
+  char *appdata_dirname;       // preferred dir name for appdata; if missing, use unique-id
   char *icon;
   char *exec;
   char *execargs;
   char *icon;
   char *exec;
   char *execargs;
index 405268e..25fbcdc 100644 (file)
@@ -49,6 +49,7 @@ char *pnd_pxml_get_app_name_it ( pnd_pxml_handle h );
 char *pnd_pxml_get_app_name_fr ( pnd_pxml_handle h );
 char *pnd_pxml_get_app_name ( pnd_pxml_handle h, char *iso_lang );
 char *pnd_pxml_get_unique_id ( pnd_pxml_handle h );
 char *pnd_pxml_get_app_name_fr ( pnd_pxml_handle h );
 char *pnd_pxml_get_app_name ( pnd_pxml_handle h, char *iso_lang );
 char *pnd_pxml_get_unique_id ( pnd_pxml_handle h );
+char *pnd_pxml_get_appdata_dirname ( pnd_pxml_handle h );
 char *pnd_pxml_get_standalone ( pnd_pxml_handle h );
 char *pnd_pxml_get_icon ( pnd_pxml_handle h );
 char *pnd_pxml_get_description_en ( pnd_pxml_handle h );
 char *pnd_pxml_get_standalone ( pnd_pxml_handle h );
 char *pnd_pxml_get_icon ( pnd_pxml_handle h );
 char *pnd_pxml_get_description_en ( pnd_pxml_handle h );
@@ -122,6 +123,7 @@ typedef struct
        int titles_c;
        int titles_alloc_c;
        char *unique_id;
        int titles_c;
        int titles_alloc_c;
        char *unique_id;
+        char *appdata_dirname;       // preferred dir name for appdata; if missing, use unique-id
        char *standalone;
        char *icon;
        pnd_localized_string_t *descriptions;
        char *standalone;
        char *icon;
        pnd_localized_string_t *descriptions;
index 4cd1e65..766a0c9 100644 (file)
@@ -7,6 +7,7 @@ extern "C" {
 
 /* <PXML id="..."> ...*/
 #define PND_PXML_ATTRNAME_UID "id"
 
 /* <PXML id="..."> ...*/
 #define PND_PXML_ATTRNAME_UID "id"
+#define PND_PXML_ATTRNAME_APPDATANAME "appdata"
 
 /* <application id="123">*/
 #define PND_PXML_APP "application"
 
 /* <application id="123">*/
 #define PND_PXML_APP "application"
index cefebbb..fd5d566 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h> /* for malloc */
 #include <string.h> /* for memset */
 #include <unistd.h> /* for fork/exec */
 #include <stdlib.h> /* for malloc */
 #include <string.h> /* for memset */
 #include <unistd.h> /* for fork/exec */
+#include <limits.h>
 
 #include <sys/types.h> /* for wait */
 #include <sys/wait.h> /* for wait */
 
 #include <sys/types.h> /* for wait */
 #include <sys/wait.h> /* for wait */
@@ -18,13 +19,11 @@ char *pnd_apps_exec_runline ( void ) {
   return ( apps_exec_runline );
 }
 
   return ( apps_exec_runline );
 }
 
-unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
-                             char *rel_exec, char *rel_startdir,
-                             char *args,
-                             unsigned int clockspeed, unsigned int options )
+unsigned char pnd_apps_exec_disco ( char *pndrun, pnd_disco_t *app,
+                                   unsigned int options, void *reserved )
 {
   char *argv [ 60 ];
 {
   char *argv [ 60 ];
-  char s_clockspeed [ 100 ];
+  char fullpath [ PATH_MAX ] = "";
   int f;
 
   //printf ( "Entering pnd_apps_exec\n" );
   int f;
 
   //printf ( "Entering pnd_apps_exec\n" );
@@ -33,27 +32,19 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
     return ( 0 );
   }
 
     return ( 0 );
   }
 
-  if ( ! fullpath ) {
+  if ( ! app -> unique_id ) {
     return ( 0 );
   }
 
     return ( 0 );
   }
 
-  if ( ! unique_id ) {
+  if ( ! app -> exec ) {
     return ( 0 );
   }
 
     return ( 0 );
   }
 
-  if ( ! rel_exec ) {
-    return ( 0 );
-  }
-
-#if 0
-  printf ( "  runscript: %s\n", pndrun );
-  printf ( "  path: %s\n", fullpath );
-  printf ( "  id: %s\n", unique_id );
-  printf ( "  exec: %s\n", rel_exec );
-  printf ( "  cwd: %s\n", rel_startdir );
-  printf ( "  clock: %u\n", clockspeed );
-#endif
+  // determine path to pnd-file
+  sprintf ( fullpath, "%s/%s", app -> object_path, app -> object_filename );
 
 
+  // nail down argv for the app
+  //
   memset ( argv, '\0', sizeof(char*) * 20 );
 
   f = 0;
   memset ( argv, '\0', sizeof(char*) * 20 );
 
   f = 0;
@@ -61,21 +52,25 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
   argv [ f++ ] = "-p";
   argv [ f++ ] = fullpath;
   argv [ f++ ] = "-e";
   argv [ f++ ] = "-p";
   argv [ f++ ] = fullpath;
   argv [ f++ ] = "-e";
-  argv [ f++ ] = rel_exec;
-  if ( rel_startdir ) {
+  argv [ f++ ] = app -> exec;
+  if ( app -> startdir ) {
     argv [ f++ ] = "-s";
     argv [ f++ ] = "-s";
-    argv [ f++ ] = rel_startdir;
+    argv [ f++ ] = app -> startdir;
   }
   }
-  if ( args ) {
+  if ( app -> execargs ) {
     argv [ f++ ] = "-a";
     argv [ f++ ] = "-a";
-    argv [ f++ ] = args;
+    argv [ f++ ] = app -> execargs;
   }
   }
-  argv [ f++ ] = "-b";
-  argv [ f++ ] = unique_id;
-  if ( clockspeed ) {
+  if ( app -> appdata_dirname ) {
+    argv [ f++ ] = "-b";
+    argv [ f++ ] = app -> appdata_dirname;
+  } else {
+    argv [ f++ ] = "-b";
+    argv [ f++ ] = app -> unique_id;
+  }
+  if ( app -> clockspeed ) {
     argv [ f++ ] = "-c";
     argv [ f++ ] = "-c";
-    snprintf ( s_clockspeed, 100, "%u", clockspeed );
-    argv [ f++ ] = s_clockspeed;
+    argv [ f++ ] = app -> clockspeed;
   }
 
   // skip -a (arguments) for now
   }
 
   // skip -a (arguments) for now
@@ -166,6 +161,41 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
   return ( 1 );
 }
 
   return ( 1 );
 }
 
+unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
+                             char *rel_exec, char *rel_startdir,
+                             char *args,
+                             unsigned int clockspeed, unsigned int options )
+{
+  pnd_disco_t d;
+  bzero ( &d, sizeof(pnd_disco_t) );
+
+  char cpuspeed [ 10 ];
+  sprintf ( cpuspeed, "%u", clockspeed );
+
+  char hackpath [ PATH_MAX ];
+  strncpy ( hackpath, fullpath, PATH_MAX );
+  char *c = strrchr ( hackpath, '/' );
+  if ( c ) {
+    *c = '\0';
+    d.object_path = hackpath;
+    d.object_filename = c + 1;
+  } else {
+    d.object_path = fullpath;
+  }
+
+  d.unique_id = unique_id;
+  d.exec = rel_exec;
+  d.startdir = rel_startdir;
+  d.execargs = args;
+  if ( clockspeed ) {
+    d.clockspeed = cpuspeed;
+  } else {
+    d.clockspeed = NULL;
+  }
+
+  return ( pnd_apps_exec_disco ( pndrun, &d, options, NULL ) );
+}
+
 void pnd_get_ro_mountpoint ( char *fullpath, char *unique_id, char *r_mountpoint, unsigned int mountpoint_len ) {
 
   if ( ! r_mountpoint ) {
 void pnd_get_ro_mountpoint ( char *fullpath, char *unique_id, char *r_mountpoint, unsigned int mountpoint_len ) {
 
   if ( ! r_mountpoint ) {
index 8b05b07..3ef81a0 100644 (file)
@@ -104,10 +104,12 @@ unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t
     // basics
     if ( p -> object_type == pnd_object_type_directory ) {
       snprintf ( buffer, 1020, "Exec=%s%s -p %s -e %s -b %s",
     // basics
     if ( p -> object_type == pnd_object_type_directory ) {
       snprintf ( buffer, 1020, "Exec=%s%s -p %s -e %s -b %s",
-                nohup, pndrun, p -> object_path, p -> exec, p -> unique_id );
+                nohup, pndrun, p -> object_path, p -> exec,
+                p -> appdata_dirname ? p -> appdata_dirname : p -> unique_id );
     } else if ( p -> object_type == pnd_object_type_pnd ) {
       snprintf ( buffer, 1020, "Exec=%s%s -p %s/%s -e %s -b %s",
     } else if ( p -> object_type == pnd_object_type_pnd ) {
       snprintf ( buffer, 1020, "Exec=%s%s -p %s/%s -e %s -b %s",
-                nohup, pndrun, p -> object_path, p -> object_filename, p -> exec, p -> unique_id );
+                nohup, pndrun, p -> object_path, p -> object_filename, p -> exec,
+                p -> appdata_dirname ? p -> appdata_dirname : p -> unique_id );
     }
 
     // start dir
     }
 
     // start dir
index d255c97..e158711 100644 (file)
@@ -92,6 +92,17 @@ int pnd_device_get_battery_gauge_perc ( void ) {
   return ( -1 );
 }
 
   return ( -1 );
 }
 
+unsigned char pnd_device_get_charge_current ( int *result ) {
+  char buffer [ 100 ];
+
+  if ( pnd_device_open_read_close ( PND_DEVICE_CHARGE_CURRENT, buffer, 100 ) ) {
+    *result = atoi ( buffer );
+    return ( 1 );
+  }
+
+  return ( 0 );
+}
+
 unsigned char pnd_device_set_led_power_brightness ( unsigned char v ) {
   char buffer [ 100 ];
 
 unsigned char pnd_device_set_led_power_brightness ( unsigned char v ) {
   char buffer [ 100 ];
 
index 074513d..1e41ead 100644 (file)
@@ -30,6 +30,7 @@ void pnd_disco_destroy ( pnd_disco_t *p ) {
 
   if ( p -> title_en ) {       free ( p -> title_en );    }
   if ( p -> unique_id ) {      free ( p -> unique_id );   }
 
   if ( p -> title_en ) {       free ( p -> title_en );    }
   if ( p -> unique_id ) {      free ( p -> unique_id );   }
+  if ( p -> appdata_dirname ) { free ( p -> appdata_dirname );   }
   if ( p -> icon )     {       free ( p -> icon );        }
   if ( p -> exec )     {       free ( p -> exec );        }
   if ( p -> execargs ) {       free ( p -> execargs );    }
   if ( p -> icon )     {       free ( p -> icon );        }
   if ( p -> exec )     {       free ( p -> exec );        }
   if ( p -> execargs ) {       free ( p -> execargs );    }
@@ -237,6 +238,9 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       if ( pnd_pxml_get_unique_id ( pxmlh ) ) {
        p -> unique_id = strdup ( pnd_pxml_get_unique_id ( pxmlh ) );
       }
       if ( pnd_pxml_get_unique_id ( pxmlh ) ) {
        p -> unique_id = strdup ( pnd_pxml_get_unique_id ( pxmlh ) );
       }
+      if ( pnd_pxml_get_appdata_dirname ( pxmlh ) ) {
+       p -> appdata_dirname = strdup ( pnd_pxml_get_appdata_dirname ( pxmlh ) );
+      }
       if ( pnd_pxml_get_clockspeed ( pxmlh ) ) {
        p -> clockspeed = strdup ( pnd_pxml_get_clockspeed ( pxmlh ) ); 
       }
       if ( pnd_pxml_get_clockspeed ( pxmlh ) ) {
        p -> clockspeed = strdup ( pnd_pxml_get_clockspeed ( pxmlh ) ); 
       }
@@ -338,6 +342,15 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
          p -> clockspeed = strdup ( v );
        }
 
          p -> clockspeed = strdup ( v );
        }
 
+       // appdata dirname
+       snprintf ( key, 100, "Application-%u.appdata", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> appdata_dirname ) {
+           free ( p -> appdata_dirname );
+         }
+         p -> appdata_dirname = strdup ( v );
+       }
+
        // categories
        snprintf ( key, 100, "Application-%u.maincategory", p -> subapp_number );
        if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
        // categories
        snprintf ( key, 100, "Application-%u.maincategory", p -> subapp_number );
        if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
index 7632c05..2b597ce 100644 (file)
@@ -176,6 +176,9 @@ void pnd_pxml_delete ( pnd_pxml_handle h ) {
   if ( p -> startdir ) {
     free ( p -> startdir );
   }
   if ( p -> startdir ) {
     free ( p -> startdir );
   }
+  if ( p -> appdata_dirname ) {
+    free ( p -> appdata_dirname );
+  }
 
   free(p); /*very important!*/
 
 
   free(p); /*very important!*/
 
@@ -338,6 +341,11 @@ char *pnd_pxml_get_unique_id ( pnd_pxml_handle h ) {
   return ( p -> unique_id );
 }
 
   return ( p -> unique_id );
 }
 
+char *pnd_pxml_get_appdata_dirname ( pnd_pxml_handle h ) {
+  pnd_pxml_t *p = (pnd_pxml_t*) h;
+  return ( p -> appdata_dirname );
+}
+
 char *pnd_pxml_get_standalone ( pnd_pxml_handle h ) {
   pnd_pxml_t *p = (pnd_pxml_t*) h;
   return ( p -> standalone );
 char *pnd_pxml_get_standalone ( pnd_pxml_handle h ) {
   pnd_pxml_t *p = (pnd_pxml_t*) h;
   return ( p -> standalone );
index 6159562..95cf3ec 100644 (file)
@@ -158,6 +158,7 @@ unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int
     if ( appwrappermode ) {
       app->unique_id = pnd_pxml_get_attribute(appElem, PND_PXML_ATTRNAME_UID);
       //pnd_log ( PND_LOG_DEFAULT, (char*)"  Subapp #%u has unique_id %s\n", appcount, app -> unique_id );
     if ( appwrappermode ) {
       app->unique_id = pnd_pxml_get_attribute(appElem, PND_PXML_ATTRNAME_UID);
       //pnd_log ( PND_LOG_DEFAULT, (char*)"  Subapp #%u has unique_id %s\n", appcount, app -> unique_id );
+      app->appdata_dirname = pnd_pxml_get_attribute(appElem, PND_PXML_ATTRNAME_APPDATANAME);
     } else {
       app->unique_id = pnd_pxml_get_attribute(hRoot.Element(), PND_PXML_ATTRNAME_UID);
       //pnd_log ( PND_LOG_DEFAULT, (char*)"  Only-app #%u has unique_id %s\n", appcount, app -> unique_id );
     } else {
       app->unique_id = pnd_pxml_get_attribute(hRoot.Element(), PND_PXML_ATTRNAME_UID);
       //pnd_log ( PND_LOG_DEFAULT, (char*)"  Only-app #%u has unique_id %s\n", appcount, app -> unique_id );
index 81be21d..7370511 100644 (file)
@@ -6,7 +6,6 @@
 - libpnd: appdata-dir-name?
 
 - add font and fontcolour control to conf
 - libpnd: appdata-dir-name?
 
 - add font and fontcolour control to conf
-- evmapperd.. no force off, if charging on /sys/class/power_supply/bq27500-0/current_now is +ve
 - About screen and shoutouts // konami code?
 - skinning .. mmenu.conf and then skin.conf in each skin dir?
   - skin picker/saver
 - About screen and shoutouts // konami code?
 - skinning .. mmenu.conf and then skin.conf in each skin dir?
   - skin picker/saver
index 8fd5bf1..467678e 100644 (file)
@@ -1462,16 +1462,8 @@ void ui_push_down ( void ) {
 void ui_push_exec ( void ) {
 
   if ( ui_selected ) {
 void ui_push_exec ( void ) {
 
   if ( ui_selected ) {
+    pnd_apps_exec_disco ( pnd_run_script, ui_selected -> ref, PND_EXEC_OPTION_NORUN, NULL );
     char buffer [ PATH_MAX ];
     char buffer [ PATH_MAX ];
-    sprintf ( buffer, "%s/%s", ui_selected -> ref -> object_path, ui_selected -> ref -> object_filename );
-    pnd_apps_exec ( pnd_run_script,
-                   buffer,
-                   ui_selected -> ref -> unique_id,
-                   ui_selected -> ref -> exec,
-                   ui_selected -> ref -> startdir,
-                   ui_selected -> ref -> execargs,
-                   ui_selected -> ref -> clockspeed ? atoi ( ui_selected -> ref -> clockspeed ) : 0,
-                   PND_EXEC_OPTION_NORUN );
     sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() );
     emit_and_quit ( buffer );
   }
     sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() );
     emit_and_quit ( buffer );
   }