15b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include "vterm_internal.h"
25b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
35b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include <stdio.h>
45b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include <stdlib.h>
55b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include <stdarg.h>
65b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include <string.h>
75b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
85b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey/*****************
95b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey * API functions *
105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey *****************/
115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void *default_malloc(size_t size, void *allocdata)
135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  void *ptr = malloc(size);
155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(ptr)
165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    memset(ptr, 0, size);
175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return ptr;
185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void default_free(void *ptr, void *allocdata)
215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  free(ptr);
235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic VTermAllocatorFunctions default_allocator = {
265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  .malloc = &default_malloc,
275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  .free   = &default_free,
285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey};
295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff SharkeyVTerm *vterm_new(int rows, int cols)
315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vterm_new_with_allocator(rows, cols, &default_allocator, NULL);
335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff SharkeyVTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata)
365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  /* Need to bootstrap using the allocator function directly */
385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata);
395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->allocator = funcs;
415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->allocdata = allocdata;
425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->rows = rows;
445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->cols = cols;
455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->parser_state = NORMAL;
475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->strbuffer_len = 64;
495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->strbuffer_cur = 0;
505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->strbuffer = vterm_allocator_malloc(vt, vt->strbuffer_len);
515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer_len = 64;
535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer_cur = 0;
545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vt;
575b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_free(VTerm *vt)
605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(vt->screen)
625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    vterm_screen_free(vt->screen);
635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(vt->state)
655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    vterm_state_free(vt->state);
665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vterm_allocator_free(vt, vt->strbuffer);
685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vterm_allocator_free(vt, vt->outbuffer);
695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vterm_allocator_free(vt, vt);
715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
736d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void *vterm_allocator_malloc(VTerm *vt, size_t size)
745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return (*vt->allocator->malloc)(size, vt->allocdata);
765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
786d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_allocator_free(VTerm *vt, void *ptr)
795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  (*vt->allocator->free)(ptr, vt->allocdata);
815b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
825b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
835b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_get_size(const VTerm *vt, int *rowsp, int *colsp)
845b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(rowsp)
865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    *rowsp = vt->rows;
875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(colsp)
885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    *colsp = vt->cols;
895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
905b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_set_size(VTerm *vt, int rows, int cols)
925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->rows = rows;
945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->cols = cols;
955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(vt->parser_callbacks && vt->parser_callbacks->resize)
975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    (*vt->parser_callbacks->resize)(rows, cols, vt->cbdata);
985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
995b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1005b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_set_parser_callbacks(VTerm *vt, const VTermParserCallbacks *callbacks, void *user)
1015b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1025b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->parser_callbacks = callbacks;
1035b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->cbdata = user;
1045b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1055b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_parser_set_utf8(VTerm *vt, int is_utf8)
1075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->mode.utf8 = is_utf8;
1095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1116d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len)
1125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(len > vt->outbuffer_len - vt->outbuffer_cur) {
1145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    fprintf(stderr, "vterm_push_output(): buffer overflow; truncating output\n");
1155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    len = vt->outbuffer_len - vt->outbuffer_cur;
1165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
1175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  memcpy(vt->outbuffer + vt->outbuffer_cur, bytes, len);
1195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer_cur += len;
1205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1226d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args)
1235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int written = vsnprintf(vt->outbuffer + vt->outbuffer_cur,
1255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      vt->outbuffer_len - vt->outbuffer_cur,
1265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      format, args);
1275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer_cur += written;
1285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1306d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_push_output_sprintf(VTerm *vt, const char *format, ...)
1315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_list args;
1335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_start(args, format);
1345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vterm_push_output_vsprintf(vt, format, args);
1355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_end(args);
1365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1386d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...)
1395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(ctrl >= 0x80 && !vt->mode.ctrl8bit)
1415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    vterm_push_output_sprintf(vt, "\e%c", ctrl - 0x40);
1425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else
1435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    vterm_push_output_sprintf(vt, "%c", ctrl);
1445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_list args;
1465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_start(args, fmt);
1475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vterm_push_output_vsprintf(vt, fmt, args);
1485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  va_end(args);
14973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey}
15073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
1516d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...)
15273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey{
15373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(!vt->mode.ctrl8bit)
15473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    vterm_push_output_sprintf(vt, "\e%c", C1_DCS - 0x40);
15573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  else
15673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    vterm_push_output_sprintf(vt, "%c", C1_DCS);
15773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
15873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  va_list args;
15973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  va_start(args, fmt);
16073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  vterm_push_output_vsprintf(vt, fmt, args);
16173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  va_end(args);
1625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
16373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  vterm_push_output_sprintf_ctrl(vt, C1_ST, "");
1645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeysize_t vterm_output_bufferlen(VTerm *vt)
1675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vterm_output_get_buffer_current(vt);
1695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeysize_t vterm_output_get_buffer_size(const VTerm *vt)
1725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1735b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vt->outbuffer_len;
1745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeysize_t vterm_output_get_buffer_current(const VTerm *vt)
1775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1785b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vt->outbuffer_cur;
1795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1815b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeysize_t vterm_output_get_buffer_remaining(const VTerm *vt)
1825b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1835b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return vt->outbuffer_len - vt->outbuffer_cur;
1845b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeysize_t vterm_output_bufferread(VTerm *vt, char *buffer, size_t len)
1875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(len > vt->outbuffer_cur)
1895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    len = vt->outbuffer_cur;
1905b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  memcpy(buffer, vt->outbuffer, len);
1925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(len < vt->outbuffer_cur)
1945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    memmove(vt->outbuffer, vt->outbuffer + len, vt->outbuffer_cur - len);
1955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  vt->outbuffer_cur -= len;
1975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return len;
1995b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
2005b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2015b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff SharkeyVTermValueType vterm_get_attr_type(VTermAttr attr)
2025b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
2035b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  switch(attr) {
2045b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_BOLD:       return VTERM_VALUETYPE_BOOL;
2055b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_UNDERLINE:  return VTERM_VALUETYPE_INT;
2065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_ITALIC:     return VTERM_VALUETYPE_BOOL;
2075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_BLINK:      return VTERM_VALUETYPE_BOOL;
2085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_REVERSE:    return VTERM_VALUETYPE_BOOL;
2095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_STRIKE:     return VTERM_VALUETYPE_BOOL;
2105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_FONT:       return VTERM_VALUETYPE_INT;
2115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_FOREGROUND: return VTERM_VALUETYPE_COLOR;
2125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_ATTR_BACKGROUND: return VTERM_VALUETYPE_COLOR;
2135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return 0; /* UNREACHABLE */
2155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
2165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff SharkeyVTermValueType vterm_get_prop_type(VTermProp prop)
2185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
2195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  switch(prop) {
2205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_CURSORVISIBLE: return VTERM_VALUETYPE_BOOL;
2215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_CURSORBLINK:   return VTERM_VALUETYPE_BOOL;
2225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_ALTSCREEN:     return VTERM_VALUETYPE_BOOL;
2235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_TITLE:         return VTERM_VALUETYPE_STRING;
2245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_ICONNAME:      return VTERM_VALUETYPE_STRING;
2255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_REVERSE:       return VTERM_VALUETYPE_BOOL;
2265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case VTERM_PROP_CURSORSHAPE:   return VTERM_VALUETYPE_INT;
2275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return 0; /* UNREACHABLE */
2295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
2305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_scroll_rect(VTermRect rect,
2325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int downward,
2335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int rightward,
2345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int (*moverect)(VTermRect src, VTermRect dest, void *user),
2355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int (*eraserect)(VTermRect rect, int selective, void *user),
2365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    void *user)
2375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
2385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermRect src;
2395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermRect dest;
2405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(abs(downward)  >= rect.end_row - rect.start_row ||
2425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     abs(rightward) >= rect.end_col - rect.start_col) {
2435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    /* Scroll more than area; just erase the lot */
2445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    (*eraserect)(rect, 0, user);
2455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return;
2465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(rightward >= 0) {
2495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    /* rect: [XXX................]
2505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     * src:     [----------------]
2515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     * dest: [----------------]
2525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     */
2535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.start_col = rect.start_col;
2545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.end_col   = rect.end_col   - rightward;
2555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.start_col  = rect.start_col + rightward;
2565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.end_col    = rect.end_col;
2575b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else {
2595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    /* rect: [................XXX]
2605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     * src:  [----------------]
2615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     * dest:    [----------------]
2625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey     */
2635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int leftward = -rightward;
2645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.start_col = rect.start_col + leftward;
2655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.end_col   = rect.end_col;
2665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.start_col  = rect.start_col;
2675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.end_col    = rect.end_col - leftward;
2685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(downward >= 0) {
2715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.start_row = rect.start_row;
2725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.end_row   = rect.end_row   - downward;
2735b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.start_row  = rect.start_row + downward;
2745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.end_row    = rect.end_row;
2755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else {
2775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int upward = -downward;
2785b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.start_row = rect.start_row + upward;
2795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    dest.end_row   = rect.end_row;
2805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.start_row  = rect.start_row;
2815b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    src.end_row    = rect.end_row - upward;
2825b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
2835b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2845b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(moverect)
2855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    (*moverect)(dest, src, user);
2865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(downward > 0)
2885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    rect.start_row = rect.end_row - downward;
2895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else if(downward < 0)
2905b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    rect.end_row = rect.start_row - downward;
2915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(rightward > 0)
2935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    rect.start_col = rect.end_col - rightward;
2945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else if(rightward < 0)
2955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    rect.end_col = rect.start_col - rightward;
2965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  (*eraserect)(rect, 0, user);
2985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
2995b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3005b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_copy_cells(VTermRect dest,
3015b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    VTermRect src,
3025b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    void (*copycell)(VTermPos dest, VTermPos src, void *user),
3035b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    void *user)
3045b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
3055b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int downward  = src.start_row - dest.start_row;
3065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int rightward = src.start_col - dest.start_col;
3075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int init_row, test_row, init_col, test_col;
3095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int inc_row, inc_col;
3105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(downward < 0) {
3125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    init_row = dest.end_row - 1;
3135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    test_row = dest.start_row - 1;
3145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    inc_row = -1;
3155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
3165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else /* downward >= 0 */ {
3175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    init_row = dest.start_row;
3185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    test_row = dest.end_row;
3195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    inc_row = +1;
3205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
3215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(rightward < 0) {
3235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    init_col = dest.end_col - 1;
3245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    test_col = dest.start_col - 1;
3255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    inc_col = -1;
3265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
3275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else /* rightward >= 0 */ {
3285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    init_col = dest.start_col;
3295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    test_col = dest.end_col;
3305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    inc_col = +1;
3315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
3325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermPos pos;
3345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  for(pos.row = init_row; pos.row != test_row; pos.row += inc_row)
3355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    for(pos.col = init_col; pos.col != test_col; pos.col += inc_col) {
3365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      VTermPos srcpos = { pos.row + downward, pos.col + rightward };
3375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      (*copycell)(pos, srcpos, user);
3385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    }
3395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
340