Added 'same path' (as pnd file) overrides
authorskeezix <skeezix@flotsam-vm.(none)>
Mon, 22 Mar 2010 18:51:32 +0000 (14:51 -0400)
committerskeezix <skeezix@flotsam-vm.(none)>
Mon, 22 Mar 2010 18:51:32 +0000 (14:51 -0400)
Can now create foo.ovr (to go with foo.pnd), in same place as foo.pnd
The ovr file can override icon title, main and main-sub1 category, and clockspeed
Can also make foo.png in same location (end in .png) to override the icon
Icon override rquires client mods, so mmenu and pndnotifyd are fixed, need pmenu fixed

apps/pndnotifyd.c
include/pnd_container.h
include/pnd_pxml.h
lib/pnd_container.c
lib/pnd_discovery.c
minimenu/TODO.txt
minimenu/mmcache.c

index a883cd6..346ab25 100644 (file)
@@ -28,6 +28,7 @@
 #include "pnd_desktop.h"
 #include "pnd_logger.h"
 #include "pnd_dbusnotify.h"
+#include "pnd_pndfiles.h"
 
 // this piece of code was simpler once; but need to grow it a bit and in a rush
 // moving all these to globals rather than refactor the code a bit; tsk tsk..
@@ -693,17 +694,37 @@ void process_discoveries ( pnd_box_handle applist, char *emitdesktoppath, char *
 
       pnd_log ( pndn_debug, "  Icon not already present, so trying to write it! %s\n", existingpath );
 
+      // handle same-path icon override for davec :)
+      char ovrfile [ PATH_MAX ];
+      char *fixpxml;
+      sprintf ( ovrfile, "%s/%s", d -> object_path, d -> object_filename );
+      fixpxml = strcasestr ( ovrfile, PND_PACKAGE_FILEEXT );
+      if ( fixpxml ) {
+       strcpy ( fixpxml, ".png" );
+       fixpxml = NULL;
+       struct stat statbuf;
+       if ( stat ( ovrfile, &statbuf ) == 0 ) {
+         d -> icon = strdup ( ovrfile );
+         fixpxml = ovrfile; // !NULL will be the trigger to skip emittinf desktop from .pnd
+       } // stat
+      } // ovr?
+
       // attempt to create icon files; if successful, alter the disco struct to contain new
       // path, otherwise leave it alone (since it could be a generic icon reference..)
-      if ( pnd_emit_icon ( emiticonpath, d ) ) {
-       // success; fix up icon path to new one..
-       if ( d -> icon ) {
-         free ( d -> icon );
+      if ( fixpxml == NULL ) {
+       // don't have an same-path override icon, so go fetch something from pnd file
+
+       if ( pnd_emit_icon ( emiticonpath, d ) ) {
+         // success; fix up icon path to new one..
+         if ( d -> icon ) {
+           free ( d -> icon );
+         }
+         d -> icon = strdup ( existingpath );
+       } else {
+         pnd_log ( pndn_debug, "  WARN: Couldn't write out icon %s\n", existingpath );
        }
-       d -> icon = strdup ( existingpath );
-      } else {
-       pnd_log ( pndn_debug, "  WARN: Couldn't write out icon %s\n", existingpath );
-      }
+
+      } // got ovr icon already?
 
     } // icon already exists?
 
index d1c374f..e0ba9fd 100644 (file)
@@ -41,6 +41,7 @@ void *pnd_box_allocinsert ( pnd_box_handle box, char *key, unsigned int size );
 
 /* find_by_key() will attempt to locate a payload based on the specified key.
  * Returns the payload pointer or NULL if not found.
+ * CASE INSENSITIVE.
  */
 void *pnd_box_find_by_key ( pnd_box_handle box, char *key );
 
index 1cc2df3..405268e 100644 (file)
@@ -14,6 +14,9 @@ extern "C" {
 
 #define PXML_MAXAPPS 20 /* max number of <application>'s within a single PXML */
 
+// for DaveC, we will support same-path-as-.pnd file override, that is simple format and not XML
+#define PXML_SAMEPATH_OVERRIDE_FILEEXT ".ovr" /* ./foo/bar.pnd could have overrides in ./foo/bar.ovr */
+
 // use this handle to interact with PXML; this hides the mechanics of parsing a PXML file so that
 // it can be upgraded with impacting applications
 typedef void* pnd_pxml_handle;
index e08080a..38657ab 100644 (file)
@@ -115,7 +115,7 @@ void *pnd_box_find_by_key ( pnd_box_handle box, char *key ) {
 
   while ( n ) {
 
-    if ( strcmp ( n -> key, key ) == 0 ) {
+    if ( strcasecmp ( n -> key, key ) == 0 ) {
       return ( NODE2PAYLOAD(n) );
     }
 
index eeee25e..a2ac551 100644 (file)
@@ -2,6 +2,9 @@
 #include <stdio.h> /* for FILE etc */
 #include <stdlib.h> /* for malloc */
 #include <unistd.h> /* for unlink */
+#include <limits.h> /* for PATH_MAX */
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #define __USE_GNU /* for strcasestr */
 #include <string.h> /* for making ftw.h happy */
@@ -17,6 +20,7 @@
 #include "pnd_apps.h"
 #include "pnd_pndfiles.h"
 #include "pnd_logger.h"
+#include "pnd_conf.h"
 
 // need these 'globals' due to the way nftw and ftw work :/
 static pnd_box_handle disco_box;
@@ -165,6 +169,10 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
     return ( 0 ); // continue tree walk
   }
 
+  // for ovr-file
+  char ovrfile [ PATH_MAX ];
+  pnd_box_handle ovrh = 0; // 0 didn't try, -1 tried and failed, >0 tried and got
+
   // iterate across apps in the PXML
   pxmlappiter = pxmlapps;
   while ( 1 ) {
@@ -175,11 +183,6 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       break; // all done
     }
 
-    // look for any overrides, if requested
-    if ( disco_overrides ) {
-      pnd_pxml_merge_override ( pxmlh, disco_overrides );
-    }
-
     // check for validity and add to resultset if it looks executable
     if ( pnd_is_pxml_valid_app ( pxmlh ) ) {
       pnd_disco_t *p;
@@ -281,6 +284,77 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
        p -> info_type = strdup ( pnd_pxml_get_info_type ( pxmlh ) );
       }
 
+      // look for any PXML overrides, if requested
+      if ( disco_overrides ) {
+       pnd_pxml_merge_override ( pxmlh, disco_overrides );
+      }
+
+      // handle ovr overrides
+      // try to load a same-path-as-pnd override file
+      if ( ovrh == 0 ) {
+       sprintf ( ovrfile, "%s/%s", p -> object_path, p -> object_filename );
+       fixpxml = strcasestr ( ovrfile, PND_PACKAGE_FILEEXT );
+       if ( fixpxml ) {
+         strcpy ( fixpxml, PXML_SAMEPATH_OVERRIDE_FILEEXT );
+         struct stat statbuf;
+         if ( stat ( ovrfile, &statbuf ) == 0 ) {
+           ovrh = pnd_conf_fetch_by_path ( ovrfile );
+
+           if ( ! ovrh ) {
+             // couldn't pull conf out of file, so don't try again
+             ovrh = (void*)(-1);
+           }
+
+         } else {
+           ovrh = (void*)(-1); // not found, don't try again
+         } // stat
+       } // can find .pnd
+      } // tried ovr yet?
+
+      // is ovr file open?
+      if ( ovrh != 0 && ovrh != (void*)(-1) ) {
+       // pull in appropriate values
+       char key [ 100 ];
+       char *v;
+
+       // title
+       snprintf ( key, 100, "Application-%u.title", p -> subapp_number );
+       pnd_log ( PND_LOG_DEFAULT, "find key %s\n", key );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         pnd_log ( PND_LOG_DEFAULT, "   find key %s\n", key );
+         if ( p -> title_en ) {
+           free ( p -> title_en );
+         }
+         p -> title_en = strdup ( v );
+       }
+
+       // clockspeed
+       snprintf ( key, 100, "Application-%u.clockspeed", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> clockspeed ) {
+           free ( p -> clockspeed );
+         }
+         p -> clockspeed = strdup ( v );
+       }
+
+       // categories
+       snprintf ( key, 100, "Application-%u.maincategory", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> main_category ) {
+           free ( p -> main_category );
+         }
+         p -> main_category = strdup ( v );
+       }
+       snprintf ( key, 100, "Application-%u.maincategorysub1", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> main_category1 ) {
+           free ( p -> main_category1 );
+         }
+         p -> main_category1 = strdup ( v );
+       }
+
+      } // got ovr conf loaded?
+
     } else {
       //printf ( "Invalid PXML; skipping.\n" );
     }
