From f4b298b8111dd9604c2ec4bab799d80b7539782a Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Sun, 5 Jan 2003 01:07:34 +0000 Subject: [PATCH] - Fixed several bugs while resizing an existing screenbuffer. - Reduced update area for some write conditions. - Started implementing event message collapsing. --- server/console.c | 97 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/server/console.c b/server/console.c index 51aa9f90855..aa610fc7ade 100644 --- a/server/console.c +++ b/server/console.c @@ -163,14 +163,38 @@ static int console_input_events_signaled( struct object *obj, struct thread *thr static void console_input_events_append( struct console_input_events* evts, struct console_renderer_event* evt) { - /* to be done even when the renderer generates the events ? */ - if (evts->num_used == evts->num_alloc) + int collapsed = FALSE; + + /* to be done even when evt has been generated by the rendere ? */ + + /* try to collapse evt into current queue's events */ + if (evts->num_used) { - evts->num_alloc += 16; - evts->events = realloc( evts->events, evts->num_alloc * sizeof(*evt) ); - assert(evts->events); + struct console_renderer_event* last = &evts->events[evts->num_used - 1]; + + if (last->event == CONSOLE_RENDERER_UPDATE_EVENT && + evt->event == CONSOLE_RENDERER_UPDATE_EVENT) + { + /* if two update events overlap, collapse them into a single one */ + if (last->u.update.bottom + 1 >= evt->u.update.top && + evt->u.update.bottom + 1 >= last->u.update.top) + { + last->u.update.top = min(last->u.update.top, evt->u.update.top); + last->u.update.bottom = max(last->u.update.bottom, evt->u.update.bottom); + collapsed = TRUE; + } + } + } + if (!collapsed) + { + if (evts->num_used == evts->num_alloc) + { + evts->num_alloc += 16; + evts->events = realloc( evts->events, evts->num_alloc * sizeof(*evt) ); + assert(evts->events); + } + evts->events[evts->num_used++] = *evt; } - evts->events[evts->num_used++] = *evt; wake_up( &evts->obj, 0 ); } @@ -291,10 +315,10 @@ static struct screen_buffer *create_console_output( struct console_input *consol evt.u.update.bottom = screen_buffer->height - 1; console_input_events_append( console_input->evt, &evt ); - evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT; - evt.u.cursor_geom.size = screen_buffer->cursor_size; - evt.u.cursor_geom.visible = screen_buffer->cursor_visible; - console_input_events_append( console_input->evt, &evt ); + evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT; + evt.u.cursor_geom.size = screen_buffer->cursor_size; + evt.u.cursor_geom.visible = screen_buffer->cursor_visible; + console_input_events_append( console_input->evt, &evt ); evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; evt.u.cursor_pos.x = screen_buffer->cursor_x; @@ -745,6 +769,15 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, } if (req->mask & SET_CONSOLE_OUTPUT_INFO_SIZE) { + unsigned cc; + + /* new screen-buffer cannot be smaller than actual window */ + if (req->width < screen_buffer->win.right - screen_buffer->win.left + 1 || + req->height < screen_buffer->win.bottom - screen_buffer->win.top + 1) + { + set_error( STATUS_INVALID_PARAMETER ); + return 0; + } /* FIXME: there are also some basic minimum and max size to deal with */ if (!change_screen_buffer_size( screen_buffer, req->width, req->height )) return 0; @@ -753,6 +786,44 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, evt.u.resize.height = req->height; console_input_events_append( screen_buffer->input->evt, &evt ); + evt.event = CONSOLE_RENDERER_UPDATE_EVENT; + evt.u.update.top = 0; + evt.u.update.bottom = screen_buffer->height - 1; + console_input_events_append( screen_buffer->input->evt, &evt ); + + /* scroll window to display sb */ + if (screen_buffer->win.right >= req->width) + { + screen_buffer->win.right -= screen_buffer->win.left; + screen_buffer->win.left = 0; + } + if (screen_buffer->win.bottom >= req->height) + { + screen_buffer->win.bottom -= screen_buffer->win.top; + screen_buffer->win.top = 0; + } + /* reset cursor if needed (normally, if cursor was outside of new sb, the + * window has been shifted so that the new position of the cursor will be + * visible */ + cc = 0; + if (screen_buffer->cursor_x >= req->width) + { + screen_buffer->cursor_x = req->width - 1; + cc++; + } + if (screen_buffer->cursor_y >= req->height) + { + screen_buffer->cursor_y = req->height - 1; + cc++; + } + if (cc) + { + evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; + evt.u.cursor_pos.x = req->cursor_x; + evt.u.cursor_pos.y = req->cursor_y; + console_input_events_append( screen_buffer->input->evt, &evt ); + } + if (screen_buffer == screen_buffer->input->active && screen_buffer->input->mode & ENABLE_WINDOW_INPUT) { @@ -851,7 +922,7 @@ static void console_input_append_hist( struct console_input* console, const WCHA } } -/* returns a line from the cachde */ +/* returns a line from the cache */ static size_t console_input_get_hist( struct console_input *console, int index ) { size_t ret = 0; @@ -1000,8 +1071,8 @@ static int write_console_output( struct screen_buffer *screen_buffer, size_t siz { struct console_renderer_event evt; evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - evt.u.update.top = y; - evt.u.update.bottom = (y * screen_buffer->width + x + i - 1) / screen_buffer->width; + evt.u.update.top = y + x / screen_buffer->width; + evt.u.update.bottom = y + (x + i - 1) / screen_buffer->width; console_input_events_append( screen_buffer->input->evt, &evt ); } return i;