2019-06-15 22:22:44 +02:00
|
|
|
#include "osc.h"
|
2019-07-18 19:26:24 +02:00
|
|
|
|
|
|
|
|
#include <string.h>
|
2019-07-05 09:46:48 +02:00
|
|
|
#include <ctype.h>
|
2019-06-15 22:22:44 +02:00
|
|
|
|
|
|
|
|
#define LOG_MODULE "osc"
|
2019-07-03 20:21:03 +02:00
|
|
|
#define LOG_ENABLE_DBG 0
|
2019-06-15 22:22:44 +02:00
|
|
|
#include "log.h"
|
2019-07-05 10:16:56 +02:00
|
|
|
#include "render.h"
|
2019-07-18 19:26:24 +02:00
|
|
|
#include "terminal.h"
|
|
|
|
|
#include "vt.h"
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
osc_query(struct terminal *term, unsigned param)
|
|
|
|
|
{
|
|
|
|
|
switch (param) {
|
|
|
|
|
case 10:
|
|
|
|
|
case 11: {
|
|
|
|
|
char reply[16];
|
|
|
|
|
snprintf(
|
2019-07-18 19:54:30 +02:00
|
|
|
reply, sizeof(reply), "\033]%u;%06x\033\\",
|
2019-07-18 19:26:24 +02:00
|
|
|
param,
|
|
|
|
|
(param == 10 ? term->foreground : term->background) & 0xffffff);
|
|
|
|
|
vt_to_slave(term, reply, strlen(reply));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
LOG_ERR("unimplemented: OSC query: %.*s",
|
|
|
|
|
(int)term->vt.osc.idx, term->vt.osc.data);
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-05 09:46:48 +02:00
|
|
|
|
2019-07-07 16:32:18 +02:00
|
|
|
void
|
2019-06-15 22:22:44 +02:00
|
|
|
osc_dispatch(struct terminal *term)
|
|
|
|
|
{
|
2019-07-18 19:26:24 +02:00
|
|
|
unsigned param = 0;
|
2019-07-05 09:46:48 +02:00
|
|
|
int data_ofs = 0;
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < term->vt.osc.idx; i++) {
|
2019-07-18 19:26:24 +02:00
|
|
|
char c = term->vt.osc.data[i];
|
2019-07-05 09:46:48 +02:00
|
|
|
|
|
|
|
|
if (c == ';') {
|
|
|
|
|
data_ofs = i + 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isdigit(c)) {
|
|
|
|
|
LOG_ERR("OSC: invalid parameter: %.*s",
|
|
|
|
|
(int)term->vt.osc.idx, term->vt.osc.data);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
2019-07-05 09:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-05 19:04:09 +02:00
|
|
|
param *= 10;
|
2019-07-05 09:46:48 +02:00
|
|
|
param += c - '0';
|
|
|
|
|
}
|
|
|
|
|
LOG_DBG("OCS: %.*s (param = %d)",
|
|
|
|
|
(int)term->vt.osc.idx, term->vt.osc.data, param);
|
|
|
|
|
|
|
|
|
|
const char *string = (const char *)&term->vt.osc.data[data_ofs];
|
|
|
|
|
|
2019-07-18 19:26:24 +02:00
|
|
|
if (strlen(string) == 1 && string[0] == '?') {
|
|
|
|
|
osc_query(term, param);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-05 09:46:48 +02:00
|
|
|
switch (param) {
|
2019-07-05 10:16:56 +02:00
|
|
|
case 0: render_set_title(term, string); break; /* icon + title */
|
2019-07-05 09:46:48 +02:00
|
|
|
case 1: break; /* icon */
|
2019-07-05 10:16:56 +02:00
|
|
|
case 2: render_set_title(term, string); break; /* title */
|
2019-07-05 09:46:48 +02:00
|
|
|
|
2019-07-05 19:04:34 +02:00
|
|
|
case 104: /* Reset Color Number 'c' */
|
|
|
|
|
case 105: /* Reset Special Color Number 'c' */
|
2019-07-16 10:20:20 +02:00
|
|
|
case 112: /* Reset text cursor color */
|
2019-07-05 19:04:34 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-05 09:46:48 +02:00
|
|
|
default:
|
|
|
|
|
LOG_ERR("unimplemented: OSC: %.*s",
|
|
|
|
|
(int)term->vt.osc.idx, term->vt.osc.data);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-07-05 09:46:48 +02:00
|
|
|
}
|
2019-06-15 22:22:44 +02:00
|
|
|
}
|
2019-07-19 08:59:35 +02:00
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
osc_ensure_size(struct terminal *term, size_t required_size)
|
|
|
|
|
{
|
|
|
|
|
if (required_size <= term->vt.osc.size)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
size_t new_size = (required_size + 127) / 128 * 128;
|
|
|
|
|
assert(new_size > 0);
|
|
|
|
|
|
|
|
|
|
uint8_t *new_data = realloc(term->vt.osc.data, new_size);
|
|
|
|
|
if (new_data == NULL) {
|
|
|
|
|
LOG_ERRNO("failed to increase size of OSC buffer");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
term->vt.osc.data = new_data;
|
|
|
|
|
term->vt.osc.size = new_size;
|
|
|
|
|
return true;
|
|
|
|
|
}
|