15b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include "vterm_internal.h"
25b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
35b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#include <stdio.h>
45b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
55b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic const VTermColor ansi_colors[] = {
65b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  /* R    G    B */
75b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {   0,   0,   0 }, // black
85b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 224,   0,   0 }, // red
95b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {   0, 224,   0 }, // green
105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 224, 224,   0 }, // yellow
115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {   0,   0, 224 }, // blue
125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 224,   0, 224 }, // magenta
135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {   0, 224, 224 }, // cyan
145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 224, 224, 224 }, // white == light grey
155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  // high intensity
175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 128, 128, 128 }, // black
185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 255,  64,  64 }, // red
195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {  64, 255,  64 }, // green
205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 255, 255,  64 }, // yellow
215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {  64,  64, 255 }, // blue
225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 255,  64, 255 }, // magenta
235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  {  64, 255, 255 }, // cyan
245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  { 255, 255, 255 }, // white for real
255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey};
265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic int ramp6[] = {
285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF,
295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey};
305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic int ramp24[] = {
325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  0x00, 0x0B, 0x16, 0x21, 0x2C, 0x37, 0x42, 0x4D, 0x58, 0x63, 0x6E, 0x79,
335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  0x85, 0x90, 0x9B, 0xA6, 0xB1, 0xBC, 0xC7, 0xD2, 0xDD, 0xE8, 0xF3, 0xFF,
345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey};
355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
366d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughesstatic void lookup_colour_ansi(const VTermState *state, long index, VTermColor *col)
375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(index >= 0 && index < 16) {
396d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes    *col = state->colors[index];
405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
436d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughesstatic void lookup_colour_palette(const VTermState *state, long index, VTermColor *col)
445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(index >= 0 && index < 16) {
465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    // Normal 8 colours or high intensity - parse as palette 0
476d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes    lookup_colour_ansi(state, index, col);
485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else if(index >= 16 && index < 232) {
505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    // 216-colour cube
515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    index -= 16;
525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->blue  = ramp6[index     % 6];
545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->green = ramp6[index/6   % 6];
555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->red   = ramp6[index/6/6 % 6];
565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
575b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else if(index >= 232 && index < 256) {
585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    // 24 greyscales
595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    index -= 232;
605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->red   = ramp24[index];
625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->green = ramp24[index];
635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->blue  = ramp24[index];
645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
676d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughesstatic int lookup_colour(const VTermState *state, int palette, const long args[], int argcount, VTermColor *col, int *index)
685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  switch(palette) {
705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case 2: // RGB mode - 3 args contain colour values directly
715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    if(argcount < 3)
725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      return argcount;
735b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->red   = CSI_ARG(args[0]);
755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->green = CSI_ARG(args[1]);
765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    col->blue  = CSI_ARG(args[2]);
775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
785b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 3;
795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case 5: // XTerm 256-colour mode
8173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    if(index)
8273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      *index = CSI_ARG_OR(args[0], -1);
8373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
846d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes    lookup_colour_palette(state, argcount ? CSI_ARG_OR(args[0], -1) : -1, col);
855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return argcount ? 1 : 0;
875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  default:
895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    fprintf(stderr, "Unrecognised colour palette %d\n", palette);
905b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 0;
915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey// Some conveniences
955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void setpenattr(VTermState *state, VTermAttr attr, VTermValueType type, VTermValue *val)
975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#ifdef DEBUG
995b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(type != vterm_get_attr_type(attr)) {
1005b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    fprintf(stderr, "Cannot set attr %d as it has type %d, not type %d\n",
1015b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey        attr, vterm_get_attr_type(attr), type);
1025b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return;
1035b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
1045b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey#endif
1055b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(state->callbacks && state->callbacks->setpenattr)
1065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    (*state->callbacks->setpenattr)(attr, val, state->cbdata);
1075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void setpenattr_bool(VTermState *state, VTermAttr attr, int boolean)
1105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermValue val = { .boolean = boolean };
1125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  setpenattr(state, attr, VTERM_VALUETYPE_BOOL, &val);
1135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void setpenattr_int(VTermState *state, VTermAttr attr, int number)
1165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermValue val = { .number = number };
1185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  setpenattr(state, attr, VTERM_VALUETYPE_INT, &val);
1195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void setpenattr_col(VTermState *state, VTermAttr attr, VTermColor color)
1225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermValue val = { .color = color };
1245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  setpenattr(state, attr, VTERM_VALUETYPE_COLOR, &val);
1255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeystatic void set_pen_col_ansi(VTermState *state, VTermAttr attr, long col)
1285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  VTermColor *colp = (attr == VTERM_ATTR_BACKGROUND) ? &state->pen.bg : &state->pen.fg;
1305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1316d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  lookup_colour_ansi(state, col, colp);
1325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  setpenattr_col(state, attr, *colp);
1345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1366d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_state_newpen(VTermState *state)
1376d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes{
1386d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  // 90% grey so that pure white is brighter
1396d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  state->default_fg.red = state->default_fg.green = state->default_fg.blue = 240;
1406d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  state->default_bg.red = state->default_bg.green = state->default_bg.blue = 0;
1416d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes
1426d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  for(int col = 0; col < 16; col++)
1436d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes    state->colors[col] = ansi_colors[col];
1446d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes}
1456d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes
1466d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_state_resetpen(VTermState *state)
1475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.bold = 0;      setpenattr_bool(state, VTERM_ATTR_BOLD, 0);
1495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.underline = 0; setpenattr_int( state, VTERM_ATTR_UNDERLINE, 0);
1505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.italic = 0;    setpenattr_bool(state, VTERM_ATTR_ITALIC, 0);
1515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.blink = 0;     setpenattr_bool(state, VTERM_ATTR_BLINK, 0);
1525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.reverse = 0;   setpenattr_bool(state, VTERM_ATTR_REVERSE, 0);
1535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.strike = 0;    setpenattr_bool(state, VTERM_ATTR_STRIKE, 0);
1545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.font = 0;      setpenattr_int( state, VTERM_ATTR_FONT, 0);
1555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
15673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  state->fg_index = -1;
15773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  state->bg_index = -1;
1585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.fg = state->default_fg;  setpenattr_col(state, VTERM_ATTR_FOREGROUND, state->default_fg);
1595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->pen.bg = state->default_bg;  setpenattr_col(state, VTERM_ATTR_BACKGROUND, state->default_bg);
1605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1626d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_state_savepen(VTermState *state, int save)
1635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  if(save) {
1655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    state->saved.pen = state->pen;
1665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
1675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  else {
1685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    state->pen = state->saved.pen;
1695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_bool(state, VTERM_ATTR_BOLD,       state->pen.bold);
1715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_int( state, VTERM_ATTR_UNDERLINE,  state->pen.underline);
1725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_bool(state, VTERM_ATTR_ITALIC,     state->pen.italic);
1735b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_bool(state, VTERM_ATTR_BLINK,      state->pen.blink);
1745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_bool(state, VTERM_ATTR_REVERSE,    state->pen.reverse);
1755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_bool(state, VTERM_ATTR_STRIKE,     state->pen.strike);
1765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_int( state, VTERM_ATTR_FONT,       state->pen.font);
1775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_col( state, VTERM_ATTR_FOREGROUND, state->pen.fg);
1785b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    setpenattr_col( state, VTERM_ATTR_BACKGROUND, state->pen.bg);
1795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
1805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1815b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1825b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_state_get_default_colors(const VTermState *state, VTermColor *default_fg, VTermColor *default_bg)
1835b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1845b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  *default_fg = state->default_fg;
1855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  *default_bg = state->default_bg;
1865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_state_get_palette_color(const VTermState *state, int index, VTermColor *col)
1895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1906d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  lookup_colour_palette(state, index, col);
1915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_state_set_default_colors(VTermState *state, const VTermColor *default_fg, const VTermColor *default_bg)
1945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
1955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->default_fg = *default_fg;
1965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->default_bg = *default_bg;
1975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
1985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
1996d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughesvoid vterm_state_set_palette_color(VTermState *state, int index, const VTermColor *col)
2006d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes{
2016d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes  if(index >= 0 && index < 16)
2026d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes    state->colors[index] = *col;
2036d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes}
2046d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes
2055b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyvoid vterm_state_set_bold_highbright(VTermState *state, int bold_is_highbright)
2065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
2075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  state->bold_is_highbright = bold_is_highbright;
2085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
2095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2106d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL void vterm_state_setpen(VTermState *state, const long args[], int argcount)
2115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
2125b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  // SGR - ECMA-48 8.3.117
2135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int argi = 0;
2155b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  int value;
2165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  while(argi < argcount) {
2185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    // This logic is easier to do 'done' backwards; set it true, and make it
2195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    // false again in the 'default' case
2205b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    int done = 1;
2215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    long arg;
2235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    switch(arg = CSI_ARG(args[argi])) {
2245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case CSI_ARG_MISSING:
2255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 0: // Reset
2265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      vterm_state_resetpen(state);
2275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 1: // Bold on
2305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.bold = 1;
2315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_BOLD, 1);
23273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      if(state->fg_index > -1 && state->fg_index < 8 && state->bold_is_highbright)
23373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey        set_pen_col_ansi(state, VTERM_ATTR_FOREGROUND, state->fg_index + (state->pen.bold ? 8 : 0));
2345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 3: // Italic on
2375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.italic = 1;
2385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_ITALIC, 1);
2395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 4: // Underline single
2425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.underline = 1;
2435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_int(state, VTERM_ATTR_UNDERLINE, 1);
2445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 5: // Blink
2475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.blink = 1;
2485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_BLINK, 1);
2495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 7: // Reverse on
2525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.reverse = 1;
2535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_REVERSE, 1);
2545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 9: // Strikethrough on
2575b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.strike = 1;
2585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_STRIKE, 1);
2595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 10: case 11: case 12: case 13: case 14:
2625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 15: case 16: case 17: case 18: case 19: // Select font
2635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.font = CSI_ARG(args[argi]) - 10;
2645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_int(state, VTERM_ATTR_FONT, state->pen.font);
2655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 21: // Underline double
2685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.underline = 2;
2695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_int(state, VTERM_ATTR_UNDERLINE, 2);
2705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2725b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 22: // Bold off
2735b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.bold = 0;
2745b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_BOLD, 0);
2755b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2765b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2775b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 23: // Italic and Gothic (currently unsupported) off
2785b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.italic = 0;
2795b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_ITALIC, 0);
2805b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2815b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2825b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 24: // Underline off
2835b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.underline = 0;
2845b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_int(state, VTERM_ATTR_UNDERLINE, 0);
2855b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2865b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2875b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 25: // Blink off
2885b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.blink = 0;
2895b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_BLINK, 0);
2905b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2915b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2925b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 27: // Reverse off
2935b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.reverse = 0;
2945b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_REVERSE, 0);
2955b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
2965b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
2975b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 29: // Strikethrough off
2985b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.strike = 0;
2995b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_bool(state, VTERM_ATTR_STRIKE, 0);
3005b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3015b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3025b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 30: case 31: case 32: case 33:
3035b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 34: case 35: case 36: case 37: // Foreground colour palette
3045b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      value = CSI_ARG(args[argi]) - 30;
30573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->fg_index = value;
3065b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      if(state->pen.bold && state->bold_is_highbright)
3075b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey        value += 8;
3085b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      set_pen_col_ansi(state, VTERM_ATTR_FOREGROUND, value);
3095b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3105b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3115b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 38: // Foreground colour alternative palette
31273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->fg_index = -1;
3135b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      if(argcount - argi < 1)
3145b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey        return;
3156d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes      argi += 1 + lookup_colour(state, CSI_ARG(args[argi+1]), args+argi+2, argcount-argi-2, &state->pen.fg, &state->fg_index);
3165b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_col(state, VTERM_ATTR_FOREGROUND, state->pen.fg);
3175b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3185b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3195b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 39: // Foreground colour default
32073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->fg_index = -1;
3215b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.fg = state->default_fg;
3225b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_col(state, VTERM_ATTR_FOREGROUND, state->pen.fg);
3235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 40: case 41: case 42: case 43:
3265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 44: case 45: case 46: case 47: // Background colour palette
32773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      value = CSI_ARG(args[argi]) - 40;
32873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->bg_index = value;
32973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      set_pen_col_ansi(state, VTERM_ATTR_BACKGROUND, value);
3305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 48: // Background colour alternative palette
33373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->bg_index = -1;
3345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      if(argcount - argi < 1)
3355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey        return;
3366d78f36633063dad0689ca42be1ad8d0313ebfabElliott Hughes      argi += 1 + lookup_colour(state, CSI_ARG(args[argi+1]), args+argi+2, argcount-argi-2, &state->pen.bg, &state->bg_index);
3375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_col(state, VTERM_ATTR_BACKGROUND, state->pen.bg);
3385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 49: // Default background
34173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->bg_index = -1;
3425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      state->pen.bg = state->default_bg;
3435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      setpenattr_col(state, VTERM_ATTR_BACKGROUND, state->pen.bg);
3445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 90: case 91: case 92: case 93:
3475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 94: case 95: case 96: case 97: // Foreground colour high-intensity palette
34873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      value = CSI_ARG(args[argi]) - 90 + 8;
34973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->fg_index = value;
35073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      set_pen_col_ansi(state, VTERM_ATTR_FOREGROUND, value);
3515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 100: case 101: case 102: case 103:
3545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    case 104: case 105: case 106: case 107: // Background colour high-intensity palette
35573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      value = CSI_ARG(args[argi]) - 100 + 8;
35673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      state->bg_index = value;
35773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey      set_pen_col_ansi(state, VTERM_ATTR_BACKGROUND, value);
3585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    default:
3615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      done = 0;
3625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      break;
3635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    }
3645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3655b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    if(!done)
3665b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey      fprintf(stderr, "libvterm: Unhandled CSI SGR %lu\n", arg);
3675b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3685b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    while(CSI_ARG_HAS_MORE(args[argi++]));
3695b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
3705b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
3715b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
3726d78f36633063dad0689ca42be1ad8d0313ebfabElliott HughesINTERNAL int vterm_state_getpen(VTermState *state, long args[], int argcount)
37373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey{
37473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  int argi = 0;
37573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
37673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.bold)
37773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 1;
37873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
37973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.italic)
38073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 3;
38173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
38273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.underline == 1)
38373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 4;
38473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
38573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.blink)
38673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 5;
38773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
38873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.reverse)
38973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 7;
39073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
39173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.strike)
39273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 9;
39373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
39473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.font)
39573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 10 + state->pen.font;
39673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
39773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->pen.underline == 2)
39873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 21;
39973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
40073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->fg_index >= 0 && state->fg_index < 8)
40173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 30 + state->fg_index;
40273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  else if(state->fg_index >= 8 && state->fg_index < 16)
40373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 90 + state->fg_index - 8;
40473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  else if(state->fg_index >= 16 && state->fg_index < 256) {
40573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = CSI_ARG_FLAG_MORE|38;
40673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = CSI_ARG_FLAG_MORE|5;
40773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = state->fg_index;
40873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  }
40973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
41073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  if(state->bg_index >= 0 && state->bg_index < 8)
41173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 40 + state->bg_index;
41273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  else if(state->bg_index >= 8 && state->bg_index < 16)
41373fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = 100 + state->bg_index - 8;
41473fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  else if(state->bg_index >= 16 && state->bg_index < 256) {
41573fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = CSI_ARG_FLAG_MORE|48;
41673fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = CSI_ARG_FLAG_MORE|5;
41773fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey    args[argi++] = state->bg_index;
41873fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  }
41973fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
42073fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey  return argi;
42173fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey}
42273fbfc38792bd96137d5b6ae3016dfc4d9805d46Jeff Sharkey
4235b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkeyint vterm_state_get_penattr(const VTermState *state, VTermAttr attr, VTermValue *val)
4245b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey{
4255b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  switch(attr) {
4265b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_BOLD:
4275b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->boolean = state->pen.bold;
4285b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4295b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4305b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_UNDERLINE:
4315b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->number = state->pen.underline;
4325b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4335b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4345b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_ITALIC:
4355b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->boolean = state->pen.italic;
4365b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4375b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4385b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_BLINK:
4395b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->boolean = state->pen.blink;
4405b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4415b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4425b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_REVERSE:
4435b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->boolean = state->pen.reverse;
4445b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4455b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4465b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_STRIKE:
4475b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->boolean = state->pen.strike;
4485b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4495b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4505b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_FONT:
4515b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->number = state->pen.font;
4525b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4535b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4545b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_FOREGROUND:
4555b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->color = state->pen.fg;
4565b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4575b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4585b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  case VTERM_ATTR_BACKGROUND:
4595b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    val->color = state->pen.bg;
4605b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey    return 1;
4615b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  }
4625b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey
4635b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey  return 0;
4645b78a3aa7741c3f44b676ccffa765cecee1cbd4cJeff Sharkey}
465