00001 /* 00002 * Template for export modules 00003 */ 00004 00005 /* $Id: exp-templ.c,v 1.8 2006/02/10 06:25:37 mschimek Exp $ */ 00006 00007 #ifdef HAVE_CONFIG_H 00008 # include "config.h" 00009 #endif 00010 00011 #include <stdio.h> 00012 #include <stdlib.h> 00013 #include <string.h> 00014 #include <errno.h> 00015 #include <limits.h> 00016 00017 #include "export.h" 00018 00019 typedef struct tmpl_instance 00020 { 00021 /* Common to all export modules */ 00022 vbi_export export; 00023 00024 /* Our private stuff */ 00025 00026 /* Options */ 00027 int flip; 00028 int day; 00029 int prime; 00030 double quality; 00031 char * comment; 00032 int weekday; 00033 00034 int counter; 00035 } tmpl_instance; 00036 00037 /* Safer than tmpl_instance *tmpl = (tmpl_instance *)(vbi_export *) e */ 00038 #define TMPL(e) PARENT(e, tmpl_instance, export); 00039 00040 static vbi_export * 00041 tmpl_new(void) 00042 { 00043 tmpl_instance *tmpl; 00044 00045 if (!(tmpl = calloc(1, sizeof(*tmpl)))) 00046 return NULL; 00047 00048 /* 00049 * The caller will initialize tmpl->export.class for us 00050 * and reset all options to their defaults, we only 00051 * have to initialize our private stuff. 00052 */ 00053 00054 tmpl->counter = 0; 00055 00056 return &tmpl->export; 00057 } 00058 00059 static void 00060 tmpl_delete(vbi_export *e) 00061 { 00062 tmpl_instance *tmpl = TMPL(e); 00063 00064 /* Uninitialize our private stuff and options */ 00065 00066 if (tmpl->comment) 00067 free(tmpl->comment); 00068 00069 free(tmpl); 00070 } 00071 00072 /* convenience */ 00073 #define elements(array) (sizeof(array) / sizeof(array[0])) 00074 00075 /* N_(), _() are NLS functions, see info gettext. */ 00076 static const char * 00077 string_menu_items[] = { 00078 N_("Sunday"), N_("Monday"), N_("Tuesday"), 00079 N_("Wednesday"), N_("Thursday"), N_("Friday"), N_("Saturday") 00080 }; 00081 00082 static int 00083 int_menu_items[] = { 00084 1, 3, 5, 7, 11, 13, 17, 19 00085 }; 00086 00087 static vbi_option_info 00088 tmpl_options[] = { 00089 VBI_OPTION_BOOL_INITIALIZER 00090 /* 00091 * Option keywords must be unique within their module 00092 * and shall contain only "AZaz09_" (be filesystem safe that is). 00093 * Note "network", "creator" and "reveal" are reserved generic 00094 * options, filtered by the export api functions. 00095 */ 00096 ("flip", N_("Boolean option"), 00097 FALSE, N_("This is a boolean option")), 00098 VBI_OPTION_INT_RANGE_INITIALIZER 00099 ("day", N_("Select a month day"), 00100 /* default, min, max, step, has no tooltip */ 00101 13, 1, 31, 1, NULL), 00102 VBI_OPTION_INT_MENU_INITIALIZER 00103 ("prime", N_("Select a prime"), 00104 0, int_menu_items, elements(int_menu_items), 00105 N_("Default is the first, '1'")), 00106 VBI_OPTION_REAL_RANGE_INITIALIZER 00107 ("quality", N_("Compression quality"), 00108 100, 1, 100, 0.01, NULL), 00109 /* VBI_OPTION_REAL_MENU_INITIALIZER like int */ 00110 VBI_OPTION_STRING_INITIALIZER 00111 ("comment", N_("Add a comment"), 00112 "default comment", N_("Another tooltip")), 00113 VBI_OPTION_MENU_INITIALIZER 00114 ("weekday", N_("Select a weekday"), 00115 2, string_menu_items, 7, N_("Default is Tuesday")) 00116 }; 00117 00118 /* 00119 * Enumerate our options (optional if we have no options). 00120 * Instead of using a table one could also dynamically create 00121 * vbi_option_info's in tmpl_instance. 00122 */ 00123 static vbi_option_info * 00124 option_enum(vbi_export *e, int index) 00125 { 00126 e = e; 00127 00128 /* Enumeration 0 ... n */ 00129 if (index < 0 || index >= (int) elements(tmpl_options)) 00130 return NULL; 00131 00132 return tmpl_options + index; 00133 } 00134 00135 #define KEYWORD(str) (strcmp(keyword, str) == 0) 00136 00137 /* 00138 * Get an option (optional if we have no options). 00139 */ 00140 static vbi_bool 00141 option_get(vbi_export *e, const char *keyword, vbi_option_value *value) 00142 { 00143 tmpl_instance *tmpl = TMPL(e); 00144 00145 if (KEYWORD("flip")) { 00146 value->num = tmpl->flip; 00147 } else if (KEYWORD("day")) { 00148 value->num = tmpl->day; 00149 } else if (KEYWORD("prime")) { 00150 value->num = tmpl->prime; 00151 } else if (KEYWORD("quality")) { 00152 value->dbl = tmpl->quality; 00153 } else if (KEYWORD("comment")) { 00154 if (!(value->str = vbi_export_strdup(e, NULL, 00155 tmpl->comment ? tmpl->comment : ""))) 00156 return FALSE; 00157 } else if (KEYWORD("weekday")) { 00158 value->num = tmpl->weekday; 00159 } else { 00160 vbi_export_unknown_option(e, keyword); 00161 return FALSE; 00162 } 00163 00164 return TRUE; /* success */ 00165 } 00166 00167 /* 00168 * Set an option (optional if we have no options). 00169 */ 00170 static vbi_bool 00171 option_set(vbi_export *e, const char *keyword, va_list args) 00172 { 00173 tmpl_instance *tmpl = TMPL(e); 00174 00175 if (KEYWORD("flip")) { 00176 tmpl->flip = !!va_arg(args, int); 00177 } else if (KEYWORD("day")) { 00178 int day = va_arg(args, int); 00179 00180 /* or clamp */ 00181 if (day < 1 || day > 31) { 00182 vbi_export_invalid_option(e, keyword, day); 00183 return FALSE; 00184 } 00185 00186 tmpl->day = day; 00187 00188 } else if (KEYWORD("prime")) { 00189 unsigned int i; 00190 unsigned int d, dmin = UINT_MAX; 00191 int value = va_arg(args, int); 00192 00193 /* or return an error */ 00194 for (i = 0; i < elements(int_menu_items); i++) 00195 if ((d = abs(int_menu_items[i] - value)) < dmin) { 00196 tmpl->prime = int_menu_items[i]; 00197 dmin = d; 00198 } 00199 00200 } else if (KEYWORD("quality")) { 00201 double quality = va_arg(args, double); 00202 00203 /* or return an error */ 00204 if (quality < 1) 00205 quality = 1; 00206 else if (quality > 100) 00207 quality = 100; 00208 00209 tmpl->quality = quality; 00210 } else if (KEYWORD("comment")) { 00211 char *comment = va_arg(args, char *); 00212 00213 /* Note the option remains unchanged in case of error */ 00214 if (!vbi_export_strdup(e, &tmpl->comment, comment)) 00215 return FALSE; 00216 } else if (KEYWORD("weekday")) { 00217 int day = va_arg(args, int); 00218 00219 /* or return an error */ 00220 tmpl->weekday = day % 7; 00221 } else { 00222 vbi_export_unknown_option(e, keyword); 00223 return FALSE; 00224 } 00225 00226 return TRUE; /* success */ 00227 } 00228 00229 /* 00230 * The output function, mandatory. 00231 */ 00232 static vbi_bool 00233 export(vbi_export *e, FILE *fp, vbi_page *pg) 00234 { 00235 tmpl_instance *tmpl = TMPL(e); 00236 00237 /* 00238 * Write pg to fp, that's all. 00239 */ 00240 fp = fp; 00241 pg = pg; 00242 00243 tmpl->counter++; /* just for fun */ 00244 00245 /* 00246 * Should any of the module functions return unsuccessful 00247 * they better post a description of the problem. 00248 * Parameters like printf, no linefeeds '\n' please. 00249 */ 00250 /* 00251 vbi_export_error_printf(_("Writing failed: %s"), strerror(errno)); 00252 */ 00253 00254 return FALSE; /* no success (since we didn't write anything) */ 00255 } 00256 00257 /* 00258 * Let's describe us. 00259 * You can leave away assignments unless mandatory. 00260 */ 00261 static vbi_export_info 00262 info_tmpl = { 00263 /* The mandatory keyword must be unique and shall 00264 contain only "AZaz09_" */ 00265 .keyword = "templ", 00266 /* When omitted this module can still be used by 00267 libzvbi clients but won't be listed in a UI. */ 00268 .label = N_("Template"), 00269 .tooltip = N_("This is just an export template"), 00270 00271 .mime_type = "misc/example", 00272 .extension = "tmpl", 00273 }; 00274 00275 vbi_export_class 00276 vbi_export_class_tmpl = { 00277 ._public = &info_tmpl, 00278 00279 /* Functions to allocate and free a tmpl_class vbi_export instance. 00280 When you omit these, libzvbi will allocate a bare struct vbi_export */ 00281 ._new = tmpl_new, 00282 ._delete = tmpl_delete, 00283 00284 /* Functions to enumerate, read and write options */ 00285 .option_enum = option_enum, 00286 .option_get = option_get, 00287 .option_set = option_set, 00288 00289 /* Function to export a page, mandatory */ 00290 .export = export 00291 }; 00292 00293 /* 00294 * This is a constructor calling vbi_register_export_module(). 00295 * (Commented out since we don't want to register the example module.) 00296 */ 00297 #if 0 00298 VBI_AUTOREG_EXPORT_MODULE(vbi_export_class_tmpl) 00299 #endif