/* * Template for export modules */ /* $Id: exp-templ.c,v 1.8 2006/02/10 06:25:37 mschimek Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include "export.h" typedef struct tmpl_instance { /* Common to all export modules */ vbi_export export; /* Our private stuff */ /* Options */ int flip; int day; int prime; double quality; char * comment; int weekday; int counter; } tmpl_instance; /* Safer than tmpl_instance *tmpl = (tmpl_instance *)(vbi_export *) e */ #define TMPL(e) PARENT(e, tmpl_instance, export); static vbi_export * tmpl_new(void) { tmpl_instance *tmpl; if (!(tmpl = calloc(1, sizeof(*tmpl)))) return NULL; /* * The caller will initialize tmpl->export.class for us * and reset all options to their defaults, we only * have to initialize our private stuff. */ tmpl->counter = 0; return &tmpl->export; } static void tmpl_delete(vbi_export *e) { tmpl_instance *tmpl = TMPL(e); /* Uninitialize our private stuff and options */ if (tmpl->comment) free(tmpl->comment); free(tmpl); } /* convenience */ #define elements(array) (sizeof(array) / sizeof(array[0])) /* N_(), _() are NLS functions, see info gettext. */ static const char * string_menu_items[] = { N_("Sunday"), N_("Monday"), N_("Tuesday"), N_("Wednesday"), N_("Thursday"), N_("Friday"), N_("Saturday") }; static int int_menu_items[] = { 1, 3, 5, 7, 11, 13, 17, 19 }; static vbi_option_info tmpl_options[] = { VBI_OPTION_BOOL_INITIALIZER /* * Option keywords must be unique within their module * and shall contain only "AZaz09_" (be filesystem safe that is). * Note "network", "creator" and "reveal" are reserved generic * options, filtered by the export api functions. */ ("flip", N_("Boolean option"), FALSE, N_("This is a boolean option")), VBI_OPTION_INT_RANGE_INITIALIZER ("day", N_("Select a month day"), /* default, min, max, step, has no tooltip */ 13, 1, 31, 1, NULL), VBI_OPTION_INT_MENU_INITIALIZER ("prime", N_("Select a prime"), 0, int_menu_items, elements(int_menu_items), N_("Default is the first, '1'")), VBI_OPTION_REAL_RANGE_INITIALIZER ("quality", N_("Compression quality"), 100, 1, 100, 0.01, NULL), /* VBI_OPTION_REAL_MENU_INITIALIZER like int */ VBI_OPTION_STRING_INITIALIZER ("comment", N_("Add a comment"), "default comment", N_("Another tooltip")), VBI_OPTION_MENU_INITIALIZER ("weekday", N_("Select a weekday"), 2, string_menu_items, 7, N_("Default is Tuesday")) }; /* * Enumerate our options (optional if we have no options). * Instead of using a table one could also dynamically create * vbi_option_info's in tmpl_instance. */ static vbi_option_info * option_enum(vbi_export *e, int index) { e = e; /* Enumeration 0 ... n */ if (index < 0 || index >= (int) elements(tmpl_options)) return NULL; return tmpl_options + index; } #define KEYWORD(str) (strcmp(keyword, str) == 0) /* * Get an option (optional if we have no options). */ static vbi_bool option_get(vbi_export *e, const char *keyword, vbi_option_value *value) { tmpl_instance *tmpl = TMPL(e); if (KEYWORD("flip")) { value->num = tmpl->flip; } else if (KEYWORD("day")) { value->num = tmpl->day; } else if (KEYWORD("prime")) { value->num = tmpl->prime; } else if (KEYWORD("quality")) { value->dbl = tmpl->quality; } else if (KEYWORD("comment")) { if (!(value->str = vbi_export_strdup(e, NULL, tmpl->comment ? tmpl->comment : ""))) return FALSE; } else if (KEYWORD("weekday")) { value->num = tmpl->weekday; } else { vbi_export_unknown_option(e, keyword); return FALSE; } return TRUE; /* success */ } /* * Set an option (optional if we have no options). */ static vbi_bool option_set(vbi_export *e, const char *keyword, va_list args) { tmpl_instance *tmpl = TMPL(e); if (KEYWORD("flip")) { tmpl->flip = !!va_arg(args, int); } else if (KEYWORD("day")) { int day = va_arg(args, int); /* or clamp */ if (day < 1 || day > 31) { vbi_export_invalid_option(e, keyword, day); return FALSE; } tmpl->day = day; } else if (KEYWORD("prime")) { unsigned int i; unsigned int d, dmin = UINT_MAX; int value = va_arg(args, int); /* or return an error */ for (i = 0; i < elements(int_menu_items); i++) if ((d = abs(int_menu_items[i] - value)) < dmin) { tmpl->prime = int_menu_items[i]; dmin = d; } } else if (KEYWORD("quality")) { double quality = va_arg(args, double); /* or return an error */ if (quality < 1) quality = 1; else if (quality > 100) quality = 100; tmpl->quality = quality; } else if (KEYWORD("comment")) { char *comment = va_arg(args, char *); /* Note the option remains unchanged in case of error */ if (!vbi_export_strdup(e, &tmpl->comment, comment)) return FALSE; } else if (KEYWORD("weekday")) { int day = va_arg(args, int); /* or return an error */ tmpl->weekday = day % 7; } else { vbi_export_unknown_option(e, keyword); return FALSE; } return TRUE; /* success */ } /* * The output function, mandatory. */ static vbi_bool export(vbi_export *e, FILE *fp, vbi_page *pg) { tmpl_instance *tmpl = TMPL(e); /* * Write pg to fp, that's all. */ fp = fp; pg = pg; tmpl->counter++; /* just for fun */ /* * Should any of the module functions return unsuccessful * they better post a description of the problem. * Parameters like printf, no linefeeds '\n' please. */ /* vbi_export_error_printf(_("Writing failed: %s"), strerror(errno)); */ return FALSE; /* no success (since we didn't write anything) */ } /* * Let's describe us. * You can leave away assignments unless mandatory. */ static vbi_export_info info_tmpl = { /* The mandatory keyword must be unique and shall contain only "AZaz09_" */ .keyword = "templ", /* When omitted this module can still be used by libzvbi clients but won't be listed in a UI. */ .label = N_("Template"), .tooltip = N_("This is just an export template"), .mime_type = "misc/example", .extension = "tmpl", }; vbi_export_class vbi_export_class_tmpl = { ._public = &info_tmpl, /* Functions to allocate and free a tmpl_class vbi_export instance. When you omit these, libzvbi will allocate a bare struct vbi_export */ ._new = tmpl_new, ._delete = tmpl_delete, /* Functions to enumerate, read and write options */ .option_enum = option_enum, .option_get = option_get, .option_set = option_set, /* Function to export a page, mandatory */ .export = export }; /* * This is a constructor calling vbi_register_export_module(). * (Commented out since we don't want to register the example module.) */ #if 0 VBI_AUTOREG_EXPORT_MODULE(vbi_export_class_tmpl) #endif