- Fixed several bugs while resizing an existing screenbuffer.
- Reduced update area for some write conditions.
- Started implementing event message collapsing.
diff --git a/server/console.c b/server/console.c
index 51aa9f9..aa610fc 100644
--- a/server/console.c
+++ b/server/console.c
@@ -163,14 +163,38 @@
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;
+ }
+ }
}
- evts->events[evts->num_used++] = *evt;
+ 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;
+ }
wake_up( &evts->obj, 0 );
}
@@ -291,10 +315,10 @@
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 @@
}
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 @@
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 @@
}
}
-/* 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 @@
{
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;