Handle case when no apps are present at all (rescan after eject, say), and hit up
[pandora-libraries.git] / minimenu / mmenu.c
index 96b5c3d..279b57c 100644 (file)
@@ -54,8 +54,11 @@ pnd_box_handle *g_active_apps = NULL;
 unsigned int g_active_appcount = 0;
 char g_username [ 128 ]; // since we have to wait for login (!!), store username here
 pnd_conf_handle g_conf = 0;
+pnd_conf_handle g_desktopconf = 0;
 
 char *pnd_run_script = NULL;
+char *g_skinpath = NULL;
+unsigned char g_x11_present = 1; // >0 if X is present
 
 int main ( int argc, char *argv[] ) {
   int logall = -1; // -1 means normal logging rules; >=0 means log all!
@@ -153,12 +156,40 @@ int main ( int argc, char *argv[] ) {
     emit_and_quit ( MM_QUIT );
   }
 
+  g_desktopconf = pnd_conf_fetch_by_id ( pnd_conf_desktop, PND_CONF_SEARCHPATH );
+
+  if ( ! g_desktopconf ) {
+    pnd_log ( pndn_error, "ERROR: Couldn't fetch desktop conf file\n" );
+    emit_and_quit ( MM_QUIT );
+  }
+
   // redo log filter
   pnd_log_set_filter ( pnd_conf_get_as_int_d ( g_conf, "minimenu.loglevel", pndn_error ) );
 
   /* setup
    */
 
+  // X11?
+  if ( pnd_conf_get_as_char ( g_conf, "minimenu.x11_present_sh" ) ) {
+    FILE *fx = popen ( pnd_conf_get_as_char ( g_conf, "minimenu.x11_present_sh" ), "r" );
+    char buffer [ 100 ];
+    if ( fx ) {
+      if ( fgets ( buffer, 100, fx ) ) {
+       if ( atoi ( buffer ) ) {
+         g_x11_present = 1;
+         pnd_log ( pndn_rem, "X11 seems to be present [pid %u]\n", atoi(buffer) );
+       } else {
+         g_x11_present = 0;
+         pnd_log ( pndn_rem, "X11 seems NOT to be present\n" );
+       }
+      } else {
+         g_x11_present = 0;
+         pnd_log ( pndn_rem, "X11 seems NOT to be present\n" );
+      }
+      pclose ( fx );
+    }
+  } // x11?
+
   // pnd_run.sh
   pnd_run_script = pnd_locate_filename ( pnd_conf_get_as_char ( g_conf, "minimenu.pndrun" ), "pnd_run.sh" );
 
@@ -167,6 +198,33 @@ int main ( int argc, char *argv[] ) {
     emit_and_quit ( MM_QUIT );
   }
 
+  pnd_run_script = strdup ( pnd_run_script ); // so we don't lose it next pnd_locate
+
+  pnd_log ( pndn_rem, "Found pnd_run.sh at '%s'\n", pnd_run_script );
+
+  // figure out skin path
+  if ( ! pnd_conf_get_as_char ( g_conf, MMENU_ARTPATH ) ||
+       ! pnd_conf_get_as_char ( g_conf, "minimenu.font" )
+     )
+  {
+    pnd_log ( pndn_error, "ERROR: Couldn't set up skin!\n" );
+    emit_and_quit ( MM_QUIT );
+  }
+
+  g_skinpath = pnd_locate_filename ( pnd_conf_get_as_char ( g_conf, MMENU_ARTPATH ),
+                                    pnd_conf_get_as_char ( g_conf, "minimenu.font" ) );
+
+  if ( ! g_skinpath ) {
+    pnd_log ( pndn_error, "ERROR: Couldn't locate skin font!\n" );
+    emit_and_quit ( MM_QUIT );
+  }
+
+  g_skinpath = strdup ( g_skinpath ); // so we don't lose it next pnd_locate
+
+  * strstr ( g_skinpath, pnd_conf_get_as_char ( g_conf, "minimenu.font" ) ) = '\0';
+
+  pnd_log ( pndn_debug, "Looks like skin is at '%s'\n", g_skinpath );
+
   // attempt to set up UI
   if ( ! ui_setup() ) {
     pnd_log ( pndn_error, "ERROR: Couldn't set up the UI!\n" );
@@ -177,20 +235,115 @@ int main ( int argc, char *argv[] ) {
   ui_loadscreen();
 
   // set up static image cache
-  if ( ! ui_imagecache ( pnd_conf_get_as_char ( g_conf, MMENU_ARTPATH ) ) ) {
+  if ( ! ui_imagecache ( g_skinpath ) ) {
     pnd_log ( pndn_error, "ERROR: Couldn't set up static UI image cache!\n" );
     emit_and_quit ( MM_QUIT );
   }
 
   /* inhale applications, icons, categories, etc
    */
+  applications_scan();
+
+  /* actual work now
+   */
+
+  while ( 1 ) { // forever!
+
+    // show the menu, or changes thereof
+    ui_render ( CHANGED_NOTHING );
+
+    // wait for input or time-based events (like animations)
+    // deal with inputs
+    ui_process_input ( 1 /* block */ );
+
+    // sleep? block?
+    usleep ( 5000 );
+
+  } // while
+
+  return ( 0 );
+}
+
+void emit_and_quit ( char *s ) {
+  printf ( "%s\n", s );
+  exit ( 0 );
+}
+
+void applications_free ( void ) {
+
+  // free up all our category apprefs, but keep the preview and icon cache's..
+  category_freeall();
+
+  // free up old disco_t
+  if ( g_active_apps ) {
+    pnd_disco_t *p = pnd_box_get_head ( g_active_apps );
+    pnd_disco_t *n;
+    while ( p ) {
+      n = pnd_box_get_next ( p );
+      pnd_disco_destroy ( p );
+      p = n;
+    }
+    pnd_box_delete ( g_active_apps );
+  }
+
+  return;
+}
+
+void applications_scan ( void ) {
 
   // show disco screen
   ui_discoverscreen ( 1 /* clear screen */ );
 
   // determine current app list, cache icons
-  pnd_log ( pndn_debug, "Looking for pnd applications here: %s\n", pnd_conf_get_as_char ( g_conf, MMENU_APP_SEARCHPATH ) );
-  g_active_apps = pnd_disco_search ( pnd_conf_get_as_char ( g_conf, MMENU_APP_SEARCHPATH ), NULL ); // ignore overrides for now
+  // - ignore overrides for now
+
+  g_active_apps = 0;
+  pnd_box_handle merge_apps = 0;
+
+  // desktop apps?
+  if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.desktop_apps", 1 ) ) {
+    pnd_log ( pndn_debug, "Looking for pnd applications here: %s\n",
+             pnd_conf_get_as_char ( g_desktopconf, "desktop.searchpath" ) );
+    g_active_apps = pnd_disco_search ( pnd_conf_get_as_char ( g_desktopconf, "desktop.searchpath" ), NULL );
+  }
+
+  // menu apps?
+  if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.menu_apps", 1 ) ) {
+    pnd_log ( pndn_debug, "Looking for pnd applications here: %s\n",
+             pnd_conf_get_as_char ( g_desktopconf, "menu.searchpath" ) );
+    merge_apps = pnd_disco_search ( pnd_conf_get_as_char ( g_desktopconf, "menu.searchpath" ), NULL );
+  }
+
+  // merge lists
+  if ( merge_apps ) {
+    if ( g_active_apps ) {
+      // got menu apps, and got desktop apps, merge
+      pnd_box_append ( g_active_apps, merge_apps );
+    } else {
+      // got menu apps, had no desktop apps, so just assign
+      g_active_apps = merge_apps;
+    }
+  }
+
+  // aux apps?
+  char *aux_apps = NULL;
+  merge_apps = 0;
+  aux_apps = pnd_conf_get_as_char ( g_conf, "minimenu.aux_searchpath" );
+  if ( aux_apps && aux_apps [ 0 ] ) {
+    pnd_log ( pndn_debug, "Looking for pnd applications here: %s\n", aux_apps );
+    merge_apps = pnd_disco_search ( aux_apps, NULL );
+  }
+
+  // merge aux apps
+  if ( merge_apps ) {
+    if ( g_active_apps ) {
+      pnd_box_append ( g_active_apps, merge_apps );
+    } else {
+      g_active_apps = merge_apps;
+    }
+  }
+
+  // do it
   g_active_appcount = pnd_box_get_size ( g_active_apps );
 
   unsigned char maxwidth, maxheight;
@@ -225,52 +378,58 @@ int main ( int argc, char *argv[] ) {
       }
     } // preview now?
 
-    // push to All category
-    // we do this first, so first category is always All
-    if ( ! category_push ( CATEGORY_ALL, iter ) ) {
-      pnd_log ( pndn_warning, "  Couldn't categorize to All: '%s'\n", IFNULL(iter -> title_en, "No Name") );
-    }
-
-    // push the categories
+    // push the categories .. or suppress application
     //
+    if ( ( pnd_pxml_get_x11 ( iter -> option_no_x11 ) != pnd_pxml_x11_required ) ||
+        ( pnd_pxml_get_x11 ( iter -> option_no_x11 ) == pnd_pxml_x11_required && g_x11_present == 1 )
+       )
+    {
 
-    // main categories
-    if ( iter -> main_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) ) {
-      if ( ! category_push ( iter -> main_category, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category, IFNULL(iter -> title_en, "No Name") );
+      // push to All category
+      // we do this first, so first category is always All
+      if ( ! category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter ) ) {
+       pnd_log ( pndn_warning, "  Couldn't categorize to All: '%s'\n", IFNULL(iter -> title_en, "No Name") );
       }
-    }
 
-    if ( iter -> main_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) ) {
-      if ( ! category_push ( iter -> main_category1, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category1, IFNULL(iter -> title_en, "No Name") );
+      // main categories
+      if ( iter -> main_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) ) {
+       if ( ! category_push ( iter -> main_category, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category, IFNULL(iter -> title_en, "No Name") );
+       }
       }
-    }
 
