set up Windows Terminal very early #2062

pull/2122/head
nick black 3 years ago
parent 890310abf8
commit 3f00d07579

@ -17,8 +17,8 @@ extern "C" {
#ifdef __MINGW64__
#include <Lmcons.h>
#define tcgetattr(x, y) (-1)
#define tcsetattr(x, y, z) (-1)
#define tcgetattr(x, y) (0)
#define tcsetattr(x, y, z) (0)
#define ECHO 0
#define ICANON 0
#define ICRNL 0

@ -164,6 +164,7 @@ void free_terminfo_cache(tinfo* ti){
munmap(ti->linux_fbuffer, ti->linux_fb_len);
}
#endif
free(ti->tpreserved);
}
// compare one terminal version against another. numerics, separated by
@ -456,7 +457,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, queried_terminals_e qterm
unsigned nonewfonts){
if(!termname){
// setupterm interprets a missing/empty TERM variable as the special value “unknown”.
termname = "unknown";
termname = ti->termname ? ti->termname : "unknown";
}
if(qterm == TERMINAL_UNKNOWN){
match_termname(termname, &qterm);
@ -686,33 +687,42 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
ti->qterm = TERMINAL_LINUX;
}
#endif
#ifndef __MINGW64__
if(ti->ttyfd >= 0){
if(tcgetattr(ti->ttyfd, &ti->tpreserved)){
logpanic("Couldn't preserve terminal state for %d (%s)\n", ti->ttyfd, strerror(errno));
return -1;
}
// enter cbreak mode regardless of user preference until we've performed
// terminal interrogation. at that point, we might restore original mode.
if(cbreak_mode(ti->ttyfd, &ti->tpreserved)){
return -1;
if(ti->qterm != TERMINAL_MSTERMINAL){
if(ti->ttyfd >= 0){
if((ti->tpreserved = calloc(1, sizeof(*ti->tpreserved))) == NULL){
return -1;
}
if(tcgetattr(ti->ttyfd, ti->tpreserved)){
logpanic("Couldn't preserve terminal state for %d (%s)\n", ti->ttyfd, strerror(errno));
free(ti->tpreserved);
return -1;
}
// enter cbreak mode regardless of user preference until we've performed
// terminal interrogation. at that point, we might restore original mode.
if(cbreak_mode(ti->ttyfd, ti->tpreserved)){
free(ti->tpreserved);
return -1;
}
// if we already know our terminal (e.g. on the linux console), there's no
// need to send the identification queries. the controls are sufficient.
bool minimal = (ti->qterm != TERMINAL_UNKNOWN);
if(send_initial_queries(ti->ttyfd, minimal)){
free(ti->tpreserved);
return -1;
}
}
// if we already know our terminal (e.g. on the linux console), there's no
// need to send the identification queries. the controls are sufficient.
bool minimal = (ti->qterm != TERMINAL_UNKNOWN);
if(send_initial_queries(ti->ttyfd, minimal)){
#ifndef __MINGW64__
// windows doesn't really have a concept of terminfo. you might ssh into other
// machines, but they'll use the terminfo installed thereon (putty, etc.).
int termerr;
if(setupterm(termtype, ti->ttyfd, &termerr)){
logpanic("Terminfo error %d for %s (see terminfo(3ncurses))\n", termerr, termtype);
free(ti->tpreserved);
return -1;
}
}
// windows doesn't really have a concept of terminfo. you might ssh into other
// machines, but they'll use the terminfo installed thereon (putty, etc.).
int termerr;
if(setupterm(termtype, ti->ttyfd, &termerr)){
logpanic("Terminfo error %d (see terminfo(3ncurses))\n", termerr);
return -1;
}
tname = termname(); // longname() is also available
tname = termname(); // longname() is also available
#endif
}
ti->sprixel_scale_height = 1;
get_default_geometry(ti);
ti->caps.utf8 = utf8;
@ -845,7 +855,7 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
}
if(nocbreak){
if(ti->ttyfd >= 0){
if(tcsetattr(ti->ttyfd, TCSANOW, &ti->tpreserved)){
if(tcsetattr(ti->ttyfd, TCSANOW, ti->tpreserved)){
ncinputlayer_stop(&ti->input);
goto err;
}
@ -882,6 +892,7 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
return 0;
err:
free(ti->tpreserved);
free(ti->esctable);
free(ti->termversion);
del_curterm(cur_term);

@ -182,16 +182,15 @@ typedef struct tinfo {
// less one times the cell height. sixel_maxy is thus recomputed whenever
// we get a resize event. it is only defined if we have sixel_maxy_pristine,
// so kitty graphics (which don't force a scroll) never deal with this.
int sixel_maxy; // maximum working sixel height
int sixel_maxy_pristine; // maximum theoretical sixel height, as queried
int sprixel_scale_height; // sprixel must be a multiple of this many rows
const char* termname; // terminal name from environment variables/init
char* termversion; // terminal version (freeform) from query responses
queried_terminals_e qterm;// detected terminal class
#ifndef __MINGW64__
struct termios tpreserved;// terminal state upon entry
#endif
ncinputlayer input; // input layer
int sixel_maxy; // maximum working sixel height
int sixel_maxy_pristine; // maximum theoretical sixel height, as queried
int sprixel_scale_height; // sprixel must be a multiple of this many rows
const char* termname; // terminal name from environment variables/init
char* termversion; // terminal version (freeform) from query responses
queried_terminals_e qterm; // detected terminal class
// we heap-allocate this one (if we use it), as it's not fully defined on Windows
struct termios *tpreserved;// terminal state upon entry
ncinputlayer input; // input layer
int default_rows; // LINES environment var / lines terminfo / 24
int default_cols; // COLUMNS environment var / cols terminfo / 80

@ -1,24 +1,11 @@
#include "termdesc.h"
#include "internal.h"
#ifdef __MINGW64__
#include <winsock2.h>
#include "windows.h"
// ti has been memset to all zeroes. windows configuration is static.
int prepare_windows_terminal(tinfo* ti, size_t* tablelen, size_t* tableused){
HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
if(in == INVALID_HANDLE_VALUE){
logerror("couldn't get input handle\n");
return -1;
}
// if we're a true Windows Terminal, SetConsoleMode() ought succeed.
// otherwise, we're something else; go ahead and query.
if(!SetConsoleMode(in, ENABLE_MOUSE_INPUT
| ENABLE_VIRTUAL_TERMINAL_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_WINDOW_INPUT)){
logerror("couldn't set input console mode\n");
return -1;
}
const struct wtermdesc {
escape_e esc;
const char* tinfo;
@ -56,6 +43,20 @@ int prepare_windows_terminal(tinfo* ti, size_t* tablelen, size_t* tableused){
}
ti->caps.rgb = true;
ti->caps.colors = 256;
HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
if(in == INVALID_HANDLE_VALUE){
logerror("couldn't get input handle\n");
return -1;
}
// if we're a true Windows Terminal, SetConsoleMode() ought succeed.
// otherwise, we're something else; go ahead and query.
if(!SetConsoleMode(in, ENABLE_MOUSE_INPUT
| ENABLE_VIRTUAL_TERMINAL_INPUT
| ENABLE_PROCESSED_INPUT
| ENABLE_WINDOW_INPUT)){
logerror("couldn't set input console mode\n");
return -1;
}
ti->caps.quadrants = true;
ti->caps.braille = true;
ti->termname = "Windows Terminal";

Loading…
Cancel
Save