implement console/window resizing

This commit is contained in:
cy384 2020-08-31 22:53:06 -04:00
parent 241c76e164
commit 155caa5629
4 changed files with 55 additions and 38 deletions

View File

@ -18,20 +18,19 @@ system requirements
to do 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 * refactor libssh2 usage to handle errors and centralize network ops
* terminal window resizing
* nicer connection dialog * nicer connection dialog
* password dialog that doesn't show the password * password dialog that doesn't show the password
* preferences * preferences
* saving/loading connection settings * saving/loading connection settings
* key authentication * key authentication
* check server keys/known hosts/keys * check server keys/known hosts/keys
* text selection + copy * improve draw speed
* figure out retro68 mcpu issue, improve 68k performance (rewrite `mbedtls_mpi_exp_mod` in assembly) * figure out retro68 mcpu issue, improve 68k connection performance (rewrite `mbedtls_mpi_exp_mod` in assembly)
* font size options * font size options
* hook in more libvterm callbacks
* feed more keyboard input to libvterm
* text selection + copy
* color * color
build build

View File

@ -39,10 +39,10 @@ void draw_screen(Rect* r)
SectRect(r, &bounds, r); SectRect(r, &bounds, r);
short minRow = (0 > (r->top - bounds.top) / con.cell_height) ? 0 : (r->top - bounds.top) / con.cell_height; 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 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); EraseRect(r);
@ -103,8 +103,8 @@ void ruler(Rect* r)
{ {
char itoc[] = {'0','1','2','3','4','5','6','7','8','9'}; char itoc[] = {'0','1','2','3','4','5','6','7','8','9'};
for (int x = 0; x < 80; x++) for (int x = 0; x < con.size_x; x++)
for (int y = 0; y < 24; y++) for (int y = 0; y < con.size_y; y++)
draw_char(x, y, r, itoc[x%10]); 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_size = qd.thePort->txSize;
short save_font_face = qd.thePort->txFace; short save_font_face = qd.thePort->txFace;
con.size_x = 80;
con.size_y = 24;
TextFont(kFontIDMonaco); TextFont(kFontIDMonaco);
TextSize(9); TextSize(9);
TextFace(normal); TextFace(normal);
@ -298,19 +301,12 @@ void console_setup(void)
InsetRect(&initial_window_bounds, 20, 20); InsetRect(&initial_window_bounds, 20, 20);
initial_window_bounds.top += 40; initial_window_bounds.top += 40;
initial_window_bounds.bottom = initial_window_bounds.top + con.cell_height * 24 + 2; 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 * 80 + 4; initial_window_bounds.right = initial_window_bounds.left + con.cell_width * con.size_x + 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 };
ConstStr255Param title = "\pssheven " SSHEVEN_VERSION; 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; Rect portRect = win->portRect;
@ -320,20 +316,19 @@ void console_setup(void)
int exit_main_loop = 0; int exit_main_loop = 0;
con.win = win; con.win = win;
memset(con.data, ' ', sizeof(char) * 24*80);
con.cursor_x = 0; con.cursor_x = 0;
con.cursor_y = 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); vterm_set_utf8(con.vterm, 0);
VTermState* vtermstate = vterm_obtain_state(con.vterm); VTermState* vtermstate = vterm_obtain_state(con.vterm);
vterm_state_reset(vtermstate, 1); vterm_state_reset(vtermstate, 1);
vterm_output_set_callback(con.vterm, output_callback, NULL);
con.vts = vterm_obtain_screen(con.vterm); con.vts = vterm_obtain_screen(con.vterm);
vterm_screen_reset(con.vts, 1); vterm_screen_reset(con.vts, 1);
vterm_screen_set_callbacks(con.vts, &vtscrcb, NULL); vterm_screen_set_callbacks(con.vts, &vtscrcb, NULL);
vterm_output_set_callback(con.vterm, output_callback, NULL);
} }

View File

@ -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;}; #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 // 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 }; struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
enum { WAIT, READ, EXIT } read_thread_command = WAIT; enum { WAIT, READ, EXIT } read_thread_command = WAIT;
@ -259,6 +259,37 @@ int process_menu_select(int32_t result)
return exit; 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) void event_loop(void)
{ {
int exit_event_loop = 0; int exit_event_loop = 0;
@ -350,14 +381,7 @@ void event_loop(void)
break; break;
case inGrow: case inGrow:
{ resize_con_window(eventWin, event);
//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));*/
}
break; break;
case inGoAway: case inGoAway:
@ -468,7 +492,7 @@ int ssh_setup_terminal(void)
{ {
int rc = 0; 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)); SSH_CHECK(libssh2_channel_shell(ssh_con.channel));
return 1; 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 // tell the read thread to quit, then let it run to actually do so
read_thread_command = EXIT; read_thread_command = EXIT;
YieldToAnyThread(); while (read_thread_state != DONE) YieldToAnyThread();
//OTCancelSynchronousCalls(ssh_con.endpoint, kOTCanceledErr); //OTCancelSynchronousCalls(ssh_con.endpoint, kOTCanceledErr);
//YieldToThread(read_thread_id); //YieldToThread(read_thread_id);
// err = DisposeThread(read_thread_id, (void*)&read_thread_result, 0); // err = DisposeThread(read_thread_id, (void*)&read_thread_result, 0);
//err = DisposeThread(read_thread_id, NULL, 0); //err = DisposeThread(read_thread_id, NULL, 0);
if (ok) end_connection();
BeginUpdate(con.win); BeginUpdate(con.win);
draw_screen(&(con.win->portRect)); draw_screen(&(con.win->portRect));
EndUpdate(con.win); EndUpdate(con.win);

View File

@ -36,7 +36,8 @@ struct ssheven_console
{ {
WindowPtr win; WindowPtr win;
char data[80][24]; int size_x;
int size_y;
int cursor_x; int cursor_x;
int cursor_y; int cursor_y;