diff --git a/ssheven-console.c b/ssheven-console.c index 1e1e718..725d4a0 100644 --- a/ssheven-console.c +++ b/ssheven-console.c @@ -131,6 +131,25 @@ inline int idx2qd(VTermColor c) // closely inspired by the retro68 console library void draw_screen(Rect* r) +{ + switch (prefs.display_mode) + { + case FASTEST: + draw_screen_fast(r); + break; + case MONOCHROME: + draw_screen_mono(r); + break; + case COLOR: + draw_screen_color(r); + break; + default: + draw_screen_color(r); + break; + } +} + +void draw_screen_color(Rect* r) { // get the intersection of our console region and the update region //Rect bounds = (con.win->portRect); @@ -234,6 +253,138 @@ void draw_screen(Rect* r) con.win->clipRgn = old; } + +void draw_screen_fast(Rect* r) +{ + // don't clobber font settings + short save_font = qd.thePort->txFont; + short save_font_size = qd.thePort->txSize; + short save_font_face = qd.thePort->txFace; + short save_font_fg = qd.thePort->fgColor; + short save_font_bg = qd.thePort->bkColor; + + TextFont(kFontIDMonaco); + TextSize(9); + TextFace(normal); + qd.thePort->bkColor = whiteColor; + qd.thePort->fgColor = blackColor; + + EraseRect(r); + + TextFont(kFontIDMonaco); + TextSize(9); + TextFace(normal); + + ScreenCell* vtsc = NULL; + VTermPos pos = {.row = 0, .col = 0}; + + for(pos.row = 0; pos.row < con.size_y; pos.row++) + { + for (pos.col = 0; pos.col < con.size_x; pos.col++) + { + vtsc = vterm_screen_unsafe_get_cell(con.vts, pos); + draw_char(pos.col, pos.row, r, (char)vtsc->chars[0]); + } + } + + // do the cursor if needed + if (con.cursor_state == 1 && + con.cursor_visible == 1) + { + Rect cursor = cell_rect(con.cursor_x, con.cursor_y, con.win->portRect); + InvertRect(&cursor); + } + + TextFont(save_font); + TextSize(save_font_size); + TextFace(save_font_face); + qd.thePort->fgColor = save_font_fg; + qd.thePort->bkColor = save_font_bg; +} + +void draw_screen_mono(Rect* r) +{ + short minRow = 0; + short maxRow = con.size_y; + short minCol = 0; + short maxCol = con.size_x; + + // don't clobber font settings + short save_font = qd.thePort->txFont; + short save_font_size = qd.thePort->txSize; + short save_font_face = qd.thePort->txFace; + short save_font_fg = qd.thePort->fgColor; + short save_font_bg = qd.thePort->bkColor; + + TextFont(kFontIDMonaco); + TextSize(9); + TextFace(normal); + qd.thePort->bkColor = prefs.bg_color; + qd.thePort->fgColor = prefs.fg_color; + + EraseRect(r); + + TextFont(kFontIDMonaco); + TextSize(9); + TextFace(normal); + + short face = normal; + Rect cr; + + ScreenCell* vtsc = NULL; + VTermPos pos = {.row = 0, .col = 0}; + + for(pos.row = minRow; pos.row < maxRow; pos.row++) + { + for (pos.col = minCol; pos.col < maxCol; pos.col++) + { + vtsc = vterm_screen_unsafe_get_cell(con.vts, pos); + + face = normal; + if (vtsc->pen.bold) face |= (condense|bold); + if (vtsc->pen.italic) face |= (condense|italic); + if (vtsc->pen.underline) face |= underline; + + if (face != normal) TextFace(face); + draw_char(pos.col, pos.row, r, (char)vtsc->chars[0]); + if (face != normal) TextFace(normal); + + if (vtsc->pen.reverse) + { + cr = cell_rect(pos.col, pos.row, *r); + InvertRect(&cr); + } + } + } + + // do the cursor if needed + if (con.cursor_state == 1 && + con.cursor_visible == 1) + { + Rect cursor = cell_rect(con.cursor_x, con.cursor_y, con.win->portRect); + InvertRect(&cursor); + } + + TextFont(save_font); + TextSize(save_font_size); + TextFace(save_font_face); + qd.thePort->fgColor = save_font_fg; + qd.thePort->bkColor = save_font_bg; + + // draw the grow icon in the bottom right corner, but not the scroll bars + // yes, this is really awkward + MacRegion bottom_right_corner = { 10, con.win->portRect}; + MacRegion* brc = &bottom_right_corner; + MacRegion** old = con.win->clipRgn; + + bottom_right_corner.rgnBBox.top = bottom_right_corner.rgnBBox.bottom - 15; + bottom_right_corner.rgnBBox.left = bottom_right_corner.rgnBBox.right - 15; + + con.win->clipRgn = &brc; + DrawGrowIcon(con.win); + con.win->clipRgn = old; +} + void ruler(Rect* r) { char itoc[] = {'0','1','2','3','4','5','6','7','8','9'}; diff --git a/ssheven-console.h b/ssheven-console.h index edd2015..c4df38b 100644 --- a/ssheven-console.h +++ b/ssheven-console.h @@ -15,6 +15,10 @@ void console_setup(void); void draw_char(int x, int y, Rect* r, char c); void draw_screen(Rect* r); +void draw_screen_fast(Rect* r); +void draw_screen_mono(Rect* r); +void draw_screen_color(Rect* r); + void bump_up_line(); int is_printable(char c); diff --git a/ssheven-constants.r b/ssheven-constants.r index 9077481..4925cf3 100644 --- a/ssheven-constants.r +++ b/ssheven-constants.r @@ -22,15 +22,8 @@ /* size in bytes for recv and send thread buffers */ #define SSHEVEN_BUFFER_SIZE 4096 -/* - * terminal type to send over ssh, determines features etc. some good options: - * "vanilla" supports basically nothing - * "vt100" just the basics - * "xterm" everything - * "xterm-mono" everything except color - * "xterm-16color" classic 16 ANSI colors only - */ -#define SSHEVEN_TERMINAL_TYPE "xterm-16color" +/* default terminal string */ +#define SSHEVEN_DEFAULT_TERM_STRING "xterm-16color" /* name for the preferences file (pascal string) */ #define PREFERENCES_FILENAME "\pssheven Preferences" diff --git a/ssheven.c b/ssheven.c index 1071233..ed1fd82 100644 --- a/ssheven.c +++ b/ssheven.c @@ -23,6 +23,33 @@ struct preferences prefs; enum { WAIT, READ, EXIT } read_thread_command = WAIT; enum { UNINTIALIZED, OPEN, CLEANUP, DONE } read_thread_state = UNINTIALIZED; +void set_terminal_string(void) +{ + /* + * terminal type to send over ssh, determines features etc. some good options: + * "vanilla" supports basically nothing + * "vt100" just the basics + * "xterm" everything + * "xterm-mono" everything except color + * "xterm-16color" classic 16 ANSI colors only + */ + switch (prefs.display_mode) + { + case FASTEST: + prefs.terminal_string = "vt100"; + break; + case MONOCHROME: + prefs.terminal_string = "xterm-mono"; + break; + case COLOR: + prefs.terminal_string = "xterm-16color"; + break; + default: + prefs.terminal_string = SSHEVEN_DEFAULT_TERM_STRING; + break; + } +} + int save_prefs(void) { int ok = 1; @@ -125,7 +152,7 @@ void init_prefs(void) prefs.pubkey_path = ""; prefs.privkey_path = ""; - prefs.terminal_string = SSHEVEN_TERMINAL_TYPE; + prefs.terminal_string = SSHEVEN_DEFAULT_TERM_STRING; prefs.auth_type = USE_PASSWORD; prefs.display_mode = COLOR; prefs.fg_color = blackColor; @@ -185,6 +212,8 @@ void load_prefs(void) prefs.hostname[0] = (unsigned char)strlen(prefs.hostname+1); prefs.username[0] = (unsigned char)strlen(prefs.username+1); prefs.port[0] = (unsigned char)strlen(prefs.port+1); + + set_terminal_string(); } if (buffer) free(buffer);