Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
a392e9a1
Commit
a392e9a1
authored
Jan 18, 2011
by
Eric Pouech
Committed by
Alexandre Julliard
Jan 19, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Correctly parse the input strings for advanced keys.
parent
46cd2994
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
223 additions
and
28 deletions
+223
-28
console.c
dlls/kernel32/console.c
+73
-28
console_private.h
dlls/kernel32/console_private.h
+1
-0
term.c
dlls/kernel32/term.c
+149
-0
No files found.
dlls/kernel32/console.c
View file @
a392e9a1
...
...
@@ -5,7 +5,7 @@
* Copyright 1997 Karl Garrison
* Copyright 1998 John Richardson
* Copyright 1998 Marcus Meissner
* Copyright 2001,2002,2004,2005 Eric Pouech
* Copyright 2001,2002,2004,2005
,2010
Eric Pouech
* Copyright 2001 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
...
...
@@ -1099,39 +1099,84 @@ enum read_console_input_return {rci_error = 0, rci_timeout = 1, rci_gotone = 2};
static
enum
read_console_input_return
bare_console_fetch_input
(
HANDLE
handle
,
int
fd
,
DWORD
timeout
)
{
struct
pollfd
pollfd
;
char
ch
;
enum
read_console_input_return
ret
;
unsigned
numEvent
;
INPUT_RECORD
ir
[
8
];
DWORD
written
;
pollfd
.
fd
=
fd
;
pollfd
.
events
=
POLLIN
;
pollfd
.
revents
=
0
;
enum
read_console_input_return
ret
;
char
input
[
8
];
int
i
;
size_t
idx
=
0
;
unsigned
numEvent
;
INPUT_RECORD
ir
[
8
];
DWORD
written
;
struct
pollfd
pollfd
;
BOOL
locked
=
FALSE
,
next_char
;
do
{
if
(
idx
==
sizeof
(
input
))
{
FIXME
(
"buffer too small (%s)
\n
"
,
wine_dbgstr_an
(
input
,
idx
));
ret
=
rci_error
;
break
;
}
pollfd
.
fd
=
fd
;
pollfd
.
events
=
POLLIN
;
pollfd
.
revents
=
0
;
next_char
=
FALSE
;
switch
(
poll
(
&
pollfd
,
1
,
timeout
))
{
case
1
:
RtlEnterCriticalSection
(
&
CONSOLE_CritSect
);
switch
(
read
(
fd
,
&
ch
,
1
))
switch
(
poll
(
&
pollfd
,
1
,
timeout
))
{
case
1
:
numEvent
=
TERM_FillSimpleChar
(
ch
,
ir
);
ret
=
WriteConsoleInputW
(
handle
,
ir
,
numEvent
,
&
written
)
?
rci_gotone
:
rci_error
;
if
(
!
locked
)
{
RtlEnterCriticalSection
(
&
CONSOLE_CritSect
);
locked
=
TRUE
;
}
i
=
read
(
fd
,
&
input
[
idx
],
1
);
if
(
i
<
0
)
{
ret
=
rci_error
;
break
;
}
if
(
i
==
0
)
{
/* actually another thread likely beat us to reading the char
* return rci_gotone, while not perfect, it should work in most of the cases (as the new event
* should be now in the queue, fed from the other thread)
*/
ret
=
rci_gotone
;
break
;
}
idx
++
;
numEvent
=
TERM_FillInputRecord
(
input
,
idx
,
ir
);
switch
(
numEvent
)
{
case
0
:
/* we need more char(s) to tell if it matches a key-db entry. wait 1/2s for next char */
timeout
=
500
;
next_char
=
TRUE
;
break
;
case
-
1
:
/* we haven't found the string into key-db, push full input string into server */
for
(
i
=
0
;
i
<
idx
;
i
++
)
{
numEvent
=
TERM_FillSimpleChar
(
input
[
i
],
ir
);
WriteConsoleInputW
(
handle
,
ir
,
numEvent
,
&
written
);
}
ret
=
idx
==
0
?
rci_timeout
:
rci_gotone
;
break
;
default:
/* we got a transformation from key-db... push this into server */
ret
=
WriteConsoleInputW
(
handle
,
ir
,
numEvent
,
&
written
)
?
rci_gotone
:
rci_error
;
break
;
}
break
;
/* actually another thread likely beat us to reading the char
* return gotone, while not perfect, it should work in most of the cases (as the new event
* should be now in the queue)
*/
case
0
:
ret
=
rci_gotone
;
break
;
case
0
:
ret
=
rci_timeout
;
break
;
default:
ret
=
rci_error
;
break
;
}
RtlLeaveCriticalSection
(
&
CONSOLE_CritSect
);
return
ret
;
case
0
:
return
rci_timeout
;
default:
return
rci_error
;
}
}
while
(
next_char
);
if
(
locked
)
RtlLeaveCriticalSection
(
&
CONSOLE_CritSect
);
return
ret
;
}
static
enum
read_console_input_return
read_console_input
(
HANDLE
handle
,
PINPUT_RECORD
ir
,
DWORD
timeout
)
...
...
dlls/kernel32/console_private.h
View file @
a392e9a1
...
...
@@ -37,5 +37,6 @@ extern WCHAR* CONSOLE_Readline(HANDLE, BOOL);
extern
BOOL
TERM_Init
(
void
);
extern
BOOL
TERM_Exit
(
void
);
extern
unsigned
TERM_FillSimpleChar
(
unsigned
real_inchar
,
INPUT_RECORD
*
ir
);
extern
int
TERM_FillInputRecord
(
const
char
*
in
,
size_t
len
,
INPUT_RECORD
*
ir
);
#endif
/* __WINE_CONSOLE_PRIVATE_H */
dlls/kernel32/term.c
View file @
a392e9a1
...
...
@@ -157,7 +157,10 @@ static void *nc_handle = NULL;
#define MAKE_FUNCPTR(f) static typeof(f) * p_##f;
MAKE_FUNCPTR
(
putp
)
MAKE_FUNCPTR
(
setupterm
)
MAKE_FUNCPTR
(
tigetstr
)
MAKE_FUNCPTR
(
tparm
)
#undef MAKE_FUNCPTR
...
...
@@ -185,7 +188,10 @@ static BOOL TERM_bind_libcurses(void)
goto sym_not_found; \
}
LOAD_FUNCPTR
(
putp
)
LOAD_FUNCPTR
(
setupterm
)
LOAD_FUNCPTR
(
tigetstr
)
LOAD_FUNCPTR
(
tparm
)
#undef LOAD_FUNCPTR
...
...
@@ -201,20 +207,163 @@ sym_not_found:
return
FALSE
;
}
#define putp p_putp
#define setupterm p_setupterm
#define tigetstr p_tigetstr
#define tparm p_tparm
struct
dbkey_descr
{
enum
dbkey_kind
{
dbk_simple
,
dbk_complex
}
kind
;
DWORD_PTR
p1
;
DWORD_PTR
p2
;
DWORD_PTR
p3
;
};
struct
dbkey_pair
{
const
char
*
string
;
struct
dbkey_descr
descr
;
};
static
struct
dbkey_pair
TERM_dbkey_init
[]
=
{
{
"kcud1"
,
{
dbk_complex
,
0x50
,
0x28
,
0
}},
{
"kcuu1"
,
{
dbk_complex
,
0x48
,
0x26
,
0
}},
{
"kcub1"
,
{
dbk_complex
,
0x4b
,
0x25
,
0
}},
{
"kcuf1"
,
{
dbk_complex
,
0x4d
,
0x27
,
0
}},
{
"khome"
,
{
dbk_complex
,
0x47
,
0x24
,
0
}},
{
"kbs"
,
{
dbk_simple
,
0x7f
,
0x00
,
0
}},
{
"kf1"
,
{
dbk_complex
,
0x3b
,
0x70
,
0
}},
{
"kf2"
,
{
dbk_complex
,
0x3c
,
0x71
,
0
}},
{
"kf3"
,
{
dbk_complex
,
0x3d
,
0x72
,
0
}},
{
"kf4"
,
{
dbk_complex
,
0x3e
,
0x73
,
0
}},
{
"kf5"
,
{
dbk_complex
,
0x3f
,
0x74
,
0
}},
{
"kf6"
,
{
dbk_complex
,
0x40
,
0x75
,
0
}},
{
"kf7"
,
{
dbk_complex
,
0x41
,
0x76
,
0
}},
{
"kf8"
,
{
dbk_complex
,
0x42
,
0x77
,
0
}},
{
"kf9"
,
{
dbk_complex
,
0x43
,
0x78
,
0
}},
{
"kf10"
,
{
dbk_complex
,
0x44
,
0x79
,
0
}},
{
"kf11"
,
{
dbk_complex
,
0xd9
,
0x7a
,
0
}},
{
"kf12"
,
{
dbk_complex
,
0xda
,
0x7b
,
0
}},
{
"kdch1"
,
{
dbk_complex
,
0x53
,
0x2e
,
0
}},
{
"kich1"
,
{
dbk_complex
,
0x52
,
0x2d
,
0
}},
{
"knp"
,
{
dbk_complex
,
0x51
,
0x22
,
0
}},
{
"kpp"
,
{
dbk_complex
,
0x49
,
0x21
,
0
}},
{
"kcbt"
,
{
dbk_simple
,
0x09
,
0x00
,
SHIFT_PRESSED
}},
{
"kend"
,
{
dbk_complex
,
0x4f
,
0x23
,
0
}},
/* {"kmous", NULL, }, */
{
"kDC"
,
{
dbk_complex
,
0x53
,
0x2e
,
SHIFT_PRESSED
}},
{
"kEND"
,
{
dbk_complex
,
0x4f
,
0x23
,
SHIFT_PRESSED
}},
{
"kHOM"
,
{
dbk_complex
,
0x47
,
0x24
,
SHIFT_PRESSED
}},
{
"kIC"
,
{
dbk_complex
,
0x52
,
0x2d
,
SHIFT_PRESSED
}},
{
"kLFT"
,
{
dbk_complex
,
0x4b
,
0x25
,
SHIFT_PRESSED
}},
{
"kRIT"
,
{
dbk_complex
,
0x4d
,
0x27
,
SHIFT_PRESSED
}},
/* Still some keys to manage:
KEY_DL KEY_IL KEY_EIC KEY_CLEAR KEY_EOS
KEY_EOL KEY_SF KEY_SR KEY_STAB KEY_CTAB
KEY_CATAB KEY_ENTER KEY_SRESET KEY_RESET KEY_PRINT
KEY_LL KEY_A1 KEY_A3 KEY_B2 KEY_C1
KEY_C3 KEY_BEG KEY_CANCEL KEY_CLOSE KEY_COMMAND
KEY_COPY KEY_CREATE KEY_EXIT KEY_FIND KEY_HELP
KEY_MARK KEY_MESSAGE KEY_MOVE KEY_NEXT KEY_OPEN
KEY_OPTIONS KEY_PREVIOUS KEY_REDO KEY_REFERENCE KEY_REFRESH
KEY_REPLACE KEY_RESTART KEY_RESUME KEY_SAVE KEY_SBEG
KEY_SCANCEL KEY_SCOMMAND KEY_SCOPY KEY_SCREATE KEY_RESIZE
KEY_SDL KEY_SELECT KEY_SEOL KEY_SEXIT KEY_SFIND
KEY_SHELP KEY_SMESSAGE KEY_SMOVE KEY_SNEXT KEY_SOPTIONS
KEY_SPREVIOUS KEY_SPRINT KEY_SREDO KEY_SREPLACE KEY_SRSUME
KEY_SSAVE KEY_SSUSPEND KEY_SUNDO KEY_SUSPEND KEY_UNDO
*/
};
static
struct
dbkey_pair
*
TERM_dbkey
;
static
unsigned
TERM_dbkey_size
;
static
unsigned
TERM_dbkey_index
;
static
BOOL
TERM_AddKeyDescr
(
const
char
*
string
,
struct
dbkey_descr
*
descr
)
{
if
(
!
string
)
return
FALSE
;
if
(
!
TERM_dbkey
)
{
TERM_dbkey_size
=
32
;
TERM_dbkey
=
HeapAlloc
(
GetProcessHeap
(),
0
,
TERM_dbkey_size
*
sizeof
(
struct
dbkey_pair
));
if
(
!
TERM_dbkey
)
return
FALSE
;
}
if
(
TERM_dbkey_index
==
TERM_dbkey_size
)
{
struct
dbkey_pair
*
new
;
new
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
TERM_dbkey
,
(
2
*
TERM_dbkey_size
)
*
sizeof
(
struct
dbkey_pair
));
if
(
!
new
)
return
FALSE
;
TERM_dbkey
=
new
;
TERM_dbkey_size
*=
2
;
}
TERM_dbkey
[
TERM_dbkey_index
].
string
=
string
;
TERM_dbkey
[
TERM_dbkey_index
].
descr
=
*
descr
;
TERM_dbkey_index
++
;
return
TRUE
;
}
static
BOOL
TERM_BuildKeyDB
(
void
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
sizeof
(
TERM_dbkey_init
)
/
sizeof
(
TERM_dbkey_init
[
0
]);
i
++
)
{
if
(
!
TERM_AddKeyDescr
(
tigetstr
(
TERM_dbkey_init
[
i
].
string
),
&
TERM_dbkey_init
[
i
].
descr
))
return
FALSE
;
}
return
TRUE
;
}
BOOL
TERM_Init
(
void
)
{
if
(
!
TERM_bind_libcurses
())
return
FALSE
;
if
(
setupterm
(
NULL
,
1
/* really ?? */
,
NULL
)
==
-
1
)
return
FALSE
;
TERM_BuildKeyDB
();
/* set application key mode */
putp
(
tigetstr
(
"smkx"
));
return
TRUE
;
}
BOOL
TERM_Exit
(
void
)
{
/* put back the cursor key mode */
putp
(
tigetstr
(
"rmkx"
));
return
TRUE
;
}
/* -1 not found, 0 cannot decide, > 0 found */
int
TERM_FillInputRecord
(
const
char
*
in
,
size_t
len
,
INPUT_RECORD
*
ir
)
{
unsigned
i
;
struct
dbkey_descr
*
found
=
NULL
;
for
(
i
=
0
;
i
<
TERM_dbkey_index
;
i
++
)
{
if
(
!
memcmp
(
TERM_dbkey
[
i
].
string
,
in
,
len
))
{
if
(
len
<
strlen
(
TERM_dbkey
[
i
].
string
))
return
0
;
if
(
found
)
return
0
;
found
=
&
TERM_dbkey
[
i
].
descr
;
}
}
if
(
!
found
)
return
-
1
;
switch
(
found
->
kind
)
{
case
dbk_simple
:
return
TERM_FillSimpleChar
(
found
->
p1
,
ir
);
case
dbk_complex
:
init_complex_char
(
&
ir
[
0
],
1
,
found
->
p1
,
found
->
p2
,
ENHANCED_KEY
|
found
->
p3
);
init_complex_char
(
&
ir
[
1
],
0
,
found
->
p1
,
found
->
p2
,
ENHANCED_KEY
|
found
->
p3
);
return
2
;
}
return
-
1
;
}
#else
BOOL
TERM_Init
(
void
)
{
return
FALSE
;}
BOOL
TERM_Exit
(
void
)
{
return
FALSE
;}
int
TERM_FillInputRecord
(
const
char
*
in
,
INPUT_RECORD
*
ir
)
{
return
-
1
;}
#endif
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