@@ -290,6 +364,11 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
 
   } // while pxmlh is good
 
+  // free up ovr
+  if ( ovrh != 0 && ovrh != (void*)(-1) ) {
+    pnd_box_delete ( ovrh );
+  }
+
   // free up the applist
   free ( pxmlapps );
 
index 43f1a8d..7bd6174 100644 (file)
@@ -6,9 +6,6 @@
 - libpnd: appdata-dir-name?
 
 - About screen and shoutouts // konami code?
-- override
-  - .desktop in same place as .pnd, override category
-  - icon
 
 - deploy..
   - .desktop for deployment, for running from xfce
index 61f6615..48a023d 100644 (file)
@@ -1,10 +1,25 @@
 
+#include <stdio.h> /* for FILE etc */
+#include <stdlib.h> /* for malloc */
+#include <unistd.h> /* for unlink */
+#include <limits.h> /* for PATH_MAX */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define __USE_GNU /* for strcasestr */
+#include <string.h> /* for making ftw.h happy */
+
+#include <fcntl.h>
 #include <limits.h>
 
 #include "SDL.h"
 #include "SDL_image.h"
 #include "SDL_rotozoom.h"
 
+#define __USE_GNU /* for strcasestr */
+#include <unistd.h> /* for unlink */
+#include <string.h> /* for making ftw.h happy */
+
 #include "pnd_pxml.h"
 #include "pnd_utility.h"
 #include "pnd_conf.h"
