+static char const * const keytable[KEY_MAX+1] = {
+ ['\n'] = "\r",
+ [KEY_UP] = "\e[A",
+ [KEY_DOWN] = "\e[B",
+ [KEY_RIGHT] = "\e[C",
+ [KEY_LEFT] = "\e[D",
+ [KEY_BACKSPACE] = "\b",
+ [KEY_HOME] = "\e[1~",
+ [KEY_IC] = "\e[2~",
+ [KEY_DC] = "\e[3~",
+ [KEY_END] = "\e[4~",
+ [KEY_PPAGE] = "\e[5~",
+ [KEY_NPAGE] = "\e[6~",
+ [KEY_SUSPEND] = "\x1A", /* Ctrl+Z gets mapped to this */
+ [KEY_F(1)] = "\e[[A",
+ [KEY_F(2)] = "\e[[B",
+ [KEY_F(3)] = "\e[[C",
+ [KEY_F(4)] = "\e[[D",
+ [KEY_F(5)] = "\e[[E",
+ [KEY_F(6)] = "\e[17~",
+ [KEY_F(7)] = "\e[18~",
+ [KEY_F(8)] = "\e[19~",
+ [KEY_F(9)] = "\e[20~",
+ [KEY_F(10)] = "\e[21~",
+};
+
+static void mtty_row_set(mtty_row_t *row, int start, int len, uint16_t attr)
+{
+ wmemset(row->text + start, 0, len);
+ for (int i = start; i < len + start; i++) {
+ row->attr[i] = attr;
+ }
+}
+
+__attribute__((noinline))
+static void mtty_row_roll(mtty_row_t *start, mtty_row_t *end, int count)
+{
+ int n = end - start;
+
+ count %= n;
+ if (count < 0)
+ count += n;
+
+ if (count) {
+ mtty_row_t *buf = alloca(count * sizeof(mtty_row_t));
+
+ memcpy(buf, start, count * sizeof(mtty_row_t));
+ memmove(start, start + count, (n - count) * sizeof(mtty_row_t));
+ memcpy(end - count, buf, count * sizeof(mtty_row_t));
+ }
+}
+