Notcurses 3.0.13
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
termdesc.c File Reference
#include <fcntl.h>
#include <unistd.h>
#include <curses.h>
#include "internal.h"
#include "windows.h"
#include "linux.h"
Include dependency graph for termdesc.c:

Go to the source code of this file.

Macros

#define TRIDEVATTR   "\x1b[=c"
 
#define PRIDEVATTR   "\x1b[c"
 
#define XTVERSION   "\x1b[>0q"
 
#define XTGETTCAP   "\x1bP+q544e;524742;687061\x1b\\"
 
#define SECDEVATTR   "\x1b[>c"
 
#define KITTYQUERY   "\x1b_Gi=1,a=q;\x1b\\"
 
#define KKBDSUPPORT   "\x1b[=27u"
 
#define KKBDQUERY   "\x1b[?u"
 
#define XTMODKEYS   "\x1b[>2;1m\x1b[>4;2m"
 
#define IDQUERIES
 
#define DEFBGQ   "\x1b]11;?\e\\"
 
#define DEFFGQ   "\x1b]10;?\e\\"
 
#define DSRCPR   "\x1b[6n"
 
#define SUMQUERY   "\x1b[?2026$p"
 
#define PIXELMOUSEQUERY   "\x1b[?1016$p"
 
#define CREGSXTSM   "\x1b[?2;1;0S"
 
#define GEOMXTSM   "\x1b[?1;1;0S"
 
#define GEOMPIXEL   "\x1b[14t"
 
#define GEOMCELL   "\x1b[18t"
 
#define DIRECTIVES
 
#define KKEYBOARD_PUSH   "\x1b[>u"
 
#define KKBDENTER   KKEYBOARD_PUSH KKBDSUPPORT
 
#define SMCUP   DECSET(SET_SMCUP)
 
#define RMCUP   DECRST(SET_SMCUP)
 
#define PQUERYBUFLEN   4096
 
#define ENVVAR   "TERM"
 

Functions

int grow_esc_table (tinfo *ti, const char *tstr, escape_e esc, size_t *tlen, size_t *tused)
 
void free_terminfo_cache (tinfo *ti)
 
int enter_alternate_screen (int fd, FILE *ttyfp, tinfo *ti, unsigned drain)
 
int leave_alternate_screen (int fd, FILE *fp, tinfo *ti, unsigned drain)
 
int interrogate_terminfo (tinfo *ti, FILE *out, unsigned utf8, unsigned noaltscreen, unsigned nocbreak, unsigned nonewfonts, int *cursor_y, int *cursor_x, ncsharedstats *stats, int lmargin, int tmargin, int rmargin, int bmargin, unsigned draininput)
 
char * termdesc_longterm (const tinfo *ti)
 
int locate_cursor (tinfo *ti, unsigned *cursor_y, unsigned *cursor_x)
 
int tiocgwinsz (int fd, struct winsize *ws)
 
int cbreak_mode (tinfo *ti)
 
int putenv_term (const char *tname)
 

Macro Definition Documentation

◆ CREGSXTSM

#define CREGSXTSM   "\x1b[?2;1;0S"

Definition at line 433 of file termdesc.c.

◆ DEFBGQ

#define DEFBGQ   "\x1b]11;?\e\\"

Definition at line 414 of file termdesc.c.

◆ DEFFGQ

#define DEFFGQ   "\x1b]10;?\e\\"

Definition at line 415 of file termdesc.c.

◆ DIRECTIVES

#define DIRECTIVES
Value:
DEFFGQ \
DEFBGQ \
KKBDQUERY \
SUMQUERY \
PIXELMOUSEQUERY \
"\x1b[?1;3;256S" /* try to set 256 cregs */ \
"\x1b[?1;3;1024S" /* try to set 1024 cregs */ \
KITTYQUERY \
CREGSXTSM \
GEOMXTSM \
GEOMPIXEL \
GEOMCELL \
PRIDEVATTR

Definition at line 446 of file termdesc.c.

◆ DSRCPR

#define DSRCPR   "\x1b[6n"

Definition at line 423 of file termdesc.c.

