diff --git a/README.md b/README.md index 48b95f0..832d7cb 100644 --- a/README.md +++ b/README.md @@ -18,20 +18,19 @@ system requirements to do ----- -* hook in more libvterm callbacks (output, termprops) -* feed keyboard input to libvterm (esp. for arrow keys) -* bold/underline/italic in character drawing code * refactor libssh2 usage to handle errors and centralize network ops -* terminal window resizing * nicer connection dialog * password dialog that doesn't show the password * preferences * saving/loading connection settings * key authentication * check server keys/known hosts/keys -* text selection + copy -* figure out retro68 mcpu issue, improve 68k performance (rewrite `mbedtls_mpi_exp_mod` in assembly) +* improve draw speed +* figure out retro68 mcpu issue, improve 68k connection performance (rewrite `mbedtls_mpi_exp_mod` in assembly) * font size options +* hook in more libvterm callbacks +* feed more keyboard input to libvterm +* text selection + copy * color build diff --git a/ssheven-console.c b/ssheven-console.c index a562e99..8d61402 100644 --- a/ssheven-console.c +++ b/ssheven-console.c @@ -39,10 +39,10 @@ void draw_screen(Rect* r) SectRect(r, &bounds, r); short minRow = (0 > (r->top - bounds.top) / con.cell_height) ? 0 : (r->top - bounds.top) / con.cell_height; - short maxRow = (24 < (r->bottom - bounds.top + con.cell_height - 1) / con.cell_height) ? 24 : (r->bottom - bounds.top + con.cell_height - 1) / con.cell_height; + short maxRow = (con.size_y < (r->bottom - bounds.top + con.cell_height - 1) / con.cell_height) ? con.size_y : (r->bottom - bounds.top + con.cell_height - 1) / con.cell_height; short minCol = (0 > (r->left - bounds.left) / con.cell_width) ? 0 : (r->left - bounds.left) / con.cell_width; - short maxCol = (80 < (r->right - bounds.left + con.cell_width - 1) / con.cell_width) ? 80 : (r->right - bounds.left + con.cell_width - 1) / con.cell_width; + short maxCol = (con.size_x < (r->right - bounds.left + con.cell_width - 1) / con.cell_width) ? con.size_x : (r->right - bounds.left + con.cell_width - 1) / con.cell_width; EraseRect(r); @@ -103,8 +103,8 @@ void ruler(Rect* r) { char itoc[] = {'0','1','2','3','4','5','6','7','8','9'}; - for (int x = 0; x < 80; x++) - for (int y = 0; y < 24; y++) + for (int x = 0; x < con.size_x; x++) + for (int y = 0; y < con.size_y; y++) draw_char(x, y, r, itoc[x%10]); } @@ -283,6 +283,9 @@ void console_setup(void) short save_font_size = qd.thePort->txSize; short save_font_face = qd.thePort->txFace; + con.size_x = 80; + con.size_y = 24; + TextFont(kFontIDMonaco); TextSize(9); TextFace(normal); @@ -298,19 +301,12 @@ void console_setup(void) InsetRect(&initial_window_bounds, 20, 20); initial_window_bounds.top += 40; - initial_window_bounds.bottom = initial_window_bounds.top + con.cell_height * 24 + 2; - initial_window_bounds.right = initial_window_bounds.left + con.cell_width * 80 + 4; - - // limits on window size changes: - // top = min vertical - // bottom = max vertical - // left = min horizontal - // right = max horizontal - //Rect window_limits = { .top = 100, .bottom = 200, .left = 100, .right = 200 }; + initial_window_bounds.bottom = initial_window_bounds.top + con.cell_height * con.size_y + 2; + initial_window_bounds.right = initial_window_bounds.left + con.cell_width * con.size_x + 4; ConstStr255Param title = "\pssheven " SSHEVEN_VERSION; - WindowPtr win = NewWindow(NULL, &initial_window_bounds, title, true, noGrowDocProc, (WindowPtr)-1, true, 0); + WindowPtr win = NewWindow(NULL, &initial_window_bounds, title, true, documentProc, (WindowPtr)-1, true, 0); Rect portRect = win->portRect; @@ -320,20 +316,19 @@ void console_setup(void) int exit_main_loop = 0; con.win = win; - memset(con.data, ' ', sizeof(char) * 24*80); con.cursor_x = 0; con.cursor_y = 0; - con.vterm = vterm_new(24, 80); + con.vterm = vterm_new(con.size_y, con.size_x); vterm_set_utf8(con.vterm, 0); VTermState* vtermstate = vterm_obtain_state(con.vterm); vterm_state_reset(vtermstate, 1); + vterm_output_set_callback(con.vterm, output_callback, NULL); + con.vts = vterm_obtain_screen(con.vterm); vterm_screen_reset(con.vts, 1); vterm_screen_set_callbacks(con.vts, &vtscrcb, NULL); - - vterm_output_set_callback(con.vterm, output_callback, NULL); } diff --git a/ssheven.c b/ssheven.c index 4d82b73..14e405a 100644 --- a/ssheven.c +++ b/ssheven.c @@ -16,7 +16,7 @@ #define SSH_CHECK(X) rc = (X); if (rc != LIBSSH2_ERROR_NONE) { printf_i("" #X " failed: %s\r\n", libssh2_error_string(rc)); return 0;}; // sinful globals -struct ssheven_console con = { NULL, {0}, 0, 0, 0, 0, 0, 0, NULL}; +struct ssheven_console con = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL }; struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL }; enum { WAIT, READ, EXIT } read_thread_command = WAIT; @@ -259,6 +259,37 @@ int process_menu_select(int32_t result) return exit; } +void resize_con_window(WindowPtr eventWin, EventRecord event) +{ + // TODO: put this somewhere else + // limits on window size + // top = min vertical + // bottom = max vertical + // left = min horizontal + // right = max horizontal + Rect window_limits = { .top = con.cell_height*2 + 2, .bottom = con.cell_height*100 + 2, .left = con.cell_width*10 + 4, .right = con.cell_width*200 + 4 }; + + long growResult = GrowWindow(eventWin, event.where, &window_limits); + if (growResult != 0) + { + int height = growResult >> 16; + int width = growResult & 0xFFFF; + + // 'snap' to a size that won't have extra pixels not in a cell + int next_height = height - ((height - 2) % con.cell_height); + int next_width = width - ((width - 4) % con.cell_width); + + SizeWindow(eventWin, next_width, next_height, true); + // don't need to erase and invalidate, since vterm callbacks on resize + + con.size_x = (next_width - 4)/con.cell_width; + con.size_y = (next_height - 2)/con.cell_height; + + vterm_set_size(con.vterm, con.size_y, con.size_x); + libssh2_channel_request_pty_size(ssh_con.channel, con.size_x, con.size_y); + } +} + void event_loop(void) { int exit_event_loop = 0; @@ -350,14 +381,7 @@ void event_loop(void) break; case inGrow: - { - //not allowing resize right now - break; - /*long growResult = GrowWindow(eventWin, event.where, &window_limits); - SizeWindow(eventWin, growResult & 0xFFFF, growResult >> 16, true); - EraseRect(&(eventWin->portRect)); - InvalRect(&(eventWin->portRect));*/ - } + resize_con_window(eventWin, event); break; case inGoAway: @@ -468,7 +492,7 @@ int ssh_setup_terminal(void) { int rc = 0; - SSH_CHECK(libssh2_channel_request_pty(ssh_con.channel, SSHEVEN_TERMINAL_TYPE)); + SSH_CHECK(libssh2_channel_request_pty_ex(ssh_con.channel, SSHEVEN_TERMINAL_TYPE, (strlen(SSHEVEN_TERMINAL_TYPE)), NULL, 0, con.size_x, con.size_y, 0, 0)); SSH_CHECK(libssh2_channel_shell(ssh_con.channel)); return 1; @@ -796,15 +820,13 @@ int main(int argc, char** argv) // tell the read thread to quit, then let it run to actually do so read_thread_command = EXIT; - YieldToAnyThread(); + while (read_thread_state != DONE) YieldToAnyThread(); //OTCancelSynchronousCalls(ssh_con.endpoint, kOTCanceledErr); //YieldToThread(read_thread_id); // err = DisposeThread(read_thread_id, (void*)&read_thread_result, 0); //err = DisposeThread(read_thread_id, NULL, 0); - if (ok) end_connection(); - BeginUpdate(con.win); draw_screen(&(con.win->portRect)); EndUpdate(con.win); diff --git a/ssheven.h b/ssheven.h index cf25abb..276dea4 100644 --- a/ssheven.h +++ b/ssheven.h @@ -36,7 +36,8 @@ struct ssheven_console { WindowPtr win; - char data[80][24]; + int size_x; + int size_y; int cursor_x; int cursor_y;