-    if ( iter -> main_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) ) {
-      if ( ! category_push ( iter -> main_category2, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category2, IFNULL(iter -> title_en, "No Name") );
+      if ( iter -> main_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) ) {
+       if ( ! category_push ( iter -> main_category1, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category1, IFNULL(iter -> title_en, "No Name") );
+       }
       }
-    }
 
-    // alt categories
-    if ( iter -> alt_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) ) {
-      if ( ! category_push ( iter -> alt_category, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category, IFNULL(iter -> title_en, "No Name") );
+      if ( iter -> main_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) ) {
+       if ( ! category_push ( iter -> main_category2, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category2, IFNULL(iter -> title_en, "No Name") );
+       }
       }
-    }
 
-    if ( iter -> alt_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) ) {
-      if ( ! category_push ( iter -> alt_category1, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category1, IFNULL(iter -> title_en, "No Name") );
+      // alt categories
+      if ( iter -> alt_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) ) {
+       if ( ! category_push ( iter -> alt_category, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category, IFNULL(iter -> title_en, "No Name") );
+       }
       }
-    }
 
-    if ( iter -> alt_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) ) {
-      if ( ! category_push ( iter -> alt_category2, iter ) ) {
-       pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category2, IFNULL(iter -> title_en, "No Name") );
+      if ( iter -> alt_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) ) {
+       if ( ! category_push ( iter -> alt_category1, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category1, IFNULL(iter -> title_en, "No Name") );
+       }
       }
-    }
+
+      if ( iter -> alt_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) ) {
+       if ( ! category_push ( iter -> alt_category2, iter ) ) {
+         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category2, IFNULL(iter -> title_en, "No Name") );
+       }
+      }
+
+    } // register with categories or filter out
 
     // next
     iter = pnd_box_get_next ( iter );
@@ -279,27 +438,5 @@ int main ( int argc, char *argv[] ) {
   // dump categories
   //category_dump();
 
-  /* actual work now
-   */
-
-  while ( 1 ) { // forever!
-
-    // show the menu, or changes thereof
-    ui_render ( CHANGED_NOTHING );
-
-    // wait for input or time-based events (like animations)
-    // deal with inputs
-    ui_process_input ( 1 /* block */ );
-
-    // sleep? block?
-    usleep ( 5000 );
-
-  } // while
-
-  return ( 0 );
-}
-
-void emit_and_quit ( char *s ) {
-  printf ( "%s\n", s );
-  exit ( 0 );
+  return;
 }