◆ ENVVAR

#define ENVVAR   "TERM"

◆ GEOMCELL

#define GEOMCELL   "\x1b[18t"

Definition at line 442 of file termdesc.c.

◆ GEOMPIXEL

#define GEOMPIXEL   "\x1b[14t"

Definition at line 439 of file termdesc.c.

◆ GEOMXTSM

#define GEOMXTSM   "\x1b[?1;1;0S"

Definition at line 436 of file termdesc.c.

◆ IDQUERIES

#define IDQUERIES
Value:
TRIDEVATTR \
XTVERSION \
XTGETTCAP \
SECDEVATTR

Definition at line 405 of file termdesc.c.

◆ KITTYQUERY

#define KITTYQUERY   "\x1b_Gi=1,a=q;\x1b\\"

Definition at line 383 of file termdesc.c.

◆ KKBDENTER

#define KKBDENTER   KKEYBOARD_PUSH KKBDSUPPORT

Definition at line 465 of file termdesc.c.

◆ KKBDQUERY

#define KKBDQUERY   "\x1b[?u"

Definition at line 395 of file termdesc.c.

◆ KKBDSUPPORT

#define KKBDSUPPORT   "\x1b[=27u"

Definition at line 390 of file termdesc.c.

◆ KKEYBOARD_PUSH

#define KKEYBOARD_PUSH   "\x1b[>u"

Definition at line 461 of file termdesc.c.

◆ PIXELMOUSEQUERY

#define PIXELMOUSEQUERY   "\x1b[?1016$p"

Definition at line 430 of file termdesc.c.

◆ PQUERYBUFLEN

#define PQUERYBUFLEN   4096

◆ PRIDEVATTR

#define PRIDEVATTR   "\x1b[c"

Definition at line 351 of file termdesc.c.

◆ RMCUP

#define RMCUP   DECRST(SET_SMCUP)

Definition at line 473 of file termdesc.c.

◆ SECDEVATTR

#define SECDEVATTR   "\x1b[>c"

Definition at line 373 of file termdesc.c.

◆ SMCUP

#define SMCUP   DECSET(SET_SMCUP)

Definition at line 472 of file termdesc.c.

◆ SUMQUERY

#define SUMQUERY   "\x1b[?2026$p"

Definition at line 427 of file termdesc.c.

◆ TRIDEVATTR

#define TRIDEVATTR   "\x1b[=c"

Definition at line 336 of file termdesc.c.

◆ XTGETTCAP

#define XTGETTCAP   "\x1bP+q544e;524742;687061\x1b\\"

Definition at line 364 of file termdesc.c.

◆ XTMODKEYS

#define XTMODKEYS   "\x1b[>2;1m\x1b[>4;2m"

Definition at line 400 of file termdesc.c.

◆ XTVERSION

#define XTVERSION   "\x1b[>0q"

Definition at line 354 of file termdesc.c.

Function Documentation

◆ cbreak_mode()

int cbreak_mode ( tinfo ti)

Definition at line 1595 of file termdesc.c.

1595 {
1596#ifndef __MINGW32__
1597 int ttyfd = ti->ttyfd;
1598 if(ttyfd < 0){
1599 return 0;
1600 }
1601 // assume it's not a true terminal (e.g. we might be redirected to a file)
1602 struct termios modtermios;
1603 memcpy(&modtermios, ti->tpreserved, sizeof(modtermios));
1604 // see termios(3). disabling ECHO and ICANON means input will not be echoed
1605 // to the screen, input is made available without enter-based buffering, and
1606 // line editing is disabled. since we have not gone into raw mode, ctrl+c
1607 // etc. still have their typical effects. ICRNL maps return to 13 (Ctrl+M)
1608 // instead of 10 (Ctrl+J).
1609 modtermios.c_lflag &= (~ECHO & ~ICANON);
1610 modtermios.c_iflag &= ~ICRNL;
1611 if(tcsetattr(ttyfd, TCSANOW, &modtermios)){
1612 logerror("error disabling echo / canonical on %d (%s)", ttyfd, strerror(errno));
1613 return -1;
1614 }
1615#else
1616 // we don't yet have a way to take Cygwin/MSYS2 out of canonical mode FIXME.
1617 DWORD mode;
1618 if(!GetConsoleMode(ti->inhandle, &mode)){
1619 logerror("error acquiring input mode");
1620 return -1;
1621 }
1622 mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
1623 if(!SetConsoleMode(ti->inhandle, mode)){
1624 logerror("error setting input mode");
1625 return -1;
1626 }
1627#endif
1628 return 0;
1629}
#define logerror(fmt,...)
Definition logging.h:32
struct termios * tpreserved
Definition termdesc.h:180
int ttyfd
Definition termdesc.h:109
Here is the caller graph for this function:

