-
Notifications
You must be signed in to change notification settings - Fork 8
/
console_win32.c
118 lines (99 loc) · 3.01 KB
/
console_win32.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <windows.h>
#include "console.h"
#include "mux.h"
static HANDLE hStdin, hStdout;
static DWORD saved_in_mode, saved_out_mode;
static void exit_cleanup(void)
{
SetConsoleMode(hStdin, saved_in_mode);
SetConsoleMode(hStdout, saved_out_mode);
}
static DWORD get_mode(HANDLE h)
{
DWORD mode;
if (GetConsoleMode(h, &mode))
return mode;
fprintf(stderr, "GetConsoleMode() failed!\n");
fprintf(stderr, "Sorry, only native Windows console is supported, no mintty\n");
exit(1);
}
static void set_mode(HANDLE h, DWORD mode)
{
if (!SetConsoleMode(h, mode)) {
fprintf(stderr, "SetConsoleMode() failed!\n");
exit(1);
}
}
void tty_init(void)
{
hStdin = (HANDLE)_get_osfhandle(STDIN_FILENO);
hStdout = (HANDLE)_get_osfhandle(STDOUT_FILENO);
saved_in_mode = get_mode(hStdin);
saved_out_mode = get_mode(hStdout);
/* Disable canonical mode and Ctrl-C interception */
set_mode(hStdin, saved_in_mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT));
/* Enable VT-100 control codes on output */
set_mode(hStdout, saved_out_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
atexit(exit_cleanup);
_setmode(STDIN_FILENO, O_BINARY);
mux_attach(0, STDIN_FILENO, STDOUT_FILENO);
}
void net_init(unsigned short port)
{
fprintf(stderr, "Network is not implemented yet on Win32\n");
abort();
}
unsigned int tty_check_writable(int fd)
{
return 1;
}
static int tty_check_readable(int fd)
{
DWORD r;
if (fd == STDIN_FILENO) {
/*
* WaitForSingleObhect() sometimes signal something other than key input events.
* This may freeze the emulator because eventually the Centurion attempts to
* read a character which isn't there. Using _kbhit() works around that.
*/
return _kbhit();
}
r = WaitForSingleObject((HANDLE)_get_osfhandle(fd), 0);
switch (r)
{
case WAIT_FAILED:
fprintf(stderr, "WaitForMultipleObject() failed in MUX\n");
exit(1);
case WAIT_OBJECT_0:
return 1;
case WAIT_TIMEOUT:
return 0;
default:
fprintf(stderr, "Unexpected WaitForMultipleObject() return value in MUX: %ld\n", r);
exit(1);
}
}
void mux_poll_fds(unsigned trace)
{
int unit;
for (unit = 0; unit < NUM_MUX_UNITS; unit++) {
int ifd = mux_get_in_poll_fd(unit);
if (ifd != -1 && tty_check_readable(ifd))
mux_set_read_ready(unit, trace);
}
}
void throttle_emulation(uint64_t expected_time_ns) {
// Unimplemented
}
void throttle_init() {
// Unimplemented
}
void throttle_set_speed(float speed) {
// Unimplemented
}