|
2 | 2 | #include <windows.h> |
3 | 3 | #else |
4 | 4 | #include <cerrno> |
| 5 | + #include <csignal> |
| 6 | + #include <fcntl.h> |
5 | 7 | #include <sys/ioctl.h> |
6 | 8 | #include <unistd.h> |
7 | 9 | #endif |
|
13 | 15 | #include <string> |
14 | 16 | #include <vector> |
15 | 17 |
|
| 18 | +#if !defined(_WIN32) |
| 19 | +namespace |
| 20 | +{ |
| 21 | +volatile std::sig_atomic_t gSignalStatus; |
| 22 | +} |
| 23 | + |
| 24 | +static void sigwinchHandler(int sig) |
| 25 | +{ |
| 26 | + if(sig == SIGWINCH) gSignalStatus = 1; |
| 27 | +} |
| 28 | +#endif |
| 29 | + |
16 | 30 | char Term::Platform::read_raw_stdin() |
17 | 31 | { |
18 | 32 | char c = getchar(); |
@@ -102,20 +116,55 @@ Term::Event Term::Platform::read_raw() |
102 | 116 | case MENU_EVENT: |
103 | 117 | case MOUSE_EVENT: |
104 | 118 | case WINDOW_BUFFER_SIZE_EVENT: |
105 | | - default: return Event(); |
| 119 | + { |
| 120 | + COORD coord{buf[i].Event.WindowBufferSizeEvent.dwSize}; |
| 121 | + return Event(Screen(coord.Y, coord.X)); |
| 122 | + } |
| 123 | + default: continue; |
106 | 124 | } |
107 | 125 | } |
108 | 126 | return Event(ret.c_str()); |
109 | 127 | } |
110 | 128 | else |
111 | 129 | return Event(); |
112 | 130 | #else |
113 | | - std::string ret(4096, '\0'); // Max for cin |
114 | | - errno = 0; |
115 | | - ::ssize_t nread{::read(0, &ret[0], ret.size())}; |
116 | | - if(nread == -1 && errno != EAGAIN) { throw Term::Exception("read() failed"); } |
117 | | - if(nread >= 1) return Event(ret.c_str()); |
| 131 | + static bool activated{false}; |
| 132 | + if(!activated) |
| 133 | + { |
| 134 | + struct sigaction sa; |
| 135 | + sigemptyset(&sa.sa_mask); |
| 136 | + sa.sa_flags = 0; |
| 137 | + sa.sa_handler = sigwinchHandler; |
| 138 | + if(sigaction(SIGWINCH, &sa, NULL) == -1) throw Term::Exception("signal() failed"); |
| 139 | + else |
| 140 | + activated = true; |
| 141 | + } |
| 142 | + |
| 143 | + if(gSignalStatus == 1) |
| 144 | + { |
| 145 | + struct winsize ws |
| 146 | + { |
| 147 | + }; |
| 148 | + ws.ws_row = 0; |
| 149 | + ws.ws_col = 0; |
| 150 | + ws.ws_xpixel = 0; |
| 151 | + ws.ws_ypixel = 0; |
| 152 | + int fd{open("/dev/tty", O_RDWR, O_NOCTTY)}; |
| 153 | + ioctl(fd, TIOCGWINSZ, &ws); |
| 154 | + close(fd); |
| 155 | + gSignalStatus = 0; |
| 156 | + if(ws.ws_row != 0 && ws.ws_col != 0) return Event(Screen(ws.ws_row, ws.ws_col)); |
| 157 | + } |
118 | 158 | else |
119 | | - return Event(); |
| 159 | + { |
| 160 | + std::string ret(4096, '\0'); // Max for cin |
| 161 | + errno = 0; |
| 162 | + ::ssize_t nread{::read(0, &ret[0], ret.size())}; |
| 163 | + if(nread == -1 && errno != EAGAIN) { throw Term::Exception("read() failed"); } |
| 164 | + if(nread >= 1) return Event(ret.c_str()); |
| 165 | + else |
| 166 | + return Event(); |
| 167 | + } |
| 168 | + return Event(); |
120 | 169 | #endif |
121 | 170 | } |
0 commit comments