◆ enter_alternate_screen()

int enter_alternate_screen ( int  fd,
FILE *  ttyfp,
tinfo ti,
unsigned  drain 
)

Definition at line 559 of file termdesc.c.

559 {
560 if(ti->in_alt_screen){
561 return 0;
562 }
563 const char* popcolors = get_escape(ti, ESCAPE_RESTORECOLORS);
564 if(popcolors){
565 if(term_emit(popcolors, ttyfp, true)){
566 return -1;
567 }
568 }
569 const char* smcup = get_escape(ti, ESCAPE_SMCUP);
570 if(smcup == NULL){
571 logerror("alternate screen is unavailable");
572 return -1;
573 }
574 if(!drain){
575 if(ti->kbdlevel){
576 if(tty_emit(KKEYBOARD_POP, fd)){
577 return -1;
578 }
579 }else{
580 if(tty_emit(XTMODKEYSUNDO, fd)){
581 return -1;
582 }
583 }
584 }
585 if(tty_emit(smcup, fd) < 0){
586 return -1;
587 }
588 if(!drain){
589 if(ti->kbdlevel){
590 if(tty_emit(KKBDENTER, fd)){
591 return -1;
592 }
593 }else{
594 if(tty_emit(XTMODKEYS, fd)){
595 return -1;
596 }
597 }
598 }
599 const char* pushcolors = get_escape(ti, ESCAPE_SAVECOLORS);
600 if(pushcolors){
601 if(term_emit(pushcolors, ttyfp, true)){
602 return -1;
603 }
604 }
605 ti->in_alt_screen = true;
606 return 0;
607}
unsigned kbdlevel
Definition termdesc.h:216
bool in_alt_screen
Definition termdesc.h:219
#define KKBDENTER
Definition termdesc.c:465
#define XTMODKEYS
Definition termdesc.c:400
return NULL
Definition termdesc.h:229
@ ESCAPE_RESTORECOLORS
Definition termdesc.h:88
@ ESCAPE_SMCUP
Definition termdesc.h:68
@ ESCAPE_SAVECOLORS
Definition termdesc.h:87
#define XTMODKEYSUNDO
Definition termdesc.h:27
#define KKEYBOARD_POP
Definition termdesc.h:22
Here is the caller graph for this function:

◆ free_terminfo_cache()

void free_terminfo_cache ( tinfo ti)

Definition at line 197 of file termdesc.c.

197 {
198 stop_inputlayer(ti);
199 loginfo("brought down input layer");
200 if(ti->pixel_cleanup){
201 ti->pixel_cleanup(ti);
202 }
203 free(ti->termversion);
204 free(ti->esctable);
205#ifdef __linux__
206 if(ti->linux_fb_fd >= 0){
207 close(ti->linux_fb_fd);
208 }
209 free(ti->linux_fb_dev);
210 if(ti->linux_fbuffer != MAP_FAILED){
211 munmap(ti->linux_fbuffer, ti->linux_fb_len);
212 }
213#endif
214 free(ti->tpreserved);
215 loginfo("destroyed terminfo cache");
216}
free(duplicated)
int stop_inputlayer(tinfo *ti)
Definition in.c:2644
#define loginfo(fmt,...)
Definition logging.h:42
void(* pixel_cleanup)(struct tinfo *)
Definition termdesc.h:158
char * esctable
Definition termdesc.h:110
char * termversion
Definition termdesc.h:177
Here is the call graph for this function:
Here is the caller graph for this function:

◆ grow_esc_table()

int grow_esc_table ( tinfo ti,
const char *  tstr,
escape_e  esc,
size_t *  tlen,
size_t *  tused 
)

Definition at line 14 of file termdesc.c.

15 {
16 // the actual table can grow past 64KB, but we can't start there, as
17 // we only have 16-bit indices.
18 if(*tused >= 65535){
19 fprintf(stderr, "Can't add escape %d to full table\n", esc);
20 return -1;
21 }
22 if(get_escape(ti, esc)){
23 fprintf(stderr, "Already defined escape %d (%s)\n",
24 esc, get_escape(ti, esc));
25 return -1;
26 }
27 size_t slen = strlen(tstr) + 1; // count the nul term
28 if(*tlen - *tused < slen){
29 // guaranteed to give us enough space to add tstr (and then some)
30 size_t newsize = *tlen + 4020 + slen; // don't pull two pages ideally
31 char* tmp = realloc(ti->esctable, newsize);
32 if(tmp == NULL){
33 return -1;
34 }
35 ti->esctable = tmp;
36 *tlen = newsize;
37 }
38 // we now are guaranteed sufficient space to copy tstr
39 memcpy(ti->esctable + *tused, tstr, slen);
40 ti->escindices[esc] = *tused + 1; // one-bias
41 *tused += slen;
42 return 0;
43}
uint16_t escindices[ESCAPE_MAX]
Definition termdesc.h:108
Here is the caller graph for this function:

◆ interrogate_terminfo()

int interrogate_terminfo ( tinfo ti,
FILE *  out,
unsigned  utf8,
unsigned  noaltscreen,
unsigned  nocbreak,
unsigned  nonewfonts,
int *  cursor_y,
int *  cursor_x,
ncsharedstats stats,
int  lmargin,
int  tmargin,
int  rmargin,
int  bmargin,
unsigned  draininput 
)

Definition at line 1294 of file termdesc.c.

