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