Directory browser is now available in config panel, and works! Will only run files...
authorskeezix <skeezix@flotsam-vm.(none)>
Mon, 24 Jan 2011 16:46:00 +0000 (11:46 -0500)
committerskeezix <skeezix@flotsam-vm.(none)>
Mon, 24 Jan 2011 16:46:00 +0000 (11:46 -0500)
minimenu/mmconf.c
minimenu/mmenu.c
minimenu/mmenu.h
minimenu/mmui.c

index 80347b0..1c1ef61 100644 (file)
@@ -31,6 +31,7 @@ confitem_t page_general[] = {
   { "Set CPU speed when leaving",    "Whether the next setting is applied or not",              "0",                "minimenu.use_run_speed",  ct_boolean },
   { "CPU speed when leaving",        "Before running app, set this speed; app may override.",   "500",              "minimenu.run_speed",      ct_cpu_speed },
   { "Show 'All' tab",                "Whethor an All tab is shown or not",                      "1",                "categories.do_all_cat",   ct_boolean },
   { "Set CPU speed when leaving",    "Whether the next setting is applied or not",              "0",                "minimenu.use_run_speed",  ct_boolean },
   { "CPU speed when leaving",        "Before running app, set this speed; app may override.",   "500",              "minimenu.run_speed",      ct_cpu_speed },
   { "Show 'All' tab",                "Whethor an All tab is shown or not",                      "1",                "categories.do_all_cat",   ct_boolean },
+  { "Show directory browser tabs",   "Show a tab for each SD card?",                            "0",                "filesystem.do_browser",   ct_boolean },
   { "Start with app selected",       "Whethor selection is placed by default or not",           "0",                "minimenu.start_selected", ct_boolean },
   { "Wrap tab change",               "Changing tab left or right, does it wrap around?",        "0",                "tabs.wraparound",         ct_boolean },
   { "Grid stop vertical",            "Changing selection up or down, does it stop or wrap?",    "0",                "grid.wrap_vert_stop",     ct_boolean },
   { "Start with app selected",       "Whethor selection is placed by default or not",           "0",                "minimenu.start_selected", ct_boolean },
   { "Wrap tab change",               "Changing tab left or right, does it wrap around?",        "0",                "tabs.wraparound",         ct_boolean },
   { "Grid stop vertical",            "Changing selection up or down, does it stop or wrap?",    "0",                "grid.wrap_vert_stop",     ct_boolean },
index 514d2b5..684ab81 100644 (file)
@@ -824,3 +824,29 @@ void emit_and_run ( char *buffer ) {
 
   return;
 }
 
   return;
 }
+
+// this code was swiped from pnd_utility pnd_exec_no_wait_1 as it became a little too minimenu-specific to remain there
+void exec_raw_binary ( char *fullpath ) {
+  int i;
+
+  if ( ( i = fork() ) < 0 ) {
+    printf ( "ERROR: Couldn't fork()\n" );
+    return;
+  }
+
+  if ( i ) {
+    return; // parent process, don't care
+  }
+
+  // child process, do something
+  execl ( "/bin/sh", "/bin/sh", "-c", fullpath, (char*) NULL );
+  //execl ( fullpath, fullpath, (char*) NULL );
+
+  // error invoking something, and we're the child process, so just die before all hell breaks lose with us thinking we're the (second!) parent on return!
+  exit ( -1 );
+
+  // getting here is an error
+  //printf ( "Error attempting to run %s\n", fullpath );
+
+  return;
+}
index 1d3868d..4a5ea36 100644 (file)
@@ -21,6 +21,7 @@ typedef enum {
 
 void emit_and_quit ( char *s );      // normal case; quit and run an app
 void emit_and_run ( char *buffer );  // odd case; run an app and stay alive
 
 void emit_and_quit ( char *s );      // normal case; quit and run an app
 void emit_and_run ( char *buffer );  // odd case; run an app and stay alive
+void exec_raw_binary ( char *fullpath ); // just fork/exec something, without exit
 
 void applications_free ( void );
 void applications_scan ( void );
 
 void applications_free ( void );
 void applications_scan ( void );
index 08d8dac..a43797a 100644 (file)
@@ -45,6 +45,8 @@
 #define CHANGED_EVERYTHING  (1<<4)  /* redraw it all! */
 unsigned int render_mask = CHANGED_EVERYTHING;
 
 #define CHANGED_EVERYTHING  (1<<4)  /* redraw it all! */
 unsigned int render_mask = CHANGED_EVERYTHING;
 
+#define MIMETYPE_EXE "/usr/bin/file"     /* check for file type prior to invocation */
+
 /* SDL
  */
 SDL_Surface *sdl_realscreen = NULL;
 /* SDL
  */
 SDL_Surface *sdl_realscreen = NULL;
@@ -1048,6 +1050,10 @@ void ui_process_input ( unsigned char block_p ) {
        // timer went off, time to load something
        if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.load_previews_later", 0 ) ) {
 
        // timer went off, time to load something
        if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.load_previews_later", 0 ) ) {
 
+         if ( ! ui_selected ) {
+           break;
+         }
+
          // load the preview pics now!
          pnd_disco_t *iter = ui_selected -> ref;
 
          // load the preview pics now!
          pnd_disco_t *iter = ui_selected -> ref;
 
@@ -1636,17 +1642,21 @@ void ui_push_exec ( void ) {
 
       } else {
        // go down
 
       } else {
        // go down
-       strcat ( g_categories [ ui_category].fspath, "/" );
-       strcat ( g_categories [ ui_category].fspath, ui_selected -> ref -> title_en );
+       char *temp = malloc ( strlen ( g_categories [ ui_category].fspath ) + strlen ( ui_selected -> ref -> title_en ) + 1 + 1 );
+       sprintf ( temp, "%s/%s", g_categories [ ui_category].fspath, ui_selected -> ref -> title_en );
+       free ( g_categories [ ui_category].fspath );
+       g_categories [ ui_category].fspath = temp;
+       //strcat ( g_categories [ ui_category].fspath, "/" );
+       //strcat ( g_categories [ ui_category].fspath, ui_selected -> ref -> title_en );
       }
 
       pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ].catname, g_categories [ ui_category ].fspath );
 
       }
 
       pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ].catname, g_categories [ ui_category ].fspath );
 