1298 {
1299 // if a specified termtype was provided in the notcurses_options, it was
1300 // loaded into our environment at TERM.
1301 const char* termtype = getenv("TERM");
1302 int foolcursor_x, foolcursor_y;
1303 if(!cursor_x){
1304 cursor_x = &foolcursor_x;
1305 }
1306 if(!cursor_y){
1307 cursor_y = &foolcursor_y;
1308 }
1309 *cursor_x = *cursor_y = -1;
1310 ti->sixelengine = NULL;
1311 ti->bg_collides_default = 0xfe000000;
1312 ti->fg_default = 0xff000000;
1313 ti->kbdlevel = UINT_MAX; // see comment in tinfo definition
1314 ti->maxpaletteread = -1;
1315 ti->qterm = TERMINAL_UNKNOWN;
1316 // we don't need a controlling tty for everything we do; allow a failure here
1317 ti->ttyfd = get_tty_fd(out);
1318 ti->gpmfd = -1;
1319 size_t tablelen = 0;
1320 size_t tableused = 0;
1321 const char* tname = NULL;
1322#ifdef __APPLE__
1323 ti->qterm = macos_early_matches();
1324#elif defined(__MINGW32__)
1325 if(termtype){
1326 logwarn("termtype (%s) ignored on windows", termtype);
1327 }
1328 if(prepare_windows_terminal(ti, &tablelen, &tableused)){
1329 logpanic("failed opening Windows ConPTY");
1330 return -1;
1331 }
1332#else
1333 ti->qterm = unix_early_matches(termtype);
1334#if defined(__linux__)
1335 ti->linux_fb_fd = -1;
1336 ti->linux_fbuffer = MAP_FAILED;
1337 // we might or might not program quadrants into the console font
1338 if(is_linux_console(ti->ttyfd)){
1339 ti->qterm = TERMINAL_LINUX;
1340 }
1341#endif
1342#endif
1343 if(ti->ttyfd >= 0){
1344 if((ti->tpreserved = calloc(1, sizeof(*ti->tpreserved))) == NULL){
1345 return -1;
1346 }
1347 if(tcgetattr(ti->ttyfd, ti->tpreserved)){
1348 logpanic("couldn't preserve terminal state for %d (%s)", ti->ttyfd, strerror(errno));
1349 free(ti->tpreserved);
1350 return -1;
1351 }
1352 // enter cbreak mode regardless of user preference until we've performed
1353 // terminal interrogation. at that point, we might restore original mode.
1354 if(cbreak_mode(ti)){
1355 free(ti->tpreserved);
1356 return -1;
1357 }
1358 // if we already know our terminal (e.g. on the linux console), there's no
1359 // need to send the identification queries. the controls are sufficient.
1360 bool minimal = (ti->qterm != TERMINAL_UNKNOWN);
1361 if(send_initial_queries(ti, minimal, noaltscreen, draininput)){
1362 goto err;
1363 }
1364 }
1365#ifndef __MINGW32__
1366 // windows doesn't really have a concept of terminfo. you might ssh into other
1367 // machines, but they'll use the terminfo installed thereon (putty, etc.).
1368 int termerr;
1369 if(setupterm(termtype, ti->ttyfd, &termerr)){
1370 logpanic("terminfo error %d for [%s] (see terminfo(3ncurses))",
1371 termerr, termtype ? termtype : "");
1372 goto err;
1373 }
1374 tname = termname(); // longname() is also available
1375#endif
1376 int linesigs_enabled = 1;
1377 if(ti->tpreserved){
1378 if(!(ti->tpreserved->c_lflag & ISIG)){
1379 linesigs_enabled = 0;
1380 }
1381 }
1382 if(init_inputlayer(ti, stdin, lmargin, tmargin, rmargin, bmargin,
1383 stats, draininput, linesigs_enabled)){
1384 goto err;
1385 }
1386 ti->sprixel_scale_height = 1;
1387 get_default_geometry(ti);
1388 ti->caps.utf8 = utf8;
1389 // allow the "rgb" boolean terminfo capability, a COLORTERM environment
1390 // variable of either "truecolor" or "24bit", or unconditionally enable it
1391 // for several terminals known to always support 8bpc rgb setaf/setab.
1392 if(ti->caps.colors == 0){
1393 int colors = tigetnum("colors");
1394 if(colors <= 0){
1395 ti->caps.colors = 1;
1396 }else{
1397 ti->caps.colors = colors;
1398 }
1399 ti->caps.rgb = query_rgb(); // independent of colors
1400 }
1401 if(do_terminfo_lookups(ti, &tablelen, &tableused)){
1402 goto err;
1403 }
1404 if(ti->ttyfd >= 0){
1405 // if the keypad needn't be explicitly enabled, smkx is not present
1406 const char* smkx = get_escape(ti, ESCAPE_SMKX);
1407 if(smkx){
1408 if(tty_emit(tiparm(smkx), ti->ttyfd) < 0){
1409 logpanic("error enabling keypad transmit mode");
1410 goto err;
1411 }
1412 }
1413 }
1414 if(tigetflag("bce") > 0){
1415 ti->bce = true;
1416 }
1417 if(ti->caps.colors > 1){
1418 const char* initc = get_escape(ti, ESCAPE_INITC);
1419 if(initc){
1420 ti->caps.can_change_colors = true;
1421 }
1422 }else{ // disable initc if there's no color support
1423 ti->escindices[ESCAPE_INITC] = 0;
1424 }
1425 // neither of these is supported on e.g. the "linux" virtual console.
1426 if(!noaltscreen){
1427 if(init_terminfo_esc(ti, "smcup", ESCAPE_SMCUP, &tablelen, &tableused) ||
1428 init_terminfo_esc(ti, "rmcup", ESCAPE_RMCUP, &tablelen, &tableused)){
1429 goto err;
1430 }
1431 const char* smcup = get_escape(ti, ESCAPE_SMCUP);
1432 if(smcup){
1433 ti->in_alt_screen = 1;
1434 // if we're not using the standard smcup, our initial hardcoded use of it
1435 // presumably had no effect; warn the user.
1436 if(strcmp(smcup, SMCUP)){
1437 logwarn("warning: non-standard smcup!");
1438 }
1439 }
1440 }else{
1441 ti->escindices[ESCAPE_SMCUP] = 0;
1442 ti->escindices[ESCAPE_RMCUP] = 0;
1443 }
1444 if(get_escape(ti, ESCAPE_CIVIS) == NULL){
1445 char* chts;
1446 if(terminfostr(&chts, "chts") == 0){
1447 if(grow_esc_table(ti, chts, ESCAPE_CIVIS, &tablelen, &tableused)){
1448 goto err;
1449 }
1450 }
1451 }
1452 if(get_escape(ti, ESCAPE_BOLD)){
1453 if(grow_esc_table(ti, "\e[22m", ESCAPE_NOBOLD, &tablelen, &tableused)){
1454 goto err;
1455 }
1456 }
1457 // if op is defined as ansi 39 + ansi 49, make the split definitions
1458 // available. this ought be asserted by extension capability "ax", but
1459 // no terminal i've found seems to do so. =[
1460 const char* op = get_escape(ti, ESCAPE_OP);
1461 if(op && strcmp(op, "\x1b[39;49m") == 0){
1462 if(grow_esc_table(ti, "\x1b[39m", ESCAPE_FGOP, &tablelen, &tableused) ||
1463 grow_esc_table(ti, "\x1b[49m", ESCAPE_BGOP, &tablelen, &tableused)){
1464 goto err;
1465 }
1466 }
1467 unsigned kitty_graphics = 0;
1468 if(ti->ttyfd >= 0){
1469 if(handle_responses(ti, &tablelen, &tableused, cursor_y, cursor_x,
1470 draininput, &kitty_graphics)){
1471 goto err;
1472 }
1473 if(nocbreak){
1474 // FIXME do this in input later, upon signaling completion?
1475 if(tcsetattr(ti->ttyfd, TCSANOW, ti->tpreserved)){
1476 goto err;
1477 }
1478 }
1479 }else{
1480 ti->kbdlevel = 0; // confirmed no support, don't bother popping
1481 }
1482 // now look up any terminfo elements we might not have received via requests
1483 if(ti->escindices[ESCAPE_HPA] == 0){
1484 if(init_terminfo_esc(ti, "hpa", ESCAPE_HPA, &tablelen, &tableused)){
1485 goto err;
1486 }
1487 }
1488 if(*cursor_x >= 0 && *cursor_y >= 0){
1489 if(add_u7_escape(ti, &tablelen, &tableused)){
1490 goto err;
1491 }
1492 }
1493 bool forcesdm = false;
1494 bool invertsixel = false;
1495 if(apply_term_heuristics(ti, tname, ti->qterm, &tablelen, &tableused,
1496 &forcesdm, &invertsixel, nonewfonts)){
1497 goto err;
1498 }
1499 build_supported_styles(ti);
1500 if(ti->pixel_draw == NULL && ti->pixel_draw_late == NULL){
1501 // color_registers was only assigned if kitty_graphics were unavailable
1502 if(ti->color_registers > 0){
1503 setup_sixel_bitmaps(ti, ti->ttyfd, forcesdm, invertsixel);
1504 }
1505 if(kitty_graphics){
1506 setup_kitty_bitmaps(ti, ti->ttyfd, NCPIXEL_KITTY_STATIC);
1507 }
1508 }
1509 return 0;
1510
1511err:
1512 if(ti->ttyfd >= 0){
1513 // if we haven't yet received a reply confirming lack of kitty keyboard
1514 // support, it'll be UINT_MAX, and we ought try to pop (in case we died
1515 // following the keyboard set, but before confirming support).
1516 if(ti->kbdlevel){
1517 tty_emit(KKEYBOARD_POP, ti->ttyfd);
1518 }
1519 tty_emit(RMCUP, ti->ttyfd);
1520 }
1521 if(ti->tpreserved){
1522 (void)tcsetattr(ti->ttyfd, TCSANOW, ti->tpreserved);
1523 free(ti->tpreserved);
1524 ti->tpreserved = NULL;
1525 }
1526 stop_inputlayer(ti);
1527 free(ti->esctable);
1528 free(ti->termversion);
1529 del_curterm(cur_term);
1530 close(ti->ttyfd);
1531 ti->ttyfd = -1;
1532 return -1;
1533}
int get_tty_fd(FILE *ttyfp)
Definition fd.c:455
int init_inputlayer(tinfo *ti, FILE *infp, int lmargin, int tmargin, int rmargin, int bmargin, ncsharedstats *stats, unsigned drain, int linesigs_enabled)
Definition in.c:2627
@ TERMINAL_LINUX
Definition in.h:35
@ TERMINAL_UNKNOWN
Definition in.h:32
bool is_linux_console(int fd)
#define logwarn(fmt,...)
Definition logging.h:37
#define logpanic(fmt,...)
Definition logging.h:22
@ NCPIXEL_KITTY_STATIC
Definition notcurses.h:1680
unsigned colors
Definition notcurses.h:1637
bool can_change_colors
Definition notcurses.h:1640
queried_terminals_e qterm
Definition termdesc.h:178
int maxpaletteread
Definition termdesc.h:193
void * sixelengine
Definition termdesc.h:175
int(* pixel_draw_late)(const struct tinfo *, struct sprixel *s, int yoff, int xoff)
Definition termdesc.h:149
bool bce
Definition termdesc.h:218
int gpmfd
Definition termdesc.h:195
uint32_t bg_collides_default
Definition termdesc.h:127
unsigned sprixel_scale_height
Definition termdesc.h:174
nccapabilities caps
Definition termdesc.h:111
uint32_t fg_default
Definition termdesc.h:130
int(* pixel_draw)(const struct tinfo *, const struct ncpile *p, struct sprixel *s, fbuf *f, int y, int x)
Definition termdesc.h:147
int color_registers
Definition termdesc.h:164
#define SMCUP
Definition termdesc.c:472
int grow_esc_table(tinfo *ti, const char *tstr, escape_e esc, size_t *tlen, size_t *tused)
Definition termdesc.c:14
int cbreak_mode(tinfo *ti)
Definition termdesc.c:1595
#define RMCUP
Definition termdesc.c:473
@ ESCAPE_CIVIS
Definition termdesc.h:54
@ ESCAPE_BOLD
Definition termdesc.h:62
@ ESCAPE_NOBOLD
Definition termdesc.h:63
@ ESCAPE_OP
Definition termdesc.h:50
@ ESCAPE_RMCUP
Definition termdesc.h:69
@ ESCAPE_SMKX
Definition termdesc.h:65
@ ESCAPE_FGOP
Definition termdesc.h:51
@ ESCAPE_INITC
Definition termdesc.h:81
@ ESCAPE_BGOP
Definition termdesc.h:52
@ ESCAPE_HPA
Definition termdesc.h:46
int prepare_windows_terminal(struct tinfo *ti, size_t *tablelen, size_t *tableused)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ leave_alternate_screen()

