diff --git a/server/console.c b/server/console.c index 3fc36446547..d602afec1f2 100644 --- a/server/console.c +++ b/server/console.c @@ -427,11 +427,6 @@ static struct list screen_buffer_list = LIST_INIT(screen_buffer_list); static const char_info_t empty_char_info = { ' ', 0x000f }; /* white on black space */ -static int console_input_is_bare( struct console_input* cin ) -{ - return cin->evt == NULL; -} - static struct fd *console_input_get_fd( struct object* obj ) { struct console_input *console_input = (struct console_input*)obj; @@ -992,239 +987,6 @@ static int write_console_input( struct console_input* console, int count, return 1; } -/* resize a screen buffer */ -static int change_screen_buffer_size( struct screen_buffer *screen_buffer, - int new_width, int new_height ) -{ - int i, old_width, old_height, copy_width, copy_height; - char_info_t *new_data; - - if (!(new_data = malloc( new_width * new_height * sizeof(*new_data) ))) - { - set_error( STATUS_NO_MEMORY ); - return 0; - } - old_width = screen_buffer->width; - old_height = screen_buffer->height; - copy_width = min( old_width, new_width ); - copy_height = min( old_height, new_height ); - - /* copy all the rows */ - for (i = 0; i < copy_height; i++) - { - memcpy( &new_data[i * new_width], &screen_buffer->data[i * old_width], - copy_width * sizeof(char_info_t) ); - } - - /* clear the end of each row */ - if (new_width > old_width) - { - /* fill first row */ - for (i = old_width; i < new_width; i++) new_data[i] = empty_char_info; - /* and blast it to the other rows */ - for (i = 1; i < copy_height; i++) - memcpy( &new_data[i * new_width + old_width], &new_data[old_width], - (new_width - old_width) * sizeof(char_info_t) ); - } - - /* clear remaining rows */ - if (new_height > old_height) - { - /* fill first row */ - for (i = 0; i < new_width; i++) new_data[old_height * new_width + i] = empty_char_info; - /* and blast it to the other rows */ - for (i = old_height+1; i < new_height; i++) - memcpy( &new_data[i * new_width], &new_data[old_height * new_width], - new_width * sizeof(char_info_t) ); - } - free( screen_buffer->data ); - screen_buffer->data = new_data; - screen_buffer->width = new_width; - screen_buffer->height = new_height; - return 1; -} - -static int set_output_info( struct screen_buffer *screen_buffer, - const struct condrv_output_info_params *params, data_size_t extra_size ) -{ - const struct condrv_output_info *info = ¶ms->info; - struct condrv_renderer_event evt; - WCHAR *font_name; - - if (params->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM) - { - if (info->cursor_size < 1 || info->cursor_size > 100) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (screen_buffer->cursor_size != info->cursor_size || - screen_buffer->cursor_visible != info->cursor_visible) - { - screen_buffer->cursor_size = info->cursor_size; - screen_buffer->cursor_visible = info->cursor_visible; - evt.event = CONSOLE_RENDERER_CURSOR_GEOM_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.cursor_geom.size = info->cursor_size; - evt.u.cursor_geom.visible = info->cursor_visible; - console_input_events_append( screen_buffer->input, &evt ); - } - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_CURSOR_POS) - { - if (info->cursor_x < 0 || info->cursor_x >= screen_buffer->width || - info->cursor_y < 0 || info->cursor_y >= screen_buffer->height) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (screen_buffer->cursor_x != info->cursor_x || screen_buffer->cursor_y != info->cursor_y) - { - screen_buffer->cursor_x = info->cursor_x; - screen_buffer->cursor_y = info->cursor_y; - evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.cursor_pos.x = info->cursor_x; - evt.u.cursor_pos.y = info->cursor_y; - console_input_events_append( screen_buffer->input, &evt ); - } - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_SIZE) - { - unsigned cc; - - /* new screen-buffer cannot be smaller than actual window */ - if (info->width < screen_buffer->win.right - screen_buffer->win.left + 1 || - info->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, info->width, info->height )) return 0; - - evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.resize.width = info->width; - evt.u.resize.height = info->height; - console_input_events_append( screen_buffer->input, &evt ); - - evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.update.top = 0; - evt.u.update.bottom = screen_buffer->height - 1; - console_input_events_append( screen_buffer->input, &evt ); - - /* scroll window to display sb */ - if (screen_buffer->win.right >= info->width) - { - screen_buffer->win.right -= screen_buffer->win.left; - screen_buffer->win.left = 0; - } - if (screen_buffer->win.bottom >= info->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 >= info->width) - { - screen_buffer->cursor_x = info->width - 1; - cc++; - } - if (screen_buffer->cursor_y >= info->height) - { - screen_buffer->cursor_y = info->height - 1; - cc++; - } - if (cc) - { - evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.cursor_pos.x = info->cursor_x; - evt.u.cursor_pos.y = info->cursor_y; - console_input_events_append( screen_buffer->input, &evt ); - } - - if (screen_buffer == screen_buffer->input->active && - screen_buffer->input->mode & ENABLE_WINDOW_INPUT) - { - INPUT_RECORD ir; - ir.EventType = WINDOW_BUFFER_SIZE_EVENT; - ir.Event.WindowBufferSizeEvent.dwSize.X = info->width; - ir.Event.WindowBufferSizeEvent.dwSize.Y = info->height; - write_console_input( screen_buffer->input, 1, &ir ); - } - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_ATTR) - { - screen_buffer->attr = info->attr; - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_POPUP_ATTR) - { - screen_buffer->popup_attr = info->popup_attr; - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW) - { - if (info->win_left < 0 || info->win_left > info->win_right || - info->win_right >= screen_buffer->width || - info->win_top < 0 || info->win_top > info->win_bottom || - info->win_bottom >= screen_buffer->height) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (screen_buffer->win.left != info->win_left || screen_buffer->win.top != info->win_top || - screen_buffer->win.right != info->win_right || screen_buffer->win.bottom != info->win_bottom) - { - screen_buffer->win.left = info->win_left; - screen_buffer->win.top = info->win_top; - screen_buffer->win.right = info->win_right; - screen_buffer->win.bottom = info->win_bottom; - evt.event = CONSOLE_RENDERER_DISPLAY_EVENT; - memset( &evt.u, 0, sizeof(evt.u) ); - evt.u.display.left = info->win_left; - evt.u.display.top = info->win_top; - evt.u.display.width = info->win_right - info->win_left + 1; - evt.u.display.height = info->win_bottom - info->win_top + 1; - console_input_events_append( screen_buffer->input, &evt ); - } - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_MAX_SIZE) - { - screen_buffer->max_width = info->max_width; - screen_buffer->max_height = info->max_height; - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_COLORTABLE) - { - memcpy( screen_buffer->color_map, info->color_map, sizeof(info->color_map) ); - } - if (params->mask & SET_CONSOLE_OUTPUT_INFO_FONT) - { - screen_buffer->font.width = info->font_width; - screen_buffer->font.height = info->font_height; - screen_buffer->font.weight = info->font_weight; - screen_buffer->font.pitch_family = info->font_pitch_family; - if (extra_size) - { - extra_size = extra_size / sizeof(WCHAR) * sizeof(WCHAR); - font_name = mem_alloc( extra_size ); - if (font_name) - { - memcpy( font_name, info + 1, extra_size ); - free( screen_buffer->font.face_name ); - screen_buffer->font.face_name = font_name; - screen_buffer->font.face_len = extra_size; - } - } - } - - return 1; -} - /* dumb dump */ static void console_input_dump( struct object *obj, int verbose ) { @@ -1360,280 +1122,6 @@ static struct fd *screen_buffer_get_fd( struct object *obj ) return NULL; } -/* read data from a screen buffer */ -static void read_console_output( struct screen_buffer *screen_buffer, unsigned int x, unsigned int y, - enum char_info_mode mode, unsigned int width ) -{ - unsigned int i, count; - char_info_t *src; - - if (x >= screen_buffer->width || y >= screen_buffer->height) - { - if (width) set_error( STATUS_INVALID_PARAMETER ); - return; - } - src = screen_buffer->data + y * screen_buffer->width + x; - - switch(mode) - { - case CHAR_INFO_MODE_TEXT: - { - WCHAR *data; - count = min( screen_buffer->data + screen_buffer->height * screen_buffer->width - src, - get_reply_max_size() / sizeof(*data) ); - if ((data = set_reply_data_size( count * sizeof(*data) ))) - { - for (i = 0; i < count; i++) data[i] = src[i].ch; - } - } - break; - case CHAR_INFO_MODE_ATTR: - { - unsigned short *data; - count = min( screen_buffer->data + screen_buffer->height * screen_buffer->width - src, - get_reply_max_size() / sizeof(*data) ); - if ((data = set_reply_data_size( count * sizeof(*data) ))) - { - for (i = 0; i < count; i++) data[i] = src[i].attr; - } - } - break; - case CHAR_INFO_MODE_TEXTATTR: - { - char_info_t *data; - SMALL_RECT *region; - if (!width || get_reply_max_size() < sizeof(*region)) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - count = min( (get_reply_max_size() - sizeof(*region)) / (width * sizeof(*data)), screen_buffer->height - y ); - width = min( width, screen_buffer->width - x ); - if (!(region = set_reply_data_size( sizeof(*region) + width * count * sizeof(*data) ))) return; - region->Left = x; - region->Top = y; - region->Right = x + width - 1; - region->Bottom = y + count - 1; - data = (char_info_t *)(region + 1); - for (i = 0; i < count; i++) - { - memcpy( &data[i * width], &src[i * screen_buffer->width], width * sizeof(*data) ); - } - } - break; - default: - set_error( STATUS_INVALID_PARAMETER ); - break; - } -} - -/* write data into a screen buffer */ -static void write_console_output( struct screen_buffer *screen_buffer, const struct condrv_output_params *params, - data_size_t size ) -{ - unsigned int i, entry_size, entry_cnt, x, y; - char_info_t *dest; - char *src; - - entry_size = params->mode == CHAR_INFO_MODE_TEXTATTR ? sizeof(char_info_t) : sizeof(WCHAR); - if (size % entry_size) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - if (params->x >= screen_buffer->width) return; - entry_cnt = size / entry_size; - - for (i = 0, src = (char *)(params + 1); i < entry_cnt; i++, src += entry_size) - { - if (params->width) - { - x = params->x + i % params->width; - y = params->y + i / params->width; - if (x >= screen_buffer->width) continue; - } - else - { - x = (params->x + i) % screen_buffer->width; - y = params->y + (params->x + i) / screen_buffer->width; - } - if (y >= screen_buffer->height) break; - - dest = &screen_buffer->data[y * screen_buffer->width + x]; - switch(params->mode) - { - case CHAR_INFO_MODE_TEXT: - dest->ch = *(const WCHAR *)src; - break; - case CHAR_INFO_MODE_ATTR: - dest->attr = *(const unsigned short *)src; - break; - case CHAR_INFO_MODE_TEXTATTR: - *dest = *(const char_info_t *)src; - break; - case CHAR_INFO_MODE_TEXTSTDATTR: - dest->ch = *(const WCHAR *)src; - dest->attr = screen_buffer->attr; - break; - default: - set_error( STATUS_INVALID_PARAMETER ); - return; - } - } - - if (i && screen_buffer == screen_buffer->input->active) - { - struct condrv_renderer_event evt; - evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - memset(&evt.u, 0, sizeof(evt.u)); - evt.u.update.top = params->y; - evt.u.update.bottom = params->width - ? min( params->y + entry_cnt / params->width, screen_buffer->height ) - 1 - : params->y + (params->x + i - 1) / screen_buffer->width; - console_input_events_append( screen_buffer->input, &evt ); - } - - if (get_reply_max_size() == sizeof(SMALL_RECT)) - { - SMALL_RECT region; - region.Left = params->x; - region.Top = params->y; - region.Right = min( params->x + params->width, screen_buffer->width ) - 1; - region.Bottom = min( params->y + entry_cnt / params->width, screen_buffer->height ) - 1; - set_reply_data( ®ion, sizeof(region) ); - } - else set_reply_data( &i, sizeof(i) ); -} - -/* fill a screen buffer with uniform data */ -static int fill_console_output( struct screen_buffer *screen_buffer, char_info_t data, - enum char_info_mode mode, int x, int y, int count, int wrap ) -{ - int i; - char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x; - - if (y >= screen_buffer->height) return 0; - - if (wrap) - end = screen_buffer->data + screen_buffer->height * screen_buffer->width; - else - end = screen_buffer->data + (y+1) * screen_buffer->width; - - if (count > end - dest) count = end - dest; - - switch(mode) - { - case CHAR_INFO_MODE_TEXT: - for (i = 0; i < count; i++) dest[i].ch = data.ch; - break; - case CHAR_INFO_MODE_ATTR: - for (i = 0; i < count; i++) dest[i].attr = data.attr; - break; - case CHAR_INFO_MODE_TEXTATTR: - for (i = 0; i < count; i++) dest[i] = data; - break; - case CHAR_INFO_MODE_TEXTSTDATTR: - for (i = 0; i < count; i++) - { - dest[i].ch = data.ch; - dest[i].attr = screen_buffer->attr; - } - break; - default: - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - - if (count && screen_buffer == screen_buffer->input->active) - { - struct condrv_renderer_event evt; - evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - memset(&evt.u, 0, sizeof(evt.u)); - evt.u.update.top = y; - evt.u.update.bottom = (y * screen_buffer->width + x + count - 1) / screen_buffer->width; - console_input_events_append( screen_buffer->input, &evt ); - } - return i; -} - -/* scroll parts of a screen buffer */ -static void scroll_console_output( struct screen_buffer *screen_buffer, int xsrc, int ysrc, int xdst, int ydst, - int w, int h, const rectangle_t *clip, char_info_t fill ) -{ - struct condrv_renderer_event evt; - rectangle_t src, dst; - int x, y; - - src.left = max( xsrc, clip->left ); - src.top = max( ysrc, clip->top ); - src.right = min( xsrc + w - 1, clip->right ); - src.bottom = min( ysrc + h - 1, clip->bottom ); - - dst.left = xdst; - dst.top = ydst; - dst.right = xdst + w - 1; - dst.bottom = ydst + h - 1; - - if (dst.left < clip->left) - { - xsrc += clip->left - dst.left; - w -= clip->left - dst.left; - dst.left = clip->left; - } - if (dst.top < clip->top) - { - ysrc += clip->top - dst.top; - h -= clip->top - dst.top; - dst.top = clip->top; - } - if (dst.right > clip->right) w -= dst.right - clip->right; - if (dst.bottom > clip->bottom) h -= dst.bottom - clip->bottom; - - if (w > 0 && h > 0) - { - if (ysrc < ydst) - { - for (y = h; y > 0; y--) - { - memcpy( &screen_buffer->data[(dst.top + y - 1) * screen_buffer->width + dst.left], - &screen_buffer->data[(ysrc + y - 1) * screen_buffer->width + xsrc], - w * sizeof(screen_buffer->data[0]) ); - } - } - else - { - for (y = 0; y < h; y++) - { - /* we use memmove here because when psrc and pdst are the same, - * copies are done on the same row, so the dst and src blocks - * can overlap */ - memmove( &screen_buffer->data[(dst.top + y) * screen_buffer->width + dst.left], - &screen_buffer->data[(ysrc + y) * screen_buffer->width + xsrc], - w * sizeof(screen_buffer->data[0]) ); - } - } - } - - for (y = src.top; y <= src.bottom; y++) - { - int left = src.left; - int right = src.right; - if (dst.top <= y && y <= dst.bottom) - { - if (dst.left <= src.left) left = max( left, dst.right + 1 ); - if (dst.left >= src.left) right = min( right, dst.left - 1 ); - } - for (x = left; x <= right; x++) screen_buffer->data[y * screen_buffer->width + x] = fill; - } - - /* FIXME: this could be enhanced, by signalling scroll */ - evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - memset(&evt.u, 0, sizeof(evt.u)); - evt.u.update.top = min( src.top, dst.top ); - evt.u.update.bottom = max( src.bottom, dst.bottom ); - console_input_events_append( screen_buffer->input, &evt ); -} - static void console_server_dump( struct object *obj, int verbose ) { assert( obj->ops == &console_server_ops ); @@ -1942,126 +1430,6 @@ static int screen_buffer_ioctl( struct fd *fd, ioctl_code_t code, struct async * switch (code) { - case IOCTL_CONDRV_GET_MODE: - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_reply_max_size() != sizeof(screen_buffer->mode)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - return set_reply_data( &screen_buffer->mode, sizeof(screen_buffer->mode) ) != NULL; - - case IOCTL_CONDRV_SET_MODE: - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_req_data_size() != sizeof(screen_buffer->mode)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - screen_buffer->mode = *(unsigned int *)get_req_data(); - return 1; - - case IOCTL_CONDRV_READ_OUTPUT: - { - const struct condrv_output_params *params = get_req_data(); - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_req_data_size() != sizeof(*params)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (console_input_is_bare( screen_buffer->input )) - { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - return 0; - } - read_console_output( screen_buffer, params->x, params->y, params->mode, params->width ); - return !get_error(); - } - - case IOCTL_CONDRV_WRITE_OUTPUT: - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_req_data_size() < sizeof(struct condrv_output_params) || - (get_reply_max_size() != sizeof(SMALL_RECT) && get_reply_max_size() != sizeof(unsigned int))) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (console_input_is_bare( screen_buffer->input )) - { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - return 0; - } - write_console_output( screen_buffer, get_req_data(), get_req_data_size() - sizeof(struct condrv_output_params) ); - return !get_error(); - - case IOCTL_CONDRV_GET_OUTPUT_INFO: - { - struct condrv_output_info *info; - data_size_t size; - - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - size = min( sizeof(*info) + screen_buffer->font.face_len, get_reply_max_size() ); - if (size < sizeof(*info)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (!(info = set_reply_data_size( size ))) return 0; - - info->cursor_size = screen_buffer->cursor_size; - info->cursor_visible = screen_buffer->cursor_visible; - info->cursor_x = screen_buffer->cursor_x; - info->cursor_y = screen_buffer->cursor_y; - info->width = screen_buffer->width; - info->height = screen_buffer->height; - info->attr = screen_buffer->attr; - info->popup_attr = screen_buffer->popup_attr; - info->win_left = screen_buffer->win.left; - info->win_top = screen_buffer->win.top; - info->win_right = screen_buffer->win.right; - info->win_bottom = screen_buffer->win.bottom; - info->max_width = screen_buffer->max_width; - info->max_height = screen_buffer->max_height; - info->font_width = screen_buffer->font.width; - info->font_height = screen_buffer->font.height; - info->font_weight = screen_buffer->font.weight; - info->font_pitch_family = screen_buffer->font.pitch_family; - memcpy( info->color_map, screen_buffer->color_map, sizeof(info->color_map) ); - size -= sizeof(*info); - if (size) memcpy( info + 1, screen_buffer->font.face_name, size ); - return 1; - } - - case IOCTL_CONDRV_SET_OUTPUT_INFO: - { - const struct condrv_output_info_params *params = get_req_data(); - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_req_data_size() < sizeof(*params)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (!screen_buffer->input) - { - set_error( STATUS_INVALID_HANDLE ); - return 0; - } - return set_output_info( screen_buffer, params, get_req_data_size() - sizeof(*params) ); - } - case IOCTL_CONDRV_ACTIVATE: if (!screen_buffer->input) { @@ -2072,68 +1440,6 @@ static int screen_buffer_ioctl( struct fd *fd, ioctl_code_t code, struct async * set_active_screen_buffer( screen_buffer->input, screen_buffer ); return 1; - case IOCTL_CONDRV_FILL_OUTPUT: - { - const struct condrv_fill_output_params *params = get_req_data(); - char_info_t data; - DWORD written; - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - if (get_req_data_size() != sizeof(*params) || - (get_reply_max_size() && get_reply_max_size() != sizeof(written))) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - data.ch = params->ch; - data.attr = params->attr; - written = fill_console_output( screen_buffer, data, params->mode, - params->x, params->y, params->count, params->wrap ); - if (written && get_reply_max_size() == sizeof(written)) - set_reply_data( &written, sizeof(written) ); - return !get_error(); - } - - case IOCTL_CONDRV_SCROLL: - { - const struct condrv_scroll_params *params = get_req_data(); - rectangle_t clip; - - if (screen_buffer->input && screen_buffer->input->server) - return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id, - async, &screen_buffer->ioctl_q ); - - if (get_req_data_size() != sizeof(*params)) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - if (console_input_is_bare( screen_buffer->input ) || !screen_buffer->input) - { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - return 0; - } - clip.left = max( params->clip.Left, 0 ); - clip.top = max( params->clip.Top, 0 ); - clip.right = min( params->clip.Right, screen_buffer->width - 1 ); - clip.bottom = min( params->clip.Bottom, screen_buffer->height - 1 ); - if (clip.left > clip.right || clip.top > clip.bottom || params->scroll.Left < 0 || params->scroll.Top < 0 || - params->scroll.Right >= screen_buffer->width || params->scroll.Bottom >= screen_buffer->height || - params->scroll.Right < params->scroll.Left || params->scroll.Top > params->scroll.Bottom || - params->origin.X < 0 || params->origin.X >= screen_buffer->width || params->origin.Y < 0 || - params->origin.Y >= screen_buffer->height) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - - scroll_console_output( screen_buffer, params->scroll.Left, params->scroll.Top, params->origin.X, params->origin.Y, - params->scroll.Right - params->scroll.Left + 1, params->scroll.Bottom - params->scroll.Top + 1, - &clip, params->fill ); - return !get_error(); - } - default: if (!screen_buffer->input || !screen_buffer->input->server || code >> 16 != FILE_DEVICE_CONSOLE) {