code-golfing: cleanup osc color related code
* adds missing function prototype * move xgetcolor() prototype to win.h (that's where all the other x.c func prototype seems to be declared at) * check for snprintf error/truncation * reduces code duplication for osc 10/11/12 * unify osc_color_response() and osc4_color_response() into a single function the latter two was suggested by Quentin Rameau in his patch review on the hackers list. ref. https://git.suckless.org/st/commit/8629d9a1da72cc18568a8f146307b0e939b77ebf.html
This commit is contained in:
parent
e88f2bf20c
commit
6d5c2b3ddb
115
st.c
115
st.c
|
@ -48,6 +48,8 @@
|
||||||
#endif // UNDERCURL_PATCH
|
#endif // UNDERCURL_PATCH
|
||||||
#define STR_BUF_SIZ ESC_BUF_SIZ
|
#define STR_BUF_SIZ ESC_BUF_SIZ
|
||||||
#define STR_ARG_SIZ ESC_ARG_SIZ
|
#define STR_ARG_SIZ ESC_ARG_SIZ
|
||||||
|
#define STR_TERM_ST "\033\\"
|
||||||
|
#define STR_TERM_BEL "\007"
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define IS_SET(flag) ((term.mode & (flag)) != 0)
|
#define IS_SET(flag) ((term.mode & (flag)) != 0)
|
||||||
|
@ -146,6 +148,7 @@ typedef struct {
|
||||||
size_t len; /* raw string length */
|
size_t len; /* raw string length */
|
||||||
char *args[STR_ARG_SIZ];
|
char *args[STR_ARG_SIZ];
|
||||||
int narg; /* nb of args */
|
int narg; /* nb of args */
|
||||||
|
char *term; /* terminator: ST or BEL */
|
||||||
} STREscape;
|
} STREscape;
|
||||||
|
|
||||||
static void execsh(char *, char **);
|
static void execsh(char *, char **);
|
||||||
|
@ -163,8 +166,7 @@ static void readcolonargs(char **, int, int[][CAR_PER_ARG]);
|
||||||
#endif // UNDERCURL_PATCH
|
#endif // UNDERCURL_PATCH
|
||||||
static void csiparse(void);
|
static void csiparse(void);
|
||||||
static void csireset(void);
|
static void csireset(void);
|
||||||
static void osc4_color_response(int num);
|
static void osc_color_response(int, int, int);
|
||||||
static void osc_color_response(int index, int num);
|
|
||||||
static int eschandle(uchar);
|
static int eschandle(uchar);
|
||||||
static void strdump(void);
|
static void strdump(void);
|
||||||
static void strhandle(void);
|
static void strhandle(void);
|
||||||
|
@ -2363,39 +2365,28 @@ csireset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
osc4_color_response(int num)
|
osc_color_response(int num, int index, int is_osc4)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
unsigned char r, g, b;
|
unsigned char r, g, b;
|
||||||
|
|
||||||
if (xgetcolor(num, &r, &g, &b)) {
|
if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
|
||||||
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
|
fprintf(stderr, "erresc: failed to fetch %s color %d\n",
|
||||||
|
is_osc4 ? "osc4" : "osc",
|
||||||
|
is_osc4 ? num : index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x%s",
|
||||||
num, r, r, g, g, b, b);
|
is_osc4 ? "4;" : "", num, r, r, g, g, b, b, strescseq.term);
|
||||||
|
if (n < 0 || n >= sizeof(buf)) {
|
||||||
|
fprintf(stderr, "error: %s while printing %s response\n",
|
||||||
|
n < 0 ? "snprintf failed" : "truncation occurred",
|
||||||
|
is_osc4 ? "osc4" : "osc");
|
||||||
|
} else {
|
||||||
ttywrite(buf, n, 1);
|
ttywrite(buf, n, 1);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
osc_color_response(int index, int num)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
char buf[32];
|
|
||||||
unsigned char r, g, b;
|
|
||||||
|
|
||||||
if (xgetcolor(index, &r, &g, &b)) {
|
|
||||||
fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
|
|
||||||
num, r, r, g, g, b, b);
|
|
||||||
|
|
||||||
ttywrite(buf, n, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2408,6 +2399,11 @@ strhandle(void)
|
||||||
int i, x, y, x1, y1, x2, y2, numimages;
|
int i, x, y, x1, y1, x2, y2, numimages;
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
Line line;
|
Line line;
|
||||||
|
const struct { int idx; char *str; } osc_table[] = {
|
||||||
|
{ defaultfg, "foreground" },
|
||||||
|
{ defaultbg, "background" },
|
||||||
|
{ defaultcs, "cursor" }
|
||||||
|
};
|
||||||
#if SCROLLBACK_PATCH
|
#if SCROLLBACK_PATCH
|
||||||
int scr = IS_SET(MODE_ALTSCREEN) ? 0 : term.scr;
|
int scr = IS_SET(MODE_ALTSCREEN) ? 0 : term.scr;
|
||||||
#else
|
#else
|
||||||
|
@ -2458,62 +2454,34 @@ strhandle(void)
|
||||||
case 8: /* Clear Hyperlinks */
|
case 8: /* Clear Hyperlinks */
|
||||||
return;
|
return;
|
||||||
case 10:
|
case 10:
|
||||||
if (narg < 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
p = strescseq.args[1];
|
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
|
||||||
osc_color_response(defaultfg, 10);
|
|
||||||
else if (xsetcolorname(defaultfg, p))
|
|
||||||
fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
|
|
||||||
else
|
|
||||||
tfulldirt();
|
|
||||||
return;
|
|
||||||
case 11:
|
case 11:
|
||||||
if (narg < 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
p = strescseq.args[1];
|
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
|
||||||
osc_color_response(defaultbg, 11);
|
|
||||||
else if (xsetcolorname(defaultbg, p))
|
|
||||||
fprintf(stderr, "erresc: invalid background color: %s\n", p);
|
|
||||||
else
|
|
||||||
tfulldirt();
|
|
||||||
return;
|
|
||||||
case 12:
|
case 12:
|
||||||
if (narg < 2)
|
if (narg < 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
p = strescseq.args[1];
|
p = strescseq.args[1];
|
||||||
|
if ((j = par - 10) < 0 || j >= LEN(osc_table))
|
||||||
|
break; /* shouldn't be possible */
|
||||||
|
|
||||||
if (!strcmp(p, "?"))
|
if (!strcmp(p, "?")) {
|
||||||
osc_color_response(defaultcs, 12);
|
osc_color_response(par, osc_table[j].idx, 0);
|
||||||
else if (xsetcolorname(defaultcs, p))
|
} else if (xsetcolorname(osc_table[j].idx, p)) {
|
||||||
fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
|
fprintf(stderr, "erresc: invalid %s color: %s\n",
|
||||||
else
|
osc_table[j].str, p);
|
||||||
|
} else {
|
||||||
tfulldirt();
|
tfulldirt();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 4: /* color set */
|
case 4: /* color set */
|
||||||
if ((par == 4 && narg < 3) || narg < 2)
|
if (narg < 3)
|
||||||
break;
|
break;
|
||||||
p = strescseq.args[((par == 4) ? 2 : 1)];
|
p = strescseq.args[2];
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 104: /* color reset */
|
case 104: /* color reset */
|
||||||
if (par == 10)
|
|
||||||
j = defaultfg;
|
|
||||||
else if (par == 11)
|
|
||||||
j = defaultbg;
|
|
||||||
else if (par == 12)
|
|
||||||
j = defaultcs;
|
|
||||||
else
|
|
||||||
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
|
||||||
|
|
||||||
if (p && !strcmp(p, "?"))
|
if (p && !strcmp(p, "?")) {
|
||||||
osc4_color_response(j);
|
osc_color_response(j, 0, 1);
|
||||||
else if (xsetcolorname(j, p)) {
|
} else if (xsetcolorname(j, p)) {
|
||||||
if (par == 104 && narg <= 1) {
|
if (par == 104 && narg <= 1) {
|
||||||
xloadcols();
|
xloadcols();
|
||||||
return; /* color reset without parameter */
|
return; /* color reset without parameter */
|
||||||
|
@ -2521,8 +2489,10 @@ strhandle(void)
|
||||||
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
|
||||||
j, p ? p : "(null)");
|
j, p ? p : "(null)");
|
||||||
} else {
|
} else {
|
||||||
if (j == defaultbg)
|
/*
|
||||||
xclearwin();
|
* TODO if defaultbg color is changed, borders
|
||||||
|
* are dirty
|
||||||
|
*/
|
||||||
tfulldirt();
|
tfulldirt();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2669,7 +2639,7 @@ strdump(void)
|
||||||
fprintf(stderr, "(%02x)", c);
|
fprintf(stderr, "(%02x)", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "ESC\\\n");
|
fprintf(stderr, (strescseq.term[0] == 0x1b) ? "ESC\\\n" : "BEL\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2861,6 +2831,7 @@ tcontrolcode(uchar ascii)
|
||||||
case '\a': /* BEL */
|
case '\a': /* BEL */
|
||||||
if (term.esc & ESC_STR_END) {
|
if (term.esc & ESC_STR_END) {
|
||||||
/* backwards compatibility to xterm */
|
/* backwards compatibility to xterm */
|
||||||
|
strescseq.term = STR_TERM_BEL;
|
||||||
strhandle();
|
strhandle();
|
||||||
} else {
|
} else {
|
||||||
xbell();
|
xbell();
|
||||||
|
@ -3074,8 +3045,10 @@ eschandle(uchar ascii)
|
||||||
tcursor(CURSOR_LOAD);
|
tcursor(CURSOR_LOAD);
|
||||||
break;
|
break;
|
||||||
case '\\': /* ST -- String Terminator */
|
case '\\': /* ST -- String Terminator */
|
||||||
if (term.esc & ESC_STR_END)
|
if (term.esc & ESC_STR_END) {
|
||||||
|
strescseq.term = STR_TERM_ST;
|
||||||
strhandle();
|
strhandle();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
|
fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
|
||||||
|
|
Loading…
Reference in New Issue