int leave_alternate_screen ( int  fd,
FILE *  fp,
tinfo ti,
unsigned  drain 
)

Definition at line 611 of file termdesc.c.

611 {
612 if(!ti->in_alt_screen){
613 return 0;
614 }
615 const char* rmcup = get_escape(ti, ESCAPE_RMCUP);
616 if(rmcup == NULL){
617 logerror("can't leave alternate screen");
618 return -1;
619 }
620 if(!drain){
621 if(ti->kbdlevel){
622 if(tty_emit(KKEYBOARD_POP, fd)){
623 return -1;
624 }
625 }else{
626 if(tty_emit(XTMODKEYSUNDO, fd)){
627 return -1;
628 }
629 }
630 }
631 const char* popcolors = get_escape(ti, ESCAPE_RESTORECOLORS);
632 if(popcolors){
633 if(term_emit(popcolors, fp, true)){
634 return -1;
635 }
636 }
637 if(tty_emit(rmcup, fd)){
638 return -1;
639 }
640 if(!drain){
641 if(ti->kbdlevel){
642 if(tty_emit(KKBDENTER, fd)){
643 return -1;
644 }
645 }else{
646 if(tty_emit(XTMODKEYS, fd)){
647 return -1;
648 }
649 }
650 }
651 const char* pushcolors = get_escape(ti, ESCAPE_SAVECOLORS);
652 if(pushcolors){
653 if(term_emit(popcolors, fp, true)){
654 return -1;
655 }
656 }
657 ti->in_alt_screen = false;
658 return 0;
659}
Here is the caller graph for this function:

