1 /*
2  * Copyright (C) 2014 haru <uobikiemukot at gmail dot com>
3  * Copyright (C) 2014 Hayaki Saito <user@zuse.jp>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "config.h"
20 #include <stdbool.h>
21 #include <stdint.h>
22 #if HAVE_WCHAR_H
23 # include <wchar.h>
24 #endif
25 
26 #if SELECTED_FONT == FONT_MILKJF
27 # include "glyph/milkjf.h"
28 #elif SELECTED_FONT == FONT_MPLUS
29 # include "glyph/mplus.h"
30 #else
31 # include "glyph/unifont.h"
32 #endif
33 #include "glyph/conf.h"
34 #include "malloc_stub.h"
35 #include "color.h"
36 
37 #define SIGWINCH 28
38 
39 /* misc */
40 enum {
41     DEBUG            = 0,      /* write dump of input to stdout, debug message to stderr */
42 };
43 
44 enum char_code {
45     /* 7 bit */
46     BEL = 0x07, BS  = 0x08, HT  = 0x09,
47     LF  = 0x0A, VT  = 0x0B, FF  = 0x0C,
48     CR  = 0x0D, ESC = 0x1B, DEL = 0x7F,
49     /* others */
50     SPACE     = 0x20,
51     BACKSLASH = 0x5C,
52 };
53 
54 enum misc {
55     BUFSIZE           = 1024,    /* read, esc, various buffer size */
56     BITS_PER_BYTE     = 8,
57     BYTES_PER_PIXEL   = 3,       /* pixel size of sixel bitmap data */
58     BITS_PER_SIXEL    = 6,       /* number of bits of a sixel */
59     ESCSEQ_SIZE       = 256,     /* limit size of terminal escape sequence */
60     MAX_ARGS          = 16,      /* max parameters of csi/osc sequence */
61     COLORS            = 256,     /* number of color */
62     UCS2_CHARS        = 0x10000, /* number of UCS2 glyph */
63     CTRL_CHARS        = 0x20,    /* number of ctrl_func */
64     ESC_CHARS         = 0x80,    /* number of esc_func */
65     DRCS_CHARSETS     = 63,      /* number of charset of DRCS (according to DRCSMMv1) */
66     GLYPH_PER_CHARSET = 96,      /* number of glyph of each DRCS charset */
67     DEFAULT_CHAR      = SPACE,   /* used for erase char */
68     BRIGHT_INC        = 8,       /* value used for brightening color */
69     OSC_GWREPT        = 8900,    /* OSC Ps: mode number of yaft GWREPT */
70 };
71 
72 enum char_attr {
73     ATTR_RESET     = 0,
74     ATTR_BOLD      = 1, /* brighten foreground */
75     ATTR_UNDERLINE = 4,
76     ATTR_BLINK     = 5, /* brighten background */
77     ATTR_REVERSE   = 7,
78 };
79 
80 static const uint8_t attr_mask[] = {
81     0x00, 0x01, 0x00, 0x00, /* 0:none      1:bold  2:none 3:none */
82     0x02, 0x04, 0x00, 0x08, /* 4:underline 5:blink 6:none 7:reverse */
83 };
84 
85 static const uint32_t bit_mask[] = {
86     0x00,
87     0x01,       0x03,       0x07,       0x0F,
88     0x1F,       0x3F,       0x7F,       0xFF,
89     0x1FF,      0x3FF,      0x7FF,      0xFFF,
90     0x1FFF,     0x3FFF,     0x7FFF,     0xFFFF,
91     0x1FFFF,    0x3FFFF,    0x7FFFF,    0xFFFFF,
92     0x1FFFFF,   0x3FFFFF,   0x7FFFFF,   0xFFFFFF,
93     0x1FFFFFF,  0x3FFFFFF,  0x7FFFFFF,  0xFFFFFFF,
94     0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
95 };
96 
97 enum term_mode {
98     MODE_RESET   = 0x00,
99     MODE_ORIGIN  = 0x01, /* origin mode: DECOM */
100     MODE_CURSOR  = 0x02, /* cursor visible: DECTCEM */
101     MODE_AMRIGHT = 0x04, /* auto wrap: DECAWM */
102 };
103 
104 enum esc_state {
105     STATE_RESET  = 0x00,
106     STATE_ESC    = 0x01, /* 0x1B, \033, ESC */
107     STATE_CSI    = 0x02, /* ESC [ */
108     STATE_OSC    = 0x04, /* ESC ] */
109     STATE_DCS    = 0x08, /* ESC P */
110 };
111 
112 enum glyph_width_t {
113     NEXT_TO_WIDE = 0,
114     HALF,
115     WIDE,
116 };
117 
118 struct margin { uint16_t top, bottom; };
119 struct point_t { uint16_t x, y; };
120 struct color_pair_t { uint8_t fg, bg; };
121 
122 struct cell_t {
123     const struct glyph_t *glyphp;   /* pointer to glyph */
124     struct color_pair_t color_pair; /* color (fg, bg) */
125     enum char_attr attribute;       /* bold, underscore, etc... */
126     enum glyph_width_t width;       /* wide char flag: WIDE, NEXT_TO_WIDE, HALF */
127     bool has_bitmap;
128     /* must be statically allocated for copy_cell() */
129     uint8_t bitmap[BYTES_PER_PIXEL * CELL_WIDTH * CELL_HEIGHT];
130 };
131 
132 struct esc_t {
133     char *buf;
134     char *bp;
135     int size;
136     enum esc_state state;
137 };
138 
139 struct charset_t {
140     uint32_t code; /* UCS4 code point: yaft only prints UCS2 and DRCSMMv1 */
141     int following_byte, count;
142     bool is_valid;
143 };
144 
145 struct state_t {   /* for save, restore state */
146     struct point_t cursor;
147     enum term_mode mode;
148     enum char_attr attribute;
149 };
150 
151 struct sixel_canvas_t {
152     uint8_t *bitmap;
153     struct point_t point;
154     int width, height;
155     int line_length;
156     uint8_t color_index;
157     uint32_t color_table[COLORS];
158 };
159 
160 typedef int (*wcwidth_func_t)(wchar_t);
161 
162 struct terminal {
163     int fd;                                      /* master fd */
164     int width, height;                           /* terminal size (pixel) */
165     int cols, lines;                             /* terminal size (cell) */
166     struct cell_t *cells;                        /* pointer to each cell: cells[cols + lines * num_of_cols] */
167     struct margin scroll;                        /* scroll margin */
168     struct point_t cursor;                       /* cursor pos (x, y) */
169     bool *line_dirty;                            /* dirty flag */
170     bool *tabstop;                               /* tabstop flag */
171     enum term_mode mode;                         /* for set/reset mode */
172     bool wrap_occured;                           /* whether auto wrap occured or not */
173     struct state_t state;                        /* for restore */
174     struct color_pair_t color_pair;              /* color (fg, bg) */
175     enum char_attr attribute;                    /* bold, underscore, etc... */
176     struct charset_t charset;                    /* store UTF-8 byte stream */
177     struct esc_t esc;                            /* store escape sequence */
178     uint32_t color_palette[COLORS];              /* 256 color palette */
179     const struct glyph_t *glyph_map[UCS2_CHARS]; /* array of pointer to glyphs[] */
180     struct glyph_t *drcs[DRCS_CHARSETS];         /* DRCS chars */
181     struct sixel_canvas_t sixel;
182     int default_fg;                              /* default foreground color */
183     int default_bg;                              /* default background color */
184     int cursor_color;                            /* corsor color */
185     int tabwidth;                                /* hardware tabstop */
186     wcwidth_func_t fn_wcwidth;                   /* wcwidth strategy */
187 };
188 
189 struct parm_t { /* for parse_arg() */
190     int argc;
191     char *argv[MAX_ARGS];
192 };
193 
194 /* emacs, -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
195 /* vim: set expandtab ts=4 : */
196 /* EOF */
197