From: Jacob Bachmeyer <jcb62281@gmail.com>
To: Jacek Caban <jacek@codeweavers.com>
Cc: Eric Pouech <eric.pouech@orange.fr>,
fortran@gcc.gnu.org, NightStrike <nightstrike@gmail.com>,
DejaGnu mailing list <dejagnu@gnu.org>
Subject: Re: testsuite under wine
Date: Fri, 23 Dec 2022 23:33:34 -0600 [thread overview]
Message-ID: <63A68F2E.6080904@gmail.com> (raw)
In-Reply-To: <446e92cc-4942-5095-b92e-bed4db13f615@codeweavers.com>
Jacek Caban wrote:
> On 12/23/22 04:51, Jacob Bachmeyer wrote:
>> Eric Pouech wrote:
>>> Le 22/12/2022 à 05:16, Jacob Bachmeyer a écrit :
>>>>> I think that it would not be enough. The way Windows consoles work
>>>>> is that we manage complete internal screen buffer and emit output
>>>>> that synchronizes the buffer with Unix terminal inside conhost.exe
>>>>> process. It means that its output heavily processed and may be
>>>>> very different from what application writes to its console handle.
>>>>> While escape codes discussed in this thread are the most prominent
>>>>> difference (and that part could, in theory, be improved on our
>>>>> side), there are more differences. For example, if application
>>>>> writes "\rA\rB\rC", conhost will process it, update its internal
>>>>> buffer which changes just one character and cursor position, and
>>>>> emit sequence to update it in Unix terminal, which could be just
>>>>> "\rC" (or even "C" if cursor was already at the beginning of the
>>>>> line). Another example would be long lines: conhost will emit
>>>>> additional EOLs instead of depending on embedder to wrap the line.
>>>>
>>>> So conhost is essentially a Wine-specific screen(1) in that sense,
>>>> except that it translates Windows screen buffer manipulations
>>>> instead of VT100 escape codes? As I understand ncurses also
>>>> implements most of this; perhaps simply delegating output to
>>>> ncurses would solve the problem? If output were simply delegated
>>>> to ncurses, (as I understand) setting TERM=dumb should be effective
>>>> to eliminate escape codes from the output, since the "dumb"
>>>> terminal does not support them.
>>>
>>> unfortunately, things are not as simple as that: on one hand we need
>>> to mimic Windows behavior, and on the other hand let apps running in
>>> wine behave like regular posix applications <g>
>>>
>>> (Note: conhost(.exe) is not wine specific, it's part of the way
>>> windows handle the console input/output)
>>
>> Right. So that is the name of the program that manages consoles in
>> Windows. I knew it was not cmd.exe itself. I was testing an
>> understanding that conhost.exe in Wine is essentially similar to GNU
>> screen, in that both emulate a console/terminal using a *nix
>> terminal. If so, then it should be possible to delegate the actual
>> output (including reductions like the example "\rA\rB\rC" to "\rC")
>> to the ncurses library and get proper sensitivity to TERM "for free"
>> as well.
>>
>> To do that, conhost.exe would need to translate the Windows console
>> buffer manipulations into curses operations, or possibly lower-level
>> terminfo operations, if you still want to roll your own optimization
>> code. If this were done, you could check if the current terminal has
>> sufficient support to properly emulate a Windows console and switch
>> to "raw" mode if the needed terminfo capabilities are not found.
>> Setting TERM=dumb in the environment would then force the use of
>> "raw" mode.
>
>
> Yes, an analogy to screen is right in many aspects, but there are also
> architectural difference that require implementation to be very
> different. ncurses operates on tty file descriptors backed by OS
> kernel. conhost needs to be able to operate on Windows names pipes,
> which are not associated with any file descriptor in Wine.
Please explain this. Programs using curses make calls into the curses
library, which ultimately produces I/O on a tty file descriptor. It
seems to me that conhost is in the same position as the curses library:
programs use Windows API calls for the console which [...across an IPC
bridge of some type?...] result in dispatches in conhost that ultimately
produce I/O on a tty file descriptor. Does conhost not actually hold
the file descriptor, instead performing translations and sending the
result back to the client process, which writes it out?
If full curses is not usable for architectural reasons, terminfo would
still be an improvement. Its setupterm() call may send any known init
strings, but it could be given either the write end of a pipe or a file
descriptor open on /dev/null if that is a problem. The terminfo
database access functions tparm(), tigetflag(), tigetnum(), and
tigetstr() all return values to their callers for further processing and
the information needed to perform curses-style terminal initialization
is stored as string capabilities in the terminfo database.
> Also my point was that if you capture the output sent by the
> application to the terminal and match that to a pattern, then any
> processing made by conhost could cause problems. Please correct me if
> I'm wrong, but my understanding is that, in the above hypothetical
> example, a test case doing printf(stdout, "\rA\rB\rC") and matching
> output to "\rA\rB\rC" would be considered valid (and fail on Wine).
This type of thing is a general problem with testing curses programs, so
the only difference would be effectively adding curses to programs that
are not expected to use it. Yes, this could break testsuites that
should work, so some kind of full bypass would be very helpful; you
already have this if wine is run inside a pipeline.
> That's why we're trying to figure out a solution that bypasses conhost
> and makes the application write directly to stdout, like usual native
> application would do. Such mode would be less compatible with Windows,
> but if tests only does simple I/O and no other console interactions,
> it should work fine. Interpreting TERM=dumb would be a possible
> solution to enter that mode.
I see two aspects to this, and I think both of them have value as
improvements to Wine:
1. Programs that only use the standard handles (a la ISO C) probably do
not /want/ full compatibility with Windows, so their I/O should be
direct to the underlying POSIX fds. Note that line endings are still an
issue here, but are /not/ Wine's problem---the program's I/O library
module is generating Windows-style line endings because it was written
for Windows.
2. Programs using Windows CUI probably should be mapped to curses; as I
see it, conhost currently is implementing a subset of curses, poorly
since it does not use terminfo. Wine should use curses if $TERM
supports curses and either pop up an X11 Wine console window or bail out
if a CUI call is made and $TERM does not support curses. (Actually, an
option to explicitly select an X11 Wine console window might be helpful
for people that want to invoke a Windows CUI program from a graphical
menu; otherwise, you might end up with the CUI silently appearing on the
console from which the X session was started... I know adding xterm to
the mix solves this, but it is a use case.)
I think the best goal here is that, for the standard handles, Wine I/O
should be equivalent to a network connection (telnet?) to a Windows
box. For CUI, Wine should actually use curses or at least terminfo, to
allow the escape codes produced to match the user's terminal. The
user's terminal might not always be a VT100-alike and custom simulated
terminals could be very reasonable for testing curses TUI programs. (To
my knowledge, there are as yet no testsuites that actually /do/ that,
but the composition seems reasonable to me.)
Finding that NightStrike's MinGW test cases are transparently using CUI
would be a MinGW issue, not a Wine issue.
It has been a long time since I have looked at Windows API, but I am
guessing that there is both some equivalent to "fwrite(stdout, ...)"
(ok, so likely something like
"WriteToHandle(GetStandardHandle(STANDARD_HANDLE_OUTPUT),...)" if I
remember the Windows API "style" and its affinity for RSI-supporting
names correctly) and a more complex API for CUI that is more closely
akin to curses. Could you delay initializing conhost until the program
actually attempts to use CUI features? For this option, CUIInit() ends
up calling newterm() and using curses if that succeeds, (possibly, after
considerable future implementation effort) popping up a Wine console
window using X11 if $DISPLAY is usable, or bailing out if neither way to
get a full Windows console works. Until CUIInit() is called, the
standard handles are just that and simply mapped through to the
underlying POSIX handles.
Is this architecturally feasible for Wine to do?
-- Jacob
next prev parent reply other threads:[~2022-12-24 5:33 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-16 2:20 NightStrike
2022-12-16 6:44 ` Thomas Koenig
2022-12-17 0:26 ` NightStrike
2022-12-17 10:52 ` Thomas Koenig
2022-12-17 23:24 ` NightStrike
2022-12-18 3:44 ` Jacob Bachmeyer
2022-12-18 21:13 ` NightStrike
2022-12-19 4:29 ` Jacob Bachmeyer
2022-12-19 10:43 ` Torbjorn SVENSSON
2022-12-19 11:00 ` NightStrike
2022-12-19 11:13 ` NightStrike
2022-12-20 3:51 ` Jacob Bachmeyer
2022-12-21 17:37 ` Jacek Caban
2022-12-22 1:01 ` NightStrike
2022-12-22 4:37 ` Jacob Bachmeyer
2022-12-23 10:36 ` NightStrike
2022-12-23 12:43 ` Eric Pouech
2022-12-24 4:00 ` Jacob Bachmeyer
2022-12-24 11:05 ` Mark Wielaard
2023-01-05 2:50 ` NightStrike
2023-01-06 3:33 ` Jacob Bachmeyer
2023-01-06 3:44 ` Jerry D
2023-01-08 7:12 ` NightStrike
2023-01-11 2:30 ` Jacob Bachmeyer
2023-01-11 9:33 ` NightStrike
2023-01-12 4:11 ` Jacob Bachmeyer
2023-01-06 3:41 ` Jerry D
2022-12-22 4:16 ` Jacob Bachmeyer
2022-12-22 8:40 ` Eric Pouech
2022-12-23 3:51 ` Jacob Bachmeyer
2022-12-23 23:32 ` Jacek Caban
2022-12-24 5:33 ` Jacob Bachmeyer [this message]
2023-01-07 1:45 ` Jacek Caban
2023-01-07 3:58 ` Jacob Bachmeyer
2023-01-09 16:03 ` Jacek Caban
2023-01-10 9:19 ` NightStrike
2023-01-11 9:10 ` NightStrike
2023-01-11 18:41 ` NightStrike
2023-01-14 23:36 ` NightStrike
2023-01-11 2:44 ` Jacob Bachmeyer
2023-01-08 6:47 ` NightStrike
2023-01-04 15:21 ` Pedro Alves
2023-01-04 15:45 ` Eric Pouech
2023-01-04 15:52 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=63A68F2E.6080904@gmail.com \
--to=jcb62281@gmail.com \
--cc=dejagnu@gnu.org \
--cc=eric.pouech@orange.fr \
--cc=fortran@gcc.gnu.org \
--cc=jacek@codeweavers.com \
--cc=nightstrike@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).