◆ locate_cursor()

int locate_cursor ( tinfo ti,
unsigned *  cursor_y,
unsigned *  cursor_x 
)

Definition at line 1558 of file termdesc.c.

1558 {
1559 const char* u7 = get_escape(ti, ESCAPE_U7);
1560 if(u7 == NULL){
1561 logwarn("no support in terminfo");
1562 return -1;
1563 }
1564 if(ti->ttyfd < 0){
1565 logwarn("no valid path for cursor report");
1566 return -1;
1567 }
1568 int fd = ti->ttyfd;
1569 if(get_cursor_location(ti->ictx, u7, cursor_y, cursor_x)){
1570 return -1;
1571 }
1572 loginfo("got a report from %d %d/%d", fd, *cursor_y, *cursor_x);
1573 return 0;
1574}
int get_cursor_location(inputctx *ictx, const char *u7, unsigned *y, unsigned *x)
Definition in.c:2785
struct inputctx * ictx
Definition termdesc.h:181
@ ESCAPE_U7
Definition termdesc.h:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ putenv_term()

int putenv_term ( const char *  tname)

Definition at line 1632 of file termdesc.c.

1632 {
1633 #define ENVVAR "TERM"
1634 const char* oldterm = getenv(ENVVAR);
1635 if(oldterm){
1636 logdebug("replacing %s value %s with %s", ENVVAR, oldterm, tname);
1637 }else{
1638 loginfo("provided %s value %s", ENVVAR, tname);
1639 }
1640 if(oldterm && strcmp(oldterm, tname) == 0){
1641 return 0;
1642 }
1643 char* buf = malloc(strlen(tname) + strlen(ENVVAR) + 1);
1644 if(buf == NULL){
1645 return -1;
1646 }
1647 int c = putenv(buf);
1648 if(c){
1649 logerror("couldn't export %s", buf);
1650 }
1651 free(buf);
1652 return c;
1653}
const nccell * c
Definition egcpool.h:296
#define logdebug(fmt,...)
Definition logging.h:52
#define ENVVAR
Here is the call graph for this function:
Here is the caller graph for this function:

