X-Git-Url: https://plomlompom.com/repos/berlin_corona.txt?a=blobdiff_plain;f=src%2Fclient%2Fwincontrol.c;fp=src%2Fclient%2Fwincontrol.c;h=275fc9c96b0aefffc9056de1a3a6601b55515a26;hb=e8e8f91cff96eebc1b440df18d9c3ef4ced1ca60;hp=01b9be84d50f74099b512c0e9688d28be9a777aa;hpb=52d7524ce047cd16192bb83bea15d36a90bb2a9f;p=plomrogue 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);