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
|
to do
|
||||||
-----
|
-----
|
||||||
* terminal resizing
|
* terminal resizing
|
||||||
* proper region invalidation/redraw
|
|
||||||
* good console emulation (to be implemented with libvterm)
|
* good console emulation (to be implemented with libvterm)
|
||||||
* saving/loading connection settings
|
* saving/loading connection settings
|
||||||
* nicer connection dialog
|
* nicer connection dialog
|
||||||
|
|
|
@ -10,6 +10,26 @@
|
||||||
|
|
||||||
void draw_char(int x, int y, Rect* r, char c)
|
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
|
// don't clobber font settings
|
||||||
short save_font = qd.thePort->txFont;
|
short save_font = qd.thePort->txFont;
|
||||||
short save_font_size = qd.thePort->txSize;
|
short save_font_size = qd.thePort->txSize;
|
||||||
|
@ -19,25 +39,17 @@ void draw_char(int x, int y, Rect* r, char c)
|
||||||
TextSize(9);
|
TextSize(9);
|
||||||
TextFace(normal);
|
TextFace(normal);
|
||||||
|
|
||||||
int cell_height = 12;
|
for(int i = minRow; i < maxRow; i++)
|
||||||
int cell_width = CharWidth('M');
|
{
|
||||||
|
for (int j = minCol; j < maxCol; j++)
|
||||||
MoveTo(r->left + x * cell_width + 2, r->top + ((y+1) * cell_height) - 2);
|
draw_char(j, i, r, con.data[j][i]);
|
||||||
DrawChar(c);
|
}
|
||||||
|
|
||||||
TextFont(save_font);
|
TextFont(save_font);
|
||||||
TextSize(save_font_size);
|
TextSize(save_font_size);
|
||||||
TextFace(save_font_face);
|
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)
|
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'};
|
||||||
|
@ -58,6 +70,8 @@ void bump_up_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < 80; x++) con.data[x][23] = ' ';
|
for (int x = 0; x < 80; x++) con.data[x][23] = ' ';
|
||||||
|
|
||||||
|
InvalRect(&(con.win->portRect));
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_printable(char c)
|
int is_printable(char c)
|
||||||
|
@ -72,6 +86,8 @@ void print_char(char c)
|
||||||
{
|
{
|
||||||
// erase current location
|
// erase current location
|
||||||
con.data[con.cursor_x][con.cursor_y] = ' ';
|
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
|
// wrap back to the previous line if possible and necessary
|
||||||
if (con.cursor_x == 0 && con.cursor_y != 0)
|
if (con.cursor_x == 0 && con.cursor_y != 0)
|
||||||
|
@ -100,6 +116,8 @@ void print_char(char c)
|
||||||
if (is_printable(c))
|
if (is_printable(c))
|
||||||
{
|
{
|
||||||
con.data[con.cursor_x][con.cursor_y] = 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++;
|
con.cursor_x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,13 +156,6 @@ void print_int(int d)
|
||||||
print_string(buffer+i+1);
|
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)
|
void print_string(const char* c)
|
||||||
{
|
{
|
||||||
while (*c != '\0')
|
while (*c != '\0')
|
||||||
|
@ -185,8 +196,6 @@ void printf_i(const char* str, ...)
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalRect(&(con.win->portRect));
|
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +220,8 @@ void console_setup(void)
|
||||||
TextSize(9);
|
TextSize(9);
|
||||||
TextFace(normal);
|
TextFace(normal);
|
||||||
|
|
||||||
int cell_height = 12;
|
con.cell_height = 12;
|
||||||
int cell_width = CharWidth('M');
|
con.cell_width = CharWidth('M');
|
||||||
|
|
||||||
TextFont(save_font);
|
TextFont(save_font);
|
||||||
TextSize(save_font_size);
|
TextSize(save_font_size);
|
||||||
|
@ -222,8 +231,8 @@ 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 + cell_height * 24 + 2;
|
initial_window_bounds.bottom = initial_window_bounds.top + con.cell_height * 24 + 2;
|
||||||
initial_window_bounds.right = initial_window_bounds.left + cell_width * 80 + 4;
|
initial_window_bounds.right = initial_window_bounds.left + con.cell_width * 80 + 4;
|
||||||
|
|
||||||
// limits on window size changes:
|
// limits on window size changes:
|
||||||
// top = min vertical
|
// top = min vertical
|
||||||
|
@ -248,6 +257,12 @@ void console_setup(void)
|
||||||
|
|
||||||
con.cursor_x = 0;
|
con.cursor_x = 0;
|
||||||
con.cursor_y = 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 set_window_title(WindowPtr w, const char* c_name);
|
||||||
|
|
||||||
void ruler(Rect* r);
|
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;};
|
#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
|
// 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 };
|
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;
|
||||||
|
@ -69,9 +69,6 @@ void ssh_read(void)
|
||||||
{
|
{
|
||||||
printf_i("channel read error: %s\n", libssh2_error_string(rc));
|
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)
|
int end_connection(void)
|
||||||
|
@ -244,10 +241,6 @@ void event_loop(void)
|
||||||
while (!WaitNextEvent(everyEvent, &event, sleep_time, NULL))
|
while (!WaitNextEvent(everyEvent, &event, sleep_time, NULL))
|
||||||
{
|
{
|
||||||
// timed out without any GUI events
|
// timed out without any GUI events
|
||||||
|
|
||||||
// process any network events
|
|
||||||
//check_network_events();
|
|
||||||
|
|
||||||
// let any other threads run before we wait for events again
|
// let any other threads run before we wait for events again
|
||||||
YieldToAnyThread();
|
YieldToAnyThread();
|
||||||
}
|
}
|
||||||
|
@ -257,7 +250,6 @@ void event_loop(void)
|
||||||
int r = 0;
|
int r = 0;
|
||||||
switch(event.what)
|
switch(event.what)
|
||||||
{
|
{
|
||||||
// TODO: don't redraw the whole screen, just do needed region
|
|
||||||
case updateEvt:
|
case updateEvt:
|
||||||
eventWin = (WindowPtr)event.message;
|
eventWin = (WindowPtr)event.message;
|
||||||
BeginUpdate(eventWin);
|
BeginUpdate(eventWin);
|
||||||
|
|
Loading…
Reference in New Issue