/* Shoe console window * * Copyright (c) 1998 by Fredrik Noring . */ #include #include #include #include #include #include #include "mp2audio.h" #include "window.h" #include "libshoe.h" #include "console.h" /* global variable from main.c */ extern int vdi_id; void initialize_console(int w, int h); static struct { int h, w; int char_w, char_h; int cell_w, cell_h; int screen_w, screen_h; int row, scroll, cur_col, cur_row; char scrollback[CONSOLE_H][CONSOLE_W+1]; int hist_row, hist_off, hist_nr, hist_min, hist_max; char hist_list[HISTORY_LEN][CONSOLE_W+1]; } console; #define transform(xywh) { (xywh)[2]+=(xywh)[0]-1; (xywh)[3]+=(xywh)[1]-1; } #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) void shrink(int *xywh1, int *xywh2) { int clip[4]; clip[0] = xywh1[0]xywh2[2]?xywh2[2]:xywh1[2]; clip[3] = xywh1[3]>xywh2[3]?xywh2[3]:xywh1[3]; vs_clip(vdi_id, 1, clip); } void cursor(int mode) { int cur[4], work[4]; if(mode) { console.cur_col = (int) strlen(console.scrollback[(console.row+console.scroll)%CONSOLE_H]); console.cur_row = console.row; } wind_get(windforms[WIND_SHOE].whandle, WF_WORKXYWH, work+0, work+1, work+2, work+3); if(console.cur_col < 0) return; cur[0] = work[0] + console.cell_w*console.cur_col+1; cur[1] = work[1] + console.cell_h*console.cur_row+1; cur[2] = cur[0] + console.cell_w-2; cur[3] = cur[1] + console.cell_h-2; vsf_color(vdi_id, mode); vr_recfl(vdi_id, cur); } void redraw_console(int *xywh, int row) { int i, j, line[4], work[4]; transform(xywh); wind_get(windforms[WIND_SHOE].whandle, WF_WORKXYWH, &work[0], &work[1], &work[2], &work[3]); work[2]++; work[3]++; transform(work); shrink(work, xywh); graf_mouse(M_OFF,0); wind_update(BEG_UPDATE); cursor(0); vsf_color(vdi_id, 0); if(row < 0) i = 0; else i = console.row; for(; i < CONSOLE_H; i++) { j = (console.scroll+i)%CONSOLE_H; line[0] = work[0]; line[1] = work[1]+console.cell_h*i; line[2] = line[0]+console.cell_w*(int)strlen(console.scrollback[j])-1; line[3] = line[1]; vr_recfl(vdi_id, line); line[0] = work[2]; line[3] += console.cell_h-1; vr_recfl(vdi_id, line); v_gtext(vdi_id, work[0], work[1]+console.cell_h-2+console.cell_h*i, console.scrollback[j]); if(row >= 0) break; } line[0] = work[0]; line[1] = work[3]; line[2] = work[2]; line[3] = work[3]; vr_recfl(vdi_id, line); cursor(1); vs_clip(vdi_id, 0, work); /* clipping off */ wind_update(END_UPDATE); graf_mouse(M_ON,0); } void print_line(char *text) { int xywh[4]; size_t left, len; char *s, saved[CONSOLE_W+1]; s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; strcpy(saved, s); left = strlen(text); while(left > 0) { s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; len = min(CONSOLE_W, left); strncpy(s, text, len); s[len] = '\0'; text += len; left -= len; if(console.row+1 < CONSOLE_H) console.row++; else console.scroll = (console.scroll+1)%CONSOLE_H; console.scrollback[(console.row+console.scroll)%CONSOLE_H][0] = '\0'; } s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; strcpy(s, saved); wind_get(windforms[WIND_SHOE].whandle, WF_FIRSTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); while(xywh[2] || xywh[3]) { redraw_console(xywh, -1); wind_get(windforms[WIND_SHOE].whandle, WF_NEXTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); } } void clear_console(void) { int i, xywh[4]; char *s, saved[CONSOLE_W+1]; s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; strcpy(saved, s); console.row = 0; console.scroll = 0; console.cur_row = console.cur_col = 0; for(i = 0; i < CONSOLE_H; i++) console.scrollback[i][0] = '\0'; s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; strcpy(s, saved); wind_get(windforms[WIND_SHOE].whandle, WF_FIRSTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); while(xywh[2] || xywh[3]) { redraw_console(xywh, -1); wind_get(windforms[WIND_SHOE].whandle, WF_NEXTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); } } void prompt_console(int key, int delta) { char *s, *h, *sap, *shoe_res; int xywh[4], pbal; size_t plen; static char p[10]; pbal = (int)inquire_balance(); if(pbal) sprintf(p, "%d> ", pbal); else sprintf(p, "> "); plen = strlen(p); s = console.scrollback[(console.row+console.scroll)%CONSOLE_H]; if(strlen(s) == 0) { strncpy(s, p, min(CONSOLE_W, plen)); s[min(CONSOLE_W, plen)] = '\0'; } sap = &s[plen]; switch((key>>8) & 0xff) { case 72: /* Arrow up */ if(console.hist_nr == console.hist_max) { h = console.hist_list[console.hist_max]; strcpy(h, sap); } if(console.hist_nr != console.hist_min) { console.hist_nr = (console.hist_nr-1+HISTORY_LEN) % HISTORY_LEN; h = console.hist_list[console.hist_nr], strncpy(sap, h, min(CONSOLE_W-plen-1,strlen(h))); sap[min(CONSOLE_W-plen-1,strlen(h))] = '\0'; prompt_console(0, -1); } break; case 80: /* Arrow down */ if(console.hist_nr != console.hist_max) { console.hist_nr = (console.hist_nr+1) % HISTORY_LEN; h = console.hist_list[console.hist_nr], strncpy(sap, h, min(CONSOLE_W-plen-1,strlen(h))); sap[min(CONSOLE_W-plen-1,strlen(h))] = '\0'; prompt_console(0, -1); } break; default: break; } switch(key & 0xff) { case 0x00: /* no key pressed */ break; case 0x08: /* backspace */ if(plen < strlen(s)) { s[strlen(s)-1] = '\0'; } break; case 0x0d: /* return */ /* Save row in history if not empty */ if(sap[0]) { h = console.hist_list[(console.hist_row+console.hist_off)%HISTORY_LEN]; strcpy(h, sap); if(console.hist_row+1 < HISTORY_LEN) console.hist_row++; else console.hist_off = (console.hist_off+1) % HISTORY_LEN; console.hist_list[(console.hist_row+console.hist_off)%HISTORY_LEN][0] = '\0'; console.hist_max=(console.hist_row+console.hist_off)%HISTORY_LEN; if(console.hist_off) console.hist_min=(console.hist_max+1)%HISTORY_LEN; else console.hist_min=0; console.hist_nr=console.hist_max; } if(console.row+1 < CONSOLE_H) console.row++; else console.scroll = (console.scroll+1)%CONSOLE_H; console.scrollback[(console.row+console.scroll)%CONSOLE_H][0] = '\0'; print_line(""); shoe_res = parse_eval(sap); if(shoe_res && shoe_res[0]) print_line(shoe_res); prompt_console(0, -1); return; default: if(strlen(s) < CONSOLE_W-1) { strncat(s, (char*)&key+1, 1); } } wind_get(windforms[WIND_SHOE].whandle, WF_FIRSTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); while(xywh[2] || xywh[3]) { redraw_console(xywh, delta); wind_get(windforms[WIND_SHOE].whandle, WF_NEXTXYWH, &xywh[0], &xywh[1], &xywh[2], &xywh[3]); } } void notify_console(char *msg) { int i; char *s; s = windforms[WIND_SHOE].wind_title + strlen(windforms[WIND_SHOE].wind_title) - 5; for(i = 0; i < 5; i++) s[i] = ' '; if(msg && strlen(msg)) { s[0] = '('; for(i = 0; i < 3 && msg[i]; i++) s[i+1] = msg[i]; s[i+1] = ')'; } wind_set(windforms[WIND_SHOE].whandle,WF_NAME, windforms[WIND_SHOE].wind_title); } void initialize_console(int w, int h) { int i; int dummy[4]; console.w = w; console.h = h; vst_point(vdi_id, 9, &console.char_w, &console.char_h, &console.cell_w, &console.cell_h); console.cell_h++; console.screen_w = console.cell_w*console.w; console.screen_h = console.cell_h*console.h; console.row = 0; console.scroll = 0; console.cur_col = console.cur_row = -1; for(i = 0; i < h; i++) console.scrollback[i][0] = '\0'; console.hist_row = 0; console.hist_off = 0; console.hist_nr = 0; console.hist_min = 0; console.hist_max = 0; for(i = 0; i < HISTORY_LEN; i++) console.hist_list[i][0] = '\0'; vsf_interior(vdi_id, FIS_SOLID); vswr_mode(vdi_id, MD_REPLACE); vst_color(vdi_id, 1); vst_effects(vdi_id, 0); vst_alignment(vdi_id, 0, 0, dummy, dummy); vst_rotation(vdi_id, 0); }