From e8e8f91cff96eebc1b440df18d9c3ef4ced1ca60 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Thu, 23 Jan 2014 06:07:38 +0100 Subject: [PATCH] Read interface config from one file (which can be set as command line argument) instead of whole directory tree. --- confclient/interface_conf | 97 +++++ confclient/keybindings_global | 16 - confclient/keybindings_wingeom | 8 - confclient/keybindings_winkeys | 3 - confclient/windows/Win_0 | 7 - confclient/windows/Win_1 | 7 - confclient/windows/Win_2 | 7 - confclient/windows/Win_c | 8 - confclient/windows/Win_i | 4 - confclient/windows/Win_k | 4 - confclient/windows/Win_l | 4 - confclient/windows/Win_m | 15 - confclient/windows/toggle_order_and_active | 2 - src/client/keybindings.c | 81 ++-- src/client/keybindings.h | 11 +- src/client/main.c | 6 +- src/client/misc.c | 87 ++++- src/client/misc.h | 3 + src/client/wincontrol.c | 423 ++++++++------------- src/client/wincontrol.h | 35 +- src/client/world.h | 1 + 21 files changed, 392 insertions(+), 437 deletions(-) create mode 100644 confclient/interface_conf delete mode 100644 confclient/keybindings_global delete mode 100644 confclient/keybindings_wingeom delete mode 100644 confclient/keybindings_winkeys delete mode 100644 confclient/windows/Win_0 delete mode 100644 confclient/windows/Win_1 delete mode 100644 confclient/windows/Win_2 delete mode 100644 confclient/windows/Win_c delete mode 100644 confclient/windows/Win_i delete mode 100644 confclient/windows/Win_k delete mode 100644 confclient/windows/Win_l delete mode 100644 confclient/windows/Win_m delete mode 100644 confclient/windows/toggle_order_and_active diff --git a/confclient/interface_conf b/confclient/interface_conf new file mode 100644 index 0000000..fdc2609 --- /dev/null +++ b/confclient/interface_conf @@ -0,0 +1,97 @@ +81 quit +265 to_a_keywin +266 to_mapwin +267 to_infowin +268 to_inv +269 to_logwin +270 to_g_keywin +271 to_wg_keywin +272 to_wk_keywin +119 winconf +62 cyc_win_f +60 cyc_win_b +262 scrl_l +360 scrl_r +114 reload_conf +67 save_conf +% +258 shift_f +259 shift_b +42 grow_h +95 shri_h +43 grow_v +45 shri_v +121 to_height_t +120 to_width_t +% +258 w_keys_d +259 w_keys_u +10 w_keys_m +% +kmicl +m +% +0 +Global keys +-13 +29 +258 g_keys_d +259 g_keys_u +10 g_keys_m +% +1 +Window geometry keys +8 +29 +258 wg_keys_d +259 wg_keys_u +10 wg_keys_m +% +2 +Window keybinding keys +3 +29 +258 wk_keys_d +259 wk_keys_u +10 wk_keys_m +% +c +Inventory +5 +33 +100 drop +259 inv_u +258 inv_d +117 use +% +i +Info +3 +33 +% +k +Available keys +0 +29 +% +l +Log +-10 +33 +% +m +Map +0 +-64 +112 pick +58 wait +107 player_u +106 player_d +104 player_l +108 player_r +259 map_u +258 map_d +260 map_l +261 map_r +46 map_c +% diff --git a/confclient/keybindings_global b/confclient/keybindings_global deleted file mode 100644 index 739af7d..0000000 --- a/confclient/keybindings_global +++ /dev/null @@ -1,16 +0,0 @@ -81 quit -265 to_a_keywin -266 to_mapwin -267 to_infowin -268 to_inv -269 to_logwin -270 to_g_keywin -271 to_wg_keywin -272 to_wk_keywin -119 winconf -62 cyc_win_f -60 cyc_win_b -262 scrl_l -360 scrl_r -114 reload_conf -67 save_conf diff --git a/confclient/keybindings_wingeom b/confclient/keybindings_wingeom deleted file mode 100644 index d322501..0000000 --- a/confclient/keybindings_wingeom +++ /dev/null @@ -1,8 +0,0 @@ -258 shift_f -259 shift_b -42 grow_h -95 shri_h -43 grow_v -45 shri_v -121 to_height_t -120 to_width_t diff --git a/confclient/keybindings_winkeys b/confclient/keybindings_winkeys deleted file mode 100644 index 8a15320..0000000 --- a/confclient/keybindings_winkeys +++ /dev/null @@ -1,3 +0,0 @@ -258 w_keys_d -259 w_keys_u -10 w_keys_m diff --git a/confclient/windows/Win_0 b/confclient/windows/Win_0 deleted file mode 100644 index e79bdcd..0000000 --- a/confclient/windows/Win_0 +++ /dev/null @@ -1,7 +0,0 @@ -Global keys -0 --13 -29 -258 g_keys_d -259 g_keys_u -10 g_keys_m diff --git a/confclient/windows/Win_1 b/confclient/windows/Win_1 deleted file mode 100644 index 645c8c4..0000000 --- a/confclient/windows/Win_1 +++ /dev/null @@ -1,7 +0,0 @@ -Window geometry keys -1 -8 -29 -258 wg_keys_d -259 wg_keys_u -10 wg_keys_m diff --git a/confclient/windows/Win_2 b/confclient/windows/Win_2 deleted file mode 100644 index c1d9448..0000000 --- a/confclient/windows/Win_2 +++ /dev/null @@ -1,7 +0,0 @@ -Window keybinding keys -2 -3 -29 -258 wk_keys_d -259 wk_keys_u -10 wk_keys_m diff --git a/confclient/windows/Win_c b/confclient/windows/Win_c deleted file mode 100644 index b513c69..0000000 --- a/confclient/windows/Win_c +++ /dev/null @@ -1,8 +0,0 @@ -Inventory -c -5 -33 -100 drop -259 inv_u -258 inv_d -117 use diff --git a/confclient/windows/Win_i b/confclient/windows/Win_i deleted file mode 100644 index dfc519f..0000000 --- a/confclient/windows/Win_i +++ /dev/null @@ -1,4 +0,0 @@ -Info -i -3 -33 diff --git a/confclient/windows/Win_k b/confclient/windows/Win_k deleted file mode 100644 index ca67a5f..0000000 --- a/confclient/windows/Win_k +++ /dev/null @@ -1,4 +0,0 @@ -Available keys -k -0 -29 diff --git a/confclient/windows/Win_l b/confclient/windows/Win_l deleted file mode 100644 index e2fff52..0000000 --- a/confclient/windows/Win_l +++ /dev/null @@ -1,4 +0,0 @@ -Log -l --10 -33 diff --git a/confclient/windows/Win_m b/confclient/windows/Win_m deleted file mode 100644 index a83973f..0000000 --- a/confclient/windows/Win_m +++ /dev/null @@ -1,15 +0,0 @@ -Map -m -0 --64 -112 pick -58 wait -107 player_u -106 player_d -104 player_l -108 player_r -259 map_u -258 map_d -260 map_l -261 map_r -46 map_c diff --git a/confclient/windows/toggle_order_and_active b/confclient/windows/toggle_order_and_active deleted file mode 100644 index f188d83..0000000 --- a/confclient/windows/toggle_order_and_active +++ /dev/null @@ -1,2 +0,0 @@ -kmicl -m \ No newline at end of file diff --git a/src/client/keybindings.c b/src/client/keybindings.c index 500deec..e57e361 100644 --- a/src/client/keybindings.c +++ b/src/client/keybindings.c @@ -6,11 +6,8 @@ #include /* FILE, sprintf(), snprintf() */ #include /* uint8_t, uint16_t, uint32_t */ #include /* free(), atoi() */ -#include /* strlen(), strchr() */ -#include "../common/readwrite.h" /* try_fopen(), textfile_sizes(), try_fgets(), - * try_fclose(), try_fclose_unlink_rename(), - * try_fwrite() - */ +#include /* strlen(), strchr(), strcmp() */ +#include "../common/readwrite.h" /* textfile_sizes(), try_fgets(),try_fwrite()*/ #include "../common/try_malloc.h" /* try_malloc() */ #include "wincontrol.h" /* get_winconf_by_win() */ #include "windows.h" /* draw_all_wins() */ @@ -162,44 +159,10 @@ extern char * get_keyname_to_keycode(uint16_t keycode) -extern void init_keybindings(char * path, struct KeyBindingDB * kbd) +extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd, + char * delim) { - char * f_name = "init_keybindings()"; - FILE * file = try_fopen(path, "r", f_name); - uint32_t lines; - uint32_t linemax = textfile_sizes(file, &lines); - char command[linemax + 1]; - char * cmdptr; - struct KeyBinding ** loc_last_ptr = &kbd->kbs; - * loc_last_ptr = 0; - while (try_fgets(command, linemax + 1, file, f_name)) - { - if ('\n' == command[0] || 0 == command[0]) - { - break; - } - * loc_last_ptr = try_malloc(sizeof(struct KeyBinding), f_name); - struct KeyBinding * kb_p = * loc_last_ptr; - kb_p->next = 0; - kb_p->key = atoi(command); - cmdptr = strchr(command, ' ') + 1; - cmdptr[strlen(cmdptr) - 1] = '\0'; - kb_p->command = get_command(cmdptr); - loc_last_ptr = & kb_p->next; - } - try_fclose(file, f_name); - kbd->edit = 0; - kbd->select = 0; -} - - - -extern void save_keybindings(char * path, struct KeyBindingDB * kbd) -{ - char * f_name = "save_keybindings()"; - char path_tmp[strlen(path) + 4 + 1]; - sprintf(path_tmp, "%s_tmp", path); - FILE * file = try_fopen(path_tmp, "w", f_name); + char * f_name = "write_keybindings_to_file()"; uint16_t linemax = 0; struct KeyBinding * kb_p = kbd->kbs; while (0 != kb_p) @@ -210,16 +173,44 @@ extern void save_keybindings(char * path, struct KeyBindingDB * kbd) } kb_p = kb_p->next; } - linemax = linemax + 6; /* + 6 = + 3 digits + whitespace + \n + \0 */ + linemax = linemax + 6; /* + 6 = + 3 digits + ' ' + '\n' + '\0' */ char line[linemax]; kb_p = kbd->kbs; while (0 != kb_p) { - snprintf(line, linemax, "%d %s\n", kb_p->key, kb_p->command->dsc_short); + sprintf(line, "%d %s\n", kb_p->key, kb_p->command->dsc_short); try_fwrite(line, sizeof(char), strlen(line), file, f_name); kb_p = kb_p->next; } - try_fclose_unlink_rename(file, path_tmp, path, f_name); + try_fwrite(delim, strlen(delim), 1, file, f_name); +} + + + +extern void read_keybindings_from_file(char * line, uint32_t linemax, + FILE * file, struct KeyBindingDB * kbd) +{ + char * f_name = "read_keybindings_from_file()"; + char * cmdptr; + struct KeyBinding ** loc_last_ptr = &kbd->kbs; + * loc_last_ptr = 0; + while (try_fgets(line, linemax + 1, file, f_name)) + { + if (!strcmp("%\n", line)) + { + break; + } + * loc_last_ptr = try_malloc(sizeof(struct KeyBinding), f_name); + struct KeyBinding * kb_p = * loc_last_ptr; + kb_p->next = 0; + kb_p->key = atoi(line); + cmdptr = strchr(line, ' ') + 1; + cmdptr[strlen(cmdptr) - 1] = '\0'; + kb_p->command = get_command(cmdptr); + loc_last_ptr = & kb_p->next; + } + kbd->edit = 0; + kbd->select = 0; } diff --git a/src/client/keybindings.h b/src/client/keybindings.h index b191c59..d0cc001 100644 --- a/src/client/keybindings.h +++ b/src/client/keybindings.h @@ -7,6 +7,7 @@ #define KEYBINDINGS_H #include /* uint8_t, uint16_t */ +#include /* FILE */ struct Command; @@ -36,11 +37,11 @@ extern struct Command * get_command_to_keycode(struct KeyBinding * kb_p, */ extern char * get_keyname_to_keycode(uint16_t keycode); -/* Initialize/save keybindings data from/to file at "path" to/from keybindings - * data pointer "kbd". - */ -extern void init_keybindings(char * path, struct KeyBindingDB * kbd); -extern void save_keybindings(char * path, struct KeyBindingDB * kbd); +/* Read/write from/to "file" "kbd", delimited by "delim". */ +extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd, + char * delim); +extern void read_keybindings_from_file(char * line, uint32_t linemax, + FILE * file, struct KeyBindingDB * kbd); /* Free keybinding chain starting at "kb_start". */ extern void free_keybindings(struct KeyBinding * kb_start); diff --git a/src/client/main.c b/src/client/main.c index 51d5606..473228c 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -17,12 +17,16 @@ struct World world; -int main() +int main(int argc, char * argv[]) { char * f_name = "main()"; /* Declare hard-coded paths here. */ world.path_server_in = "server/in"; + world.path_interface_conf = "confclient/interface_conf"; + + /* Parse command line arguments. */ + obey_argv(argc, argv); /* So error exits also go through the client's cleanup() function. */ set_cleanup_func(cleanup); diff --git a/src/client/misc.c b/src/client/misc.c index 01cf1d2..ff1600c 100644 --- a/src/client/misc.c +++ b/src/client/misc.c @@ -3,41 +3,91 @@ #include "misc.h" #include /* delwin(), endwin(), refresh() */ #include /* uint8_t, uint16_t */ +#include /* sprintf() */ +#include /* exit(), free() */ #include /* memset(), strlen() */ +#include /* global optarg, getopt() */ +#include "../common/readwrite.h" /* try_fopen(), try_fclose(), + * try_fclose_unlink_rename(), + */ #include "cleanup.h" /* for set_cleanup_flag() */ -#include "keybindings.h" /* init_keybindings(), free_keybindings(), - * save_keybindings() +#include "keybindings.h" /* free_keybindings(), read_keybindings_from_file(), + * write_keybindings_to_file() */ #include "map_window.h" /* for map_center() */ -#include "wincontrol.h" /* struct WinConf, init_winconfs(), init_wins(), - * sorted_wintoggle_and_activate(), get_win_by_id(), - * get_winconf_by_win(), toggle_window(), - * get_next_winconf_id() +#include "wincontrol.h" /* struct WinConf, init_wins(), get_winconf_by_win(), + * sorted_win_toggle_and_activate(), get_win_by_id(), + * toggle_window(), write_winconf_of_id_to_file(), + * read_winconf_from_file(), get_next_winconf_id(), + * read_order_wins_visible_active(), + * write_order_wins_visible_active() */ #include "windows.h" /* struct Win, make_pad(), suspend_win(), free_win() */ #include "world.h" /* global world */ +extern void obey_argv(int argc, char * argv[]) +{ + int opt; + while (-1 != (opt = getopt(argc, argv, "i:"))) + { + if ('i' == opt) + { + world.path_interface_conf = optarg; + } + else + { + exit(EXIT_FAILURE); + } + } +} + + + extern void save_interface_conf() { - save_keybindings("confclient/keybindings_global", &world.kb_global); - save_keybindings("confclient/keybindings_wingeom", &world.kb_wingeom); - save_keybindings("confclient/keybindings_winkeys", &world.kb_winkeys); - save_win_configs(); + char * f_name = "save_interface_conf()"; + char * path = world.path_interface_conf; + char path_tmp[strlen(path) + 4 + 1]; + sprintf(path_tmp, "%s_tmp", path); + FILE * file = try_fopen(path_tmp, "w", f_name); + char * delim = "%\n"; + write_keybindings_to_file(file, &world.kb_global, delim); + write_keybindings_to_file(file, &world.kb_wingeom, delim); + write_keybindings_to_file(file, &world.kb_winkeys, delim); + write_order_wins_visible_active(file, delim); + uint8_t i; + for (i = 0; i < strlen(world.winconf_db.ids); i++) + { + write_winconf_of_id_to_file(file, world.winconf_db.ids[i], delim); + } + try_fclose_unlink_rename(file, path_tmp, path, f_name); } extern void load_interface_conf() { - init_keybindings("confclient/keybindings_global", &world.kb_global); - init_keybindings("confclient/keybindings_wingeom", &world.kb_wingeom); - init_keybindings("confclient/keybindings_winkeys", &world.kb_winkeys); - init_winconfs(); + char * f_name = "load_interface_conf()"; + + /* Read keybindings and WincConf DB from interface config file. */ + FILE * file = try_fopen(world.path_interface_conf, "r", f_name); + uint32_t linemax = textfile_sizes(file, NULL); + char line[linemax + 1]; + read_keybindings_from_file(line, linemax, file, &world.kb_global); + read_keybindings_from_file(line, linemax, file, &world.kb_wingeom); + read_keybindings_from_file(line, linemax, file, &world.kb_winkeys); + read_order_wins_visible_active(line, linemax, file); + while (read_winconf_from_file(line, linemax, file)); + try_fclose(file, f_name); + + /* Build windows as defined by read interface data and toggle them on. */ make_pad(); init_wins(); - sorted_wintoggle_and_activate(); + sorted_win_toggle_and_activate(); + + /* So that the interface config data and the window structs get freed. */ set_cleanup_flag(CLEANUP_INTERFACE); } @@ -46,8 +96,11 @@ extern void load_interface_conf() extern void unload_interface_conf() { free_keybindings(world.kb_global.kbs); + world.kb_global.kbs = NULL; free_keybindings(world.kb_wingeom.kbs); + world.kb_wingeom.kbs = NULL; free_keybindings(world.kb_winkeys.kbs); + world.kb_winkeys.kbs = NULL; while (0 != world.wmeta.active) { suspend_win(world.wmeta.active); @@ -70,8 +123,8 @@ extern void reset_windows() endwin(); /* "[S]tandard way" to recalibrate ncurses post SIGWINCH, says */ refresh(); /* . */ struct Win * w_p = world.wmeta.chain_start; - char win_ids[strlen(world.winconf_db.winconf_ids) + 1]; - memset(win_ids, '\0', strlen(world.winconf_db.winconf_ids) + 1); + char win_ids[strlen(world.winconf_db.ids) + 1]; + memset(win_ids, '\0', strlen(world.winconf_db.ids) + 1); uint8_t i = 0; char active = '\0'; for (; NULL != w_p; w_p = w_p->next, i++) diff --git a/src/client/misc.h b/src/client/misc.h index 31e3ee0..e849703 100644 --- a/src/client/misc.h +++ b/src/client/misc.h @@ -11,6 +11,9 @@ +/* Parses command line argument -i into client configuration. */ +extern void obey_argv(int argc, char * argv[]); + /* Save / load (init) / unload (free/dissolve) / reload interface configuration * data, world.wmeta.pad (initialized before opening any windows to the height * of the terminal screen and a width of 1) and window chains. diff --git a/src/client/wincontrol.c b/src/client/wincontrol.c index 01b9be8..275fc9c 100644 --- a/src/client/wincontrol.c +++ b/src/client/wincontrol.c @@ -2,15 +2,13 @@ #include "wincontrol.h" #include /* global errno */ -#include /* DIR, struct dirent, opendir(), closedir(), readdir() */ #include /* NULL */ #include /* uint8_t, uint16_t, uint32_t */ -#include /* FILE */ +#include /* FILE, sprintf() */ #include /* free(), atoi() */ -#include /* strlen(), strchr(), strstr(), memcpy() */ -#include "../common/readwrite.h" /* try_fopen(), textfile_sizes(), try_fgets(), - * textfile_sizes(), try_fwrite(), try_fgetc(), - * try_fclose_unlink_rename(), try_fputc() +#include /* strlen(), strchr(), memcpy() */ +#include "../common/readwrite.h" /* try_fgets(), try_fwrite(), try_fgetc(), + * try_fputc() */ #include "../common/rexit.h" /* exit_err(), exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ @@ -30,18 +28,9 @@ -/* Return string "prefix" + "id"; malloc()'s string, remember to call free()! */ -static char * string_prefixed_id(char * prefix, char id); - -/* Initialize Winconf of "id" from appropriate config file.*/ -static void init_winconf_from_file(char id, struct WinConf * winconf); - /* Wrapper around init_win() called with values from Winconf of "id". */ static void init_win_from_winconf(char id); -/* Save title, draw function, size of window identified by "id" to conffile. */ -static void save_win_config(char id); - /* Free data pointed to inside individual WinConf struct of "id". */ static void free_winconf_data(char id); @@ -50,7 +39,7 @@ static void free_winconf_data(char id); */ static void set_winconf_geometry(char id); -/* Get WinConf by "id"; get id of WinConf mothering "win". */ +/* Get WinConf by "id". */ static struct WinConf * get_winconf_by_id(char id); /* Get (Win->draw) function identified by "c"; NULL if c not mapped to one. */ @@ -58,144 +47,6 @@ static void * get_drawfunc_by_char(char c); -static char * string_prefixed_id(char * prefix, char id) -{ - uint8_t size = strlen(prefix) + 2; - char * path = try_malloc(size, "string_prefixed_id()"); - sprintf(path, "%s_", prefix); - path[size - 2] = id; - return path; -} - - - -static void init_winconf_from_file(char id, struct WinConf * winconf) -{ - /* Assign WinConf id to filename path, error message context, winconf->id.*/ - char * tmp = "init_winconf_from_file() on window id '_'"; - char * context = try_malloc(strlen(tmp) + 1, "init_winconf_from_file()"); - memcpy(context, tmp, strlen(tmp) + 1); - context[strlen(tmp) - 2] = id; - char * path = string_prefixed_id("confclient/windows/Win_", id); - winconf->id = id; - - /* Prepare reading in file line by line into "line" array. */ - FILE * file = try_fopen(path, "r", context); - free(path); - uint32_t linemax = textfile_sizes(file, NULL); - char line[linemax + 1]; - - /* Read/determine winconf->title, ->draw, ->height(_type),->width(_type). */ - try_fgets(line, linemax + 1, file, context); - winconf->title = try_malloc(strlen(line), context); - memcpy(winconf->title, line, strlen(line) - 1); /* Eliminate newline char */ - winconf->title[strlen(line) - 1] = '\0'; /* char at end of string. */ - try_fgets(line, linemax + 1, file, context); - winconf->draw = line[0]; - try_fgets(line, linemax + 1, file, context); - winconf->height = atoi(line); - winconf->height_type = (0 >= winconf->height); - try_fgets(line, linemax + 1, file, context); - winconf->width = atoi(line); - winconf->width_type = (0 >= winconf->width); - - /* Read in window-specific keybindings (winconf->kb). */ - char command[linemax + 1]; - char * cmdptr; - struct KeyBinding ** loc_last_ptr = &winconf->kb.kbs; - * loc_last_ptr = 0; - while (try_fgets(command, linemax + 1, file, context)) - { - if ('\n' == command[0] || 0 == command[0]) - { - break; - } - * loc_last_ptr = try_malloc(sizeof(struct KeyBinding), context); - struct KeyBinding * kb_p = * loc_last_ptr; - kb_p->next = 0; - kb_p->key = atoi(command); - cmdptr = strchr(command, ' ') + 1; - cmdptr[strlen(cmdptr) - 1] = '\0'; - kb_p->command = get_command(cmdptr); - loc_last_ptr = & kb_p->next; - } - - /* Init remaining values to zero and cleaning up. */ - winconf->view = 0; - winconf->kb.edit = 0; - winconf->kb.select = 0; - try_fclose(file, context); - free(context); -} - - - -static void init_win_from_winconf(char id) -{ - char * err = "get_drawfunc_by_char() returns NULL to init_win_from_file()."; - struct WinConf * winconf = get_winconf_by_id(id); - void * f = get_drawfunc_by_char(winconf->draw); - exit_err(NULL == f, err); - init_win(&winconf->win, winconf->title, winconf->height, winconf->width, f); -} - - - -static void save_win_config(char id) -{ - char * f_name = "save_win_config()"; - - /* Prepare atomic file saving. */ - char * path_tmp = string_prefixed_id("confclient/windows/Win_tmp_", id); - FILE * file = try_fopen(path_tmp, "w", f_name); - - /* Save, line by line, ->title, ->draw, ->height and ->width. */ - struct WinConf * wc = get_winconf_by_id(id); - uint8_t size = strlen(wc->title) + 2; - if (size < 7) /* Ensure that at least 5 + 2 char fit into line so that */ - { /* the digit representation of any uint16_t may be stored. */ - size = 7; - } - char line[size]; - sprintf(line, "%s\n", wc->title); - try_fwrite(line, sizeof(char), strlen(line), file, f_name); - sprintf(line, "%c\n", wc->draw); - try_fwrite(line, sizeof(char), strlen(line), file, f_name); - sprintf(line, "%d\n", wc->height); - try_fwrite(line, sizeof(char), strlen(line), file, f_name); - sprintf(line, "%d\n", wc->width); - try_fwrite(line, sizeof(char), strlen(line), file, f_name); - - /* Save window-specific keybindings (->kb.kbs). */ - uint16_t linemax = 0; - struct KeyBinding * kb_p = wc->kb.kbs; - while (0 != kb_p) - { - if (strlen(kb_p->command->dsc_short) > linemax) - { - linemax = strlen(kb_p->command->dsc_short); - } - kb_p = kb_p->next; - } - linemax = linemax + 6; /* + 6: + 3 digits + whitespace + \n + \0 */ - char kb_line[linemax]; - kb_p = wc->kb.kbs; - while (0 != kb_p) - { - sprintf(kb_line, "%d %s\n", kb_p->key, kb_p->command->dsc_short); - try_fwrite(kb_line, sizeof(char), strlen(kb_line), file, f_name); - kb_p = kb_p->next; - } - - /* Finish atomic file saving and clean up. */ - char * path = string_prefixed_id("confclient/windows/Win_", id); - try_fclose_unlink_rename(file, path_tmp, path, f_name); - free(path); - free(path_tmp); -} - - - static void free_winconf_data(char id) { struct WinConf * wc = get_winconf_by_id(id); @@ -229,21 +80,6 @@ static void set_winconf_geometry(char id) -static struct WinConf * get_winconf_by_id(char id) -{ - uint8_t i = 0; - while (1) - { - if (id == world.winconf_db.winconfs[i].id) - { - return &world.winconf_db.winconfs[i]; - } - i++; - } -} - - - static void * get_drawfunc_by_char(char c) { @@ -284,6 +120,32 @@ static void * get_drawfunc_by_char(char c) +extern void init_win_from_winconf(char id) +{ + char * err = "get_drawfunc_by_char() returns NULL to init_win_from_file()."; + struct WinConf * winconf = get_winconf_by_id(id); + void * f = get_drawfunc_by_char(winconf->draw); + exit_err(NULL == f, err); + init_win(&winconf->win, winconf->title, winconf->height, winconf->width, f); +} + + + +static struct WinConf * get_winconf_by_id(char id) +{ + uint8_t i = 0; + while (1) + { + if (id == world.winconf_db.winconfs[i].id) + { + return &world.winconf_db.winconfs[i]; + } + i++; + } +} + + + extern struct WinConf * get_winconf_by_win(struct Win * win) { uint8_t i = 0; @@ -307,48 +169,123 @@ extern struct Win * get_win_by_id(char id) -extern void init_winconfs() +extern uint8_t read_winconf_from_file(char * line, uint32_t linemax, FILE * file) { - char * f_name = "init_winconfs()"; - - /* Fill world.winconf_db.winconf_ids with confclient/windows/Win_* - * filenames' end chars. - */ - uint8_t max_wins = 255; /* Maximum number of window ids to store. */ - DIR * dp = opendir("confclient/windows"); - exit_trouble(NULL == dp, f_name, "opendir()"); - struct dirent * fn; - errno = 0; - char * winconf_ids = try_malloc(max_wins + 1, f_name); - uint8_t i = 0; - char id; - while (NULL != (fn = readdir(dp)) && i < max_wins) + char * f_name = "read_winconf_from_file()"; + int test = try_fgetc(file, f_name); + if (EOF == test) + { + return 0; + } + struct WinConf winconf; + winconf.id = (char) test; + winconf.draw = winconf.id; + try_fgetc(file, f_name); + try_fgets(line, linemax + 1, file, f_name); + winconf.title = try_malloc(strlen(line), f_name); + memcpy(winconf.title, line, strlen(line) - 1); /* Eliminate newline char */ + winconf.title[strlen(line) - 1] = '\0'; /* char at end of string. */ + try_fgets(line, linemax + 1, file, f_name); + winconf.height = atoi(line); + winconf.height_type = (0 >= winconf.height); + try_fgets(line, linemax + 1, file, f_name); + winconf.width = atoi(line); + winconf.width_type = (0 >= winconf.width); + read_keybindings_from_file(line, linemax, file, &winconf.kb); + winconf.win = NULL; + winconf.view = 0; + winconf.center.y = 0; + winconf.center.x = 0; + if (world.winconf_db.ids) + { + uint8_t old_ids_size = strlen(world.winconf_db.ids); + char * new_ids = try_malloc(old_ids_size + 1 + 1, f_name); + sprintf(new_ids, "%s%c", world.winconf_db.ids, winconf.id); + free(world.winconf_db.ids); + world.winconf_db.ids = new_ids; + uint16_t old_winconfs_size = old_ids_size * sizeof(struct WinConf); + uint16_t new_winconfs_size = old_winconfs_size + sizeof(struct WinConf); + struct WinConf * new_winconfs = try_malloc(new_winconfs_size, f_name); + memcpy(new_winconfs, world.winconf_db.winconfs, old_winconfs_size); + new_winconfs[old_ids_size] = winconf; + free(world.winconf_db.winconfs); + world.winconf_db.winconfs = new_winconfs; + } + else { - if (5 == strlen(fn->d_name) && fn->d_name == strstr(fn->d_name, "Win_")) - { - id = fn->d_name[4]; - winconf_ids[i] = id; - i++; - } + world.winconf_db.ids = try_malloc(2, f_name); + sprintf(world.winconf_db.ids, "%c", winconf.id); + world.winconf_db.winconfs = try_malloc(sizeof(struct WinConf), f_name); + *world.winconf_db.winconfs = winconf; } - winconf_ids[i] = '\0'; - exit_trouble(errno, f_name, "readdir()"); - exit_trouble(closedir(dp), f_name, "closedir()"); - world.winconf_db.winconf_ids = try_malloc(strlen(winconf_ids) + 1, f_name); - memcpy(world.winconf_db.winconf_ids, winconf_ids, strlen(winconf_ids) + 1); - free(winconf_ids); - - /* Initialize world.winconf_db.winconfs from Win_* files named in - * world.winconf_db.winconf_ids. - */ - size_t size = strlen(world.winconf_db.winconf_ids) * sizeof(struct WinConf); - world.winconf_db.winconfs = try_malloc(size, f_name); - i = 0; - while (0 != (id = get_next_winconf_id())) + return 1; +} + + + +extern void write_winconf_of_id_to_file(FILE * file, char c, char * delim) +{ + char * f_name = "write_winconf_of_id_to_file()"; + struct WinConf * wc = get_winconf_by_id(c); + uint8_t size = strlen(wc->title) + 2; + if (size < 7) /* Ensure that at least 5 + 2 char fit into line so that */ + { /* the digit representation of any uint16_t may be stored. */ + size = 7; + } + char line[size]; + sprintf(line, "%c\n", wc->draw); + try_fwrite(line, sizeof(char), strlen(line), file, f_name); + sprintf(line, "%s\n", wc->title); + try_fwrite(line, sizeof(char), strlen(line), file, f_name); + sprintf(line, "%d\n", wc->height); + try_fwrite(line, sizeof(char), strlen(line), file, f_name); + sprintf(line, "%d\n", wc->width); + try_fwrite(line, sizeof(char), strlen(line), file, f_name); + write_keybindings_to_file(file, &wc->kb, delim); +} + + + +extern void read_order_wins_visible_active(char * line, uint32_t linemax, FILE * file) +{ + char * f_name = "read_order_wins_visible_active()"; + char win_order[linemax + 1]; + try_fgets(win_order, linemax + 1, file, f_name); + world.winconf_db.order = try_malloc(linemax, f_name); + win_order[strlen(win_order) - 1] = '\0'; + sprintf(world.winconf_db.order, "%s", win_order); + int char_or_eof = try_fgetc(file, f_name); + char * err_eof = "fgetc() unexpectedly hitting EOF"; + exit_trouble(EOF == char_or_eof, f_name, err_eof); + world.winconf_db.active = (uint8_t) char_or_eof; + exit_trouble(EOF == try_fgetc(file, f_name), f_name, err_eof); + try_fgets(line, linemax + 1, file, f_name); +} + + + +extern void write_order_wins_visible_active(FILE * file, char * delim) +{ + char * f_name = "write_order_wins_visible_active()"; + char line[strlen(world.winconf_db.ids) + 2]; + struct Win * w_p = world.wmeta.chain_start; + char active = ' '; + uint8_t i; + for (; NULL != w_p; w_p = w_p->next, i++) { - init_winconf_from_file(id, &world.winconf_db.winconfs[i]); - i++; + struct WinConf * wc_p = get_winconf_by_win(w_p); + line[i] = wc_p->id; + if (w_p == world.wmeta.active) + { + active = wc_p->id; + } } + line[i] = '\n'; + line[i + 1] = '\0'; + try_fwrite(line, sizeof(char), strlen(line), file, f_name); + try_fputc(active, file, f_name); + try_fputc('\n', file, f_name); + try_fwrite(delim, strlen(delim), 1, file, f_name); } @@ -360,8 +297,12 @@ extern void free_winconfs() { free_winconf_data(id); } - free(world.winconf_db.winconf_ids); + free(world.winconf_db.ids); + world.winconf_db.ids = NULL; free(world.winconf_db.winconfs); + world.winconf_db.winconfs = NULL; + free(world.winconf_db.order); + world.winconf_db.order = NULL; } @@ -377,43 +318,28 @@ extern void init_wins() -extern void sorted_wintoggle_and_activate() +extern void sorted_win_toggle_and_activate() { - char * f_name = "sorted_wintoggle_and_activate()"; - - /* Read from file order of windows to be toggled + active win selection. */ - char * path = "confclient/windows/toggle_order_and_active"; - FILE * file = try_fopen(path, "r", f_name); - uint32_t linemax = textfile_sizes(file, NULL); - char win_order[linemax + 1]; - try_fgets(win_order, linemax + 1, file, f_name); - int char_or_eof = try_fgetc(file, f_name); - exit_trouble(EOF==char_or_eof, f_name, "fgetc() unexpectedly hitting EOF"); - uint8_t a = (uint8_t) char_or_eof; - try_fclose(file, f_name); - - /* Toggle windows and set active window selection. */ uint8_t i = 0; - for (; i < strlen(win_order) - 1; i++) + for (; i < strlen(world.winconf_db.order); i++) { - if (NULL == strchr(world.winconf_db.winconf_ids, win_order[i])) + if (NULL == strchr(world.winconf_db.ids, world.winconf_db.order[i])) { continue; } - toggle_window(win_order[i]); - if (a == (uint8_t) win_order[i]) + toggle_window(world.winconf_db.order[i]); + if (world.winconf_db.active == (uint8_t) world.winconf_db.order[i]) { - world.wmeta.active = get_win_by_id(win_order[i]); + world.wmeta.active = get_win_by_id(world.winconf_db.order[i]); } } } - extern char get_next_winconf_id() { static uint8_t i = 0; - char c = world.winconf_db.winconf_ids[i]; + char c = world.winconf_db.ids[i]; if (0 == c) { i = 0; @@ -425,45 +351,6 @@ extern char get_next_winconf_id() -extern void save_win_configs() -{ - char * f_name = "save_win_configs()"; - - /* Save individual world.winconf_db.winconfs to their proper files. */ - uint8_t max_wins = 255; /* n of WinConf fitting into world.winconf_db */ - char id; - while (0 != (id = get_next_winconf_id())) - { - save_win_config(id); - } - - /* Save order of windows to toggle on start / which to select as active. */ - char * path = "confclient/windows/toggle_order_and_active"; - char * path_tmp = "confclient/windows/toggle_order_and_active_tmp"; - FILE * file = try_fopen(path_tmp, "w", f_name); - char line[max_wins + 2]; - struct Win * w_p = world.wmeta.chain_start; - uint8_t i = 0; - while (0 != w_p && i < max_wins) - { - struct WinConf * wc = get_winconf_by_win(w_p); - line[i] = wc->id; - w_p = w_p->next; - i++; - } - line[i] = '\n'; - line[i + 1] = '\0'; - try_fwrite(line, sizeof(char), strlen(line), file, f_name); - if (0 != world.wmeta.active) - { - struct WinConf * wc = get_winconf_by_win(world.wmeta.active); - try_fputc(wc->id, file, f_name); - } - try_fclose_unlink_rename(file, path_tmp, path, f_name); -} - - - extern void toggle_window(char id) { struct Win * win = get_win_by_id(id); diff --git a/src/client/wincontrol.h b/src/client/wincontrol.h index e025cce..67c72bc 100644 --- a/src/client/wincontrol.h +++ b/src/client/wincontrol.h @@ -7,9 +7,9 @@ #ifndef WINCONTROL_H #define WINCONTROL_H -#include /* for uint8_t, int16_t */ -#include "keybindings.h" /* for KeyBindingDB struct */ -#include "../common/yx_uint16.h" /* for yx_uint16 struct */ +#include /* uint8_t, int16_t */ +#include "keybindings.h" /* struct KeyBindingDB */ +#include "../common/yx_uint16.h" /* yx_uint16 struct */ struct Win; @@ -17,7 +17,9 @@ struct Win; struct WinConfDB { struct WinConf * winconfs; - char * winconf_ids; + char * ids; + char active; /* id of window selected as active */ + char * order; /* order of visible windows (identified by IDs) */ }; /* Stores a window's configuration (like geometry, keybindings) and a pointer to @@ -46,26 +48,27 @@ struct WinConf extern struct WinConf * get_winconf_by_win(struct Win * win); extern struct Win * get_win_by_id(char id); -/* Create, initialize (from config files)/free world.winconfs and their Wins. */ -extern void init_winconfs(); +/* Free all WinConf DB data. */ extern void free_winconfs(); + +/* Initialize Win structs for WinConfs in WinConf database. */ extern void init_wins(); -/* Toggle windows in the order desribed by 1st line of toggle_order_and_active - * file in client config windows directory, where each char may fit a Winconf.id - * in world.winconfs. Silently ignore id chars not found there. The 1st char of - * the 2nd line of the same file determines which window (by its .id) to focus - * as active (but only if this window belongs to the ones just toggled). +/* Toggle windows in order set by world.win_order. Point active window selection + * to window identified by world.winconf_db.active. */ -extern void sorted_wintoggle_and_activate(); +extern void sorted_win_toggle_and_activate(); + +/* Read/write world.win_order and world.winconf_db.active from/to "file". */ +extern void read_order_wins_visible_active(char * line, uint32_t linemax, FILE * file); +extern void write_order_wins_visible_active(FILE * file, char * delim); /* Iterate over chars of world.winconf_db.winconf_ids array. Restart after \0.*/ extern char get_next_winconf_id(); -/* Save world.winconfs, visible window chain and active window selection to the - * respective configuration files in client config windows directory. - */ -extern void save_win_configs(); +/* Read/write individual WinConf (identified by "c") from/to file. */ +extern uint8_t read_winconf_from_file(char * line, uint32_t linemax, FILE * file); +extern void write_winconf_of_id_to_file(FILE * file, char c, char * delim); /* Toggle "window configuration" view for active window. Sets sensible * Win.center values for the various configuration views (for winconf_geometry: diff --git a/src/client/world.h b/src/client/world.h index 80fae71..4e92bb2 100644 --- a/src/client/world.h +++ b/src/client/world.h @@ -30,6 +30,7 @@ struct World struct yx_uint16 player_pos; char * log; char * path_server_in; + char * path_interface_conf; char * player_inventory; uint16_t turn; uint16_t score; -- 2.30.2