diff -uNr jfbterm-0.4.6-han-3.4-orig/main.c jfbterm-0.4.6-han-3.4/main.c --- jfbterm-0.4.6-han-3.4-orig/main.c 2004-06-03 19:41:13.000000000 +0900 +++ jfbterm-0.4.6-han-3.4/main.c 2005-11-19 21:35:25.000000000 +0900 @@ -381,6 +381,9 @@ #endif TCapability* fcap; char* cp; +#ifdef JFB_SCROLLBACK + char *histlen; +#endif const char* tn; char* en; #if 1 // Hangul @@ -450,6 +453,11 @@ tfbm_open(&gFramebuffer); util_privilege_drop(); +#ifdef JFB_SCROLLBACK + histlen = tcaps_find_first(&(gApp.gCaps), "history"); + if(!histlen) histlen = "256"; + tvterm_set_histlen(atoi(histlen)); +#endif tn = tcaps_find_first(&(gApp.gCaps), "term"); if (!tn) { tn = "jfbterm"; diff -uNr jfbterm-0.4.6-han-3.4-orig/term.c jfbterm-0.4.6-han-3.4/term.c --- jfbterm-0.4.6-han-3.4-orig/term.c 2004-06-03 19:41:13.000000000 +0900 +++ jfbterm-0.4.6-han-3.4/term.c 2005-11-19 21:36:09.000000000 +0900 @@ -70,6 +70,103 @@ static void tterm_set_utmp(TTerm* p); static void tterm_reset_utmp(TTerm* p); +#define JFB_SCROLLBACK +#ifdef JFB_SCROLLBACK +/* + * temporary patch for scrollback on jfbterm + * nskystars at yahoo.com, 20051119 + * - preliminary test version, may have many problems + */ + +#include +#include + +int set_kb_entry(unsigned short table, unsigned short keycode, + unsigned short value, unsigned short *oldvalue) +{ + struct kbentry ke; + + ke.kb_table = table; + ke.kb_index = keycode; + + if(ioctl(fileno(stdin), KDGKBENT, &ke)) + return -1; + + if(oldvalue) *oldvalue = ke.kb_value; + ke.kb_value = value; + + if(ioctl(fileno(stdin), KDSKBENT, &ke)) + return -1; + + return 0; +} + +int set_kb_entry_nowrite(unsigned short table, unsigned short keycode, + unsigned short value, unsigned short *oldvalue) +{ + struct kbentry ke; + + ke.kb_table = table; + ke.kb_index = keycode; + + if(ioctl(fileno(stdin), KDGKBENT, &ke)) + return -1; + + ke.kb_value = value; + + if(ioctl(fileno(stdin), KDSKBENT, &ke)) + return -1; + + return 0; +} + +unsigned short scroll_forward = 0; +unsigned short scroll_backward = 0; + +#define SHIFT_TABLE 1 +#define PAGE_UP_KEYCODE 104 +#define PAGE_DOWN_KEYCODE 109 +#define PAGE_UP_ACTION 0x0118 +#define PAGE_DOWN_ACTION 0x0119 + +void restore_scrollback(void) { + if(scroll_backward) + set_kb_entry(SHIFT_TABLE, PAGE_UP_KEYCODE, scroll_backward, 0); + if(scroll_forward) + set_kb_entry(SHIFT_TABLE, PAGE_DOWN_KEYCODE, scroll_forward, 0); +} + +int disable_scrollback(void) { + if(set_kb_entry(SHIFT_TABLE, PAGE_UP_KEYCODE, PAGE_UP_ACTION, &scroll_backward)) + return -1; + if(set_kb_entry(SHIFT_TABLE, PAGE_DOWN_KEYCODE, PAGE_DOWN_ACTION, &scroll_forward)) + return -1; + atexit(restore_scrollback); + return 0; +} + +void restore_scrollback_nowrite(void) { + if(scroll_backward) + set_kb_entry_nowrite(SHIFT_TABLE, PAGE_UP_KEYCODE, scroll_backward, 0); + if(scroll_forward) + set_kb_entry_nowrite(SHIFT_TABLE, PAGE_DOWN_KEYCODE, scroll_forward, 0); +} + +int disable_scrollback_nowrite(void) { + if(set_kb_entry_nowrite(SHIFT_TABLE, PAGE_UP_KEYCODE, PAGE_UP_ACTION, &scroll_backward)) + return -1; + if(set_kb_entry_nowrite(SHIFT_TABLE, PAGE_DOWN_KEYCODE, PAGE_DOWN_ACTION, &scroll_forward)) + return -1; + return 0; +} + +int cur_page = 0; + +void reset_scrollback_counter(void) { + cur_page = 0; +} +#endif + void send_hangup( int closure) { @@ -141,6 +238,11 @@ } #endif +#ifdef JFB_SCROLLBACK +int tvterm_get_hist_size(TVterm *p); +void tvterm_refresh_hist(TVterm *p, int page); +#endif + #define BUF_SIZE 1024 void tterm_start(TTerm* p, const char* tn, const char* en) { @@ -162,6 +264,9 @@ int tfbm_set_blank(int, int); # define DIMMER_TIMEOUT (3 * 60 * 10) /* 3 min */ #endif +#ifdef JFB_SCROLLBACK + int hist_total_pages; +#endif tterm_init(p, en); if (!tterm_get_ptytty(p)) { @@ -196,6 +301,11 @@ tterm_set_utmp(p); signal(SIGCHLD, sigchld); atexit(application_final); +#ifdef JFB_SCROLLBACK + disable_scrollback(); + hist_total_pages = 0; + cur_page = 0; +#endif /* not available * VtInit(); @@ -238,6 +348,29 @@ #endif if (ret > 0) { #if 1 // Hangul +#ifdef JFB_SCROLLBACK +if(get_shift_state() && + buf[0] == '\033' && + buf[1] == '[' && + buf[2] == '5' && + buf[3] == '~') { + hist_total_pages = tvterm_get_hist_size(&(p->vterm)) / ((&(p->vterm))->ycap / 2) + 1; + if(hist_total_pages > cur_page) + tvterm_refresh_hist(&(p->vterm), ++cur_page); +} +else if(get_shift_state() && + buf[0] == '\033' && + buf[1] == '[' && + buf[2] == '6' && + buf[3] == '~') { + if(cur_page > 0) + tvterm_refresh_hist(&(p->vterm), --cur_page); + if(cur_page == 0) + tvterm_refresh(&(p->vterm)); +} +else { + cur_page = 0; +#endif if(process_hangul_input) { for(i = 0; i < ret; i++) { c = buf[i]; @@ -283,6 +416,9 @@ else { write(p->ptyfd, buf, ret); } +#ifdef JFB_SCROLLBACK +} +#endif #else write(p->ptyfd, buf, ret); #endif diff -uNr jfbterm-0.4.6-han-3.4-orig/vterm.c jfbterm-0.4.6-han-3.4/vterm.c --- jfbterm-0.4.6-han-3.4-orig/vterm.c 2004-06-03 19:41:13.000000000 +0900 +++ jfbterm-0.4.6-han-3.4/vterm.c 2005-11-19 21:34:28.000000000 +0900 @@ -436,6 +436,14 @@ p->altCs = FALSE; } +#ifdef JFB_SCROLLBACK +static int histlen; +void tvterm_set_histlen(int len) +{ + histlen = len; +} +#endif + void tvterm_start(TVterm* p) { p->pen.x = 0; @@ -470,6 +478,12 @@ p->text = (u_int *)calloc(p->xcap4, p->ycap * sizeof(u_int)); p->attr = (u_char *)calloc(p->xcap4, p->ycap); p->flag = (u_char *)calloc(p->xcap4, p->ycap); +#ifdef JFB_SCROLLBACK + p->histsize = histlen; + p->htext = (u_int *)calloc(p->xcap4, p->histsize * sizeof(u_int)); + p->hattr = (u_char *)calloc(p->xcap4, p->histsize); + p->hflag = (u_char *)calloc(p->xcap4, p->histsize); +#endif ioctl(0, KDSETMODE, KD_GRAPHICS); /* @@ -502,6 +516,11 @@ util_free(p->text); util_free(p->attr); util_free(p->flag); +#ifdef JFB_SCROLLBACK + util_free(p->htext); + util_free(p->hattr); + util_free(p->hflag); +#endif } void tvterm_push_current_pen(TVterm* p, TBool b) diff -uNr jfbterm-0.4.6-han-3.4-orig/vterm.h jfbterm-0.4.6-han-3.4/vterm.h --- jfbterm-0.4.6-han-3.4-orig/vterm.h 2004-06-03 19:41:13.000000000 +0900 +++ jfbterm-0.4.6-han-3.4/vterm.h 2005-11-19 21:34:28.000000000 +0900 @@ -158,6 +158,19 @@ u_int* text; /* 1 文字当たり 4 bytes */ u_char* attr; u_char* flag; +#define JFB_SCROLLBACK +#ifdef JFB_SCROLLBACK +/* + * temporary patch for scrollback on jfbterm + * nskystars at yahoo.com, 20051119 + * - preliminary test version, may have many problems + */ + + int histsize; + u_int *htext; + u_char *hattr; + u_char *hflag; +#endif } TVterm; void tvterm_insert_n_chars(TVterm* p, int n); diff -uNr jfbterm-0.4.6-han-3.4-orig/vtermlow.c jfbterm-0.4.6-han-3.4/vtermlow.c --- jfbterm-0.4.6-han-3.4-orig/vtermlow.c 2004-06-03 19:41:13.000000000 +0900 +++ jfbterm-0.4.6-han-3.4/vtermlow.c 2005-11-19 21:34:28.000000000 +0900 @@ -135,6 +135,64 @@ } /*---------------------------------------------------------------------------*/ +#define JFB_SCROLLBACK +#ifdef JFB_SCROLLBACK +/* + * temporary patch for scrollback on jfbterm + * nskystars at yahoo.com, 20051119 + * - preliminary test version, may have many problems + */ + +static int hist_start = -1; +static int hist_next = 0; + +static inline u_int tvterm_hist_coord_to_index(TVterm *p, u_int x, u_int y) +{ + return (p->textHead + x + y * p->xcap4) % (p->xcap4 * p->histsize); +} + +int tvterm_get_hist_size(TVterm *p) +{ + if(hist_start == -1) + return 0; + else if(hist_start == hist_next) + return p->histsize; + return hist_next - hist_start; +} + +int tvterm_get_abs_hist_line(TVterm *p, int rel) +{ + if(hist_start == -1 || rel >= tvterm_get_hist_size(p)) + return -1; + return (hist_next - (rel + 1) + p->histsize) % p->histsize; +} + +void tvterm_move_to_hist(TVterm *p, int dst, int src, int n) +{ + memmove(p->htext+dst, p->text+src, n*sizeof(u_int)); + memmove(p->hattr+dst, p->attr+src, n); + memmove(p->hflag+dst, p->flag+src, n); +} + +void tvterm_move_from_hist(TVterm *p, int dst, int src, int n) +{ + memmove(p->text+dst, p->htext+src, n*sizeof(u_int)); + memmove(p->attr+dst, p->hattr+src, n); + memmove(p->flag+dst, p->hflag+src, n); +} + +void tvterm_insert_hist_line(TVterm *p, int src) +{ + int dst; + dst = tvterm_hist_coord_to_index(p, 0, hist_next); + tvterm_move_to_hist(p, dst, src, p->xcap4); + + if(hist_start == hist_next || hist_start == -1) + hist_start = ++hist_start % p->histsize; + hist_next = ++hist_next % p->histsize; +} +#endif + void tvterm_delete_n_chars(TVterm* p, int n) { u_int addr; @@ -336,6 +394,137 @@ } } +#ifdef JFB_SCROLLBACK +void tvterm_refresh_hist(TVterm *p, int page) +{ + u_int i; + int x, y; + u_int lang; + u_char ch, ch2; + u_int chlw; + u_char fc, bc, fg; + TFont *pf; + const u_char *glyph; + u_int w, gw; + + int scrollup_len; + int cur_hist_size; + int scroll_min; + int ty; + + tvterm_show_cursor(p, FALSE); + + scrollup_len = (p->ycap / 2) * page; + cur_hist_size = tvterm_get_hist_size(p); + if(scrollup_len > cur_hist_size) + scrollup_len = cur_hist_size; + scroll_min = scrollup_len - p->ycap; + if(scroll_min < 0) scroll_min = 0; + + for(ty = scrollup_len - 1; ty >= scroll_min; ty--) { + y = tvterm_get_abs_hist_line(p, ty); + for(x = 0; x < p->xcap; x++) { + i = tvterm_hist_coord_to_index(p, x, y); + p->hflag[i] = p->hflag[i] & ~CLEAN_S; + } + } + + for(ty = scrollup_len - 1; ty >= scroll_min; ty--) { + y = tvterm_get_abs_hist_line(p, ty); + for(x = 0; x < p->xcap; x++) { + i = tvterm_hist_coord_to_index(p, x, y); + w = 1; + fg = p->hflag[i]; + if(fg & CLEAN_S) { + continue; + } + fc = p->hattr[i] & 0xf; + bc = p->hattr[i] >> 4; + chlw = p->htext[i]; + ch2 = (chlw >> 8) & 0xff; + ch = chlw & 0xff; + lang = (chlw >> 24) & 0xff; + p->hflag[i] |= CLEAN_S; + + if(fg & CODEIS_1) { + pf = &(gFont[lang]); + i++; + p->hflag[i] |= CLEAN_S; + w = 2; + } else { + pf = &(gFont[lang]); + } + + glyph = pf->conv(pf, chlw, &gw); + gFramebuffer.cap.fill(&gFramebuffer, + gFontsWidth * x, gFontsHeight * (scrollup_len - 1 - ty), + gFontsWidth * w, + gFontsHeight, bc); + if(chlw == 0) + continue; + gFramebuffer.cap.overlay(&gFramebuffer, + gFontsWidth * x, gFontsHeight * (scrollup_len - 1 - ty), + glyph, gw, pf->height, pf->bytew, fc); + } + } + + for(y = 0; y < (p->ycap - scrollup_len); y ++) { + for(x = 0; x < p->xcap; x ++) { + i = tvterm_coord_to_index(p, x, y); + p->flag[i] = p->flag[i] & ~CLEAN_S; + } + } + + for(y = 0; y < p->ycap - scrollup_len; y ++) { + for(x = 0; x < p->xcap; x ++) { + i = tvterm_coord_to_index(p, x, y); + w = 1; + fg = p->flag[i]; + if(fg & CLEAN_S) { + continue; + } + fc = p->attr[i] & 0xf; + bc = p->attr[i] >> 4; + chlw = p->text[i]; + ch2 = (chlw >> 8) & 0xFF; + ch = chlw & 0xFF; + lang = (chlw >> 24) & 0xFF; + p->flag[i] |= CLEAN_S; + + if (fg & CODEIS_1) { + pf = &(gFont[lang]); + i++; + p->flag[i] |= CLEAN_S; + w = 2; + } else { + pf = &(gFont[lang]); + } + + glyph = pf->conv(pf, chlw, &gw); + gFramebuffer.cap.fill(&gFramebuffer, + gFontsWidth * x, gFontsHeight * (y + scrollup_len), + gFontsWidth * w, + gFontsHeight, bc); + if (chlw == 0) + continue; + gFramebuffer.cap.overlay(&gFramebuffer, + gFontsWidth * x, gFontsHeight * (y + scrollup_len), + glyph, gw, pf->height, pf->bytew, fc); + } + } + + for(y = 0; y < p->ycap; y++) { + for(x = 0; x < p->xcap; x++) { + i = tvterm_coord_to_index(p, x, y); + p->flag[i] = p->flag[i] & ~CLEAN_S; + } + } + + if(p->release) { + sig_leave_virtual_console(SIGUSR1); + } +} +#endif /*---------------------------------------------------------------------------*/ static TVterm* sig_obj = NULL; @@ -378,7 +567,11 @@ tvterm_refresh(p); } - +#ifdef JFB_SCROLLBACK +void restore_scrollback_nowrite(void); +void disable_scrollback_nowrite(void); +void reset_scrollback_counter(void); +#endif static void sig_leave_virtual_console(int signum) { @@ -389,6 +582,10 @@ } else { sig_obj->release = FALSE; sig_obj->active = FALSE; +#ifdef JFB_SCROLLBACK + restore_scrollback_nowrite(); + reset_scrollback_counter(); +#endif /* * SetTextMode(); */ @@ -404,6 +601,9 @@ tvterm_register_signal(sig_obj); signal(SIGUSR2, sig_enter_virtual_console); } +#ifdef JFB_SCROLLBACK + disable_scrollback_nowrite(); +#endif } void tvterm_wput(TVterm* p, u_int idx, u_char ch1, u_char ch2) @@ -581,6 +781,12 @@ if (btm <= top + line) { tvterm_text_clean_band(p, top, btm); } else { +#ifdef JFB_SCROLLBACK + for(n = top; n < top + line; n++) { + src = tvterm_coord_to_index(p, 0, n); + tvterm_insert_hist_line(p, src); + } +#endif for (n = top; n < btm - line; n ++) { dst = tvterm_coord_to_index(p, 0, n); src = tvterm_coord_to_index(p, 0, n+line);