2019-06-15 22:22:44 +02:00
|
|
|
#include "csi.h"
|
|
|
|
|
|
2019-06-17 18:57:12 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
2019-06-18 21:55:39 +02:00
|
|
|
#if defined(_DEBUG)
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
#define LOG_MODULE "csi"
|
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-06-17 19:33:10 +02:00
|
|
|
#include "grid.h"
|
2019-07-10 16:04:16 +02:00
|
|
|
#include "vt.h"
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-22 21:31:28 +02:00
|
|
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
|
|
|
|
|
2019-07-08 15:56:15 +02:00
|
|
|
static const struct rgb colors_regular[] = {
|
|
|
|
|
{0.000000, 0.000000, 0.000000}, /* 0x000000 */
|
|
|
|
|
{0.800000, 0.576471, 0.576471}, /* 0xcc9393 */
|
|
|
|
|
{0.498039, 0.623529, 0.498039}, /* 0x7f9f7f */
|
|
|
|
|
{0.815686, 0.749020, 0.560784}, /* 0xd0bf8f */
|
|
|
|
|
{0.423529, 0.627451, 0.639216}, /* 0x6ca0a3 */
|
|
|
|
|
{0.862745, 0.549020, 0.764706}, /* 0xdc8cc3 */
|
|
|
|
|
{0.576471, 0.878431, 0.890196}, /* 0x93e0e3 */
|
|
|
|
|
{0.862745, 0.862745, 0.800000}, /* 0xdcdccc */
|
2019-06-23 15:00:27 +02:00
|
|
|
};
|
|
|
|
|
|
2019-07-08 15:56:15 +02:00
|
|
|
static const struct rgb colors_bright[] = {
|
|
|
|
|
{0.000000, 0.000000, 0.000000}, /* 0x000000 */
|
|
|
|
|
{0.862745, 0.639216, 0.639216}, /* 0xdca3a3 */
|
|
|
|
|
{0.749020, 0.921569, 0.749020}, /* 0xbfebbf */
|
|
|
|
|
{0.941176, 0.874510, 0.686275}, /* 0xf0dfaf */
|
|
|
|
|
{0.549020, 0.815686, 0.827451}, /* 0x8cd0d3 */
|
|
|
|
|
{0.862745, 0.549020, 0.764706}, /* 0xdc8cc3 */
|
|
|
|
|
{0.576471, 0.878431, 0.890196}, /* 0x93e0e3 */
|
|
|
|
|
{1.000000, 1.000000, 1.000000}, /* 0xffffff */
|
2019-06-23 15:00:27 +02:00
|
|
|
};
|
|
|
|
|
|
2019-07-08 15:56:15 +02:00
|
|
|
static struct rgb colors256[256];
|
2019-06-23 15:00:27 +02:00
|
|
|
|
|
|
|
|
static void __attribute__((constructor))
|
|
|
|
|
initialize_colors256(void)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < 8; i++)
|
|
|
|
|
colors256[i] = colors_regular[i];
|
|
|
|
|
for (size_t i = 0; i < 8; i++)
|
|
|
|
|
colors256[8 + i] = colors_bright[i];
|
|
|
|
|
|
|
|
|
|
for (size_t r = 0; r < 6; r++) {
|
|
|
|
|
for (size_t g = 0; g < 6; g++) {
|
|
|
|
|
for (size_t b = 0; b < 6; b++) {
|
2019-07-08 15:56:15 +02:00
|
|
|
colors256[16 + r * 6 * 6 + g * 6 + b] = (struct rgb) {
|
2019-06-26 20:33:32 +02:00
|
|
|
r * 51 / 255.0,
|
|
|
|
|
g * 51 / 255.0,
|
|
|
|
|
b * 51 / 255.0,
|
|
|
|
|
};
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-26 20:33:32 +02:00
|
|
|
for (size_t i = 0; i < 24; i++){
|
2019-07-08 15:56:15 +02:00
|
|
|
colors256[232 + i] = (struct rgb) {
|
2019-06-26 20:33:32 +02:00
|
|
|
i * 11 / 255.0,
|
|
|
|
|
i * 11 / 255.0,
|
|
|
|
|
i * 11 / 255.0,
|
|
|
|
|
};
|
|
|
|
|
}
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-22 21:38:47 +02:00
|
|
|
static void
|
|
|
|
|
sgr_reset(struct terminal *term)
|
|
|
|
|
{
|
2019-06-26 19:44:31 +02:00
|
|
|
memset(&term->vt.attrs, 0, sizeof(term->vt.attrs));
|
2019-06-22 21:38:47 +02:00
|
|
|
term->vt.dim = false;
|
2019-06-29 21:09:58 +02:00
|
|
|
term->vt.attrs.foreground = term->foreground;
|
|
|
|
|
term->vt.attrs.background = term->background;
|
2019-06-22 21:38:47 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-07 16:32:18 +02:00
|
|
|
static void
|
2019-06-15 22:22:44 +02:00
|
|
|
csi_sgr(struct terminal *term)
|
|
|
|
|
{
|
2019-06-22 21:38:47 +02:00
|
|
|
if (term->vt.params.idx == 0) {
|
|
|
|
|
sgr_reset(term);
|
2019-07-07 16:32:18 +02:00
|
|
|
return;
|
2019-06-22 21:38:47 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++) {
|
2019-06-23 15:00:27 +02:00
|
|
|
const int param = term->vt.params.v[i].value;
|
|
|
|
|
|
|
|
|
|
switch (param) {
|
2019-06-15 22:22:44 +02:00
|
|
|
case 0:
|
2019-06-22 21:38:47 +02:00
|
|
|
sgr_reset(term);
|
2019-06-15 22:22:44 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-16 16:44:42 +02:00
|
|
|
case 1: term->vt.attrs.bold = true; break;
|
2019-06-15 22:22:44 +02:00
|
|
|
case 2: term->vt.dim = true; break;
|
2019-06-16 16:44:42 +02:00
|
|
|
case 3: term->vt.attrs.italic = true; break;
|
|
|
|
|
case 4: term->vt.attrs.underline = true; break;
|
|
|
|
|
case 5: term->vt.attrs.blink = true; break;
|
|
|
|
|
case 6: term->vt.attrs.blink = true; break;
|
|
|
|
|
case 7: term->vt.attrs.reverse = true; break;
|
|
|
|
|
case 8: term->vt.attrs.conceal = true; break;
|
|
|
|
|
case 9: term->vt.attrs.strikethrough = true; break;
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-16 16:44:42 +02:00
|
|
|
case 22: term->vt.attrs.bold = term->vt.dim = false; break;
|
|
|
|
|
case 23: term->vt.attrs.italic = false; break;
|
|
|
|
|
case 24: term->vt.attrs.underline = false; break;
|
|
|
|
|
case 25: term->vt.attrs.blink = false; break;
|
|
|
|
|
case 27: term->vt.attrs.reverse = false; break;
|
|
|
|
|
case 28: term->vt.attrs.conceal = false; break;
|
|
|
|
|
case 29: term->vt.attrs.strikethrough = false; break;
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-19 11:12:45 +02:00
|
|
|
/* Regular foreground colors */
|
2019-06-23 15:00:27 +02:00
|
|
|
case 30:
|
|
|
|
|
case 31:
|
|
|
|
|
case 32:
|
|
|
|
|
case 33:
|
|
|
|
|
case 34:
|
|
|
|
|
case 35:
|
|
|
|
|
case 36:
|
|
|
|
|
case 37:
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_foreground = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
term->vt.attrs.foreground = colors_regular[param - 30];
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 38: {
|
2019-07-04 09:57:02 +02:00
|
|
|
if (term->vt.params.idx - i - 1 >= 2 &&
|
2019-06-23 15:00:27 +02:00
|
|
|
term->vt.params.v[i + 1].value == 5)
|
|
|
|
|
{
|
|
|
|
|
size_t idx = term->vt.params.v[i + 2].value;
|
|
|
|
|
term->vt.attrs.foreground = colors256[idx];
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_foreground = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
i += 2;
|
2019-07-04 09:57:02 +02:00
|
|
|
} else if (term->vt.params.idx - i - 1 >= 4 &&
|
2019-06-23 15:00:27 +02:00
|
|
|
term->vt.params.v[i + 1].value == 2)
|
|
|
|
|
{
|
2019-06-26 20:33:32 +02:00
|
|
|
uint8_t r = term->vt.params.v[i + 2].value;
|
|
|
|
|
uint8_t g = term->vt.params.v[i + 3].value;
|
|
|
|
|
uint8_t b = term->vt.params.v[i + 4].value;
|
2019-07-08 15:56:15 +02:00
|
|
|
term->vt.attrs.foreground = (struct rgb) {
|
2019-06-26 20:33:32 +02:00
|
|
|
r / 255.0,
|
|
|
|
|
g / 255.0,
|
|
|
|
|
b / 255.0,
|
|
|
|
|
};
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_foreground = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
i += 4;
|
|
|
|
|
} else {
|
|
|
|
|
LOG_ERR("invalid CSI SGR sequence");
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-06-26 19:44:31 +02:00
|
|
|
case 39:
|
2019-06-29 21:09:58 +02:00
|
|
|
term->vt.attrs.foreground = term->foreground;
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_foreground = false;
|
|
|
|
|
break;
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-19 11:12:45 +02:00
|
|
|
/* Regular background colors */
|
2019-06-23 15:00:27 +02:00
|
|
|
case 40:
|
|
|
|
|
case 41:
|
|
|
|
|
case 42:
|
|
|
|
|
case 43:
|
|
|
|
|
case 44:
|
|
|
|
|
case 45:
|
|
|
|
|
case 46:
|
|
|
|
|
case 47:
|
|
|
|
|
term->vt.attrs.background = colors_regular[param - 40];
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_background = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 48: {
|
2019-07-04 09:57:02 +02:00
|
|
|
if (term->vt.params.idx - i - 1 >= 2 &&
|
2019-06-23 15:00:27 +02:00
|
|
|
term->vt.params.v[i + 1].value == 5)
|
|
|
|
|
{
|
|
|
|
|
size_t idx = term->vt.params.v[i + 2].value;
|
|
|
|
|
term->vt.attrs.background = colors256[idx];
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_background = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
i += 2;
|
2019-07-04 09:57:02 +02:00
|
|
|
} else if (term->vt.params.idx - i - 1 >= 4 &&
|
2019-06-23 15:00:27 +02:00
|
|
|
term->vt.params.v[i + 1].value == 2)
|
|
|
|
|
{
|
2019-06-26 20:33:32 +02:00
|
|
|
uint8_t r = term->vt.params.v[i + 2].value;
|
|
|
|
|
uint8_t g = term->vt.params.v[i + 3].value;
|
|
|
|
|
uint8_t b = term->vt.params.v[i + 4].value;
|
2019-07-08 15:56:15 +02:00
|
|
|
term->vt.attrs.background = (struct rgb) {
|
2019-06-26 20:33:32 +02:00
|
|
|
r / 255.0,
|
|
|
|
|
g / 255.0,
|
|
|
|
|
b / 255.0,
|
|
|
|
|
};
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_background = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
i += 4;
|
|
|
|
|
} else {
|
|
|
|
|
LOG_ERR("invalid CSI SGR sequence");
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-06-26 19:44:31 +02:00
|
|
|
case 49:
|
2019-06-29 21:09:58 +02:00
|
|
|
term->vt.attrs.background = term->background;
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_background = false;
|
|
|
|
|
break;
|
2019-06-15 22:22:44 +02:00
|
|
|
|
2019-06-19 11:12:45 +02:00
|
|
|
/* Bright foreground colors */
|
2019-06-23 15:00:27 +02:00
|
|
|
case 90:
|
|
|
|
|
case 91:
|
|
|
|
|
case 92:
|
|
|
|
|
case 93:
|
|
|
|
|
case 94:
|
|
|
|
|
case 95:
|
|
|
|
|
case 96:
|
|
|
|
|
case 97:
|
|
|
|
|
term->vt.attrs.foreground = colors_bright[param - 90];
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_foreground = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
break;
|
2019-06-19 11:12:45 +02:00
|
|
|
|
|
|
|
|
/* Regular background colors */
|
2019-06-23 15:00:27 +02:00
|
|
|
case 100:
|
|
|
|
|
case 101:
|
|
|
|
|
case 102:
|
|
|
|
|
case 103:
|
|
|
|
|
case 104:
|
|
|
|
|
case 105:
|
|
|
|
|
case 106:
|
|
|
|
|
case 107:
|
|
|
|
|
term->vt.attrs.background = colors_bright[param - 100];
|
2019-06-26 19:44:31 +02:00
|
|
|
term->vt.attrs.have_background = true;
|
2019-06-23 15:00:27 +02:00
|
|
|
break;
|
2019-06-19 11:12:45 +02:00
|
|
|
|
2019-06-15 22:22:44 +02:00
|
|
|
default:
|
|
|
|
|
LOG_ERR("unimplemented: CSI: SGR: %u", term->vt.params.v[i].value);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-15 22:22:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-04 19:35:01 +02:00
|
|
|
static const char *
|
|
|
|
|
csi_as_string(struct terminal *term, uint8_t final)
|
2019-06-15 22:22:44 +02:00
|
|
|
{
|
2019-07-04 19:35:01 +02:00
|
|
|
static char msg[1024];
|
|
|
|
|
int c = snprintf(msg, sizeof(msg), "CSI: ");
|
2019-06-18 21:55:39 +02:00
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
if (term->vt.private != 0)
|
|
|
|
|
c += snprintf(&msg[c], sizeof(msg) - c, "%c", term->vt.private);
|
2019-06-23 13:36:13 +02:00
|
|
|
|
2019-06-18 21:55:39 +02:00
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++){
|
2019-07-04 19:35:01 +02:00
|
|
|
c += snprintf(&msg[c], sizeof(msg) - c, "%d",
|
2019-06-18 21:55:39 +02:00
|
|
|
term->vt.params.v[i].value);
|
|
|
|
|
|
|
|
|
|
for (size_t j = 0; i < term->vt.params.v[i].sub.idx; j++) {
|
2019-07-04 19:35:01 +02:00
|
|
|
c += snprintf(&msg[c], sizeof(msg) - c, ":%d",
|
2019-06-18 21:55:39 +02:00
|
|
|
term->vt.params.v[i].sub.value[j]);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-04 19:35:01 +02:00
|
|
|
c += snprintf(&msg[c], sizeof(msg) - c, "%s",
|
2019-06-18 21:55:39 +02:00
|
|
|
i == term->vt.params.idx - 1 ? "" : ";");
|
2019-06-15 22:22:44 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-05 09:46:48 +02:00
|
|
|
c += snprintf(&msg[c], sizeof(msg) - c, "%c (%zu parameters)",
|
2019-06-18 21:55:39 +02:00
|
|
|
final, term->vt.params.idx);
|
2019-07-04 19:35:01 +02:00
|
|
|
return msg;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 16:32:18 +02:00
|
|
|
void
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_dispatch(struct terminal *term, uint8_t final)
|
|
|
|
|
{
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_DBG("%s", csi_as_string(term, final));
|
2019-06-18 21:55:39 +02:00
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
switch (term->vt.private) {
|
|
|
|
|
case 0: {
|
2019-06-17 18:57:12 +02:00
|
|
|
switch (final) {
|
|
|
|
|
case 'c':
|
2019-07-07 16:32:18 +02:00
|
|
|
write(term->ptmx, "\033[?6c", 5);
|
|
|
|
|
break;
|
2019-06-17 18:57:12 +02:00
|
|
|
|
2019-06-24 19:59:54 +02:00
|
|
|
case 'd': {
|
2019-06-24 20:05:24 +02:00
|
|
|
/* VPA - vertical line position absolute */
|
2019-07-10 16:04:16 +02:00
|
|
|
int row = min(vt_param_get(term, 0, 1), term->rows);
|
2019-06-29 21:15:32 +02:00
|
|
|
term_cursor_to(term, row - 1, term->cursor.col);
|
2019-06-24 19:59:54 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 18:57:12 +02:00
|
|
|
case 'm':
|
2019-07-07 16:32:18 +02:00
|
|
|
csi_sgr(term);
|
|
|
|
|
break;
|
2019-06-17 18:57:12 +02:00
|
|
|
|
2019-06-24 20:17:02 +02:00
|
|
|
case 'A':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_cursor_up(term, vt_param_get(term, 0, 1));
|
2019-06-22 21:31:28 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:05:31 +02:00
|
|
|
case 'e':
|
2019-06-24 20:17:02 +02:00
|
|
|
case 'B':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_cursor_down(term, vt_param_get(term, 0, 1));
|
2019-06-22 21:31:28 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:17:02 +02:00
|
|
|
case 'C':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_cursor_right(term, vt_param_get(term, 0, 1));
|
2019-06-22 21:31:28 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:17:02 +02:00
|
|
|
case 'D':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_cursor_left(term, vt_param_get(term, 0, 1));
|
2019-06-22 21:31:28 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:08:44 +02:00
|
|
|
case 'G': {
|
|
|
|
|
/* Cursor horizontal absolute */
|
2019-07-10 16:04:16 +02:00
|
|
|
int col = min(vt_param_get(term, 0, 1), term->cols);
|
2019-07-03 22:21:44 +02:00
|
|
|
term_cursor_to(term, term->cursor.row, col - 1);
|
2019-06-24 20:08:44 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-23 14:11:35 +02:00
|
|
|
case 'H': {
|
|
|
|
|
/* Move cursor */
|
2019-07-10 16:04:16 +02:00
|
|
|
int row = min(vt_param_get(term, 0, 1), term->rows);
|
|
|
|
|
int col = min(vt_param_get(term, 1, 1), term->cols);
|
2019-06-29 21:03:28 +02:00
|
|
|
term_cursor_to(term, row - 1, col - 1);
|
2019-06-23 14:11:35 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 18:57:12 +02:00
|
|
|
case 'J': {
|
2019-06-19 10:04:47 +02:00
|
|
|
/* Erase screen */
|
|
|
|
|
|
2019-07-10 16:04:16 +02:00
|
|
|
int param = vt_param_get(term, 0, 0);
|
2019-06-19 10:04:47 +02:00
|
|
|
switch (param) {
|
|
|
|
|
case 0:
|
|
|
|
|
/* From cursor to end of screen */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&term->cursor,
|
|
|
|
|
&(struct coord){term->cols - 1, term->rows - 1});
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
/* From start of screen to cursor */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(term, &(struct coord){0, 0}, &term->cursor);
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
/* Erase entire screen */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&(struct coord){0, 0},
|
|
|
|
|
&(struct coord){term->cols - 1, term->rows - 1});
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("%s: invalid argument: %d",
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_as_string(term, final), param);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-19 10:04:47 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2019-06-17 18:57:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'K': {
|
2019-06-19 10:04:47 +02:00
|
|
|
/* Erase line */
|
|
|
|
|
|
2019-07-10 16:04:16 +02:00
|
|
|
int param = vt_param_get(term, 0, 0);
|
2019-06-19 10:04:47 +02:00
|
|
|
switch (param) {
|
|
|
|
|
case 0:
|
|
|
|
|
/* From cursor to end of line */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&term->cursor,
|
|
|
|
|
&(struct coord){term->cols - 1, term->cursor.row});
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
/* From start of line to cursor */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term, &(struct coord){0, term->cursor.row}, &term->cursor);
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
/* Entire line */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&(struct coord){0, term->cursor.row},
|
|
|
|
|
&(struct coord){term->cols - 1, term->cursor.row});
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("%s: invalid argument: %d",
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_as_string(term, final), param);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-19 10:04:47 +02:00
|
|
|
}
|
2019-06-17 18:57:12 +02:00
|
|
|
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-23 21:12:32 +02:00
|
|
|
case 'L': {
|
2019-06-29 21:15:32 +02:00
|
|
|
if (term->cursor.row < term->scroll_region.start ||
|
|
|
|
|
term->cursor.row >= term->scroll_region.end)
|
2019-06-23 21:12:32 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
int count = min(
|
2019-07-10 16:04:16 +02:00
|
|
|
vt_param_get(term, 0, 1),
|
2019-06-29 21:15:32 +02:00
|
|
|
term->scroll_region.end - term->cursor.row);
|
2019-06-23 21:12:32 +02:00
|
|
|
|
2019-06-29 21:03:28 +02:00
|
|
|
term_scroll_reverse_partial(
|
|
|
|
|
term,
|
2019-06-25 20:11:08 +02:00
|
|
|
(struct scroll_region){
|
2019-06-29 21:15:32 +02:00
|
|
|
.start = term->cursor.row,
|
2019-06-29 21:08:08 +02:00
|
|
|
.end = term->scroll_region.end},
|
2019-06-23 21:12:32 +02:00
|
|
|
count);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'M': {
|
2019-06-29 21:15:32 +02:00
|
|
|
if (term->cursor.row < term->scroll_region.start ||
|
|
|
|
|
term->cursor.row >= term->scroll_region.end)
|
2019-06-23 21:12:32 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
int count = min(
|
2019-07-10 16:04:16 +02:00
|
|
|
vt_param_get(term, 0, 1),
|
2019-06-29 21:15:32 +02:00
|
|
|
term->scroll_region.end - term->cursor.row);
|
2019-06-23 21:12:32 +02:00
|
|
|
|
2019-06-29 21:03:28 +02:00
|
|
|
term_scroll_partial(
|
|
|
|
|
term,
|
2019-06-25 20:11:08 +02:00
|
|
|
(struct scroll_region){
|
2019-06-29 21:15:32 +02:00
|
|
|
.start = term->cursor.row,
|
2019-06-29 21:08:08 +02:00
|
|
|
.end = term->scroll_region.end},
|
2019-06-23 21:12:32 +02:00
|
|
|
count);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-22 21:31:28 +02:00
|
|
|
case 'P': {
|
|
|
|
|
/* DCH: Delete character */
|
2019-06-19 10:04:47 +02:00
|
|
|
|
2019-07-02 22:19:43 +02:00
|
|
|
/* Number of characters to delete */
|
|
|
|
|
int count = min(
|
2019-07-10 16:04:16 +02:00
|
|
|
vt_param_get(term, 0, 1), term->cols - term->cursor.col);
|
2019-06-17 18:57:12 +02:00
|
|
|
|
2019-07-02 22:19:43 +02:00
|
|
|
/* Number of characters left after deletion (on current line) */
|
|
|
|
|
int remaining = term->cols - (term->cursor.col + count);
|
2019-06-22 21:31:28 +02:00
|
|
|
|
2019-07-02 22:19:43 +02:00
|
|
|
/* 'Delete' characters by moving the remaining ones */
|
2019-07-08 13:57:31 +02:00
|
|
|
memmove(&term->grid->cur_row->cells[term->cursor.col],
|
|
|
|
|
&term->grid->cur_row->cells[term->cursor.col + count],
|
|
|
|
|
remaining * sizeof(term->grid->cur_row->cells[0]));
|
|
|
|
|
#if 0
|
2019-06-29 21:15:32 +02:00
|
|
|
term_damage_update(term, term->cursor.linear, remaining);
|
2019-07-08 13:57:31 +02:00
|
|
|
#else
|
|
|
|
|
term->grid->cur_row->dirty = true;
|
|
|
|
|
#endif
|
2019-07-02 22:19:43 +02:00
|
|
|
|
|
|
|
|
/* Erase the remainder of the line */
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&(struct coord){term->cursor.col + remaining, term->cursor.row},
|
|
|
|
|
&(struct coord){term->cols - 1, term->cursor.row});
|
|
|
|
|
#if 0
|
2019-07-02 22:19:43 +02:00
|
|
|
term_erase(
|
|
|
|
|
term, term->cursor.linear + remaining,
|
|
|
|
|
term->cursor.linear + remaining + count);
|
2019-07-08 13:57:31 +02:00
|
|
|
#endif
|
2019-06-19 10:04:47 +02:00
|
|
|
break;
|
2019-07-03 14:47:01 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-04 19:39:23 +02:00
|
|
|
case 'S':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_scroll(term, vt_param_get(term, 0, 1));
|
2019-07-04 19:39:23 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'T':
|
2019-07-10 16:04:16 +02:00
|
|
|
term_scroll_reverse(term, vt_param_get(term, 0, 1));
|
2019-07-04 19:39:23 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-03 15:58:49 +02:00
|
|
|
case 'X': {
|
|
|
|
|
/* Erase chars */
|
|
|
|
|
int count = min(
|
2019-07-10 16:04:16 +02:00
|
|
|
vt_param_get(term, 0, 1), term->cols - term->cursor.col);
|
2019-07-03 15:58:49 +02:00
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
term_erase(
|
|
|
|
|
term,
|
|
|
|
|
&term->cursor,
|
|
|
|
|
&(struct coord){term->cursor.col + count, term->cursor.row});
|
|
|
|
|
|
|
|
|
|
#if 0
|
2019-07-03 15:58:49 +02:00
|
|
|
memset(&term->grid->cur_line[term->cursor.col],
|
|
|
|
|
0, count * sizeof(term->grid->cur_line[0]));
|
|
|
|
|
term_damage_erase(term, term->cursor.linear, count);
|
2019-07-08 13:57:31 +02:00
|
|
|
#endif
|
2019-07-03 15:58:49 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-03 21:16:41 +02:00
|
|
|
case 'h':
|
|
|
|
|
/* smir - insert mode enable */
|
2019-07-03 14:47:01 +02:00
|
|
|
assert(false && "untested");
|
2019-07-03 21:16:41 +02:00
|
|
|
term->insert_mode = true;
|
|
|
|
|
break;
|
2019-07-03 14:47:01 +02:00
|
|
|
|
2019-07-03 21:16:41 +02:00
|
|
|
case 'l':
|
|
|
|
|
/* rmir - insert mode disable */
|
|
|
|
|
term->insert_mode = false;
|
2019-07-03 14:47:01 +02:00
|
|
|
break;
|
2019-06-17 18:57:12 +02:00
|
|
|
|
2019-06-23 18:02:49 +02:00
|
|
|
case 'r': {
|
2019-07-10 16:04:16 +02:00
|
|
|
int start = vt_param_get(term, 0, 1);
|
|
|
|
|
int end = min(vt_param_get(term, 1, term->rows), term->rows);
|
2019-06-23 21:12:32 +02:00
|
|
|
|
2019-06-23 18:02:49 +02:00
|
|
|
/* 1-based */
|
2019-06-29 21:08:08 +02:00
|
|
|
term->scroll_region.start = start - 1;
|
|
|
|
|
term->scroll_region.end = end;
|
2019-06-23 21:12:32 +02:00
|
|
|
|
2019-07-03 15:59:28 +02:00
|
|
|
term_cursor_to(term, start - 1, 0);
|
2019-07-01 19:13:45 +02:00
|
|
|
|
2019-07-03 14:24:46 +02:00
|
|
|
LOG_DBG("scroll region: %d-%d",
|
|
|
|
|
term->scroll_region.start,
|
|
|
|
|
term->scroll_region.end);
|
2019-06-23 18:02:49 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-22 22:25:50 +02:00
|
|
|
case 't':
|
|
|
|
|
/*
|
|
|
|
|
* TODO: xterm's terminfo specifies *both* \e[?1049h *and*
|
|
|
|
|
* \e[22;0;0t in smcup, but only one is necessary. We
|
|
|
|
|
* should provide our own terminfo with *only* \e[?1049h
|
|
|
|
|
* (and \e[?1049l for rmcup)
|
|
|
|
|
*/
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_WARN("ignoring %s", csi_as_string(term, final));
|
2019-06-22 22:25:50 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-23 18:17:36 +02:00
|
|
|
case 'n': {
|
|
|
|
|
if (term->vt.params.idx > 0) {
|
2019-07-10 16:04:16 +02:00
|
|
|
int param = vt_param_get(term, 0, 0);
|
2019-06-23 18:17:36 +02:00
|
|
|
switch (param) {
|
|
|
|
|
case 6: {
|
|
|
|
|
/* u7 - cursor position query */
|
|
|
|
|
/* TODO: we use 0-based position, while the xterm
|
|
|
|
|
* terminfo says the receiver of the reply should
|
2019-06-24 19:03:19 +02:00
|
|
|
* decrement, hence we must add 1 */
|
2019-06-23 18:17:36 +02:00
|
|
|
char reply[64];
|
|
|
|
|
snprintf(reply, sizeof(reply), "\x1b[%d;%dR",
|
2019-06-29 21:15:32 +02:00
|
|
|
term->cursor.row + 1,
|
|
|
|
|
term->cursor.col + 1);
|
2019-06-23 18:17:36 +02:00
|
|
|
write(term->ptmx, reply, strlen(reply));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("unimplemented: %s, parameter = %d",
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_as_string(term, final), param);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-23 18:17:36 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("%s: missing parameter", csi_as_string(term, final));
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
2019-06-23 18:17:36 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-22 22:25:50 +02:00
|
|
|
case '=':
|
|
|
|
|
/*
|
|
|
|
|
* TODO: xterm's terminfo specifies *both* \e[?1h *and*
|
|
|
|
|
* \e= in smkx, but only one is necessary. We should
|
|
|
|
|
* provide our own terminfo with *only* \e[?1h (and \e[?1l
|
|
|
|
|
* for rmkx)
|
|
|
|
|
*/
|
|
|
|
|
LOG_WARN("ignoring CSI with final '='");
|
|
|
|
|
break;
|
|
|
|
|
|
2019-06-17 18:57:12 +02:00
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("unimplemented: %s", csi_as_string(term, final));
|
2019-06-17 18:57:12 +02:00
|
|
|
abort();
|
2019-07-10 15:03:16 +02:00
|
|
|
break;
|
2019-06-17 18:57:12 +02:00
|
|
|
}
|
2019-06-22 22:25:50 +02:00
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
break; /* private == 0 */
|
|
|
|
|
}
|
2019-06-22 22:25:50 +02:00
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
case '?': {
|
2019-06-22 22:25:50 +02:00
|
|
|
switch (final) {
|
|
|
|
|
case 'h': {
|
|
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++) {
|
|
|
|
|
switch (term->vt.params.v[i].value) {
|
|
|
|
|
case 1:
|
2019-07-09 11:07:06 +02:00
|
|
|
term->cursor_keys_mode = CURSOR_KEYS_APPLICATION;
|
2019-06-22 22:25:50 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:01:12 +02:00
|
|
|
case 5:
|
2019-07-05 20:12:40 +02:00
|
|
|
term->reverse = true;
|
|
|
|
|
term_damage_all(term);
|
2019-06-24 20:01:12 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-03 14:47:34 +02:00
|
|
|
case 7:
|
2019-07-03 21:18:06 +02:00
|
|
|
term->auto_margin = true;
|
2019-07-03 14:47:34 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-23 18:17:58 +02:00
|
|
|
case 12:
|
2019-07-04 10:04:52 +02:00
|
|
|
/* Ignored */
|
2019-06-23 18:17:58 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 25:
|
2019-07-03 14:14:46 +02:00
|
|
|
term->hide_cursor = false;
|
2019-06-23 18:17:58 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:01:12 +02:00
|
|
|
case 1000:
|
2019-07-05 14:24:51 +02:00
|
|
|
term->mouse_tracking = MOUSE_CLICK;
|
2019-06-24 20:01:12 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1002:
|
2019-07-05 15:13:06 +02:00
|
|
|
term->mouse_tracking = MOUSE_DRAG;
|
2019-07-05 14:24:51 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1003:
|
2019-07-05 15:13:06 +02:00
|
|
|
term->mouse_tracking = MOUSE_MOTION;
|
2019-06-24 20:01:12 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-03 16:00:06 +02:00
|
|
|
case 1005:
|
|
|
|
|
LOG_WARN("unimplemented: UTF-8 mouse");
|
2019-07-05 15:13:06 +02:00
|
|
|
/* term->mouse_reporting = MOUSE_UTF8; */
|
2019-07-03 16:00:06 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:01:12 +02:00
|
|
|
case 1006:
|
2019-07-05 15:13:06 +02:00
|
|
|
term->mouse_reporting = MOUSE_SGR;
|
2019-06-24 20:01:12 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-03 16:00:06 +02:00
|
|
|
case 1015:
|
2019-07-05 19:40:52 +02:00
|
|
|
term->mouse_reporting = MOUSE_URXVT;
|
2019-07-03 16:00:06 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-22 22:25:50 +02:00
|
|
|
case 1049:
|
2019-06-29 21:23:36 +02:00
|
|
|
if (term->grid != &term->alt) {
|
|
|
|
|
term->grid = &term->alt;
|
2019-06-29 21:15:32 +02:00
|
|
|
term->saved_cursor = term->cursor;
|
2019-07-01 19:25:04 +02:00
|
|
|
|
2019-07-02 22:23:54 +02:00
|
|
|
term_cursor_to(term, term->cursor.row, term->cursor.col);
|
|
|
|
|
|
2019-07-01 19:25:04 +02:00
|
|
|
tll_free(term->alt.damage);
|
|
|
|
|
tll_free(term->alt.scroll_damage);
|
2019-07-05 09:09:58 +02:00
|
|
|
|
2019-07-08 13:57:31 +02:00
|
|
|
//grid_memclear(term->grid, 0, term->rows * term->cols);
|
|
|
|
|
//term_damage_erase(term, 0, term->rows * term->cols);
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
2019-06-22 22:25:50 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2004:
|
|
|
|
|
term->bracketed_paste = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("%s: unimplemented param: %d",
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_as_string(term, final),
|
2019-06-22 22:25:50 +02:00
|
|
|
term->vt.params.v[i].value);
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'l': {
|
|
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++) {
|
|
|
|
|
switch (term->vt.params.v[i].value) {
|
|
|
|
|
case 1:
|
2019-07-09 11:07:06 +02:00
|
|
|
term->cursor_keys_mode = CURSOR_KEYS_NORMAL;
|
2019-06-22 22:25:50 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-24 20:01:12 +02:00
|
|
|
case 5:
|
2019-07-05 20:12:40 +02:00
|
|
|
term->reverse = false;
|
|
|
|
|
term_damage_all(term);
|
2019-06-24 20:01:12 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-03 14:47:34 +02:00
|
|
|
case 7:
|
2019-07-03 21:18:06 +02:00
|
|
|
term->auto_margin = false;
|
2019-07-03 14:47:34 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-23 18:17:58 +02:00
|
|
|
case 12:
|
2019-07-04 10:04:52 +02:00
|
|
|
/* Ignored */
|
2019-06-23 18:17:58 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 25:
|
2019-07-03 14:14:46 +02:00
|
|
|
term->hide_cursor = true;
|
2019-06-23 18:17:58 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-07-05 14:24:51 +02:00
|
|
|
case 1000: /* MOUSE_NORMAL */
|
|
|
|
|
case 1002: /* MOUSE_BUTTON_EVENT */
|
|
|
|
|
case 1003: /* MOUSE_ANY_EVENT */
|
|
|
|
|
case 1005: /* MOUSE_UTF8 */
|
|
|
|
|
case 1006: /* MOUSE_SGR */
|
|
|
|
|
case 1015: /* MOUSE_URXVT */
|
|
|
|
|
term->mouse_tracking = MOUSE_NONE;
|
2019-07-03 16:00:06 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-22 22:25:50 +02:00
|
|
|
case 1049:
|
2019-06-29 21:23:36 +02:00
|
|
|
if (term->grid == &term->alt) {
|
|
|
|
|
term->grid = &term->normal;
|
2019-06-23 15:00:27 +02:00
|
|
|
|
2019-06-29 21:15:32 +02:00
|
|
|
term->cursor = term->saved_cursor;
|
2019-07-02 22:23:54 +02:00
|
|
|
term_cursor_to(term, term->cursor.row, term->cursor.col);
|
|
|
|
|
|
2019-07-01 19:25:04 +02:00
|
|
|
tll_free(term->alt.damage);
|
|
|
|
|
tll_free(term->alt.scroll_damage);
|
|
|
|
|
|
2019-06-29 21:03:28 +02:00
|
|
|
term_damage_all(term);
|
2019-06-23 15:00:27 +02:00
|
|
|
}
|
2019-06-22 22:25:50 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2004:
|
|
|
|
|
term->bracketed_paste = false;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("%s: unimplemented param: %d",
|
2019-07-04 19:35:01 +02:00
|
|
|
csi_as_string(term, final),
|
2019-06-22 22:25:50 +02:00
|
|
|
term->vt.params.v[i].value);
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-03 16:00:27 +02:00
|
|
|
case 's':
|
2019-07-03 21:33:23 +02:00
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++) {
|
|
|
|
|
switch (term->vt.params.v[i].value) {
|
|
|
|
|
case 1001: /* save old highlight mouse tracking mode? */
|
|
|
|
|
LOG_WARN(
|
|
|
|
|
"unimplemented: CSI ?1001s "
|
|
|
|
|
"(save 'highlight mouse tracking' mode)");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-04 19:35:01 +02:00
|
|
|
LOG_ERR("unimplemented: CSI %s", csi_as_string(term, final));
|
2019-07-03 21:33:23 +02:00
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2019-07-03 16:00:27 +02:00
|
|
|
case 'r':
|
2019-07-03 21:33:23 +02:00
|
|
|
for (size_t i = 0; i < term->vt.params.idx; i++) {
|
|
|
|
|
switch (term->vt.params.v[i].value) {
|
|
|
|
|
case 1001: /* restore old highlight mouse tracking mode? */
|
|
|
|
|
LOG_WARN(
|
|
|
|
|
"unimplemented: CSI ?1001r "
|
|
|
|
|
"(restore 'highlight mouse tracking' mode)");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-04 19:35:01 +02:00
|
|
|
LOG_ERR("unimplemented: CSI %s", csi_as_string(term, final));
|
2019-07-03 21:33:23 +02:00
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-03 16:00:27 +02:00
|
|
|
break;
|
|
|
|
|
|
2019-06-22 22:25:50 +02:00
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("unimplemented: %s", csi_as_string(term, final));
|
2019-06-22 22:25:50 +02:00
|
|
|
abort();
|
|
|
|
|
}
|
2019-07-10 15:03:16 +02:00
|
|
|
|
|
|
|
|
break; /* private == '?' */
|
2019-06-22 22:25:50 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
case '>': {
|
2019-06-24 20:01:41 +02:00
|
|
|
switch (final) {
|
|
|
|
|
case 'c': {
|
2019-07-10 16:04:16 +02:00
|
|
|
int param = vt_param_get(term, 0, 0);
|
2019-06-24 20:01:41 +02:00
|
|
|
if (param != 0) {
|
|
|
|
|
LOG_ERR(
|
|
|
|
|
"unimplemented: send device attributes with param = %d",
|
|
|
|
|
param);
|
2019-07-07 16:32:18 +02:00
|
|
|
abort();
|
|
|
|
|
break;
|
2019-06-24 20:01:41 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-07 16:32:18 +02:00
|
|
|
write(term->ptmx, "\033[?6c", 5);
|
|
|
|
|
break;
|
2019-06-24 20:01:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("unimplemented: %s", csi_as_string(term, final));
|
2019-06-24 20:01:41 +02:00
|
|
|
abort();
|
|
|
|
|
}
|
2019-07-10 15:03:16 +02:00
|
|
|
|
|
|
|
|
break; /* private == '>' */
|
2019-06-24 20:01:41 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-10 15:03:16 +02:00
|
|
|
default:
|
2019-07-10 14:57:59 +02:00
|
|
|
LOG_ERR("unimplemented: %s", csi_as_string(term, final));
|
2019-06-22 22:25:50 +02:00
|
|
|
abort();
|
2019-07-10 15:03:16 +02:00
|
|
|
break;
|
2019-06-15 22:22:44 +02:00
|
|
|
}
|
|
|
|
|
}
|