I am trying to retrieve the background, foreground / cursor color through
the appropriate xterm escape OSC 10/11/12.
This will allow me to create terminal mode graphics in R with the current
terminal theme. (Black is the default plotting color and you can't see it
on a dark terminal, and it's better to just read out the foreground than to
guess based on the background.)
This works in a normal bash terminal with black bg, white fg, and green
cursor :
~$read -rs -d \\ -p $'\e]10;?\e\\' b ; echo "$b" | xxd
00000000: 1b5d 3130 3b72 6762 3a62 3262 322f 6232 .]10;rgb:b2b2/b2
00000010: 6232 2f62 3262 321b 0a b2/b2b2..
~$read -rs -d \\ -p $'\e]11;?\e\\' b ; echo "$b" | xxd
00000000: 1b5d 3131 3b72 6762 3a30 3030 302f 3030 .]11;rgb:0000/00
00000010: 3030 2f30 3030 301b 0a 00/0000..
~$read -rs -d \\ -p $'\e]12;?\e\\' b ; echo "$b" | xxd
00000000: 1b5d 3132 3b72 6762 3a35 3235 322f 6164 .]12;rgb:5252/ad
00000010: 6164 2f37 3037 301b 0a ad/7070..
However, within screen, 11 (background) works but 10/12 do not.
I've attached a patch that adds them to ansi.c. Both getting and setting
appear to work.
Best,
Neal
diff --git a/src/ansi.c b/src/ansi.c
index 9ee4ffa..18085cd 100644
--- a/src/ansi.c
+++ b/src/ansi.c
@@ -1263,11 +1263,31 @@ static int StringEnd(Window *win)
}
break;
}
- if (typ == 0 || typ == 1 || typ == 2 || typ == 11 || typ == 20 || typ == 39 || typ == 49) {
+ if (typ == 0 || typ == 1 || typ == 2 || typ == 10 || typ == 11 || typ == 12 || typ == 20 || typ == 39 || typ == 49) {
int typ2;
- typ2 = typ / 10;
+ // typ2 is the position of code in osc parallel arrays w_xtermosc and and d_xtermosc
+ switch(typ) {
+ case 0:
+ case 1:
+ case 2:
+ typ2 = 0; break;
+ case 10:
+ typ2 = 1; break;
+ case 11:
+ typ2 = 2; break;
+ case 12:
+ typ2 = 3; break;
+ case 20:
+ typ2 = 4; break;
+ case 39:
+ typ2 = 5; break;
+ case 49:
+ typ2 = 6; break;
+ }
+
+
if (strcmp(win->w_xtermosc[typ2], p)) {
- if (typ != 11 || strcmp("?", p)) {
+ if ((typ != 10 && typ != 11 && typ != 12) || strcmp("?", p)) {
strncpy(win->w_xtermosc[typ2], p, ARRAY_SIZE(win->w_xtermosc[typ2]) - 1);
win->w_xtermosc[typ2][ARRAY_SIZE(win->w_xtermosc[typ2]) - 1] = 0;
}
@@ -1279,7 +1299,7 @@ static int StringEnd(Window *win)
SetXtermOSC(typ2, p, t);
if ((typ2 == 3 || typ2 == 4) && D_xtermosc[typ2])
Redisplay(0);
- if (typ == 11 && !strcmp("?", p))
+ if ((typ == 10 || typ == 11 || typ == 12) && !strcmp("?", p))
break;
}
}
@@ -1729,7 +1749,7 @@ static void SelectRendition(Window *win)
}
continue;
}
- /* truecolor (24bit) colour space; example escape \e[48;5;12;13;14m
+ /* truecolor (24bit) colour space; example escape \e[48;5;12;13;14m
* where 12;13;14 are rgb values */
if ((j == 38 || j == 48) && i + 4 < win->w_NumArgs && win->w_args[i + 1] == 2) {
uint8_t r, g, b;
@@ -1773,9 +1793,9 @@ static void SelectRendition(Window *win)
else
attr |= j;
} while (++i < win->w_NumArgs);
-
+
win->w_rend.attr = attr;
-
+
win->w_rend.colorbg = colorbg;
win->w_rend.colorfg = colorfg;
LSetRendition(&win->w_layer, &win->w_rend);
diff --git a/src/display.c b/src/display.c
index 0ec6c33..6fab30c 100644
--- a/src/display.c
+++ b/src/display.c
@@ -1273,7 +1273,7 @@ int color256to88(int color)
/*
* SetColor - Sets foreground and background color
* 0x00000000 <- default color ("transparent")
- * one note here that "null" variable is pointer to array of 0 and that's one of reasons to use it this way
+ * one note here that "null" variable is pointer to array of 0 and that's one of reasons to use it this way
* 0x0100000x <- 16 base color
* 0x020000xx <- 256 color
* 0x04xxxxxx <- truecolor
@@ -1339,7 +1339,7 @@ void SetColor(uint32_t foreground, uint32_t background)
//AddCStr2(D_CAF, f); //FIXME
tputs(tparm("\033[38;5;%dm", f), 1, DoAddChar);
}
-
+
}
if (f != of && (f & 0x04000000) && hastruecolor) {
uint8_t _r, _g, _b;
@@ -2142,7 +2142,9 @@ void SetXtermOSC(int i, char *s, char *t)
{
static char *oscs[][2] = {
{WT_FLAG ";", "screen"}, /* set window title */
+ {"10;", ""}, /* foreground RGB */
{"11;", ""}, /* background RGB */
+ {"12;", ""}, /* cursor RGB */
{"20;", ""}, /* background */
{"39;", "black"}, /* default foreground (black?) */
{"49;", "white"} /* default background (white?) */
@@ -2167,7 +2169,7 @@ void SetXtermOSC(int i, char *s, char *t)
void ClearAllXtermOSC(void)
{
- for (int i = 4; i >= 0; i--)
+ for (int i = 6; i >= 0; i--)
SetXtermOSC(i, NULL, "\a");
if (D_xtermosc[0])
AddStr("\033[23;" WT_FLAG "t"); /* unstack titles (xterm patch #251) */
diff --git a/src/display.h b/src/display.h
index 531b9c8..5197a69 100644
--- a/src/display.h
+++ b/src/display.h
@@ -124,7 +124,7 @@ struct Display {
does not */
int d_bracketed; /* bracketed paste mode */
int d_cursorstyle; /* cursor style */
- int d_xtermosc[5]; /* osc used */
+ int d_xtermosc[7]; /* osc used */
struct mchar d_lpchar; /* missing char */
struct timeval d_status_time; /* time of status display */
DisplayStatus d_status; /* is status displayed? */
@@ -134,8 +134,8 @@ struct Display {
int d_status_buflen; /* last message buffer len */
int d_status_lastx; /* position of the cursor */
int d_status_lasty; /* before status was displayed */
- int d_status_obuflen; /* saved obuflen */
- int d_status_obuffree; /* saved obuffree */
+ int d_status_obuflen; /* saved obuflen */
+ int d_status_obuffree; /* saved obuffree */
int d_status_obufpos; /* end of status position in obuf */
Event d_statusev; /* timeout event */
Event d_hstatusev; /* hstatus changed event */
diff --git a/src/window.h b/src/window.h
index bc08c6c..0b7c27b 100644
--- a/src/window.h
+++ b/src/window.h
@@ -222,7 +222,7 @@ struct Window {
int w_silencewait; /* wait for silencewait secs */
int w_silence; /* silence status (Lloyd Zusman) */
char w_norefresh; /* dont redisplay when switching to that win */
- char w_xtermosc[5][2560]; /* special xterm/rxvt escapes */
+ char w_xtermosc[7][2560]; /* special xterm/rxvt escapes */
int w_mouse; /* mouse mode 0,9,1000 */
int w_extmouse; /* extended mouse mode 0,1006 */
bool w_bracketed; /* bracketed paste mode */