Hi all,

I've noticed that the Alt key parsing of the following program has different 
behavior across the different compiler chains/shells on Windows. Consider the 
following program that reads 4 characters from standard input. 
```
#include <cstdio>

int main() {
    char x[4] {};
    fgets(reinterpret_cast<char*>(&x), 4, stdin);
    for (int i {0}; i < 4; ++i) {
        printf("%x ", x[i]);
    }
    return 0;
}
```
Perform these steps:
1. compile (g++ test.cc under cygwin, cl test.cc under MSVC)
2. execute
3. hit "Alt" and "1" at the same time and then hit enter

Here is a table of the output of this program when compiled with different 
toolchains and executed in various terminals.

+-------------------------------+----------------+--------------+------------+
|           COMPILER            | Cygwin Mintty  | MSYS2 Mintty |    CMD     |
+-------------------------------+----------------+--------------+------------+
| Cygwin g++                    | 1b 31 a 0      | 1b 31 0 0*   | 1b 31 0 0* |
| Cygwin x86_64-w64-mingw32-g++ | 31 a 0 0       | 31 a 0 0     | 31 a 0 0   |
| MSYS2 UCRT g++                | 31 a 0 0       | 31 a 0 0     | 31 a 0 0   |
| Visual Studio 2022            | 31 a 0 0       | 31 a 0 0     | 31 a 0 0   |
+-------------------------------+----------------+--------------+------------+
-----------------------------------------------------------------------------
* cygwin1.dll was copied into the current directory in order to run the program 
within these terminals. I didn't get a chance to hit enter - the application 
just quits. 

I thought different C libraries might be the problem, so I tried a pure-winapi 
version:
```
#include <cstdio>
#include <windows.h>

int main() {
        // On Cygwin, apparently these are distinct - stdin points to a pipe 
rather than a console buffer
    HANDLE hstdin {GetStdHandle(STD_INPUT_HANDLE)};
    HANDLE hconin {CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, 
FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)};
    printf("STDIN Handle: %p\n", hstdin);
    printf("CONIN Handle: %p\n", hconin);

    DWORD stdtype {GetFileType(hstdin)};
    DWORD contype {GetFileType(hconin)};
    printf("STDIN Filetype: %x\n", stdtype);
    printf("CONIN Filetype: %x\n", contype);

    char x[4] {};
    DWORD nread {0};
        // You might ask: Why not read from hconin? The test program will hang
    ReadFile(hstdin, &x, 4, &nread, NULL);
    for (int i {0}; i < 4; ++i) {
        printf("%x ", x[i]);
    }
    printf("\n");
 
    return 0;
}
```
New matrix:
+-------------------------------+----------------+--------------+------------+
|           COMPILER            | Cygwin Mintty  | MSYS2 Mintty |    CMD     |
+-------------------------------+----------------+--------------+------------+
| Cygwin g++                    | 1b 31 a 0      | 1b 31 0 0*   | 1b 31 0 0* |
| Cygwin x86_64-w64-mingw32-g++ | 31 d a 0       | 31 d a 0     | 31 d a 0   |
| MSYS2 UCRT g++                | 31 d a 0       | 31 d a 0     | 31 d a 0   |
| Visual Studio 2022            | 31 d a 0       | 31 d a 0     | 31 d a 0   |
+-------------------------------+----------------+--------------+------------+

What does Cygwin do differently that allows it to capture Alt key presses? The 
above tables suggest the presence of cygwin1.dll in the program is relevant. 
I'm guessing that the backend magic (e.g. pipes for standard input, invisible 
consoles) that Cygwin performs plays some role, but thought people on this list 
would be much more familiar with the inner workings and would be able to 
provide a fuller explanation.

Thanks,
William

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to