server: Remove no longer needed server-side screen buffer ioctls.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-10-13 16:29:34 +02:00 committed by Alexandre Julliard
parent dc6f6e9ef3
commit 2e74000537
1 changed files with 0 additions and 694 deletions

View File

@ -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 = &params->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( &region, 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)
{