Skip to content

Add Windows support.

Jezza requested to merge Jezza/termion:windows-support into master

Edit: It's all done and ready now.


I had some spare time and I love termion, so I thought I'd add support for windows. I'm by no means a windows programmer, so if I've botched something or there's a better way to do something, feel free to say something. The implementation itself is pretty much done. It's complete enough that I could run most of the examples. The tests are another matter... I'll need to look into it, but basically, the tests themselves just don't work.

I've marked this as a WIP as there's still some things to do.

First:

As I said, some of the examples don't work or have odd behaviour. Those in question:

  • async (At a quick glance, it's not doing the thing it's supposed to... Or at least, it looks very weird. An error is printed out, so that's probably something I should look into.)

  • detect_color (An internal error, haven't looked into it yet because it's getting late...)

  • is_tty (Kind of a weird question, because I have no idea if it even makes sense. It's not possible to construct a fd to stdout without explicitly doing so in windows... It's an open topic.)

  • mouse (The mouse itself does generate events. For example, the click example does work.)

  • truecolor (This just looks weird. I think it might have something to do with the refresh rate of the console...)

Second:

Code review! I have no idea if what I did was the correct thing to do in that scenario. For example, I use std's handle when fetching the stdout handle, but in the attr module, I just use the win api directly. Now, I know they're both functionally equivalent, but I should probably standardise it. There's also the "problem" of returning a fs::File as the tty. A good idea might be to switch winapi's HANDLE to std's, and then just use winapi's stdout handle, and only use rust for the fs::File conversion.

Third:

Some of the flags I pass to the console api. I know that we need all except one flag: ENABLE_VIRTUAL_TERMINAL_PROCESSING. I only added it because the documentation says it's typically used in conjunction with ENABLE_VIRTUAL_TERMINAL_INPUT. I'm about 99% we don't need it, or arguably, even want it...

Fourth:

Is is_tty necessary for windows? I alluded to the main reason why I think this right now. To construct a HANDLE to something that could be a tty requires some pretty explicit pipework in windows. At least, from what I can tell. I'm not opposed to implementing it, I'm basically just trying to confirm that "yeah, it's technically needed." All that needs to be done in this case is basically just pull out the fd that the incoming stream uses, and check it against the stdout. That's probably going to be a bit messy though. Rust does have a IntoRawHandle for things that can be turned into raw handles. Files, stdout, etc, already implement it. I don't know if I can decompose a RawHandle... I'll need to look into it.


After all of that is done, I would consider this done. In the meantime, as it stands, it does work, so people are free to poke around on this branch, and see what breaks.

Edited by Jezza

Merge request reports