Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
02984317
Commit
02984317
authored
Aug 27, 2020
by
Jacek Caban
Committed by
Alexandre Julliard
Aug 27, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
conhost: Initial support for screen buffers.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
15684bd5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
2 deletions
+98
-2
conhost.c
programs/conhost/conhost.c
+98
-2
No files found.
programs/conhost/conhost.c
View file @
02984317
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#include "wine/condrv.h"
#include "wine/condrv.h"
#include "wine/server.h"
#include "wine/server.h"
#include "wine/rbtree.h"
#include "wine/debug.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
conhost
);
WINE_DEFAULT_DEBUG_CHANNEL
(
conhost
);
...
@@ -45,6 +46,7 @@ struct console
...
@@ -45,6 +46,7 @@ struct console
{
{
HANDLE
server
;
/* console server handle */
HANDLE
server
;
/* console server handle */
unsigned
int
mode
;
/* input mode */
unsigned
int
mode
;
/* input mode */
struct
screen_buffer
*
active
;
/* active screen buffer */
INPUT_RECORD
*
records
;
/* input records */
INPUT_RECORD
*
records
;
/* input records */
unsigned
int
record_count
;
/* number of input records */
unsigned
int
record_count
;
/* number of input records */
unsigned
int
record_size
;
/* size of input records buffer */
unsigned
int
record_size
;
/* size of input records buffer */
...
@@ -61,6 +63,15 @@ struct console
...
@@ -61,6 +63,15 @@ struct console
unsigned
int
win
;
/* window handle if backend supports it */
unsigned
int
win
;
/* window handle if backend supports it */
};
};
struct
screen_buffer
{
struct
console
*
console
;
/* console reference */
unsigned
int
id
;
/* screen buffer id */
unsigned
int
width
;
/* size (w-h) of the screen buffer */
unsigned
int
height
;
struct
wine_rb_entry
entry
;
/* map entry */
};
static
void
*
ioctl_buffer
;
static
void
*
ioctl_buffer
;
static
size_t
ioctl_buffer_size
;
static
size_t
ioctl_buffer_size
;
...
@@ -76,6 +87,41 @@ static void *alloc_ioctl_buffer( size_t size )
...
@@ -76,6 +87,41 @@ static void *alloc_ioctl_buffer( size_t size )
return
ioctl_buffer
;
return
ioctl_buffer
;
}
}
static
int
screen_buffer_compare_id
(
const
void
*
key
,
const
struct
wine_rb_entry
*
entry
)
{
struct
screen_buffer
*
screen_buffer
=
WINE_RB_ENTRY_VALUE
(
entry
,
struct
screen_buffer
,
entry
);
return
(
unsigned
int
)
key
-
screen_buffer
->
id
;
}
static
struct
wine_rb_tree
screen_buffer_map
=
{
screen_buffer_compare_id
};
static
struct
screen_buffer
*
create_screen_buffer
(
struct
console
*
console
,
int
id
,
int
width
,
int
height
)
{
struct
screen_buffer
*
screen_buffer
;
if
(
!
(
screen_buffer
=
malloc
(
sizeof
(
*
screen_buffer
)
)))
return
NULL
;
screen_buffer
->
console
=
console
;
screen_buffer
->
id
=
id
;
screen_buffer
->
width
=
width
;
screen_buffer
->
height
=
height
;
if
(
wine_rb_put
(
&
screen_buffer_map
,
(
const
void
*
)
id
,
&
screen_buffer
->
entry
))
{
ERR
(
"id %x already exists
\n
"
,
id
);
return
NULL
;
}
return
screen_buffer
;
}
static
void
destroy_screen_buffer
(
struct
screen_buffer
*
screen_buffer
)
{
if
(
screen_buffer
->
console
->
active
==
screen_buffer
)
screen_buffer
->
console
->
active
=
NULL
;
wine_rb_remove
(
&
screen_buffer_map
,
&
screen_buffer
->
entry
);
free
(
screen_buffer
);
}
static
NTSTATUS
read_console_input
(
struct
console
*
console
,
size_t
out_size
)
static
NTSTATUS
read_console_input
(
struct
console
*
console
,
size_t
out_size
)
{
{
size_t
count
=
min
(
out_size
/
sizeof
(
INPUT_RECORD
),
console
->
record_count
);
size_t
count
=
min
(
out_size
/
sizeof
(
INPUT_RECORD
),
console
->
record_count
);
...
@@ -158,7 +204,7 @@ static NTSTATUS set_console_title( struct console *console, const WCHAR *in_titl
...
@@ -158,7 +204,7 @@ static NTSTATUS set_console_title( struct console *console, const WCHAR *in_titl
{
{
WCHAR
*
title
=
NULL
;
WCHAR
*
title
=
NULL
;
TRACE
(
"%s
\n
"
,
debugstr_wn
(
in_title
,
size
)
);
TRACE
(
"%s
\n
"
,
debugstr_wn
(
in_title
,
size
/
sizeof
(
WCHAR
)
)
);
if
(
size
)
if
(
size
)
{
{
...
@@ -171,6 +217,27 @@ static NTSTATUS set_console_title( struct console *console, const WCHAR *in_titl
...
@@ -171,6 +217,27 @@ static NTSTATUS set_console_title( struct console *console, const WCHAR *in_titl
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
static
NTSTATUS
screen_buffer_ioctl
(
struct
screen_buffer
*
screen_buffer
,
unsigned
int
code
,
const
void
*
in_data
,
size_t
in_size
,
size_t
*
out_size
)
{
switch
(
code
)
{
case
IOCTL_CONDRV_CLOSE_OUTPUT
:
if
(
in_size
||
*
out_size
)
return
STATUS_INVALID_PARAMETER
;
destroy_screen_buffer
(
screen_buffer
);
return
STATUS_SUCCESS
;
case
IOCTL_CONDRV_ACTIVATE
:
if
(
in_size
||
*
out_size
)
return
STATUS_INVALID_PARAMETER
;
screen_buffer
->
console
->
active
=
screen_buffer
;
return
STATUS_SUCCESS
;
default:
FIXME
(
"unsupported ioctl %x
\n
"
,
code
);
return
STATUS_NOT_SUPPORTED
;
}
}
static
NTSTATUS
console_input_ioctl
(
struct
console
*
console
,
unsigned
int
code
,
const
void
*
in_data
,
static
NTSTATUS
console_input_ioctl
(
struct
console
*
console
,
unsigned
int
code
,
const
void
*
in_data
,
size_t
in_size
,
size_t
*
out_size
)
size_t
in_size
,
size_t
*
out_size
)
{
{
...
@@ -324,6 +391,7 @@ static NTSTATUS process_console_ioctls( struct console *console )
...
@@ -324,6 +391,7 @@ static NTSTATUS process_console_ioctls( struct console *console )
{
{
size_t
out_size
=
0
,
in_size
;
size_t
out_size
=
0
,
in_size
;
unsigned
int
code
;
unsigned
int
code
;
int
output
;
NTSTATUS
status
=
STATUS_SUCCESS
;
NTSTATUS
status
=
STATUS_SUCCESS
;
for
(;;)
for
(;;)
...
@@ -339,6 +407,7 @@ static NTSTATUS process_console_ioctls( struct console *console )
...
@@ -339,6 +407,7 @@ static NTSTATUS process_console_ioctls( struct console *console )
wine_server_set_reply
(
req
,
ioctl_buffer
,
ioctl_buffer_size
);
wine_server_set_reply
(
req
,
ioctl_buffer
,
ioctl_buffer_size
);
status
=
wine_server_call
(
req
);
status
=
wine_server_call
(
req
);
code
=
reply
->
code
;
code
=
reply
->
code
;
output
=
reply
->
output
;
out_size
=
reply
->
out_size
;
out_size
=
reply
->
out_size
;
in_size
=
wine_server_reply_size
(
reply
);
in_size
=
wine_server_reply_size
(
reply
);
}
}
...
@@ -357,7 +426,32 @@ static NTSTATUS process_console_ioctls( struct console *console )
...
@@ -357,7 +426,32 @@ static NTSTATUS process_console_ioctls( struct console *console )
return
status
;
return
status
;
}
}
status
=
console_input_ioctl
(
console
,
code
,
ioctl_buffer
,
in_size
,
&
out_size
);
if
(
code
==
IOCTL_CONDRV_INIT_OUTPUT
)
{
TRACE
(
"initializing output %x
\n
"
,
output
);
if
(
console
->
active
)
create_screen_buffer
(
console
,
output
,
console
->
active
->
width
,
console
->
active
->
height
);
else
create_screen_buffer
(
console
,
output
,
80
,
150
);
}
else
if
(
!
output
)
{
status
=
console_input_ioctl
(
console
,
code
,
ioctl_buffer
,
in_size
,
&
out_size
);
}
else
{
struct
wine_rb_entry
*
entry
;
if
(
!
(
entry
=
wine_rb_get
(
&
screen_buffer_map
,
(
const
void
*
)
output
)))
{
ERR
(
"invalid screen buffer id %x
\n
"
,
output
);
status
=
STATUS_INVALID_HANDLE
;
}
else
{
status
=
screen_buffer_ioctl
(
WINE_RB_ENTRY_VALUE
(
entry
,
struct
screen_buffer
,
entry
),
code
,
ioctl_buffer
,
in_size
,
&
out_size
);
}
}
}
}
}
}
...
@@ -484,5 +578,7 @@ int __cdecl wmain(int argc, WCHAR *argv[])
...
@@ -484,5 +578,7 @@ int __cdecl wmain(int argc, WCHAR *argv[])
return
1
;
return
1
;
}
}
if
(
!
(
console
.
active
=
create_screen_buffer
(
&
console
,
1
,
width
,
height
)))
return
1
;
return
main_loop
(
&
console
,
signal
);
return
main_loop
(
&
console
,
signal
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment