mirror of https://github.com/cy384/ssheven.git
fixing screen redraw/region invalidation (less flicker, faster)
This commit is contained in:
parent
a9fbb1092a
commit
30a64faf16
|
@ -19,7 +19,6 @@ system requirements
|
|||
to do
|
||||
-----
|
||||
* terminal resizing
|
||||
* proper region invalidation/redraw
|
||||
* good console emulation (to be implemented with libvterm)
|
||||
* saving/loading connection settings
|
||||
* nicer connection dialog
|
||||
|
|
|
@ -10,6 +10,26 @@
|
|||
|
||||
void draw_char(int x, int y, Rect* r, char c)
|
||||
{
|
||||
MoveTo(r->left + x * con.cell_width + 2, r->top + ((y+1) * con.cell_height) - 2);
|
||||
DrawChar(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void draw_screen(Rect* r)
|
||||
{
|
||||
// get the intersection of our console region and the update region
|
||||
Rect bounds = (con.win->portRect);
|
||||
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 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;
|
||||
|
||||
EraseRect(r);
|
||||
|
||||
// don't clobber font settings
|
||||
short save_font = qd.thePort->txFont;
|
||||
short save_font_size = qd.thePort->txSize;
|
||||
|
@ -19,25 +39,17 @@ void draw_char(int x, int y, Rect* r, char c)
|
|||
TextSize(9);
|
||||
TextFace(normal);
|
||||
|
||||
int cell_height = 12;
|
||||
int cell_width = CharWidth('M');
|
||||
|
||||
MoveTo(r->left + x * cell_width + 2, r->top + ((y+1) * cell_height) - 2);
|
||||
DrawChar(c);
|
||||
for(int i = minRow; i < maxRow; i++)
|
||||
{
|
||||
for (int j = minCol; j < maxCol; j++)
|
||||
draw_char(j, i, r, con.data[j][i]);
|
||||
}
|
||||
|
||||
TextFont(save_font);
|
||||
TextSize(save_font_size);
|
||||
TextFace(save_font_face);
|
||||
}
|
||||
|
||||
void draw_screen(Rect* r)
|
||||
{
|
||||
EraseRect(r);
|
||||
for (int x = 0; x < 80; x++)
|
||||
for (int y = 0; y < 24; y++)
|
||||
draw_char(x, y, r, con.data[x][y]);
|
||||
}
|
||||
|
||||
void ruler(Rect* r)
|
||||
{
|
||||
char itoc[] = {'0','1','2','3','4','5','6','7','8','9'};
|
||||
|
@ -58,6 +70,8 @@ void bump_up_line()
|
|||
}
|
||||
|
||||
for (int x = 0; x < 80; x++) con.data[x][23] = ' ';
|
||||
|
||||
InvalRect(&(con.win->portRect));
|
||||
}
|
||||
|
||||
int is_printable(char c)
|
||||
|
@ -72,6 +86,8 @@ void print_char(char c)
|
|||
{
|
||||
// erase current location
|
||||
con.data[con.cursor_x][con.cursor_y] = ' ';
|
||||
Rect inval = cell_rect(con.cursor_x, con.cursor_y, (con.win->portRect));
|
||||
InvalRect(&inval);
|
||||
|
||||
// wrap back to the previous line if possible and necessary
|
||||
if (con.cursor_x == 0 && con.cursor_y != 0)
|
||||
|
@ -100,6 +116,8 @@ void print_char(char c)
|
|||
if (is_printable(c))
|
||||
{
|
||||
con.data[con.cursor_x][con.cursor_y] = c;
|
||||
Rect inval = cell_rect(con.cursor_x, con.cursor_y, (con.win->portRect));
|
||||
InvalRect(&inval);
|
||||
con.cursor_x++;
|
||||
}
|
||||
|
||||
|
@ -138,13 +156,6 @@ void print_int(int d)
|
|||
print_string(buffer+i+1);
|
||||
}
|
||||
|
||||
void print_string_i(const char* c)
|
||||
{
|
||||
print_string(c);
|
||||
// TODO invalidate only the correct region
|
||||
InvalRect(&(con.win->portRect));
|
||||
}
|
||||
|
||||
void print_string(const char* c)
|
||||
{
|
||||
while (*c != '\0')
|
||||
|
@ -185,8 +196,6 @@ void printf_i(const char* str, ...)
|
|||
str++;
|
||||
}
|
||||
|
||||
InvalRect(&(con.win->portRect));
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
@ -211,8 +220,8 @@ void console_setup(void)
|
|||
TextSize(9);
|
||||
TextFace(normal);
|
||||
|
||||
int cell_height = 12;
|
||||
int cell_width = CharWidth('M');
|
||||
con.cell_height = 12;
|
||||
con.cell_width = CharWidth('M');
|
||||
|
||||
TextFont(save_font);
|
||||
TextSize(save_font_size);
|
||||
|
@ -222,8 +231,8 @@ void console_setup(void)
|
|||
InsetRect(&initial_window_bounds, 20, 20);
|
||||
initial_window_bounds.top += 40;
|
||||
|
||||
initial_window_bounds.bottom = initial_window_bounds.top + cell_height * 24 + 2;
|
||||
initial_window_bounds.right = initial_window_bounds.left + cell_width * 80 + 4;
|
||||
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
|
||||
|
@ -248,6 +257,12 @@ void console_setup(void)
|
|||
|
||||
con.cursor_x = 0;
|
||||
con.cursor_y = 0;
|
||||
|
||||
}
|
||||
|
||||
Rect cell_rect(int x, int y, Rect bounds)
|
||||
{
|
||||
Rect r = { (short) (bounds.top + y * con.cell_height), (short) (bounds.left + x * con.cell_width + 2),
|
||||
(short) (bounds.top + (y+1) * con.cell_height), (short) (bounds.left + (x+1) * con.cell_width + 2) };
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -28,3 +28,5 @@ void printf_i(const char* c, ...);
|
|||
void set_window_title(WindowPtr w, const char* c_name);
|
||||
|
||||
void ruler(Rect* r);
|
||||
|
||||
Rect cell_rect(int x, int y, Rect bounds);
|
||||
|
|
10
ssheven.c
10
ssheven.c
|
@ -16,7 +16,7 @@
|
|||
#define SSH_CHECK(X) rc = (X); if (rc != LIBSSH2_ERROR_NONE) { printf_i("" #X " failed: %s\n", libssh2_error_string(rc)); return 0;};
|
||||
|
||||
// sinful globals
|
||||
struct ssheven_console con = { NULL, {0}, 0, 0 };
|
||||
struct ssheven_console con = { NULL, {0}, 0, 0, 0 , 0 };
|
||||
struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
|
||||
|
||||
enum { WAIT, READ, EXIT } read_thread_command = WAIT;
|
||||
|
@ -69,9 +69,6 @@ void ssh_read(void)
|
|||
{
|
||||
printf_i("channel read error: %s\n", libssh2_error_string(rc));
|
||||
}
|
||||
|
||||
// TODO invalidate only the correct region
|
||||
InvalRect(&(con.win->portRect));
|
||||
}
|
||||
|
||||
int end_connection(void)
|
||||
|
@ -244,10 +241,6 @@ void event_loop(void)
|
|||
while (!WaitNextEvent(everyEvent, &event, sleep_time, NULL))
|
||||
{
|
||||
// timed out without any GUI events
|
||||
|
||||
// process any network events
|
||||
//check_network_events();
|
||||
|
||||
// let any other threads run before we wait for events again
|
||||
YieldToAnyThread();
|
||||
}
|
||||
|
@ -257,7 +250,6 @@ void event_loop(void)
|
|||
int r = 0;
|
||||
switch(event.what)
|
||||
{
|
||||
// TODO: don't redraw the whole screen, just do needed region
|
||||
case updateEvt:
|
||||
eventWin = (WindowPtr)event.message;
|
||||
BeginUpdate(eventWin);
|
||||
|
|
Loading…
Reference in New Issue