-      // rescan the dir
-      category_fs_restock ( &(g_categories [ ui_category ]) );
       // forget the selection, nolonger applies
       ui_selected = NULL;
       ui_set_selected ( ui_selected );
       // forget the selection, nolonger applies
       ui_selected = NULL;
       ui_set_selected ( ui_selected );
+      // rescan the dir
+      category_fs_restock ( &(g_categories [ ui_category ]) );
       // redraw the grid
       render_mask |= CHANGED_SELECTION;
 
       // redraw the grid
       render_mask |= CHANGED_SELECTION;
 
@@ -1675,7 +1685,38 @@ void ui_push_exec ( void ) {
 
        // is it even executable? if we don't have handlers for non-executables yet (Jan 2011 we don't),
        // then don't even try to run things not-flagged as executable.. but wait most people are on
 
        // is it even executable? if we don't have handlers for non-executables yet (Jan 2011 we don't),
        // then don't even try to run things not-flagged as executable.. but wait most people are on
-       // FAT filesystems, what a drag, we can't tell.
+       // FAT filesystems, what a drag, we can't tell at the fs level.
+       // ... but we can still invoke 'file' and grep out the good bits, at least.
+       //
+       // open a stream reading 'file /path/to/file' and check output for 'executable'
+       // -- not checking for "ARM" so it can pick up x86 (or whatever native) executables in build environment
+       unsigned char is_executable = 0;
+
+       // popen test
+       {
+         char popenbuf [ FILENAME_MAX ];
+         snprintf ( popenbuf, FILENAME_MAX, "%s %s/%s", MIMETYPE_EXE, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en );
+
+         FILE *marceau;
+         if ( ! ( marceau = popen ( popenbuf, "r" ) ) ) {
+           return; // error, we need some useful error handling and dialog boxes here
+         }
+
+         if ( fgets ( popenbuf, FILENAME_MAX, marceau ) ) {
+           //printf ( "File test returns: %s\n", popenbuf );
+           if ( strstr ( popenbuf, "executable" ) != NULL ) {
+             is_executable = 1;
+           }
+         }
+
+         pclose ( marceau );
+
+       } // popen test
+
+       if ( ! is_executable ) {
+         fprintf ( stderr, "ERROR: File to invoke is not executable, skipping. (%s)\n", ui_selected -> ref -> title_en );
+         return; // need some error handling here
+       }
 
 #if 0 // eat up any pending SDL events and toss 'em?
        {
 
 #if 0 // eat up any pending SDL events and toss 'em?
        {
@@ -1689,13 +1730,22 @@ void ui_push_exec ( void ) {
 
 #if 1
        // just exec it
 
 #if 1
        // just exec it
+       //
+
+       // get CWD so we can restore it on return
        char cwd [ PATH_MAX ];
        getcwd ( cwd, PATH_MAX );
 
        char cwd [ PATH_MAX ];
        getcwd ( cwd, PATH_MAX );
 
+       // full path to executable so we don't rely on implicit "./"
+       char execbuf [ FILENAME_MAX ];
+       snprintf ( execbuf, FILENAME_MAX, "%s/%s", g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en );
+
+       // do it!
        chdir ( g_categories [ ui_category ].fspath );
        chdir ( g_categories [ ui_category ].fspath );
-       pnd_exec_no_wait_1 ( ui_selected -> ref -> title_en, NULL );
+       exec_raw_binary ( execbuf /*ui_selected -> ref -> title_en*/ );
        chdir ( cwd );
 #else
        chdir ( cwd );
 #else
+       // DEPRECATED / NOT TESTED
        // get mmwrapper to run it
        char buffer [ PATH_MAX ];
        sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en );
        // get mmwrapper to run it
        char buffer [ PATH_MAX ];
        sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en );