◆ termdesc_longterm()

char * termdesc_longterm ( const tinfo ti)

Definition at line 1535 of file termdesc.c.

1535 {
1536 size_t tlen = strlen(ti->termname) + 1;
1537 size_t slen = tlen;
1538 if(ti->termversion){
1539 slen += strlen(ti->termversion) + 1;
1540 }
1541 char* ret = malloc(slen);
1542 if(ret){
1543 memcpy(ret, ti->termname, tlen);
1544 if(ti->termversion){
1545 ret[tlen - 1] = ' ';
1546 strcpy(ret + tlen, ti->termversion);
1547 }
1548 }
1549 return ret;
1550}
const char * termname
Definition termdesc.h:176
Here is the caller graph for this function:

◆ tiocgwinsz()

int tiocgwinsz ( int  fd,
struct winsize *  ws 
)

Definition at line 1576 of file termdesc.c.

1576 {
1577#ifndef __MINGW32__
1578 int i = ioctl(fd, TIOCGWINSZ, ws);
1579 if(i < 0){
1580 logerror("TIOCGWINSZ failed on %d (%s)", fd, strerror(errno));
1581 return -1;
1582 }
1583 if(ws->ws_row <= 0 || ws->ws_col <= 0){
1584 logerror("bogon from TIOCGWINSZ on %d (%d/%d)",
1585 fd, ws->ws_row, ws->ws_col);
1586 return -1;
1587 }
1588#else
1589 (void)fd;
1590 (void)ws;
1591#endif
1592 return 0;
1593}
Here is the caller graph for this function: