X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=src%2Fclient%2Fwincontrol.c;h=5b82053992d85ed270dd54ae223f9adc9f5294e1;hb=fb9b40f0535b28b37b64983240c4b78e74ee9a2c;hp=b272905e50bce5cbdba8e001151daa9cd478b053;hpb=dd9d65ee727ac7e95801da0f8b5bae7009811802;p=plomrogue diff --git a/src/client/wincontrol.c b/src/client/wincontrol.c index b272905..5b82053 100644 --- a/src/client/wincontrol.c +++ b/src/client/wincontrol.c @@ -2,14 +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() */ @@ -29,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); @@ -49,154 +39,12 @@ 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. */ static void * get_drawfunc_by_char(char c); -/* Iterate over chars of world.winconf_db.winconf_ids array. Restart after \0.*/ -static char get_next_winconf_id(); - - - -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; - kb_p->name = try_malloc(strlen(cmdptr), context); - memcpy(kb_p->name, cmdptr, strlen(cmdptr) - 1); - kb_p->name[strlen(cmdptr) - 1] = '\0'; - 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->name) > linemax) - { - linemax = strlen(kb_p->name); - } - 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->name); - 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) @@ -218,7 +66,7 @@ static void set_winconf_geometry(char id) } else if (1 == wcp->height_type) { - wcp->height = wcp->win->framesize.y - world.wmeta.padsize.y + 1; + wcp->height = wcp->win->framesize.y - world.wins.padsize.y + 1; } if (0 == wcp->width_type) { @@ -226,22 +74,7 @@ static void set_winconf_geometry(char id) } else if (1 == wcp->width_type) { - wcp->width = wcp->win->framesize.x - world.wmeta.padsize.x; - } -} - - - -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++; + wcp->width = wcp->win->framesize.x - world.wins.padsize.x; } } @@ -287,17 +120,28 @@ static void * get_drawfunc_by_char(char c) -static char get_next_winconf_id() +extern void init_win_from_winconf(char id) { - static uint8_t i = 0; - char c = world.winconf_db.winconf_ids[i]; - if (0 == c) + 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->id); + 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) { - i = 0; - return c; + if (id == world.wins.winconfs[i].id) + { + return &world.wins.winconfs[i]; + } + i++; } - i++; - return c; } @@ -307,9 +151,9 @@ extern struct WinConf * get_winconf_by_win(struct Win * win) uint8_t i = 0; while (1) { - if (win == world.winconf_db.winconfs[i].win) + if (win == world.wins.winconfs[i].win) { - return &world.winconf_db.winconfs[i]; + return &world.wins.winconfs[i]; } i++; } @@ -325,48 +169,124 @@ 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; + 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.wins.ids) + { + uint8_t old_ids_size = strlen(world.wins.ids); + char * new_ids = try_malloc(old_ids_size + 1 + 1, f_name); + sprintf(new_ids, "%s%c", world.wins.ids, winconf.id); + free(world.wins.ids); + world.wins.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.wins.winconfs, old_winconfs_size); + new_winconfs[old_ids_size] = winconf; + free(world.wins.winconfs); + world.wins.winconfs = new_winconfs; + } + else { - if (5 == strlen(fn->d_name) && fn->d_name == strstr(fn->d_name, "Win_")) + world.wins.ids = try_malloc(2, f_name); + sprintf(world.wins.ids, "%c", winconf.id); + world.wins.winconfs = try_malloc(sizeof(struct WinConf), f_name); + *world.wins.winconfs = winconf; + } + 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->id); + 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.wins.order = try_malloc(linemax, f_name); + win_order[strlen(win_order) - 1] = '\0'; + sprintf(world.wins.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.wins.id_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.wins.ids) + 2]; + struct Win * w_p = world.wins.chain_start; + char active = ' '; + uint8_t i; + for (; NULL != w_p; w_p = w_p->next, i++) + { + struct WinConf * wc_p = get_winconf_by_win(w_p); + line[i] = wc_p->id; + if (w_p == world.wins.win_active) { - id = fn->d_name[4]; - winconf_ids[i] = id; - i++; + active = wc_p->id; } } - 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())) - { - init_winconf_from_file(id, &world.winconf_db.winconfs[i]); - i++; - } + 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); } @@ -378,8 +298,12 @@ extern void free_winconfs() { free_winconf_data(id); } - free(world.winconf_db.winconf_ids); - free(world.winconf_db.winconfs); + free(world.wins.ids); + world.wins.ids = NULL; + free(world.wins.winconfs); + world.wins.winconfs = NULL; + free(world.wins.order); + world.wins.order = NULL; } @@ -395,74 +319,35 @@ 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.wins.order); i++) { - if (NULL == strchr(world.winconf_db.winconf_ids, win_order[i])) + if (NULL == strchr(world.wins.ids, world.wins.order[i])) { continue; } - toggle_window(win_order[i]); - if (a == (uint8_t) win_order[i]) + toggle_window(world.wins.order[i]); + if (world.wins.id_active == (uint8_t) world.wins.order[i]) { - world.wmeta.active = get_win_by_id(win_order[i]); + world.wins.win_active = get_win_by_id(world.wins.order[i]); } } } - -extern void save_win_configs() +extern char get_next_winconf_id() { - 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) + static uint8_t i = 0; + char c = world.wins.ids[i]; + if (0 == c) { - struct WinConf * wc = get_winconf_by_win(world.wmeta.active); - try_fputc(wc->id, file, f_name); + i = 0; + return c; } - try_fclose_unlink_rename(file, path_tmp, path, f_name); + i++; + return c; } @@ -470,7 +355,7 @@ extern void save_win_configs() extern void toggle_window(char id) { struct Win * win = get_win_by_id(id); - if (0 == win->prev && world.wmeta.chain_start != win) /* Win struct is */ + if (0 == win->prev && world.wins.chain_start != win) /* Win struct is */ { /* outside chain? */ append_win(win); } @@ -484,7 +369,7 @@ extern void toggle_window(char id) extern void toggle_winconfig() { - struct Win * win = world.wmeta.active; + struct Win * win = world.wins.win_active; struct WinConf * wcp = get_winconf_by_win(win); if (0 == wcp->view) { @@ -503,7 +388,7 @@ extern void toggle_winconfig() else { wcp->view = 0; - win->draw = get_drawfunc_by_char(wcp->draw); + win->draw = get_drawfunc_by_char(wcp->id); win->center = wcp->center; } } @@ -512,7 +397,7 @@ extern void toggle_winconfig() extern void toggle_win_size_type(char axis) { - struct Win * win = world.wmeta.active; + struct Win * win = world.wins.win_active; struct WinConf * wcp = get_winconf_by_win(win); if ('y' == axis) { @@ -521,7 +406,7 @@ extern void toggle_win_size_type(char axis) return; } wcp->width_type = ( 0 == wcp->width_type - && win->framesize.x <= world.wmeta.padsize.x); + && win->framesize.x <= world.wins.padsize.x); set_winconf_geometry(wcp->id); } @@ -531,11 +416,11 @@ extern void scroll_pad(char dir) { if ('+' == dir) { - reset_pad_offset(world.wmeta.pad_offset + 1); + reset_pad_offset(world.wins.pad_offset + 1); } else if ('-' == dir) { - reset_pad_offset(world.wmeta.pad_offset - 1); + reset_pad_offset(world.wins.pad_offset - 1); } } @@ -543,9 +428,9 @@ extern void scroll_pad(char dir) extern void growshrink_active_window(char change) { - if (0 != world.wmeta.active) + if (0 != world.wins.win_active) { - struct yx_uint16 size = world.wmeta.active->framesize; + struct yx_uint16 size = world.wins.win_active->framesize; if (change == '-') { size.y--; @@ -563,9 +448,9 @@ extern void growshrink_active_window(char change) size.x++; } resize_active_win(size); - struct WinConf * wcp = get_winconf_by_win(world.wmeta.active); + struct WinConf * wcp = get_winconf_by_win(world.wins.win_active); if ( 1 == wcp->width_type - && world.wmeta.active->framesize.x > world.wmeta.padsize.x) + && world.wins.win_active->framesize.x > world.wins.padsize.x) { wcp->width_type = 0; }