diff options
author | toni <matzeton@googlemail.com> | 2014-12-07 03:20:34 +0100 |
---|---|---|
committer | toni <matzeton@googlemail.com> | 2014-12-07 20:39:45 +0100 |
commit | f365c0c482ab20a13af6155890c1784227559b6f (patch) | |
tree | 0bfe4edb59dd699a84e975d4c9cb8007892e7fb3 | |
parent | e3ec8f9259d132eec7071343931fd26733d1dd64 (diff) | |
parent | fc17c62cd6872ad16b2f87857f346c3da66cd4a2 (diff) |
Merge branch 'master' of github.com:freecoding/naskpass
-rw-r--r-- | ui.c | 125 | ||||
-rw-r--r-- | ui.h | 22 | ||||
-rw-r--r-- | ui_ani.c | 27 | ||||
-rw-r--r-- | ui_ani.h | 7 | ||||
-rw-r--r-- | ui_input.c | 74 | ||||
-rw-r--r-- | ui_input.h | 18 |
6 files changed, 179 insertions, 94 deletions
@@ -3,6 +3,7 @@ #include <stdbool.h> #include <unistd.h> #include <pthread.h> +#include <semaphore.h> #include <string.h> #include <ncurses.h> #include <sys/time.h> @@ -18,13 +19,13 @@ static pthread_t thrd; static bool active; static pthread_cond_t cnd_update = PTHREAD_COND_INITIALIZER; static pthread_mutex_t mtx_update = PTHREAD_MUTEX_INITIALIZER; - -pthread_mutex_t tmretmtx = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t ncbsy = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mtx_cb = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mtx_busy = PTHREAD_MUTEX_INITIALIZER; +static sem_t sem_rdy; void -register_ui_elt(ui_callback uicb, ui_callback post_uicb, void *data, WINDOW *wnd, chtype attrs) +register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd) { struct nask_ui *tmp, *new; @@ -36,10 +37,8 @@ register_ui_elt(ui_callback uicb, ui_callback post_uicb, void *data, WINDOW *wnd } new = calloc(1, sizeof(struct nask_ui)); new->ui_elt_cb = uicb; - new->postui_elt_cb = post_uicb; new->do_update = true; new->wnd = wnd; - new->attrs = attrs; new->data = data; new->next = NULL; if (nui == NULL) { @@ -70,47 +69,29 @@ unregister_ui_elt(void *data) } } -void -set_update(void *ptr_data, bool do_update) -{ - struct nask_ui *cur = nui; - - while (cur != NULL) { - if (ptr_data == cur->data) { - cur->do_update = do_update; - break; - } - cur = cur->next; - } -} - static int -do_ui_update(void) +do_ui_update(bool timed_out) { int retval = UICB_OK; + int curx = getcurx(wnd_main); + int cury = getcury(wnd_main); struct nask_ui *cur = nui; /* call all draw callback's */ + erase(); while (cur != NULL) { if (cur->ui_elt_cb != NULL) { - attron(cur->attrs); - cur->ui_elt_cb(cur->wnd, cur->data, cur->do_update); - attroff(cur->attrs); + pthread_mutex_lock(&mtx_cb); + cur->ui_elt_cb(cur->wnd, cur->data, cur->do_update, timed_out); + doupdate(); + pthread_mutex_unlock(&mtx_cb); } else { retval = UICB_ERR_CB; } cur = cur->next; } + wmove(wnd_main, cury, curx); refresh(); - /* call all post draw callback's */ - while (cur != NULL) { - if (cur->postui_elt_cb != NULL) { - if (cur->postui_elt_cb(cur->wnd, cur->data, cur->do_update) == UICB_CURSOR) { - break; - } - } - cur = cur->next; - } return (retval); } @@ -121,17 +102,20 @@ ui_thrd(void *arg) struct timespec wait; pthread_mutex_lock(&mtx_update); - do_ui_update(); gettimeofday(&now, NULL); - wait.tv_sec = now.tv_sec + 1; + wait.tv_sec = now.tv_sec + UILOOP_TIMEOUT; wait.tv_nsec = now.tv_usec * 1000; - do_ui_update(); + do_ui_update(false); + sem_post(&sem_rdy); while (active == true) { + pthread_mutex_unlock(&mtx_busy); pthread_cond_timedwait(&cnd_update, &mtx_update, &wait); - wait.tv_sec += 1; + wait.tv_sec += UILOOP_TIMEOUT; + pthread_mutex_lock(&mtx_busy); if (active == false) break; - do_ui_update(); + do_ui_update(true); } + pthread_mutex_unlock(&mtx_busy); pthread_mutex_unlock(&mtx_update); return (NULL); } @@ -167,46 +151,85 @@ free_ui(void) int run_ui_thrd(void) { + pthread_mutex_lock(&mtx_busy); active = true; + pthread_mutex_unlock(&mtx_busy); return (pthread_create(&thrd, NULL, &ui_thrd, NULL)); } int stop_ui_thrd(void) { + pthread_mutex_lock(&mtx_busy); active = false; + pthread_mutex_unlock(&mtx_busy); return (pthread_join(thrd, NULL)); } +static bool +process_key(int key, struct input *a, WINDOW *win) +{ + bool retval = true; + + pthread_mutex_lock(&mtx_busy); + switch (key) { + case UIKEY_ENTER: + case UIKEY_BACKSPACE: + del_input(win, a); + break; + case UIKEY_ESC: + retval = active = false; + ui_thrd_force_update(); + break; + case UIKEY_DOWN: + case UIKEY_UP: + case UIKEY_LEFT: + case UIKEY_RIGHT: + break; + default: + add_input(win, a, key); + } + //mvprintw(0,0,"*%d*", key); + pthread_mutex_unlock(&mtx_busy); + return (retval); +} + int main(int argc, char **argv) { - struct input *pw_input = init_input(1,7,20,"PASSWORD", 128); - struct input *c = init_input(3,8,25,"BLABLUBB", 128); - struct anic *heartbeat = init_anic(2,2); - struct anic *a = init_anic(4,4); - struct anic *b = init_anic(6,6); + struct input *pw_input = init_input(1,7,20,"PASSWORD",128,COLOR_PAIR(3)); + struct anic *heartbeat = init_anic(2,2,A_BOLD | COLOR_PAIR(3)); + struct anic *a = init_anic(4,4,0); + struct anic *b = init_anic(6,6,COLOR_PAIR(1)); a->state = '-'; b->state = '\\'; + char key = '\0'; + if (sem_init(&sem_rdy, 0, 0) == -1) { + perror("init semaphore"); + exit(1); + } init_ui(); - register_anic(heartbeat, A_BOLD | COLOR_PAIR(3)); - register_anic(a,0); register_anic(b,COLOR_PAIR(1)); - register_input(NULL, pw_input, COLOR_PAIR(3)); - register_input(NULL, c, COLOR_PAIR(3)); + register_anic(heartbeat); + register_anic(a); register_anic(b); + register_input(NULL, pw_input); + activate_input(wnd_main, pw_input); if (run_ui_thrd() != 0) { exit(EXIT_FAILURE); } - wgetch(wnd_main); - ui_thrd_force_update(); + sem_wait(&sem_rdy); + while ((key = wgetch(wnd_main)) != '\0' && process_key(key, pw_input, wnd_main) == true) { + pthread_mutex_lock(&mtx_busy); + activate_input(wnd_main, pw_input); + pthread_mutex_unlock(&mtx_busy); + } stop_ui_thrd(); unregister_ui_elt(a); unregister_ui_elt(heartbeat); unregister_ui_elt(b); unregister_ui_elt(pw_input); - unregister_ui_elt(c); free_input(pw_input); free_anic(heartbeat); - free_anic(a); free_anic(b); free_input(c); + free_anic(a); free_anic(b); free_ui(); return (0); } @@ -2,36 +2,42 @@ #define UI_H 1 #include <ncurses.h> +#include <stdint.h> #define UICB_OK 0 #define UICB_ERR_UNDEF 1 #define UICB_ERR_NOP 2 #define UICB_ERR_CB 3 -#define UICB_CURSOR 4 +#define UICB_ERR_BUF 4 +#define UILOOP_TIMEOUT 1 -typedef int (*ui_callback)(WINDOW *, void *, bool); +#define UIKEY_ENTER 10 +#define UIKEY_BACKSPACE 7 +#define UIKEY_ESC 27 +#define UIKEY_DOWN 2 +#define UIKEY_UP 3 +#define UIKEY_LEFT 4 +#define UIKEY_RIGHT 5 + + +typedef int (*ui_callback)(WINDOW *, void *, bool, bool); struct nask_ui { ui_callback ui_elt_cb; - ui_callback postui_elt_cb; bool do_update; WINDOW *wnd; - chtype attrs; void *data; struct nask_ui *next; }; void -register_ui_elt(ui_callback uicb, ui_callback post_uicb, void *data, WINDOW *wnd, chtype attrs); +register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd); void unregister_ui_elt(void *data); void -set_update(void *ptr_data, bool do_update); - -void ui_thrd_force_update(void); void @@ -3,17 +3,18 @@ #include "ui.h" #include "ui_ani.h" -#define ANIC_INITSTATE '\0' +#define ANIC_INITSTATE '|' struct anic * -init_anic(unsigned int x, unsigned int y) +init_anic(unsigned int x, unsigned int y, chtype attrs) { struct anic *a = calloc(1, sizeof(struct anic)); a->x = x; a->y = y; a->state = ANIC_INITSTATE; + a->attrs = attrs; return (a); } @@ -24,30 +25,34 @@ free_anic(struct anic *a) } int -anic_cb(WINDOW *win, void *data, bool needs_update) +anic_cb(WINDOW *win, void *data, bool needs_update, bool timed_out) { struct anic *a = (struct anic *) data; if (a == NULL) return (UICB_ERR_UNDEF); - switch (a->state) { - default: - case '|': a->state = '/'; break; - case '/': a->state = '-'; break; - case '-': a->state = '\\'; break; - case '\\': a->state = '|'; break; + if (timed_out == true) { + switch (a->state) { + default: + case '|': a->state = '/'; break; + case '/': a->state = '-'; break; + case '-': a->state = '\\'; break; + case '\\': a->state = '|'; break; + } } if (needs_update == true) { + attron(a->attrs); if (win != NULL) { mvwaddch(win, a->y, a->x, a->state); } else { mvaddch(a->y, a->x, a->state); } + attroff(a->attrs); } else return (UICB_ERR_NOP); return (UICB_OK); } void -register_anic(struct anic *a, chtype attr) +register_anic(struct anic *a) { - register_ui_elt(anic_cb, NULL, (void *) a, NULL, attr); + register_ui_elt(anic_cb, (void *) a, NULL); } @@ -8,18 +8,19 @@ struct anic { unsigned int x; unsigned int y; char state; + chtype attrs; }; struct anic * -init_anic(unsigned int x, unsigned int y); +init_anic(unsigned int x, unsigned int y, chtype attrs); void free_anic(struct anic *a); int -anic_cb(WINDOW *win, void *data, bool needs_update); +anic_cb(WINDOW *win, void *data, bool needs_update, bool timed_out); void -register_anic(struct anic *a, chtype attr); +register_anic(struct anic *a); #endif @@ -6,19 +6,20 @@ struct input * -init_input(unsigned int x, unsigned int y, unsigned int width, char *prompt, size_t input_len) +init_input(unsigned int x, unsigned int y, unsigned int width, char *prompt, size_t input_len, chtype attrs) { struct input *a = calloc(1, sizeof(struct input)); a->x = x; a->y = y; a->width = width; + a->cur_pos = 0; a->input = calloc(input_len+1, sizeof(char)); a->input_max = input_len; a->input_len = 0; a->input_pos = 0; a->prompt = strdup(prompt); - a->active = false; + a->attrs = attrs; return (a); } @@ -33,12 +34,32 @@ free_input(struct input *a) } static void +print_input_text(WINDOW *win, struct input *a) +{ + size_t start = 0; + size_t p_len = strlen(a->prompt); + + char tmp[a->width + 1]; + memset(tmp, '\0', a->width + 1); + if (a->input_pos >= a->width) { + start = a->input_pos - a->width; + } + strncpy(tmp, (char *)(a->input + start), a->width); + if (win == NULL) { + mvprintw(a->y, a->x + p_len, "%s", tmp); + } else { + mvwprintw(win, a->y, a->x + p_len, "%s", tmp); + } +} + +static void print_input(WINDOW *win, struct input *a) { char *tmp; int i; size_t p_len = strlen(a->prompt); + attron(a->attrs); if (win == NULL) { mvprintw(a->y, a->x, a->prompt); tmp = calloc(a->width+1, sizeof(char)); @@ -47,40 +68,59 @@ print_input(WINDOW *win, struct input *a) } mvprintw(a->y, a->x + p_len, tmp); free(tmp); - mvprintw(a->y, a->x + p_len, a->input); + } else { } + print_input_text(win, a); + attroff(a->attrs); } int -post_input_cb(WINDOW *win, void *data, bool needs_update) +activate_input(WINDOW *win, struct input *a) { - struct input *a = (struct input *) data; - if (a == NULL) return (UICB_ERR_UNDEF); - if (a->active == true) { - if (win == NULL) { - move(a->y, a->x + a->input_pos); - } else { - wmove(win, a->y, a->x + a->input_pos); - } - return (UICB_CURSOR); + size_t p_len = strlen(a->prompt); + if (win == NULL) { + move(a->y, a->x + p_len + a->cur_pos); + } else { + wmove(win, a->y, a->x + p_len + a->cur_pos); } return (UICB_OK); } +int +add_input(WINDOW *win, struct input *a, int key) +{ + if (a == NULL) return (UICB_ERR_UNDEF); + if (a->input_len >= a->input_max) return (UICB_ERR_BUF); + *(a->input + a->input_pos) = (char) key; + ++a->input_pos; + ++a->input_len; + a->cur_pos = (a->cur_pos+1 < a->width ? a->cur_pos+1 : a->cur_pos); + print_input(win, a); + //mvwprintw(win, 10, 1, "w:%d,cp:%d,im:%lu,il:%lu,ip:%lu,s:%s", a->width, a->cur_pos, a->input_max, a->input_len, a->input_pos, a->input); + return (UICB_OK); +} int -input_cb(WINDOW *win, void *data, bool needs_update) +del_input(WINDOW *win, struct input *a) +{ + return (UICB_OK); +} + +int +input_cb(WINDOW *win, void *data, bool needs_update, bool timed_out) { struct input *a = (struct input *) data; if (a == NULL) return (UICB_ERR_UNDEF); - print_input(win, a); + if (needs_update || timed_out) { + print_input(win, a); + } return (UICB_OK); } void -register_input(WINDOW *win, struct input *a, chtype attr) +register_input(WINDOW *win, struct input *a) { - register_ui_elt(input_cb, post_input_cb, (void *) a, win, attr); + register_ui_elt(input_cb, (void *) a, win); } @@ -8,24 +8,34 @@ struct input { unsigned int x; unsigned int y; unsigned int width; + unsigned int cur_pos; char *input; size_t input_max; size_t input_len; size_t input_pos; char *prompt; - bool active; + chtype attrs; }; struct input * -init_input(unsigned int x, unsigned int y, unsigned int width, char *prompt, size_t input_len); +init_input(unsigned int x, unsigned int y, unsigned int width, char *prompt, size_t input_len, chtype attrs); void free_input(struct input *a); int -input_cb(WINDOW *win, void *data, bool needs_update); +activate_input(WINDOW *win, struct input *a); + +int +add_input(WINDOW *win, struct input *a, int key); + +int +del_input(WINDOW *win, struct input *a); + +int +input_cb(WINDOW *win, void *data, bool needs_update, bool timed_out); void -register_input(WINDOW *win, struct input *a, chtype attr); +register_input(WINDOW *win, struct input *a); #endif |