From cdeb497c72cb74f48504401277bbb3a7547c430d Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Thu, 14 May 2026 17:24:14 +0300 Subject: [PATCH] UI: gets rid of char accumulator and use everywhere wchar_t --- TODO.md | 2 -- src/modals/ask_server_addr.c | 7 ++++++- src/modals/login_credentials.c | 8 ++++++-- src/modals/register.c | 18 ++++++++++++------ src/widget/input.c | 31 ++++++++++++++++++------------- src/widget/input.h | 2 +- src/windows/fs_file_list.c | 1 - 7 files changed, 43 insertions(+), 26 deletions(-) diff --git a/TODO.md b/TODO.md index 604a9ef..13d26e1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,5 @@ # TODO: -- [ ] Input: get rid of char accumulator and use everywhere wchar_t - ## Current: - [ ] File upload multiline description (window) - [ ] Separate common structures in the common.h diff --git a/src/modals/ask_server_addr.c b/src/modals/ask_server_addr.c index ea4251b..19b83a7 100644 --- a/src/modals/ask_server_addr.c +++ b/src/modals/ask_server_addr.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -19,11 +20,15 @@ void asa_modal_dialogue_callback(w_cb_args_t *args) { d_args.element = app->active_widget; w_input_t *in_ip = d->g_content->elements[0].element; w_input_t *in_port = d->g_content->elements[1].element; + char *ip_val = w_input_get_value(in_ip); + char *port_val = w_input_get_value(in_port); w_dialogue_callback_default(&d_args); if (d_args.resp_data.code == cbrp_val) { switch (d_args.resp_data.val.val.num) { case 1: - get_ip_port(app->params, in_ip->value, in_port->value); + get_ip_port(app->params, ip_val, port_val); + free(ip_val); + free(port_val); if (connect_to_server(app)) { d->needs_destroy = true; app->query_args->state = S_WAIT_SERVER; diff --git a/src/modals/login_credentials.c b/src/modals/login_credentials.c index 9acad5a..6c42b41 100644 --- a/src/modals/login_credentials.c +++ b/src/modals/login_credentials.c @@ -21,20 +21,24 @@ void init_login_credentials_modal_cb(w_cb_args_t *args) { d_args.element = app->active_widget; w_input_t *in_name = d->g_content->elements[0].element; w_input_t *in_pass = d->g_content->elements[1].element; + char *name_value = w_input_get_value(in_name); + char *pass_value = w_input_get_value(in_pass); w_dialogue_callback_default(&d_args); if (d_args.resp_data.code == cbrp_val) { switch (d_args.resp_data.val.val.num) { case 1: app->params->uname = malloc(in_name->value_len + 1); app->params->pass = malloc(in_pass->value_len + 1); - strncpy(app->params->uname, in_name->value, in_name->value_len); + strncpy(app->params->uname, name_value, in_name->value_len); app->params->uname[in_name->value_len] = 0; - strncpy(app->params->pass, in_pass->value, in_pass->value_len); + strncpy(app->params->pass, pass_value, in_pass->value_len); app->params->pass[in_pass->value_len] = 0; server_send_string(app->query_args, app->params->uname); app->query_args->state = S_WAIT_SERVER; d->needs_destroy = true; app_draw_bars(app); + free(name_value); + free(pass_value); break; case 2: app->query_args->state = S_ASK_LOGIN_TYPE; diff --git a/src/modals/register.c b/src/modals/register.c index 0b6e94e..78a828f 100644 --- a/src/modals/register.c +++ b/src/modals/register.c @@ -37,6 +37,12 @@ void init_register_modal_cb(w_cb_args_t *args) { w_input_t *in_email = d->g_content->elements[2].element; w_input_t *in_pass = g_passwords->elements[0].element; w_input_t *in_pass_r = g_passwords->elements[1].element; + + char *name_value = w_input_get_value(in_name); + char *email_value = w_input_get_value(in_email); + char *pass_value = w_input_get_value(in_pass); + char *pass_r_value = w_input_get_value(in_pass_r); + if (in_name->value_len == 0) { w_alert("Name field is empty!"); return; @@ -49,22 +55,22 @@ void init_register_modal_cb(w_cb_args_t *args) { w_alert("One of password's field is empty!"); return; } - if (strcmp(in_pass->value, in_pass_r->value)) { + if (strcmp(pass_value, pass_r_value)) { w_alert("Your passwords do not match!"); - in_pass->value[0] = '\0'; + in_pass->w_value[0] = '\0'; in_pass->value_len = 0; - in_pass_r->value[0] = '\0'; + in_pass_r->w_value[0] = '\0'; in_pass_r->value_len = 0; return; } app->params->uname = malloc(in_name->value_len + 1); app->params->pass = malloc(in_pass->value_len + 1); - strncpy(app->params->uname, in_name->value, in_name->value_len); + strncpy(app->params->uname, name_value, in_name->value_len); app->params->uname[in_name->value_len] = 0; - strncpy(app->params->pass, in_pass->value, in_pass->value_len); + strncpy(app->params->pass, pass_value, in_pass->value_len); app->params->pass[in_pass->value_len] = 0; server_send_string(app->query_args, "register %s %s %*s\n", app->params->uname, - app->params->pass, (int)in_email->value_len, in_email->value + app->params->pass, (int)in_email->value_len, email_value ); app->query_args->state = S_WAIT_REGISTER_CONFIRMATION; } diff --git a/src/widget/input.c b/src/widget/input.c index fac4a66..3adbd54 100644 --- a/src/widget/input.c +++ b/src/widget/input.c @@ -27,15 +27,16 @@ bool w_input_default_key_action(w_cb_args_t *args) { if (input->value_len) { if (input->cur_pos > 0) { start_pos = input->value_len-- - input->cur_pos; - memmove(input->value + start_pos - 1, input->value + start_pos, - input->value_len - start_pos + 2); + memmove(input->w_value + start_pos - 1, input->w_value + start_pos, + sizeof(wchar_t) * (input->value_len - start_pos + 2)); } else { - input->value[--input->value_len] = '\0'; + input->w_value[--input->value_len] = '\0'; } } break; default: - if (input->value_len == input->max_len) break; + if (input->value_len == input->max_len) + break; long_key[0] = key; input->value_len++; if ((key & 0xC0) == 0xC0) { @@ -48,14 +49,10 @@ bool w_input_default_key_action(w_cb_args_t *args) { mbstowcs(w_key, (const char *)&long_key, 2); if (input->cur_pos > 0) { start_pos = input->value_len - input->cur_pos; - memmove(input->value + start_pos + 1, input->value + start_pos, - input->value_len - start_pos); - input->value[start_pos] = key; - strcpy(input->value + start_pos, long_key); - input->w_value[start_pos] = w_key[0]; + memmove(input->w_value + start_pos + 1, input->w_value + start_pos, + sizeof(wchar_t) * (input->value_len - start_pos)); + input->w_value[start_pos] = key; } else { - strcpy(input->value + input->value_len, long_key); - input->w_value[input->value_len - 1] = w_key[0]; input->w_value[input->value_len] = '\0'; } @@ -77,7 +74,7 @@ w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label, if (input->w.sz.x < t_len) input->w.sz.x = t_len; input->w.ps.x = 1; - input->value[0] = '\0'; + input->w_value[0] = '\0'; input->value_len = 0; input->max_len = length; input->is_hidden = is_hidden_value; @@ -147,5 +144,13 @@ int32_t w_input_draw(w_input_t *input, int32_t active_id) { wattroff(win, A_BOLD | A_REVERSE); return 0; } +/* Uses malloc! need to invoke free() after use of output */ +char *w_input_get_value(w_input_t *input) { + char *c_output = malloc(sizeof (wchar_t) * input->value_len); + const wchar_t *p; + p = input->w_value; + wcsrtombs(c_output, &p, input->value_len, NULL); + return c_output; +} -void w_input_destroy(w_input_t *btn) { free(btn); } \ No newline at end of file +void w_input_destroy(w_input_t *input) { free(input); } \ No newline at end of file diff --git a/src/widget/input.h b/src/widget/input.h index a4f49c7..7936c77 100644 --- a/src/widget/input.h +++ b/src/widget/input.h @@ -11,7 +11,6 @@ typedef struct { w_t w; wchar_t w_value[INPUT_TEXT]; - char value[INPUT_TEXT*2]; int32_t cur_pos; /* is relative to the end of a string */ int32_t value_len; int32_t max_len; @@ -24,5 +23,6 @@ w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label, int32_t size, int32_t is_hidden_value); int32_t w_input_draw(w_input_t *input, int32_t active_id); void w_input_destroy(w_input_t *input); +char *w_input_get_value(w_input_t *input); #endif \ No newline at end of file diff --git a/src/windows/fs_file_list.c b/src/windows/fs_file_list.c index c99549e..0c673e5 100644 --- a/src/windows/fs_file_list.c +++ b/src/windows/fs_file_list.c @@ -3,7 +3,6 @@ #include #include -#include #include #include #include