@@ -118,11 +133,37 @@ unsigned char cache_icon ( pnd_disco_t *app, unsigned char maxwidth, unsigned ch
 
   // not cached, load it up
   //
-
-  // pull icon into buffer
+  unsigned char *iconbuf = NULL;
   unsigned int buflen = 0;
-  unsigned char *iconbuf;
-  iconbuf = pnd_emit_icon_to_buffer ( app, &buflen );
+
+  // same-path override?
+  char ovrfile [ PATH_MAX ];
+  char *fixpxml;
+  sprintf ( ovrfile, "%s/%s", app -> object_path, app -> object_filename );
+  fixpxml = strcasestr ( ovrfile, PND_PACKAGE_FILEEXT );
+  if ( fixpxml ) {
+    strcpy ( fixpxml, ".png" );
+    struct stat statbuf;
+    if ( stat ( ovrfile, &statbuf ) == 0 ) {
+      buflen = statbuf.st_size;
+      if ( ( iconbuf = malloc ( statbuf.st_size ) ) ) {
+       int fd = open ( ovrfile, O_RDONLY );
+       if ( fd >= 0 ) {
+         if ( read ( fd, iconbuf, statbuf.st_size ) != statbuf.st_size ) {
+           free ( iconbuf );
+           close ( fd );
+           return ( 0 );
+         }
+         close ( fd );
+       } // open
+      } // malloc
+    } // stat
+  } // ovr?
+
+  // pull icon into buffer from .pnd
+  if ( ! iconbuf ) {
+    iconbuf = pnd_emit_icon_to_buffer ( app, &buflen );
+  }
 
   if ( ! iconbuf ) {
     return ( 0 );