From 3ba1721c0f8b962466bb2d68d3adccdeb60ff915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 5 Jul 2019 09:46:48 +0200 Subject: [PATCH] osc: implement change window title and icon --- csi.c | 2 +- main.c | 10 +++++++++- osc.c | 41 ++++++++++++++++++++++++++++++++++++++++- terminal.h | 17 +++++++++++------ vt.c | 5 ++++- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/csi.c b/csi.c index ada6183e..04174aa6 100644 --- a/csi.c +++ b/csi.c @@ -274,7 +274,7 @@ csi_as_string(struct terminal *term, uint8_t final) i == term->vt.params.idx - 1 ? "" : ";"); } - c += snprintf(&msg[c], sizeof(msg) - c, "%c (%d parameters)", + c += snprintf(&msg[c], sizeof(msg) - c, "%c (%zu parameters)", final, term->vt.params.idx); return msg; } diff --git a/main.c b/main.c index 1b1aea13..a6a2ccf5 100644 --- a/main.c +++ b/main.c @@ -819,6 +819,13 @@ keyboard_repeater(void *arg) return 1; } +/* TODO: move to a render API? */ +void +render_set_title(struct renderer *renderer, const char *title) +{ + xdg_toplevel_set_title(renderer->xdg_toplevel, title); +} + int main(int argc, char *const *argv) { @@ -965,10 +972,11 @@ main(int argc, char *const *argv) xdg_surface_add_listener(c.wl.xdg_surface, &xdg_surface_listener, &c); c.wl.xdg_toplevel = xdg_surface_get_toplevel(c.wl.xdg_surface); + c.term.renderer.xdg_toplevel = c.wl.xdg_toplevel; /* TODO */ xdg_toplevel_add_listener(c.wl.xdg_toplevel, &xdg_toplevel_listener, &c); xdg_toplevel_set_app_id(c.wl.xdg_toplevel, "f00ter"); - xdg_toplevel_set_title(c.wl.xdg_toplevel, "f00ter"); + render_set_title(&c.term.renderer, "f00ter"); wl_surface_commit(c.wl.surface); wl_display_roundtrip(c.wl.display); diff --git a/osc.c b/osc.c index 2882d546..c0c5ab98 100644 --- a/osc.c +++ b/osc.c @@ -1,12 +1,51 @@ #include "osc.h" +#include +#include "terminal.h" #define LOG_MODULE "osc" #define LOG_ENABLE_DBG 0 #include "log.h" +/* TODO */ +void render_set_title(struct renderer *renderer, const char *title); + bool osc_dispatch(struct terminal *term) { - LOG_DBG("OCS: %.*s", (int)term->vt.osc.idx, term->vt.osc.data); + int param = 0; + int data_ofs = 0; + + for (size_t i = 0; i < term->vt.osc.idx; i++) { + int c = term->vt.osc.data[i]; + + 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); + return false; + } + + 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]; + + switch (param) { + case 0: render_set_title(&term->renderer, string); break; /* icon + title */ + case 1: break; /* icon */ + case 2: render_set_title(&term->renderer, string); break; /* title */ + + default: + LOG_ERR("unimplemented: OSC: %.*s", + (int)term->vt.osc.idx, term->vt.osc.data); + return false; + } + return true; } diff --git a/terminal.h b/terminal.h index 9349de01..b65216bb 100644 --- a/terminal.h +++ b/terminal.h @@ -74,7 +74,7 @@ struct grid { struct vt_subparams { unsigned value[16]; - int idx; + size_t idx; }; struct vt_param { @@ -86,20 +86,20 @@ struct vt { int state; /* enum state */ struct { struct vt_param v[16]; - int idx; + size_t idx; } params; struct { uint8_t data[2]; - int idx; + size_t idx; } intermediates; struct { uint8_t data[1024]; - int idx; + size_t idx; } osc; struct { uint8_t data[4]; - int idx; - int left; + size_t idx; + size_t left; } utf8; struct attributes attrs; struct attributes saved_attrs; @@ -125,6 +125,10 @@ struct kbd { } repeat; }; +struct renderer { + struct xdg_toplevel *xdg_toplevel; /* TODO: this doesn't belong here */ +}; + enum decckm { DECCKM_CSI, DECCKM_SS3 }; enum keypad_mode { KEYPAD_NUMERICAL, KEYPAD_APPLICATION }; enum charset { CHARSET_ASCII, CHARSET_GRAPHIC }; @@ -145,6 +149,7 @@ struct terminal { struct vt vt; struct kbd kbd; + struct renderer renderer; int cols; int rows; diff --git a/vt.c b/vt.c index 8ef16bfb..12a5147d 100644 --- a/vt.c +++ b/vt.c @@ -799,10 +799,13 @@ action(struct terminal *term, enum action action, uint8_t c) break; case ACTION_OSC_PUT: - term->vt.osc.data[term->vt.osc.idx++] = c; + if (term->vt.osc.idx < (int)sizeof(term->vt.osc.data) - 1) + term->vt.osc.data[term->vt.osc.idx++] = c; break; case ACTION_OSC_END: + assert(term->vt.osc.idx < sizeof(term->vt.osc.data)); + term->vt.osc.data[term->vt.osc.idx] = '\0'; return osc_dispatch(term); case ACTION_HOOK: