diff -urN cui83/cui.c cui84/cui.c --- cui83/cui.c Thu Mar 27 23:00:00 2014 +++ cui84/cui.c Fri Mar 28 03:00:00 2014 @@ -410,39 +410,42 @@ #define KEY_FD 0 static fd_set sel_rfs, res_rfs; +static int sel_inited = FALSE; -static void +void cui_select_init(void) { FD_ZERO(&sel_rfs); + FD_SET(KEY_FD, &sel_rfs); + sel_inited = TRUE; } -static void +void cui_select_add(int fd) { FD_SET(fd, &sel_rfs); } -static void +void cui_select_del(int fd) { FD_CLR(fd, &sel_rfs); } -static int +int cui_select(void) { - int nfds = 1, fd; + int nfds = 0, fd; struct timeval tm; res_rfs = sel_rfs; - for(fd=0; fd nfds) nfds = fd; tm.tv_sec = 0; tm.tv_usec = 100*1000; - return select(nfds, &res_rfs, NULL, NULL, &tm); + return select(nfds+1, &res_rfs, NULL, NULL, &tm); } -static int +int cui_select_chk(int fd) { return FD_ISSET(fd, &res_rfs); @@ -458,16 +461,24 @@ cui_readable_list readable_list = NULL; +static void +cui_readable_select_setup(void) +{ + cui_readable_list p = readable_list; + cui_select_init(); + for(; p; p=p->next) cui_select_add(p->fd); +} + void cui_readable_add(cui obj, int fd) { cui_readable_list p; - if((p = malloc(sizeof(struct cui_readable_list))) == NULL) ERR("No Mem"); p->obj = obj; p->fd = fd; p->next = readable_list; readable_list = p; + cui_readable_select_setup(); } void @@ -478,6 +489,7 @@ if(p == NULL) return; *prev = p->next; free(p); + cui_readable_select_setup(); } void @@ -517,8 +529,7 @@ cui_clear(top_obj); cui_draw(top_obj); - cui_select_init(); - cui_select_add(KEY_FD); + if(!sel_inited) cui_select_init(); while(cui_running_get()){ cui_timer_work(); diff -urN cui83/cui_test.c cui84/cui_test.c --- cui83/cui_test.c Thu Mar 27 23:00:00 2014 +++ cui84/cui_test.c Fri Mar 28 03:00:00 2014 @@ -309,7 +309,7 @@ { /* CUI_EVT_BUTTON */ - cui term = (cui)prm; + cui term = ((cui_terminal)prm)->term; int i, n, x, y; char buf[1024]; static int cnt = 0; @@ -421,7 +421,8 @@ cui in_hoge = cui_scpanel_sheet_get(sc_hoge); cui bs_term = cui_base_new(bs, 1, 2, 0, 0); cui btn_term = cui_button_new(bs_term, 0, 1, "test"); - cui term = cui_term_new(bs_term, 0, 2, 30, 15); + //cui term = cui_term_new(bs_term, 0, 2, 30, 15); + cui term = cui_terminal_new(bs_term, 0, 2, 30, 15); cui bs_timer = cui_base_new(bs, 1, 2, 0, 0); cui lb_timer1 = cui_label_new(bs_timer, 0, 1, "0 "); cui lb_timer2 = cui_label_new(bs_timer, 10, 1, "not yet"); @@ -475,9 +476,9 @@ strcpy(lb_timer1_buf, "0"); cui_label_str_set(lb_timer1, lb_timer1_buf); - cui_timer_set_bind(lb_timer1, 1000, 0, lb_timer_hdr, lb_timer1_buf); - cui_timer_set_bind(lb_timer2, 200, 0, lb_timer_hdr, NULL); - cui_timer_set_bind(lb_timer3, 10*1000, 1, lb_timer_hdr, NULL); + cui_timer_set_bind(lb_timer1, 1000, FALSE, lb_timer_hdr, lb_timer1_buf); + cui_timer_set_bind(lb_timer2, 200, FALSE, lb_timer_hdr, NULL); + cui_timer_set_bind(lb_timer3, 10*1000, TRUE, lb_timer_hdr, NULL); cui_tab_new(bs, 1, 1, -1, (char *[]){"foo", "bar", "hoge", "term", "timer", NULL}, tab_sheets, 0); diff -urN cui83/term.c cui84/term.c --- cui83/term.c Thu Mar 27 22:00:00 2014 +++ cui84/term.c Fri Mar 28 03:00:00 2014 @@ -1,9 +1,14 @@ #include "term.h" #include "handler.h" +#include "fill.h" +#include "rszbox.h" +#include "key.h" +#include "timer.h" #include #include #include #include +#include #define UPDATE_FLG (1<<7) @@ -342,6 +347,7 @@ { cui_term p = (cui_term)obj; + if(p->cursor_onoff) cui_term_buf(obj, p->cx, p->cy)[1] |= UPDATE_FLG; p->cx = 0; if(p->cy < obj->h-1) p->cy++; else{ @@ -372,6 +378,136 @@ cui_term_update(cui obj) { hdr_update(obj); +} + +/**/ + +#define TIMEOUT_MSEC (3*1000) + +static void +boot_sh(cui obj) +{ + cui_terminal p = (cui_terminal)obj; + int pipe_to_sh[2], pipe_from_sh[2]; + int ret; + + if(pipe(pipe_to_sh) < 0) ERR("pipe"); + if(pipe(pipe_from_sh) < 0) ERR("pipe"); + if((ret = fork()) < 0) ERR("fork"); + if(ret == 0){ /* child */ + close(pipe_to_sh[1]); + close(pipe_from_sh[0]); + dup2(pipe_to_sh[0] ,0); + dup2(pipe_from_sh[1] ,1); + dup2(pipe_from_sh[1] ,2); + close(pipe_to_sh[0]); + close(pipe_from_sh[1]); + + execl("/bin/sh", "/bin/sh", "-i", (char *)NULL); + exit(0); + } + /* parent */ + close(pipe_to_sh[0]); + close(pipe_from_sh[1]); + p->pipe_r = pipe_from_sh[0]; + p->pipe_w = pipe_to_sh[1]; +} + +cui +cui_terminal_new(cui parent, int x, int y, int w, int h) +{ + cui obj = cui_alloc(sizeof(struct cui_terminal)); + cui_terminal_init(obj, parent, x, y, w, h); + return obj; +} + +void +cui_terminal_init(cui obj, cui parent, int x, int y, int w, int h) +{ + cui_terminal p = (cui_terminal)obj; + int evts; + + cui_base_init(obj, parent, x, y, w, h); + obj->flags |= CUI_FLG_CAN_FOCUS; + + p->term = cui_term_new(obj, 1, 0, w-2, h); + p->in_key_mode = FALSE; + + p->fill_l = cui_fill_new(obj, 0, 0, 1, h, "|", CUI_ATTR_NORMAL); + p->fill_r = cui_fill_new(obj, w-1, 0, 1, h-1, "|", CUI_ATTR_NORMAL); + p->rszbox = cui_rszbox_new(obj); + + boot_sh(obj); + + evts = CUI_EVT_DRAW|CUI_EVT_KEY|CUI_EVT_RESIZE|CUI_EVT_TIMER|CUI_EVT_READABLE; + cui_bind(obj, evts, cui_terminal_hdr, NULL); + + cui_readable_add(obj, p->pipe_r); +} + +void +cui_terminal_in_key_mode_set(cui obj, int in_key_mode) +{ + int attr; + + cui_terminal p = (cui_terminal)obj; + if(p->in_key_mode == in_key_mode) return; + + p->in_key_mode = in_key_mode; + attr = in_key_mode ? CUI_ATTR_REVERSE : CUI_ATTR_NORMAL; + cui_fill_attr_set(p->fill_l, attr); + cui_fill_attr_set(p->fill_r, attr); + + cui_timer_set(obj, TIMEOUT_MSEC, TRUE); +} + +int +cui_terminal_hdr(cui obj, int evt, int val, void *prm) +{ + cui_terminal p = (cui_terminal)obj; + char *s, buf[1024]; + int n; + + switch(evt){ + case CUI_EVT_DRAW: + s = val == CUI_DRAW_FOCUS ? "/" : "|"; + cui_label_str_set(p->fill_l, s); + cui_label_str_set(p->fill_r, s); + return TRUE; + + case CUI_EVT_KEY: + if(!p->in_key_mode){ + if(val == CUI_KEY_ENTER){ + cui_terminal_in_key_mode_set(obj, TRUE); + return TRUE; + } + return FALSE; + } + /* in_key_mode */ + if(val == CUI_KEY_ENTER) val = '\n'; + cui_term_putc(p->term, val); + if(write(p->pipe_w, &val, 1) != 1) ERR("write"); + cui_timer_set(obj, TIMEOUT_MSEC, TRUE); + return TRUE; + + case CUI_EVT_RESIZE: + cui_wh_set(p->term, obj->w-2, obj->h); + cui_wh_set(p->fill_l, 1, obj->h); + cui_xywh_set(p->fill_r, obj->w-1, 0, 1, obj->h-1); + cui_xy_set(p->rszbox, obj->w-1, obj->h-1); + return TRUE; + + case CUI_EVT_TIMER: + cui_terminal_in_key_mode_set(obj, FALSE); + return TRUE; + + case CUI_EVT_READABLE: + if((n = read(p->pipe_r, buf, 1024-1)) < 0) ERR("read"); + buf[n] = '\0'; + cui_term_puts(p->term, buf); + return TRUE; + } + return FALSE; } /* EOF */ diff -urN cui83/term.h cui84/term.h --- cui83/term.h Wed Mar 26 23:00:00 2014 +++ cui84/term.h Fri Mar 28 03:00:00 2014 @@ -17,6 +17,14 @@ int ow, oh; } *cui_term; +typedef struct cui_terminal{ + struct cui_base base; + cui term, fill_l, fill_r, rszbox; + int in_key_mode; + int pipe_r, pipe_w; + +} *cui_terminal; + cui cui_term_new(cui parent, int x, int y, int w, int h); void cui_term_init(cui obj, cui parent, int x, int y, int w, int h); int cui_term_hdr(cui obj, int evt, int val, void *prm); @@ -35,5 +43,12 @@ char *cui_term_buf(cui obj, int cx, int cy); void cui_term_move(cui obj, int cx, int cy); void cui_term_update(cui obj); + +/**/ + +cui cui_terminal_new(cui parent, int x, int y, int w, int h); +void cui_terminal_init(cui obj, cui parent, int x, int y, int w, int h); +int cui_terminal_hdr(cui obj, int evt, int val, void *prm); +void cui_terminal_in_key_mode_set(cui obj, int in_key_mode); #endif