/* * config.c: Routines to read/write the vtxrc-file * * $Id: config.c,v 1.5 1997/07/13 02:22:21 mb Exp mb $ * * Copyright (c) 1994-96 Martin Buck * Read COPYING for more information * */ #include #include #include #include #include #include #include #include "vtx_assert.h" #include "safe_malloc.h" #include "misc.h" #include "postscript.h" #include "tvchannels.h" #include "xinit.h" #include "config.h" #include "pglayout_1_1.xbm" #include "pglayout_1_2.xbm" #include "pglayout_2_2.xbm" #include "pglayout_2_3.xbm" #include "pglayout_1_1l.xbm" #include "pglayout_2_1l.xbm" #include "pglayout_2_2l.xbm" #include "pglayout_3_2l.xbm" #include "pglayout_3_3l.xbm" const scr_update_t update_table[] = { { "None", 3 }, { "Slow", 2 }, { "Fast", 0 } }; const int update_table_count = 3; typedef struct { char *spooldir, *tv_system; char *printer[PRN_COUNT]; vtxdisp_t display_mode; int update_speed, font; pglayout_t layout; ps_papertype_t papersize; int popup_rows[POPUP_COUNT]; /* Entries for POPUP_TOPTEXT/FASTEXT are unused */ placement_t popup_placement[POPUP_COUNT]; int popup_startup[POPUP_COUNT]; int decoration[WM_COUNT]; int menudefault[MENU_COUNT]; unsigned tv_disp : 1; unsigned interlace : 1; unsigned sticky_fcs : 1; unsigned group_iconify : 1; unsigned auto_top : 1; unsigned auto_search : 1; unsigned auto_reset : 1; unsigned cont_queue_search : 1; unsigned cont_search : 1; unsigned spool_only : 1; unsigned top_sorted : 1; unsigned blinkdis : 1; } config_t; static config_t conf; static const char *placement_str[] = { "centered", "left", "right", "top", "bottom" }; static const char *bool_str[] = { "false", "true" }; #define XBMDATA(name) name##_bits, name##_width, name##_height pglayout_data_t pglayout_data[] = { { 1, 1, FALSE, XBMDATA(pglayout_1_1) }, { 1, 2, FALSE, XBMDATA(pglayout_1_2) }, { 2, 2, FALSE, XBMDATA(pglayout_2_2) }, { 2, 3, FALSE, XBMDATA(pglayout_2_3) }, { 1, 1, TRUE, XBMDATA(pglayout_1_1l) }, { 2, 1, TRUE, XBMDATA(pglayout_2_1l) }, { 2, 2, TRUE, XBMDATA(pglayout_2_2l) }, { 3, 2, TRUE, XBMDATA(pglayout_3_2l) }, { 3, 3, TRUE, XBMDATA(pglayout_3_3l) }, { 0, 0, 0, NULL, 0, 0 } }; #undef XBMDATA static int lookup_menuname(menuent_t men, const char *tag) { int ent; if (*tag == '\0') { return 2; } for (ent = 0; menu_tags[men][ent]; ent++) { if (!strcasecmp(tag, menu_tags[men][ent])) { return ent + 2; } } return 2; } int config_parse_bool(const char *key, const char *val, const char *name, int *retval, int *invalid) { if (!name || !strcasecmp(key, name)) { if (!strcasecmp(val, "true") || !strcmp(val, "1")) { *retval = TRUE; } else if (!strcasecmp(val, "false") || !strcmp(val, "0")) { *retval = FALSE; } else { *invalid = TRUE; return FALSE; } return TRUE; } return FALSE; } int config_parse_int(const char *key, const char *val, const char *name, int min, int max, int base, int *retval, int *invalid) { char *tail; int tmpval; if (!name || !strcasecmp(key, name)) { tmpval = strtol(val, &tail, base); if (*val && *tail == '\0' && tmpval >= min && tmpval <= max) { *retval = tmpval; return TRUE; } else { *invalid = TRUE; return FALSE; } } return FALSE; } void config_init(void) { int printer, popup, men; const char *tv_system; config_set_spooldir(""); if (tvch_chan2freq(NULL, NULL, &tv_system, NULL) < 0) { config_set_tvsystem(""); } else { config_set_tvsystem(tv_system); } for (printer = 0; printer < PRN_COUNT; printer++) { config_set_printer(printer, "|lpr"); } config_set_display_mode(DISPOFF); config_set_update_speed(1); config_set_font(0); config_set_layout(LAYOUT_1_2); config_set_papersize(PAPER_A4); for (popup = 0; popup < POPUP_COUNT; popup++) { switch(popup) { case POPUP_HISTORY: config_set_popup_rows(popup, 9); break; case POPUP_HOTLIST: config_set_popup_rows(popup, 11); break; case POPUP_SELST: config_set_popup_rows(popup, 5); break; } config_set_placement(popup, PLACEMENT_CENTER); config_set_startup(popup, FALSE); } config_set_tv_disp(FALSE); config_set_interlace(TRUE); config_set_sticky_fcs(FALSE); config_set_group_iconify(TRUE); config_set_auto_top(FALSE); config_set_auto_search(FALSE); config_set_auto_reset(TRUE); config_set_cont_queue_search(TRUE); config_set_cont_search(FALSE); config_set_spool_only(FALSE); config_set_top_sorted(TRUE); config_set_blinkdis(FALSE); config_set_wmdeco(WM_OFS_X, 0); config_set_wmdeco(WM_OFS_Y, 0); config_set_wmdeco(WM_LB, 0); config_set_wmdeco(WM_RB, 0); config_set_wmdeco(WM_TB, 0); config_set_wmdeco(WM_BB, 0); config_set_wmdeco(WM_ADJUSTED, WM_ADJ_NONE); for (men = 0; men < MENU_COUNT; men++) { config_set_menudefault(men, 2); } } int config_load(const char *fname, int private) { int err, invalid, lcount = 0, popup_p, popup_s, tmpval; char line[256], token[100], value[100], tmpstr[100]; FILE *file; if (!(file = fopen(fname, "r"))) { return -1; } while (1) { if (!fgets(line, sizeof(line), file)) { if (feof(file)) break; err = errno; fclose(file); errno = err; return -1; } lcount++; value[0] = '\0'; popup_p = popup_s = -1; invalid = FALSE; if (line[0] == '#' || sscanf(line, " %1c ", tmpstr) <= 0) { /* Skip comments or empty lines */ continue; } else if (sscanf(line, " %99[^\1- =] %1[=] %99[^\1-\37] ", token, tmpstr, value) < 2) { fprintf(stderr, "%s:%d: Warning: Syntax error, line ignored:\n%s\n", fname, lcount, line); continue; } if (!strcasecmp(token, "font")) { int font; for (font = 0; font <= vtxmaxfont; font++) { if (!strcasecmp(value, vtxfonts[font].fontname)) { config_set_font(font); break; } } if (font > vtxmaxfont) { invalid = TRUE; } } else if (!strcasecmp(token, "screen_updates")) { int speed; invalid = TRUE; for (speed = 0; speed < update_table_count; speed++) { if (!strcasecmp(value, update_table[speed].menu_string)) { config_set_update_speed(speed); invalid = FALSE; break; } } } else if (!strcasecmp(token, "pagelayout")) { int xpages, ypages, layout; invalid = TRUE; tmpstr[0] = '\0'; if (sscanf(value, " %d x %d %99c ", &xpages, &ypages, tmpstr) >= 2) { for (layout = 0; pglayout_data[layout].bits; layout++) { if (((pglayout_data[layout].landscape && !strcasecmp("_landscape", tmpstr)) || (!pglayout_data[layout].landscape && !strlen(tmpstr))) && pglayout_data[layout].xpages == xpages && pglayout_data[layout].ypages == ypages) { config_set_layout(layout); invalid = FALSE; break; } } } } else if (!strcasecmp(token, "papersize")) { int size; invalid = TRUE; for (size = 0; ps_paperdata[size].name; size++) { if (!strcasecmp(value, ps_paperdata[size].name)) { config_set_papersize(size); invalid = FALSE; break; } } } else if (!strcasecmp(token, "history_placement")) { popup_p = POPUP_HISTORY; } else if (!strcasecmp(token, "toptext_placement")) { popup_p = POPUP_TOPTEXT; } else if (!strcasecmp(token, "fastext_placement")) { popup_p = POPUP_FASTEXT; } else if (!strcasecmp(token, "search_placement")) { popup_p = POPUP_SEARCH; } else if (!strcasecmp(token, "hotlist_placement")) { popup_p = POPUP_HOTLIST; } else if (!strcasecmp(token, "stationlist_placement")) { popup_p = POPUP_SELST; } else if (!strcasecmp(token, "history_startup")) { popup_s = POPUP_HISTORY; } else if (!strcasecmp(token, "toptext_startup")) { popup_s = POPUP_TOPTEXT; } else if (!strcasecmp(token, "fastext_startup")) { popup_s = POPUP_FASTEXT; } else if (!strcasecmp(token, "search_startup")) { popup_s = POPUP_SEARCH; } else if (!strcasecmp(token, "hotlist_startup")) { popup_s = POPUP_HOTLIST; } else if (!strcasecmp(token, "stationlist_startup")) { popup_s = POPUP_SELST; } else if (!strcasecmp(token, "display_mode")) { if (!strcasecmp(value, "normal")) { config_set_display_mode(DISPNORM); } else if (!strcasecmp(value, "transparent")) { config_set_display_mode(DISPTRANS); } else if (!strcasecmp(value, "insert")) { config_set_display_mode(DISPINS); } else { invalid = TRUE; } } else if (!strcasecmp(token, "spooldir")) { config_set_spooldir(value); } else if (!strcasecmp(token, "tv_system")) { if (tvch_chan2freq(value, NULL, NULL, NULL) >= 0) { config_set_tvsystem(value); } else { fprintf(stderr, "%s:%d: Warning: TV system unknown, line ignored:\n%s\n", fname, lcount, line); } } else if (!strcasecmp(token, "default_cps_printer")) { config_set_printer(PRN_CPS, value); } else if (!strcasecmp(token, "default_ps_printer")) { config_set_printer(PRN_PS, value); } else if (!strcasecmp(token, "default_ascii_printer")) { config_set_printer(PRN_ASCII, value); } else if (!strcasecmp(token, "default_bm_printer")) { config_set_printer(PRN_BM, value); } else if (!strcasecmp(token, "wm_offset")) { if (strcasecmp(value, "auto")) { int x, y; if (sscanf(value, "%d , %d", &x, &y) != 2 || x < -50 || x > 50 || y < -50 || y > 50) { invalid = TRUE; x = y = 0; } config_set_wmdeco(WM_OFS_X, x); config_set_wmdeco(WM_OFS_Y, y); config_set_wmdeco(WM_ADJUSTED, WM_ADJ_CONFIG); } } else if (!strcasecmp(token, "wm_decoration")) { if (strcasecmp(value, "auto")) { int lb, rb, tb, bb; if (sscanf(value, "%d , %d , %d , %d", &lb, &rb, &tb, &bb) != 4 || lb < 0 || lb > 50 || rb < 0 || rb > 50 || tb < 0 || tb > 50 || bb < 0 || bb > 50) { invalid = TRUE; lb = rb = bb = 10; tb = 30; } config_set_wmdeco(WM_LB, lb); config_set_wmdeco(WM_RB, rb); config_set_wmdeco(WM_TB, tb); config_set_wmdeco(WM_BB, bb); config_set_wmdeco(WM_ADJUSTED, WM_ADJ_CONFIG); } } else if (!strcasecmp(token, "file_menudefault")) { config_set_menudefault(FILE_MENU, lookup_menuname(FILE_MENU, value)); } else if (!strcasecmp(token, "win_menudefault")) { config_set_menudefault(WINDOW_MENU, lookup_menuname(WINDOW_MENU, value)); } else if (!strcasecmp(token, "opt_menudefault")) { config_set_menudefault(OPT_MENU, lookup_menuname(OPT_MENU, value)); } else if (config_parse_bool(token, value, "auto_reset", &tmpval, &invalid)) { config_set_auto_reset(tmpval); } else if (config_parse_bool(token, value, "cont_queue_search", &tmpval, &invalid)) { config_set_cont_queue_search(tmpval); /* FIXME: Recognize old cont_hot_search for compatibility with Version 0.6. Remove this * after 0.7 */ } else if (config_parse_bool(token, value, "cont_hot_search", &tmpval, &invalid)) { fprintf(stderr, "%s: Warning: Obsolete entry 'cont_hot_search' found in %s.\n" "Please re-save your global options.\n", smalloc_progname, fname); config_set_cont_queue_search(tmpval); } else if (config_parse_bool(token, value, "cont_search", &tmpval, &invalid)) { config_set_cont_search(tmpval); } else if (config_parse_bool(token, value, "display_on_tv", &tmpval, &invalid)) { config_set_tv_disp(tmpval); } else if (config_parse_bool(token, value, "use_interlace", &tmpval, &invalid)) { config_set_interlace(tmpval); } else if (config_parse_bool(token, value, "toptext_when_active", &tmpval, &invalid)) { config_set_auto_top(tmpval); } else if (config_parse_bool(token, value, "search_on_match", &tmpval, &invalid)) { config_set_auto_search(tmpval); } else if (config_parse_bool(token, value, "sticky_filechoosers", &tmpval, &invalid)) { config_set_sticky_fcs(tmpval); } else if (config_parse_bool(token, value, "group_iconify", &tmpval, &invalid)) { config_set_group_iconify(tmpval); } else if (config_parse_bool(token, value, "spool_only", &tmpval, &invalid)) { config_set_spool_only(tmpval); } else if (config_parse_bool(token, value, "toptext_sorted", &tmpval, &invalid)) { config_set_top_sorted(tmpval); } else if (config_parse_bool(token, value, "disable_blinking", &tmpval, &invalid)) { config_set_blinkdis(tmpval); } else if (config_parse_int(token, value, "stationlist_lines", 5, 50, 10, &tmpval, &invalid)) { config_set_popup_rows(POPUP_SELST, tmpval); } else if (config_parse_int(token, value, "hotlist_lines", 11, 50, 10, &tmpval, &invalid)) { config_set_popup_rows(POPUP_HOTLIST, tmpval); } else if (config_parse_int(token, value, "history_lines", 9, 50, 10, &tmpval, &invalid)) { config_set_popup_rows(POPUP_HISTORY, tmpval); } else if (!invalid) { fprintf(stderr, "%s:%d: Warning: Syntax error, line ignored:\n%s\n", fname, lcount, line); } if (popup_p != -1) { placement_t placement; for (placement = PLACEMENT_CENTER; placement < PLACEMENT_COUNT; placement++) { if (!strcasecmp(placement_str[placement], value)) { config_set_placement(popup_p, placement); break; } } if (placement >= PLACEMENT_COUNT) { invalid = TRUE; } } else if (popup_s != -1) { if (config_parse_bool(NULL, value, NULL, &tmpval, &invalid)) { config_set_startup(popup_s, tmpval); } } if (invalid) { fprintf(stderr, "%s:%d: Warning: Invalid value, line ignored:\n%s\n", fname, lcount, line); } } return fclose(file); } int config_save(const char *fname) { int err, layout; FILE *file; if ((file = fopen(fname, "w"))) { fprintf(file, "# This file was created by " VTXWINNAME ", Version " VTXVERSION "\n\n"); fprintf(file, "font=%s\n", vtxfonts[config_get_font()].fontname); fprintf(file, "screen_updates=%c%s\n\n", tolower(*update_table[config_get_update_speed()].menu_string), update_table[config_get_update_speed()].menu_string + 1); fprintf(file, "history_placement=%s\n", placement_str[config_get_placement(POPUP_HISTORY)]); fprintf(file, "toptext_placement=%s\n", placement_str[config_get_placement(POPUP_TOPTEXT)]); fprintf(file, "fastext_placement=%s\n", placement_str[config_get_placement(POPUP_FASTEXT)]); fprintf(file, "search_placement=%s\n", placement_str[config_get_placement(POPUP_SEARCH)]); fprintf(file, "hotlist_placement=%s\n", placement_str[config_get_placement(POPUP_HOTLIST)]); fprintf(file, "stationlist_placement=%s\n", placement_str[config_get_placement(POPUP_SELST)]); fprintf(file, "history_startup=%s\n", bool_str[config_get_startup(POPUP_HISTORY)]); fprintf(file, "toptext_startup=%s\n", bool_str[config_get_startup(POPUP_TOPTEXT)]); fprintf(file, "fastext_startup=%s\n", bool_str[config_get_startup(POPUP_FASTEXT)]); fprintf(file, "search_startup=%s\n", bool_str[config_get_startup(POPUP_SEARCH)]); fprintf(file, "hotlist_startup=%s\n", bool_str[config_get_startup(POPUP_HOTLIST)]); fprintf(file, "stationlist_startup=%s\n", bool_str[config_get_startup(POPUP_SELST)]); fprintf(file, "toptext_when_active=%s\n", (config_get_auto_top() ? "true" : "false")); fprintf(file, "search_on_match=%s\n", (config_get_auto_search() ? "true" : "false")); fprintf(file, "sticky_filechoosers=%s\n", (config_get_sticky_fcs() ? "true" : "false")); fprintf(file, "group_iconify=%s\n\n", (config_get_group_iconify() ? "true" : "false")); fprintf(file, "stationlist_lines=%d\n", config_get_popup_rows(POPUP_SELST)); fprintf(file, "hotlist_lines=%d\n", config_get_popup_rows(POPUP_HOTLIST)); fprintf(file, "history_lines=%d\n\n", config_get_popup_rows(POPUP_HISTORY)); fprintf(file, "file_menudefault=%s\n", menu_tags[FILE_MENU][config_get_menudefault(FILE_MENU) - 2]); fprintf(file, "win_menudefault=%s\n", menu_tags[WINDOW_MENU][config_get_menudefault(WINDOW_MENU) - 2]); fprintf(file, "opt_menudefault=%s\n\n", menu_tags[OPT_MENU][config_get_menudefault(OPT_MENU) - 2]); fprintf(file, "display_on_tv=%s\n", (config_get_tv_disp() ? "true" : "false")); fprintf(file, "use_interlace=%s\n", (config_get_interlace() ? "true" : "false")); fprintf(file, "display_mode=%s\n\n", (config_get_display_mode() == DISPNORM ? "normal" : (config_get_display_mode() == DISPTRANS ? "transparent" : "insert"))); fprintf(file, "tv_system=%s\n\n", config_get_tvsystem()); fprintf(file, "auto_reset=%s\n", (config_get_auto_reset() ? "true" : "false")); fprintf(file, "cont_queue_search=%s\n", (config_get_cont_queue_search() ? "true" : "false")); fprintf(file, "cont_search=%s\n", (config_get_cont_search() ? "true" : "false")); fprintf(file, "toptext_sorted=%s\n", (config_get_top_sorted() ? "true" : "false")); fprintf(file, "disable_blinking=%s\n\n", (config_get_blinkdis() ? "true" : "false")); fprintf(file, "spooldir=%s\n", config_get_spooldir()); fprintf(file, "spool_only=%s\n", (config_get_spool_only() ? "true" : "false")); fprintf(file, "default_cps_printer=%s\n", config_get_printer(PRN_CPS)); fprintf(file, "default_ps_printer=%s\n", config_get_printer(PRN_PS)); fprintf(file, "default_ascii_printer=%s\n", config_get_printer(PRN_ASCII)); fprintf(file, "default_bm_printer=%s\n\n", config_get_printer(PRN_BM)); layout = config_get_layout(); fprintf(file, "pagelayout=%dx%d%s\n", pglayout_data[layout].xpages, pglayout_data[layout].ypages, (pglayout_data[layout].landscape ? "_landscape" : "")); fprintf(file, "papersize=%s\n\n", ps_paperdata[config_get_papersize()].name); if (config_get_wmdeco(WM_ADJUSTED) == WM_ADJ_CONFIG) { fprintf(file, "wm_offset=%d,%d\n", config_get_wmdeco(WM_OFS_X), config_get_wmdeco(WM_OFS_Y)); fprintf(file, "wm_decoration=%d,%d,%d,%d\n", config_get_wmdeco(WM_LB), config_get_wmdeco(WM_RB), config_get_wmdeco(WM_TB), config_get_wmdeco(WM_BB)); } else { fprintf(file, "wm_offset=auto\nwm_decoration=auto\n"); } } if (!file || ferror(file) || fclose(file)) { err = errno; if (file) { fclose(file); } errno = err; return -1; } return 0; } const char* config_get_printer(printer_t printer) { return conf.printer[printer]; } void config_set_printer(printer_t printer, const char *str) { free(conf.printer[printer]); conf.printer[printer] = sstrdup(str); } const char* config_get_spooldir(void) { return conf.spooldir; } void config_set_spooldir(const char *str) { free(conf.spooldir); conf.spooldir = sstrdup(str); } int config_get_tv_disp(void) { return conf.tv_disp; } void config_set_tv_disp(int val) { conf.tv_disp = !!val; } int config_get_interlace(void) { return conf.interlace; } void config_set_interlace(int val) { conf.interlace = !!val; } int config_get_sticky_fcs(void) { return conf.sticky_fcs; } void config_set_sticky_fcs(int val) { conf.sticky_fcs = !!val; } int config_get_group_iconify(void) { return conf.group_iconify; } void config_set_group_iconify(int val) { conf.group_iconify = !!val; } int config_get_auto_top(void) { return conf.auto_top; } void config_set_auto_top(int val) { conf.auto_top = !!val; } int config_get_auto_search(void) { return conf.auto_search; } void config_set_auto_search(int val) { conf.auto_search = !!val; } int config_get_auto_reset(void) { return conf.auto_reset; } void config_set_auto_reset(int val) { conf.auto_reset = !!val; } int config_get_cont_queue_search(void) { return conf.cont_queue_search; } void config_set_cont_queue_search(int val) { conf.cont_queue_search = !!val; } int config_get_cont_search(void) { return conf.cont_search; } void config_set_cont_search(int val) { conf.cont_search = !!val; } vtxdisp_t config_get_display_mode(void) { return conf.display_mode; } void config_set_display_mode(vtxdisp_t val) { conf.display_mode = val; } int config_get_update_speed(void) { return conf.update_speed; } void config_set_update_speed(int val) { conf.update_speed = val; } int config_get_popup_rows(popup_t popup) { return conf.popup_rows[popup]; } void config_set_popup_rows(popup_t popup, int val) { conf.popup_rows[popup] = val; } placement_t config_get_placement(popup_t popup) { return conf.popup_placement[popup]; } void config_set_placement(popup_t popup, placement_t val) { conf.popup_placement[popup] = val; } int config_get_startup(popup_t popup) { return conf.popup_startup[popup]; } void config_set_startup(popup_t popup, int val) { conf.popup_startup[popup] = !!val; } int config_get_font(void) { return conf.font; } void config_set_font(int val) { conf.font = val; } int config_get_wmdeco(wmdeco_t wm) { return conf.decoration[wm]; } void config_set_wmdeco(wmdeco_t wm, int val) { conf.decoration[wm] = val; } int config_get_spool_only(void) { return conf.spool_only; } void config_set_spool_only(int val) { conf.spool_only = !!val; } int config_get_top_sorted(void) { return conf.top_sorted; } void config_set_top_sorted(int val) { conf.top_sorted = !!val; } pglayout_t config_get_layout(void) { return conf.layout; } void config_set_layout(pglayout_t val) { conf.layout = val; } ps_papertype_t config_get_papersize(void) { return conf.papersize; } void config_set_papersize(ps_papertype_t val) { conf.papersize = val; } const char * config_get_tvsystem(void) { return conf.tv_system; } void config_set_tvsystem(const char *tv_system) { free(conf.tv_system); conf.tv_system = sstrdup(tv_system); } int config_get_menudefault(menuent_t men) { return conf.menudefault[men]; } void config_set_menudefault(menuent_t men, int val) { conf.menudefault[men] = val; } int config_get_blinkdis(void) { return conf.blinkdis; } void config_set_blinkdis(int val) { conf.blinkdis = !!val; }