diff --git a/include/wine/condrv.h b/include/wine/condrv.h index 36412f57313..4d681f6ea73 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -29,6 +29,9 @@ #define IOCTL_CONDRV_PEEK CTL_CODE(FILE_DEVICE_CONSOLE, 12, METHOD_BUFFERED, FILE_READ_ACCESS) #define IOCTL_CONDRV_GET_INPUT_INFO CTL_CODE(FILE_DEVICE_CONSOLE, 13, METHOD_BUFFERED, FILE_READ_PROPERTIES) +/* console output ioctls */ +#define IOCTL_CONDRV_GET_OUTPUT_INFO CTL_CODE(FILE_DEVICE_CONSOLE, 32, METHOD_BUFFERED, FILE_WRITE_PROPERTIES) + /* console renderer ioctls */ #define IOCTL_CONDRV_GET_RENDERER_EVENTS CTL_CODE(FILE_DEVICE_CONSOLE, 70, METHOD_BUFFERED, FILE_READ_PROPERTIES) @@ -41,6 +44,30 @@ struct condrv_input_info unsigned int input_count; /* number of available input records */ }; +/* IOCTL_CONDRV_GET_OUTPUT_INFO result */ +struct condrv_output_info +{ + short int cursor_size; /* size of cursor (percentage filled) */ + short int cursor_visible; /* cursor visibility flag */ + short int cursor_x; /* position of cursor (x, y) */ + short int cursor_y; + short int width; /* width of the screen buffer */ + short int height; /* height of the screen buffer */ + short int attr; /* default fill attributes (screen colors) */ + short int popup_attr; /* pop-up color attributes */ + short int win_left; /* window actually displayed by renderer */ + short int win_top; /* the rect area is expressed within the */ + short int win_right; /* boundaries of the screen buffer */ + short int win_bottom; + short int max_width; /* maximum size (width x height) for the window */ + short int max_height; + short int font_width; /* font size (width x height) */ + short int font_height; + short int font_weight; /* font weight */ + short int font_pitch_family; /* font pitch & family */ + unsigned int color_map[16]; /* color table */ +}; + /* IOCTL_CONDRV_GET_RENDERER_EVENTS result */ struct condrv_renderer_event { diff --git a/server/console.c b/server/console.c index d67cec5f4c7..22af8e3b355 100644 --- a/server/console.c +++ b/server/console.c @@ -553,18 +553,18 @@ static struct screen_buffer *create_console_output( struct console_input *consol memset( screen_buffer->color_map, 0, sizeof(screen_buffer->color_map) ); list_add_head( &screen_buffer_list, &screen_buffer->entry ); - if (fd == -1) - screen_buffer->fd = NULL; + if (fd != -1) + screen_buffer->fd = create_anonymous_fd( &screen_buffer_fd_ops, fd, &screen_buffer->obj, + FILE_SYNCHRONOUS_IO_NONALERT ); else + screen_buffer->fd = alloc_pseudo_fd( &screen_buffer_fd_ops, &screen_buffer->obj, + FILE_SYNCHRONOUS_IO_NONALERT ); + if (!screen_buffer->fd) { - if (!(screen_buffer->fd = create_anonymous_fd( &screen_buffer_fd_ops, fd, &screen_buffer->obj, - FILE_SYNCHRONOUS_IO_NONALERT ))) - { - release_object( screen_buffer ); - return NULL; - } - allow_fd_caching(screen_buffer->fd); + release_object( screen_buffer ); + return NULL; } + allow_fd_caching(screen_buffer->fd); if (!(screen_buffer->data = malloc( screen_buffer->width * screen_buffer->height * sizeof(*screen_buffer->data) ))) @@ -1634,8 +1634,51 @@ static int console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async * static int screen_buffer_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) { - set_error( STATUS_INVALID_HANDLE ); - return 0; + struct screen_buffer *screen_buffer = get_fd_user( fd ); + + switch (code) + { + case IOCTL_CONDRV_GET_OUTPUT_INFO: + { + struct condrv_output_info *info; + data_size_t size; + + 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; + } + + default: + set_error( STATUS_INVALID_HANDLE ); + return 0; + } } static int console_input_events_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )