aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoni <matzeton@googlemail.com>2014-12-07 03:20:34 +0100
committertoni <matzeton@googlemail.com>2014-12-07 20:39:45 +0100
commitf365c0c482ab20a13af6155890c1784227559b6f (patch)
tree0bfe4edb59dd699a84e975d4c9cb8007892e7fb3
parente3ec8f9259d132eec7071343931fd26733d1dd64 (diff)
parentfc17c62cd6872ad16b2f87857f346c3da66cd4a2 (diff)
Merge branch 'master' of github.com:freecoding/naskpass
-rw-r--r--ui.c125
-rw-r--r--ui.h22
-rw-r--r--ui_ani.c27
-rw-r--r--ui_ani.h7
-rw-r--r--ui_input.c74
-rw-r--r--ui_input.h18
6 files changed, 179 insertions, 94 deletions
diff --git a/ui.c b/ui.c
index e321689..5d58d28 100644
--- a/ui.c
+++ b/ui.c
@@ -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);
}
diff --git a/ui.h b/ui.h
index 5fac530..b75ad41 100644
--- a/ui.h
+++ b/ui.h
@@ -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
diff --git a/ui_ani.c b/ui_ani.c
index c7aa61c..1fd308a 100644
--- a/ui_ani.c
+++ b/ui_ani.c
@@ -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);
}
diff --git a/ui_ani.h b/ui_ani.h
index 43a98b3..9622885 100644
--- a/ui_ani.h
+++ b/ui_ani.h
@@ -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
diff --git a/ui_input.c b/ui_input.c
index af88b3a..28660cf 100644
--- a/ui_input.c
+++ b/ui_input.c
@@ -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);
}
diff --git a/ui_input.h b/ui_input.h
index b9e816e..7b3a623 100644
--- a/ui_input.h
+++ b/ui_input.h
@@ -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