#include "swap.h"
// Default color set
-// BOLD is more saturated, except for white and black themselves
+#define COLORS 256
#define DEFAULT_COLORS \
- {0, 0x00,0x00,0x00}, {0, 0x22,0x22,0x22}, \
- {0, 0xdd,0x00,0x00}, {0, 0xff,0x00,0x00}, \
- {0, 0x00,0xdd,0x00}, {0, 0x00,0xff,0x00}, \
- {0, 0xdd,0xdd,0x00}, {0, 0xff,0xff,0x00}, \
- {0, 0x00,0x00,0xdd}, {0, 0x00,0x00,0xff}, \
- {0, 0xdd,0x00,0xdd}, {0, 0xff,0x00,0xff}, \
- {0, 0x00,0xdd,0xdd}, {0, 0x00,0xff,0xff}, \
- {0, 0xff,0xff,0xff}, {0, 0xdd,0xdd,0xdd},
-
-static RGBColorType defaultColors[16] = {
+ {0, 0x00,0x00,0x00}, {0, 0xbb,0x00,0x00}, {0, 0x00,0xbb,0x00}, {0, 0xbb,0xbb,0x00}, \
+ {0, 0x00,0x00,0xbb}, {0, 0xbb,0x00,0xbb}, {0, 0x00,0xbb,0xbb}, {0, 0xbb,0xbb,0xbb}, \
+ {0, 0x55,0x55,0x55}, {0, 0xff,0x55,0x55}, {0, 0x55,0xff,0x55}, {0, 0xff,0xff,0x55}, \
+ {0, 0x55,0x55,0xff}, {0, 0xff,0x55,0xff}, {0, 0x55,0xff,0xff}, {0, 0xff,0xff,0xff}, \
+ {0, 0x00,0x00,0x00}, {0, 0x00,0x00,0x33}, {0, 0x00,0x00,0x66}, \
+ {0, 0x00,0x00,0x99}, {0, 0x00,0x00,0xcc}, {0, 0x00,0x00,0xff}, \
+ {0, 0x00,0x33,0x00}, {0, 0x00,0x33,0x33}, {0, 0x00,0x33,0x66}, \
+ {0, 0x00,0x33,0x99}, {0, 0x00,0x33,0xcc}, {0, 0x00,0x33,0xff}, \
+ {0, 0x00,0x66,0x00}, {0, 0x00,0x66,0x33}, {0, 0x00,0x66,0x66}, \
+ {0, 0x00,0x66,0x99}, {0, 0x00,0x66,0xcc}, {0, 0x00,0x66,0xff}, \
+ {0, 0x00,0x99,0x00}, {0, 0x00,0x99,0x33}, {0, 0x00,0x99,0x66}, \
+ {0, 0x00,0x99,0x99}, {0, 0x00,0x99,0xcc}, {0, 0x00,0x99,0xff}, \
+ {0, 0x00,0xcc,0x00}, {0, 0x00,0xcc,0x33}, {0, 0x00,0xcc,0x66}, \
+ {0, 0x00,0xcc,0x99}, {0, 0x00,0xcc,0xcc}, {0, 0x00,0xcc,0xff}, \
+ {0, 0x00,0xff,0x00}, {0, 0x00,0xff,0x33}, {0, 0x00,0xff,0x66}, \
+ {0, 0x00,0xff,0x99}, {0, 0x00,0xff,0xcc}, {0, 0x00,0xff,0xff}, \
+ {0, 0x33,0x00,0x00}, {0, 0x33,0x00,0x33}, {0, 0x33,0x00,0x66}, \
+ {0, 0x33,0x00,0x99}, {0, 0x33,0x00,0xcc}, {0, 0x33,0x00,0xff}, \
+ {0, 0x33,0x33,0x00}, {0, 0x33,0x33,0x33}, {0, 0x33,0x33,0x66}, \
+ {0, 0x33,0x33,0x99}, {0, 0x33,0x33,0xcc}, {0, 0x33,0x33,0xff}, \
+ {0, 0x33,0x66,0x00}, {0, 0x33,0x66,0x33}, {0, 0x33,0x66,0x66}, \
+ {0, 0x33,0x66,0x99}, {0, 0x33,0x66,0xcc}, {0, 0x33,0x66,0xff}, \
+ {0, 0x33,0x99,0x00}, {0, 0x33,0x99,0x33}, {0, 0x33,0x99,0x66}, \
+ {0, 0x33,0x99,0x99}, {0, 0x33,0x99,0xcc}, {0, 0x33,0x99,0xff}, \
+ {0, 0x33,0xcc,0x00}, {0, 0x33,0xcc,0x33}, {0, 0x33,0xcc,0x66}, \
+ {0, 0x33,0xcc,0x99}, {0, 0x33,0xcc,0xcc}, {0, 0x33,0xcc,0xff}, \
+ {0, 0x33,0xff,0x00}, {0, 0x33,0xff,0x33}, {0, 0x33,0xff,0x66}, \
+ {0, 0x33,0xff,0x99}, {0, 0x33,0xff,0xcc}, {0, 0x33,0xff,0xff}, \
+ {0, 0x66,0x00,0x00}, {0, 0x66,0x00,0x33}, {0, 0x66,0x00,0x66}, \
+ {0, 0x66,0x00,0x99}, {0, 0x66,0x00,0xcc}, {0, 0x66,0x00,0xff}, \
+ {0, 0x66,0x33,0x00}, {0, 0x66,0x33,0x33}, {0, 0x66,0x33,0x66}, \
+ {0, 0x66,0x33,0x99}, {0, 0x66,0x33,0xcc}, {0, 0x66,0x33,0xff}, \
+ {0, 0x66,0x66,0x00}, {0, 0x66,0x66,0x33}, {0, 0x66,0x66,0x66}, \
+ {0, 0x66,0x66,0x99}, {0, 0x66,0x66,0xcc}, {0, 0x66,0x66,0xff}, \
+ {0, 0x66,0x99,0x00}, {0, 0x66,0x99,0x33}, {0, 0x66,0x99,0x66}, \
+ {0, 0x66,0x99,0x99}, {0, 0x66,0x99,0xcc}, {0, 0x66,0x99,0xff}, \
+ {0, 0x66,0xcc,0x00}, {0, 0x66,0xcc,0x33}, {0, 0x66,0xcc,0x66}, \
+ {0, 0x66,0xcc,0x99}, {0, 0x66,0xcc,0xcc}, {0, 0x66,0xcc,0xff}, \
+ {0, 0x66,0xff,0x00}, {0, 0x66,0xff,0x33}, {0, 0x66,0xff,0x66}, \
+ {0, 0x66,0xff,0x99}, {0, 0x66,0xff,0xcc}, {0, 0x66,0xff,0xff}, \
+ {0, 0x99,0x00,0x00}, {0, 0x99,0x00,0x33}, {0, 0x99,0x00,0x66}, \
+ {0, 0x99,0x00,0x99}, {0, 0x99,0x00,0xcc}, {0, 0x99,0x00,0xff}, \
+ {0, 0x99,0x33,0x00}, {0, 0x99,0x33,0x33}, {0, 0x99,0x33,0x66}, \
+ {0, 0x99,0x33,0x99}, {0, 0x99,0x33,0xcc}, {0, 0x99,0x33,0xff}, \
+ {0, 0x99,0x66,0x00}, {0, 0x99,0x66,0x33}, {0, 0x99,0x66,0x66}, \
+ {0, 0x99,0x66,0x99}, {0, 0x99,0x66,0xcc}, {0, 0x99,0x66,0xff}, \
+ {0, 0x99,0x99,0x00}, {0, 0x99,0x99,0x33}, {0, 0x99,0x99,0x66}, \
+ {0, 0x99,0x99,0x99}, {0, 0x99,0x99,0xcc}, {0, 0x99,0x99,0xff}, \
+ {0, 0x99,0xcc,0x00}, {0, 0x99,0xcc,0x33}, {0, 0x99,0xcc,0x66}, \
+ {0, 0x99,0xcc,0x99}, {0, 0x99,0xcc,0xcc}, {0, 0x99,0xcc,0xff}, \
+ {0, 0x99,0xff,0x00}, {0, 0x99,0xff,0x33}, {0, 0x99,0xff,0x66}, \
+ {0, 0x99,0xff,0x99}, {0, 0x99,0xff,0xcc}, {0, 0x99,0xff,0xff}, \
+ {0, 0xcc,0x00,0x00}, {0, 0xcc,0x00,0x33}, {0, 0xcc,0x00,0x66}, \
+ {0, 0xcc,0x00,0x99}, {0, 0xcc,0x00,0xcc}, {0, 0xcc,0x00,0xff}, \
+ {0, 0xcc,0x33,0x00}, {0, 0xcc,0x33,0x33}, {0, 0xcc,0x33,0x66}, \
+ {0, 0xcc,0x33,0x99}, {0, 0xcc,0x33,0xcc}, {0, 0xcc,0x33,0xff}, \
+ {0, 0xcc,0x66,0x00}, {0, 0xcc,0x66,0x33}, {0, 0xcc,0x66,0x66}, \
+ {0, 0xcc,0x66,0x99}, {0, 0xcc,0x66,0xcc}, {0, 0xcc,0x66,0xff}, \
+ {0, 0xcc,0x99,0x00}, {0, 0xcc,0x99,0x33}, {0, 0xcc,0x99,0x66}, \
+ {0, 0xcc,0x99,0x99}, {0, 0xcc,0x99,0xcc}, {0, 0xcc,0x99,0xff}, \
+ {0, 0xcc,0xcc,0x00}, {0, 0xcc,0xcc,0x33}, {0, 0xcc,0xcc,0x66}, \
+ {0, 0xcc,0xcc,0x99}, {0, 0xcc,0xcc,0xcc}, {0, 0xcc,0xcc,0xff}, \
+ {0, 0xcc,0xff,0x00}, {0, 0xcc,0xff,0x33}, {0, 0xcc,0xff,0x66}, \
+ {0, 0xcc,0xff,0x99}, {0, 0xcc,0xff,0xcc}, {0, 0xcc,0xff,0xff}, \
+ {0, 0xff,0x00,0x00}, {0, 0xff,0x00,0x33}, {0, 0xff,0x00,0x66}, \
+ {0, 0xff,0x00,0x99}, {0, 0xff,0x00,0xcc}, {0, 0xff,0x00,0xff}, \
+ {0, 0xff,0x33,0x00}, {0, 0xff,0x33,0x33}, {0, 0xff,0x33,0x66}, \
+ {0, 0xff,0x33,0x99}, {0, 0xff,0x33,0xcc}, {0, 0xff,0x33,0xff}, \
+ {0, 0xff,0x66,0x00}, {0, 0xff,0x66,0x33}, {0, 0xff,0x66,0x66}, \
+ {0, 0xff,0x66,0x99}, {0, 0xff,0x66,0xcc}, {0, 0xff,0x66,0xff}, \
+ {0, 0xff,0x99,0x00}, {0, 0xff,0x99,0x33}, {0, 0xff,0x99,0x66}, \
+ {0, 0xff,0x99,0x99}, {0, 0xff,0x99,0xcc}, {0, 0xff,0x99,0xff}, \
+ {0, 0xff,0xcc,0x00}, {0, 0xff,0xcc,0x33}, {0, 0xff,0xcc,0x66}, \
+ {0, 0xff,0xcc,0x99}, {0, 0xff,0xcc,0xcc}, {0, 0xff,0xcc,0xff}, \
+ {0, 0xff,0xff,0x00}, {0, 0xff,0xff,0x33}, {0, 0xff,0xff,0x66}, \
+ {0, 0xff,0xff,0x99}, {0, 0xff,0xff,0xcc}, {0, 0xff,0xff,0xff}, \
+ {0, 0x00,0x00,0x00}, {0, 0x11,0x11,0x11}, {0, 0x22,0x22,0x22}, {0, 0x33,0x33,0x33}, \
+ {0, 0x44,0x44,0x44}, {0, 0x55,0x55,0x55}, {0, 0x66,0x66,0x66}, {0, 0x77,0x77,0x77}, \
+ {0, 0x88,0x88,0x88}, {0, 0x99,0x99,0x99}, {0, 0xaa,0xaa,0xaa}, {0, 0xbb,0xbb,0xbb}, \
+ {0, 0xcc,0xcc,0xcc}, {0, 0xdd,0xdd,0xdd}, {0, 0xee,0xee,0xee}, {0, 0xff,0xff,0xff},
+
+static RGBColorType defaultColors[COLORS] = {
DEFAULT_COLORS
};
-static RGBColorType colors[16] = {
+static RGBColorType colors[COLORS] = {
DEFAULT_COLORS
};
}
}
-
int char_width(Context ctx, unsigned int uc)
{
// palm: fixme
void do_text(Context ctx, int x, int y, char *text, int len,
- unsigned long attr, unsigned long lattr)
+ struct attr_tag attrs, unsigned long lattr)
{
#define LEFT(rr) ((rr).topLeft.x)
#define TOP(rr) ((rr).topLeft.y)
RectangleType r, big, fill;
RectangleType closeBox;
int closeBoxInvalid = 0;
+ unsigned long attr = attrs.attr;
+ unsigned long colors = attrs.color;
closeBox.topLeft.x = RIGHT(dd->gadgetBounds) - dd->closeBoxSize;
closeBox.topLeft.y = TOP(dd->gadgetBounds);
r.extent.x = len * font_width;
r.extent.y = font_height;
- fg_color = (attr & ATTR_FGMASK) >> ATTR_FGSHIFT;
- bg_color = (attr & ATTR_BGMASK) >> ATTR_BGSHIFT;
+ fg_color = (colors & ATTR_FGMASK) >> ATTR_FGSHIFT;
+ bg_color = (colors & ATTR_BGMASK) >> ATTR_BGSHIFT;
// handle VT100 linedraw chars
// 0x5f maps to space
if (fg_color == (ATTR_DEFFG >> ATTR_FGSHIFT)) fg_color = DefaultForeColor;
if (bg_color == (ATTR_DEFBG >> ATTR_BGSHIFT)) bg_color = DefaultBackColor;
- // translate into indexes into colors[]
- fg_color *= 2;
- bg_color *= 2;
-
if (attr & ATTR_REVERSE) {
int temp = fg_color;
fg_color = bg_color;
}
// fixme can do real bold and underline with bigger fonts
- if ((attr & ATTR_BOLD) || (attr & ATTR_UNDER)) {
- fg_color++;
+ if ((attr & ATTR_BOLD) && (fg_color < 8)) {// || (attr & ATTR_UNDER)) {
+ fg_color += 8;
}
// fixme allow optional real blink
- if (attr & ATTR_BLINK) {
- bg_color++;
- }
+/* if (attr & ATTR_BLINK) { */
+/* bg_color++; */
+/* } */
set_palm_color(fg_color, bg_color);
WinDrawChars(text, len, r.topLeft.x, r.topLeft.y);
+
if (SectRect(r, closeBox)) closeBoxInvalid = 1;
// If the drawn rect extends to any edge of the text area, fill the
void do_cursor(Context ctx, int x, int y, char *text, int len,
- unsigned long attr, unsigned long lattr)
+ struct attr_tag attr, unsigned long lattr)
{
do_text(ctx, x, y, text, len, attr, lattr);
}
* ATTR_INVALID is an illegal colour combination.
*/
+struct attr_tag {
+ unsigned long attr; /* Character and basic attributes */
+ unsigned long color; /* Color information */
+};
+
+/* Combines char/charset/attr and color attributes into the struct */
+#define ATTR_COMBINE(x,y) ((struct attr_tag){ x, y })
+#define ATTR_WRAP(x) ((struct attr_tag){ x, 0 })
+
+/* Stores line count and line attributes in attr_tag */
+/* Yes, this is a hack */
+#define LINE_COLS(x) (((x)[0]).color)
+#define LINE_ATTRS(x) (((x)[0]).attr)
+
#define TATTR_ACTCURS 0x4UL /* active cursor (block) */
#define TATTR_PASCURS 0x2UL /* passive cursor (box) */
#define TATTR_RIGHTCURS 0x1UL /* cursor-on-RHS */
-#define LATTR_NORM 0x00000000UL
-#define LATTR_WIDE 0x01000000UL
-#define LATTR_TOP 0x02000000UL
-#define LATTR_BOT 0x03000000UL
-#define LATTR_MODE 0x03000000UL
-#define LATTR_WRAPPED 0x10000000UL
+#define LATTR_NORM 0x00000000UL
+#define LATTR_WIDE 0x01000000UL
+#define LATTR_TOP 0x02000000UL
+#define LATTR_BOT 0x03000000UL
+#define LATTR_MODE 0x03000000UL
+#define LATTR_WRAPPED 0x10000000UL
#define LATTR_WRAPPED2 0x20000000UL
-#define ATTR_INVALID 0x03FF0000UL
-
/* Like Linux use the F000 page for direct to font. */
#define ATTR_OEMCP 0x0000F000UL /* OEM Codepage DTF */
#define ATTR_ACP 0x0000F100UL /* Ansi Codepage DTF */
#define ATTR_UNDER 0x08000000UL
#define ATTR_REVERSE 0x10000000UL
#define ATTR_BLINK 0x20000000UL
-#define ATTR_FGMASK 0x001F0000UL
-#define ATTR_BGMASK 0x03E00000UL
-#define ATTR_COLOURS 0x03FF0000UL
-#define ATTR_FGSHIFT 16
-#define ATTR_BGSHIFT 21
-
-#define ATTR_DEFAULT 0x01280000UL /* bg 9, fg 8 */
-#define ATTR_DEFFG 0x00080000UL
-#define ATTR_DEFBG 0x01200000UL
-#define ERASE_CHAR (ATTR_DEFAULT | ATTR_ASCII | ' ')
-#define ATTR_MASK 0xFFFFFF00UL
+#define ATTR_CLEAR 0x00000000UL
+
+#define ATTR_FGMASK 0x000001FFUL
+#define ATTR_BGMASK 0x0003FE00UL
+#define ATTR_COLOURS 0x0003FFFFUL
+#define ATTR_FGSHIFT 0
+#define ATTR_BGSHIFT 9
+
+#define ATTR_DEFFG (256 << ATTR_FGSHIFT)
+#define ATTR_DEFBG (258 << ATTR_BGSHIFT)
+#define ATTR_DEFCOLORS (ATTR_DEFFG | ATTR_DEFBG)
+
+#define ATTR_INVALID ATTR_COMBINE( ATTR_CLEAR, ATTR_COLOURS )
+#define ATTR_INVALIDATE(x) ((x).color |= ATTR_COLOURS )
+#define ATTR_DEFAULT ATTR_COMBINE( ATTR_CLEAR, ATTR_DEFCOLORS )
+
+#define ERASE_CHAR ATTR_COMBINE( ATTR_CLEAR | ATTR_ASCII | ' ', ATTR_DEFCOLORS )
+#define ATTR_MASK 0xFC00FF00UL
#define CHAR_MASK 0x000000FFUL
#define ATTR_CUR_AND (~(ATTR_BOLD|ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS))
#define ATTR_CUR_XOR 0x016A0000UL
+#define ATTR_CHAR(x) ATTR_COMBINE((x).attr & CHAR_MASK, 0)
+#define ATTR_CHARALL(x) ATTR_COMBINE((x).attr & (CHAR_MASK | CSET_MASK), 0)
+#define ATTR_ATTRS(x) ATTR_COMBINE((x).attr & ATTR_MASK, (x).color)
+
+#define ATTR_AND(x,y) ATTR_COMBINE((x).attr & (y).attr, (x).color & (y).color)
+#define ATTR_OR(x,y) ATTR_COMBINE((x).attr | (y).attr, (x).color | (y).color)
+#define ATTR_XOR(x,y) ATTR_COMBINE((x).attr ^ (y).attr, (x).color ^ (y).color)
+
+#define ATTR_ZERO(x) (!((x).attr | (x).color))
+#define ATTR_EQUAL(x,y) ATTR_ZERO(ATTR_XOR(x,y))
+
+#define ATTR_ON(x,y) (ATTR_COMBINE((x).attr | (y), (x).color))
+#define ATTR_OFF(x,y) (ATTR_COMBINE((x).attr & ~(y), (x).color))
+#define ATTR_STATE(x,y) ((x).attr & (y))
+
struct sesslist {
int nsessions;
char **sessions;
* Exports from window.c.
*/
void request_resize(void *frontend, int, int);
-void do_text(Context, int, int, char *, int, unsigned long, unsigned long);
-void do_cursor(Context, int, int, char *, int, unsigned long, unsigned long);
+void do_text(Context, int, int, char *, int, struct attr_tag, unsigned long);
+void do_cursor(Context, int, int, char *, int, struct attr_tag, unsigned long);
int char_width(Context ctx, unsigned int uc);
#ifdef OPTIMISE_SCROLL
void do_scroll(Context, int, int, int);
* then we must look one space further to the left.
*/
#define UCSGET(a, x) \
- ( (x)>0 && ((a)[(x)] & (CHAR_MASK | CSET_MASK)) == UCSWIDE ? \
+ ( (x)>0 && ((a)[(x)].attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE ? \
(a)[(x)-1] : (a)[(x)] )
/*
* Internal prototypes.
*/
-static unsigned long *resizeline(unsigned long *, int);
+static struct attr_tag *resizeline(struct attr_tag *, int);
static int sblines(Terminal *term);
-static unsigned long *lineptr(Terminal *, int, int);
+static struct attr_tag *lineptr(Terminal *, int, int);
static void power_on(Terminal *term);
static int find_last_nonempty_line(Terminal * term, tree234 * screen);
static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos);
static void term_print_finish(Terminal *term);
static void do_paint(Terminal *term, Context ctx, int may_optimise);
static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel);
-static int wordtype(Terminal *term, uint32_t uc) /* NOT*/;
+static int wordtype(Terminal *term, struct attr_tag uc) /* NOT*/;
static pos sel_spread_half(Terminal *term, pos p, int dir);
static void sel_spread(Terminal *term);
static void deselect(Terminal *term);
/*
* Resize a line to make it `cols' columns wide.
*/
-static unsigned long *resizeline(unsigned long *line, int cols)
+static struct attr_tag *resizeline(struct attr_tag *line, int cols)
{
int i, oldlen;
- unsigned long lineattrs;
+ unsigned long lineattrs;
- if (line[0] != (unsigned long)cols) {
+ /*
+ * This is a bit of a hack here. We're going to use the attrs
+ * field to store line length. Since everthing used to be
+ * unsigned longs, this used to be trivial.
+ * Old structure: len[ul] {chars...}[ul+] lattrs[ul]
+ * New structure: len stored in color field of first attr_tag,
+ line attrs in attr field of first attr_tag,
+ attr_tags for each charater from there
+ */
+ if (LINE_COLS(line) != (unsigned long)cols) {
/*
* This line is the wrong length, which probably means it
* hasn't been accessed since a resize. Resize it now.
*/
- oldlen = line[0];
- lineattrs = line[oldlen + 1];
- line = sresize(line, 2 + cols, TTYPE);
- line[0] = cols;
+ oldlen = LINE_COLS(line);
+ lineattrs = LINE_ATTRS(line);
+ line = sresize(line, 1 + cols, TTYPE);
+ LINE_COLS(line) = (unsigned long)cols;
for (i = oldlen; i < cols; i++)
line[i + 1] = ERASE_CHAR;
- line[cols + 1] = lineattrs & LATTR_MODE;
+ LINE_ATTRS(line) = lineattrs & LATTR_MODE;
}
return line;
* whether the y coordinate is non-negative or negative
* (respectively).
*/
-static unsigned long *lineptr(Terminal *term, int y, int lineno)
+static struct attr_tag *lineptr(Terminal *term, int y, int lineno)
{
- unsigned long *line, *newline;
+ struct attr_tag *line, *newline;
tree234 *whichtree;
int treeindex;
term->alt_utf = term->utf = term->save_utf = 0;
term->utf_state = 0;
term->alt_sco_acs = term->sco_acs = term->save_sco_acs = 0;
- term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = ATTR_ASCII;
+ term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = ATTR_WRAP(ATTR_ASCII);
term->rvideo = 0;
term->in_vbell = FALSE;
term->cursor_on = 1;
term_update(term);
}
+static void set_erase_char(Terminal *term)
+{
+ term->erase_char = ERASE_CHAR;
+ if (term->use_bce)
+ term->erase_char = ATTR_OR(ERASE_CHAR, term->curr_attr);
+}
+
/*
* When the user reconfigures us, we need to check the forbidden-
* alternate-screen config option, disable raw mouse mode if the
term->alt_om = term->dec_om = term->cfg.dec_om;
if (reset_bce) {
term->use_bce = term->cfg.bce;
- if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
- else
- term->erase_char = ERASE_CHAR;
+ set_erase_char(term);
}
if (reset_blink)
term->blink_is_real = term->cfg.blinktext;
set_raw_mouse_mode(term->frontend, 0);
}
if (term->cfg.no_remote_charset) {
- term->cset_attr[0] = term->cset_attr[1] = ATTR_ASCII;
+ term->cset_attr[0] = term->cset_attr[1] = ATTR_WRAP(ATTR_ASCII);
term->sco_acs = term->alt_sco_acs = 0;
term->utf = 0;
}
*/
void term_clrsb(Terminal *term)
{
- unsigned long *line;
+ struct attr_tag *line;
term->disptop = 0;
while ((line = delpos234(term->scrollback, 0)) != NULL) {
sfree(line);
term->nbeeps = 0;
term->lastbeep = FALSE;
term->beep_overloaded = FALSE;
- term->attr_mask = 0xffffffff;
+ term->attr_mask = ATTR_COMBINE(ATTR_MASK|CHAR_MASK, ATTR_COLOURS);
term->resize_fn = NULL;
term->resize_ctx = NULL;
term->in_term_out = FALSE;
void term_free(Terminal *term)
{
- unsigned long *line;
+ struct attr_tag *line;
while ((line = delpos234(term->scrollback, 0)) != NULL)
sfree(line);
void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
{
tree234 *newalt;
- unsigned long *newdisp, *line;
+ struct attr_tag *newdisp, *line;
int i, j;
int sblen;
int save_alt_which = term->alt_which;
term->savecurs.y += 1;
} else {
/* Add a new blank line at the bottom of the screen. */
- line = snewn(newcols + 2, TTYPE);
- line[0] = newcols;
+ line = snewn(newcols + 1, TTYPE);
+ LINE_COLS(line) = newcols;
+ LINE_ATTRS(line) = LATTR_NORM;
for (j = 0; j < newcols; j++)
line[j + 1] = ERASE_CHAR;
- line[newcols + 1] = LATTR_NORM;
addpos234(term->screen, line, count234(term->screen));
}
term->rows += 1;
/* Make a new alternate screen. */
newalt = newtree234(NULL);
for (i = 0; i < newrows; i++) {
- line = snewn(newcols + 2, TTYPE);
- line[0] = newcols;
+ line = snewn(newcols + 1, TTYPE);
+ LINE_COLS(line) = newcols;
+ LINE_ATTRS(line) = LATTR_NORM;
for (j = 0; j < newcols; j++)
line[j + 1] = term->erase_char;
- line[newcols + 1] = LATTR_NORM;
addpos234(newalt, line, i);
}
if (term->alt_screen) {
{
int i;
for (i = count234(screen) - 1; i >= 0; i--) {
- unsigned long *line = index234(screen, i);
+ struct attr_tag *line = index234(screen, i);
int j;
- int cols = line[0];
+ int cols = LINE_COLS(line);
for (j = 0; j < cols; j++) {
- if (line[j + 1] != term->erase_char) break;
+ if (!ATTR_EQUAL(line[j + 1], term->erase_char)) break;
}
if (j != cols) break;
}
*/
static void scroll(Terminal *term, int topline, int botline, int lines, int sb)
{
- unsigned long *line, *line2;
+ struct attr_tag *line, *line2;
int i, seltop, olddisptop, shift;
if (topline != 0 || term->alt_which != 0)
line = resizeline(line, term->cols);
for (i = 0; i < term->cols; i++)
line[i + 1] = term->erase_char;
- line[term->cols + 1] = 0;
+ LINE_ATTRS(line) = 0;
addpos234(term->screen, line, topline);
if (term->selstart.y >= topline && term->selstart.y <= botline) {
if (sblen == term->savelines) {
sblen--, line2 = delpos234(term->scrollback, 0);
} else {
- line2 = snewn(term->cols + 2, TTYPE);
- line2[0] = term->cols;
+ line2 = snewn(term->cols + 1, TTYPE);
+ LINE_COLS(line2) = term->cols;
term->tempsblines += 1;
}
addpos234(term->scrollback, line, sblen);
line = resizeline(line, term->cols);
for (i = 0; i < term->cols; i++)
line[i + 1] = term->erase_char;
- line[term->cols + 1] = LATTR_NORM;
+ LINE_ATTRS(line) = LATTR_NORM;
addpos234(term->screen, line, botline);
/*
*/
static void scroll_display(Terminal *term, int topline, int botline, int lines)
{
- unsigned long *start, *end;
+ struct attr_tag *start, *end;
int distance, size, i;
start = term->disptext + topline * (term->cols + 1);
term->dispcurs <= start + distance + size)
term->dispcurs -= distance;
for (i = 0; i < distance; i++)
- (start + size)[i] |= ATTR_INVALID;
+ ATTR_INVALIDATE((start + size)[i]);
} else {
memmove(start + distance, start, size * TSIZE);
if (term->dispcurs >= start && term->dispcurs <= start + size)
term->dispcurs += distance;
for (i = 0; i < distance; i++)
- start[i] |= ATTR_INVALID;
+ ATTR_INVALIDATE(start[i]);
}
save_scroll(term, topline, botline, lines);
}
term->sco_acs = term->save_sco_acs;
fix_cpos;
if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
+ set_erase_char(term);
}
}
*/
static void check_boundary(Terminal *term, int x, int y)
{
- unsigned long *ldata;
+ struct attr_tag *ldata;
/* Validate input coordinates, just in case. */
if (x == 0 || x > term->cols)
ldata = lineptr(y);
if (x == term->cols) {
- ldata[x] &= ~LATTR_WRAPPED2;
+ LINE_ATTRS(ldata-1) &= ~LATTR_WRAPPED2;
} else {
- if ((ldata[x] & (CHAR_MASK | CSET_MASK)) == UCSWIDE) {
- ldata[x-1] = ldata[x] =
- (ldata[x-1] &~ (CHAR_MASK | CSET_MASK)) | ATTR_ASCII | ' ';
+ if ((ldata[x].attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE) {
+ ldata[x-1].attr = ldata[x].attr =
+ (ldata[x-1].attr &~ (CHAR_MASK | CSET_MASK)) | ATTR_ASCII | ' ';
}
}
}
scroll(term, 0, scrolllines - 1, scrolllines, TRUE);
fix_cpos;
} else {
- unsigned long *ldata = lineptr(start.y);
+ struct attr_tag *ldata = lineptr(start.y);
while (poslt(start, end)) {
if (start.x == term->cols) {
if (!erase_lattr)
- ldata[start.x] &= ~(LATTR_WRAPPED | LATTR_WRAPPED2);
+ LINE_ATTRS(ldata-1) &= ~(LATTR_WRAPPED | LATTR_WRAPPED2);
else
- ldata[start.x] = LATTR_NORM;
+ LINE_ATTRS(ldata-1) = LATTR_NORM;
} else {
ldata[start.x] = term->erase_char;
}
int dir = (n < 0 ? -1 : +1);
int m;
pos cursplus;
- unsigned long *ldata;
+ struct attr_tag *ldata;
n = (n < 0 ? -n : n);
if (n > term->cols - term->curs.x)
if (term->sco_acs == 2) c |= 0x80;
c |= ATTR_SCOACS;
} else {
- switch (term->cset_attr[term->cset]) {
+ switch (term->cset_attr[term->cset].attr) {
/*
* Linedraw characters are different from 'ESC ( B'
* only for a small range. For ones outside that
term->curs.x--;
term->wrapnext = FALSE;
fix_cpos;
- if (!term->cfg.no_dbackspace) /* destructive bksp might be disabled */
- *term->cpos = (' ' | term->curr_attr | ATTR_ASCII);
+ if (!term->cfg.no_dbackspace) /* destructive bksp might be disabled */
+ *term->cpos = ATTR_OR(term->curr_attr, ATTR_WRAP( ATTR_ASCII | ' '));
} else
/* Or normal C0 controls. */
if ((c & 0xffffffe0L) == 0 && term->termstate < DO_CTRLS) {
case '\t': /* HT: Character tabulation */
{
pos old_curs = term->curs;
- unsigned long *ldata = lineptr(term->curs.y);
+ struct attr_tag *ldata = lineptr(term->curs.y);
do {
term->curs.x++;
} while (term->curs.x < term->cols - 1 &&
!term->tabs[term->curs.x]);
- if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM) {
+ if ((LINE_ATTRS(ldata-1) & LATTR_MODE) != LATTR_NORM) {
if (term->curs.x >= term->cols / 2)
term->curs.x = term->cols / 2 - 1;
} else {
/* Only graphic characters get this far;
* ctrls are stripped above */
if (term->wrapnext && term->wrap) {
- term->cpos[1] |= LATTR_WRAPPED;
+ LINE_ATTRS(lineptr(term->curs.y)-1) |= LATTR_WRAPPED;
if (term->curs.y == term->marg_b)
scroll(term, term->marg_t, term->marg_b, 1, TRUE);
else if (term->curs.y < term->rows - 1)
check_boundary(term, term->curs.x, term->curs.y);
check_boundary(term, term->curs.x+2, term->curs.y);
if (term->curs.x == term->cols-1) {
- *term->cpos++ = ATTR_ASCII | ' ' | term->curr_attr;
- *term->cpos |= LATTR_WRAPPED | LATTR_WRAPPED2;
+ *term->cpos = ATTR_OR(term->curr_attr, ATTR_WRAP(ATTR_ASCII | ' '));
+ LINE_ATTRS(lineptr(term->curs.y)-1) |= LATTR_WRAPPED | LATTR_WRAPPED2;
if (term->curs.y == term->marg_b)
scroll(term, term->marg_t, term->marg_b,
1, TRUE);
check_boundary(term, term->curs.x, term->curs.y);
check_boundary(term, term->curs.x+2, term->curs.y);
}
- *term->cpos++ = c | term->curr_attr;
- *term->cpos++ = UCSWIDE | term->curr_attr;
+ *term->cpos++ = ATTR_OR(ATTR_WRAP(c), term->curr_attr);
+ *term->cpos++ = ATTR_OR(ATTR_WRAP(UCSWIDE), term->curr_attr);
term->curs.x++;
break;
case 1:
check_boundary(term, term->curs.x, term->curs.y);
check_boundary(term, term->curs.x+1, term->curs.y);
- *term->cpos++ = c | term->curr_attr;
+ *term->cpos++ = ATTR_OR(ATTR_WRAP(c), term->curr_attr);
break;
default:
continue;
term->curs.x--;
term->wrapnext = TRUE;
if (term->wrap && term->vt52_mode) {
- term->cpos[1] |= LATTR_WRAPPED;
+ LINE_ATTRS(lineptr(term->curs.y)-1) |= LATTR_WRAPPED;
if (term->curs.y == term->marg_b)
scroll(term, term->marg_t, term->marg_b, 1, TRUE);
else if (term->curs.y < term->rows - 1)
case ANSI('8', '#'): /* DECALN: fills screen with Es :-) */
compatibility(VT100);
{
- unsigned long *ldata;
+ struct attr_tag *ldata;
int i, j;
pos scrtop, scrbot;
for (i = 0; i < term->rows; i++) {
ldata = lineptr(i);
- for (j = 0; j < term->cols; j++)
- ldata[j] = ATTR_DEFAULT | 'E';
- ldata[term->cols] = 0;
+ for (j = 0; j < term->cols; j++) {
+ ldata[j] = ATTR_OR(ATTR_DEFAULT, ATTR_WRAP('E'));
+ }
+ LINE_ATTRS(ldata-1)= 0;
}
term->disptop = 0;
term->seen_disp_event = TRUE;
compatibility(VT100);
{
unsigned long nlattr;
- unsigned long *ldata;
+ struct attr_tag *ldata;
switch (ANSI(c, term->esc_query)) {
case ANSI('3', '#'): /* DECDHL: 2*height, top */
nlattr = LATTR_TOP;
break;
}
ldata = lineptr(term->curs.y);
- ldata[term->cols] &= ~LATTR_MODE;
- ldata[term->cols] |= nlattr;
+ LINE_ATTRS(ldata-1) &= ~LATTR_MODE;
+ LINE_ATTRS(ldata-1) |= nlattr;
}
break;
/* GZD4: G0 designate 94-set */
case ANSI('A', '('):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[0] = ATTR_GBCHR;
+ term->cset_attr[0] = ATTR_WRAP(ATTR_GBCHR);
break;
case ANSI('B', '('):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[0] = ATTR_ASCII;
+ term->cset_attr[0] = ATTR_WRAP(ATTR_ASCII);
break;
case ANSI('0', '('):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[0] = ATTR_LINEDRW;
+ term->cset_attr[0] = ATTR_WRAP(ATTR_LINEDRW);
break;
case ANSI('U', '('):
compatibility(OTHER);
if (!term->cfg.no_remote_charset)
- term->cset_attr[0] = ATTR_SCOACS;
+ term->cset_attr[0] = ATTR_WRAP(ATTR_SCOACS);
break;
/* G1D4: G1-designate 94-set */
case ANSI('A', ')'):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[1] = ATTR_GBCHR;
+ term->cset_attr[1] = ATTR_WRAP(ATTR_GBCHR);
break;
case ANSI('B', ')'):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[1] = ATTR_ASCII;
+ term->cset_attr[1] = ATTR_WRAP(ATTR_ASCII);
break;
case ANSI('0', ')'):
compatibility(VT100);
if (!term->cfg.no_remote_charset)
- term->cset_attr[1] = ATTR_LINEDRW;
+ term->cset_attr[1] = ATTR_WRAP(ATTR_LINEDRW);
break;
case ANSI('U', ')'):
compatibility(OTHER);
if (!term->cfg.no_remote_charset)
- term->cset_attr[1] = ATTR_SCOACS;
+ term->cset_attr[1] = ATTR_WRAP(ATTR_SCOACS);
break;
/* DOCS: Designate other coding system */
case ANSI('8', '%'): /* Old Linux code */
break;
case 1: /* enable bold */
compatibility(VT100AVO);
- term->curr_attr |= ATTR_BOLD;
+ term->curr_attr.attr |= ATTR_BOLD;
break;
case 21: /* (enable double underline) */
compatibility(OTHER);
case 4: /* enable underline */
compatibility(VT100AVO);
- term->curr_attr |= ATTR_UNDER;
+ term->curr_attr.attr |= ATTR_UNDER;
break;
case 5: /* enable blink */
compatibility(VT100AVO);
- term->curr_attr |= ATTR_BLINK;
+ term->curr_attr.attr |= ATTR_BLINK;
break;
case 6: /* SCO light bkgrd */
compatibility(SCOANSI);
term->blink_is_real = FALSE;
- term->curr_attr |= ATTR_BLINK;
+ term->curr_attr.attr |= ATTR_BLINK;
break;
case 7: /* enable reverse video */
- term->curr_attr |= ATTR_REVERSE;
+ term->curr_attr.attr |= ATTR_REVERSE;
break;
case 10: /* SCO acs off */
compatibility(SCOANSI);
term->sco_acs = 2; break;
case 22: /* disable bold */
compatibility2(OTHER, VT220);
- term->curr_attr &= ~ATTR_BOLD;
+ term->curr_attr.attr &= ~ATTR_BOLD;
break;
case 24: /* disable underline */
compatibility2(OTHER, VT220);
- term->curr_attr &= ~ATTR_UNDER;
+ term->curr_attr.attr &= ~ATTR_UNDER;
break;
case 25: /* disable blink */
compatibility2(OTHER, VT220);
- term->curr_attr &= ~ATTR_BLINK;
+ term->curr_attr.attr &= ~ATTR_BLINK;
break;
case 27: /* disable reverse video */
compatibility2(OTHER, VT220);
- term->curr_attr &= ~ATTR_REVERSE;
+ term->curr_attr.attr &= ~ATTR_REVERSE;
break;
case 30:
case 31:
case 36:
case 37:
/* foreground */
- term->curr_attr &= ~ATTR_FGMASK;
- term->curr_attr |=
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.color |=
(uint32_t)(term->esc_args[i] - 30) << ATTR_FGSHIFT;
break;
case 90:
case 96:
case 97:
/* xterm-style bright foreground */
- term->curr_attr &= ~ATTR_FGMASK;
- term->curr_attr |=
- ((uint32_t)(term->esc_args[i] - 90 + 16) << ATTR_FGSHIFT);
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.color |=
+ ((uint32_t)(term->esc_args[i] - 90 + 8) << ATTR_FGSHIFT);
break;
case 39: /* default-foreground */
- term->curr_attr &= ~ATTR_FGMASK;
- term->curr_attr |= ATTR_DEFFG;
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.color |= ATTR_DEFFG;
break;
case 40:
case 41:
case 46:
case 47:
/* background */
- term->curr_attr &= ~ATTR_BGMASK;
- term->curr_attr |=
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.color |=
(uint32_t)(term->esc_args[i] - 40) << ATTR_BGSHIFT;
break;
case 100:
case 106:
case 107:
/* xterm-style bright background */
- term->curr_attr &= ~ATTR_BGMASK;
- term->curr_attr |=
- ((uint32_t)(term->esc_args[i] - 100 + 16) << ATTR_BGSHIFT);
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.color |=
+ ((uint32_t)(term->esc_args[i] - 100 + 8) << ATTR_BGSHIFT);
break;
case 49: /* default-background */
- term->curr_attr &= ~ATTR_BGMASK;
- term->curr_attr |= ATTR_DEFBG;
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.color |= ATTR_DEFBG;
break;
+ case 38: /* xterm 256-colour mode */
+ if (i+2 < term->esc_nargs &&
+ term->esc_args[i+1] == 5) {
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.color |=
+ ((term->esc_args[i+2] & 0xFF)
+ << ATTR_FGSHIFT);
+ i += 2;
+ }
+ break;
+ case 48: /* xterm 256-colour mode */
+ if (i+2 < term->esc_nargs &&
+ term->esc_args[i+1] == 5) {
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.color |=
+ ((term->esc_args[i+2] & 0xFF)
+ << ATTR_BGSHIFT);
+ i += 2;
+ }
}
}
if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK |
- ATTR_BGMASK)));
+ set_erase_char(term);
}
break;
case 's': /* save cursor */
{
int n = def(term->esc_args[0], 1);
pos cursplus;
- unsigned long *p = term->cpos;
+ struct attr_tag *p = term->cpos;
if (n > term->cols - term->curs.x)
n = term->cols - term->curs.x;
cursplus = term->curs;
compatibility(SCOANSI);
term->blink_is_real = FALSE;
if (term->esc_args[0]>=1)
- term->curr_attr |= ATTR_BLINK;
+ term->curr_attr.attr |= ATTR_BLINK;
else
- term->curr_attr &= ~ATTR_BLINK;
+ term->curr_attr.attr &= ~ATTR_BLINK;
break;
case ANSI('E', '='):
compatibility(SCOANSI);
(sco2ansicolour[term->esc_args[0] & 0x7] |
(uint32_t)((term->esc_args[0] & 0x8) << 1)) <<
ATTR_FGSHIFT;
- term->curr_attr &= ~ATTR_FGMASK;
- term->curr_attr |= colour;
- term->default_attr &= ~ATTR_FGMASK;
- term->default_attr |= colour;
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.color |= colour;
+ term->default_attr.color &= ~ATTR_FGMASK;
+ term->default_attr.color |= colour;
}
break;
case ANSI('G', '='): /* set normal background */
(sco2ansicolour[term->esc_args[0] & 0x7] |
(uint32_t)((term->esc_args[0] & 0x8) << 1)) <<
ATTR_BGSHIFT;
- term->curr_attr &= ~ATTR_BGMASK;
- term->curr_attr |= colour;
- term->default_attr &= ~ATTR_BGMASK;
- term->default_attr |= colour;
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.color |= colour;
+ term->default_attr.color &= ~ATTR_BGMASK;
+ term->default_attr.color |= colour;
}
break;
case ANSI('L', '='):
compatibility(SCOANSI);
term->use_bce = (term->esc_args[0] <= 0);
- term->erase_char = ERASE_CHAR;
- if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
+ set_erase_char(term);
break;
case ANSI('p', '"'): /* DECSCL: set compat level */
/*
*
*/
case 'F':
- term->cset_attr[term->cset = 0] = ATTR_LINEDRW;
+ term->cset_attr[term->cset = 0] = ATTR_WRAP(ATTR_LINEDRW);
break;
case 'G':
- term->cset_attr[term->cset = 0] = ATTR_ASCII;
+ term->cset_attr[term->cset = 0] = ATTR_WRAP(ATTR_ASCII);
break;
case 'H':
move(term, 0, 0, 0);
break;
case 'p':
/* compatibility(ATARI) */
- term->curr_attr |= ATTR_REVERSE;
+ term->curr_attr.attr |= ATTR_REVERSE;
break;
case 'q':
/* compatibility(ATARI) */
- term->curr_attr &= ~ATTR_REVERSE;
+ term->curr_attr.attr &= ~ATTR_REVERSE;
break;
case 'v': /* wrap Autowrap on - Wyse style */
/* compatibility(ATARI) */
/* compatibility(OTHER) */
term->vt52_bold = FALSE;
term->curr_attr = ATTR_DEFAULT;
- if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
+ set_erase_char(term);
break;
case 'S':
/* compatibility(VI50) */
- term->curr_attr |= ATTR_UNDER;
+ term->curr_attr.attr |= ATTR_UNDER;
break;
case 'W':
/* compatibility(VI50) */
- term->curr_attr &= ~ATTR_UNDER;
+ term->curr_attr.attr &= ~ATTR_UNDER;
break;
case 'U':
/* compatibility(VI50) */
term->vt52_bold = TRUE;
- term->curr_attr |= ATTR_BOLD;
+ term->curr_attr.attr |= ATTR_BOLD;
break;
case 'T':
/* compatibility(VI50) */
term->vt52_bold = FALSE;
- term->curr_attr &= ~ATTR_BOLD;
+ term->curr_attr.attr &= ~ATTR_BOLD;
break;
#endif
}
#ifdef VT52_PLUS
case VT52_FG:
term->termstate = TOPLEVEL;
- term->curr_attr &= ~ATTR_FGMASK;
- term->curr_attr &= ~ATTR_BOLD;
- term->curr_attr |= (c & 0x7) << ATTR_FGSHIFT;
+ term->curr_attr.color &= ~ATTR_FGMASK;
+ term->curr_attr.attr &= ~ATTR_BOLD;
+ term->curr_attr.color |= (c & 0x7) << ATTR_FGSHIFT;
if ((c & 0x8) || term->vt52_bold)
- term->curr_attr |= ATTR_BOLD;
+ term->curr_attr.attr |= ATTR_BOLD;
- if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
+ set_erase_char(term);
break;
case VT52_BG:
term->termstate = TOPLEVEL;
- term->curr_attr &= ~ATTR_BGMASK;
- term->curr_attr &= ~ATTR_BLINK;
- term->curr_attr |= (c & 0x7) << ATTR_BGSHIFT;
+ term->curr_attr.color &= ~ATTR_BGMASK;
+ term->curr_attr.attr &= ~ATTR_BLINK;
+ term->curr_attr.color |= (c & 0x7) << ATTR_BGSHIFT;
- /* Note: bold background */
if (c & 0x8)
- term->curr_attr |= ATTR_BLINK;
+ term->curr_attr.attr |= ATTR_BLINK;
- if (term->use_bce)
- term->erase_char = (' ' | ATTR_ASCII |
- (term->curr_attr &
- (ATTR_FGMASK | ATTR_BGMASK)));
+ set_erase_char(term);
break;
#endif
default: break; /* placate gcc warning about enum use */
* alike to scroll-optimise one to the other. Return the degree of
* similarity.
*/
-static int linecmp(Terminal *term, unsigned long *a, unsigned long *b)
+static int linecmp(Terminal *term, struct attr_tag *a, struct attr_tag *b)
{
int i, n;
unsigned long rv, cursor;
pos scrpos;
char ch[1024];
- long cursor_background = ERASE_CHAR;
+ struct attr_tag cursor_background = ERASE_CHAR;
unsigned long ticks;
#ifdef OPTIMISE_SCROLL
struct scrollregion *sr;
* to display the cursor covering the _whole_ character,
* exactly as if it were one space to the left.
*/
- unsigned long *ldata = lineptr(term->curs.y);
+ struct attr_tag *ldata = lineptr(term->curs.y);
our_curs_x = term->curs.x;
if (our_curs_x > 0 &&
- (ldata[our_curs_x] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+ (ldata[our_curs_x].attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
our_curs_x--;
}
term->disptext + our_curs_y * (term->cols + 1) +
our_curs_x)) {
if (term->dispcurs > term->disptext &&
- (*term->dispcurs & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
- term->dispcurs[-1] |= ATTR_INVALID;
- if ( (term->dispcurs[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
- term->dispcurs[1] |= ATTR_INVALID;
- *term->dispcurs |= ATTR_INVALID;
+ ((*term->dispcurs).attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+ ATTR_INVALIDATE(term->dispcurs[-1]);
+ if ( (term->dispcurs[1].attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+ ATTR_INVALIDATE(term->dispcurs[1]);
+ ATTR_INVALIDATE(*term->dispcurs);
term->curstype = 0;
}
term->dispcurs = NULL;
/* The normal screen data */
for (i = 0; i < term->rows; i++) {
- unsigned long *ldata;
+ struct attr_tag *ldata;
unsigned long lattr;
int idx, dirty_line, dirty_run, selected;
- unsigned long attr = 0;
+ struct attr_tag attr = ATTR_WRAP(ATTR_CLEAR);
int updated_line = 0;
int start = 0;
int ccount = 0;
scrpos.y = i + term->disptop;
ldata = lineptr(scrpos.y);
- lattr = (ldata[term->cols] & LATTR_MODE);
+ lattr = (LINE_ATTRS(ldata-1) & LATTR_MODE);
idx = i * (term->cols + 1);
- dirty_run = dirty_line = (ldata[term->cols] !=
- term->disptext[idx + term->cols]);
- term->disptext[idx + term->cols] = ldata[term->cols];
+ dirty_run = dirty_line = (LINE_ATTRS(ldata-1) !=
+ term->disptext[idx].attr); /* abstraction violation */
+ term->disptext[idx + term->cols].attr = LINE_ATTRS(ldata-1); /* abstraction violation */
for (j = 0; j < term->cols; j++, idx++) {
- unsigned long tattr, tchar;
- unsigned long *d = ldata + j;
+ struct attr_tag tattr, tchar;
+ struct attr_tag *d = ldata + j;
int break_run;
scrpos.x = j;
- tchar = (*d & (CHAR_MASK | CSET_MASK));
- tattr = (*d & (ATTR_MASK ^ CSET_MASK));
+ tchar = ATTR_CHARALL((*d));// & (CHAR_MASK | CSET_MASK));
+ tattr = ATTR_ATTRS((*d));// & (ATTR_MASK ^ CSET_MASK));
+ tattr.attr &= ~CSET_MASK;
// GrP fixme Don't remap any characters here for now.
/*
switch (tchar & CSET_MASK) {
break;
}
*/
- tattr |= (tchar & CSET_MASK);
- tchar &= CHAR_MASK;
- if ((d[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
- tattr |= ATTR_WIDE;
+ tattr.attr |= (tchar.attr & CSET_MASK);
+ tchar.attr &= CHAR_MASK;
+ if ((d[1].attr & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+ tattr.attr |= ATTR_WIDE;
/* Video reversing things */
if (term->selstate == DRAGGING || term->selstate == SELECTED) {
posPlt(scrpos, term->selend));
} else
selected = FALSE;
- tattr = (tattr ^ rv
- ^ (selected ? ATTR_REVERSE : 0UL));
+
+ tattr = ATTR_XOR( tattr,
+ ATTR_WRAP( rv ^ (selected
+ ? ATTR_REVERSE
+ : ATTR_CLEAR) ) ) ;
/* 'Real' blinking ? */
- if (term->blink_is_real && (tattr & ATTR_BLINK)) {
+ if (term->blink_is_real && ATTR_STATE(tattr, ATTR_BLINK)) {
if (term->has_focus && term->tblinker) {
- tchar = ' '; // term->ucsdata->unitab_line[(unsigned char)' '];
+ tchar = ATTR_WRAP(' '); // term->ucsdata->unitab_line[(unsigned char)' '];
}
- tattr &= ~ATTR_BLINK;
+ tattr = ATTR_OFF(tattr, ATTR_BLINK);
}
/*
* Check the font we'll _probably_ be using to see if
* the character is wide when we don't want it to be.
*/
- if ((tchar | tattr) != (term->disptext[idx]& ~ATTR_NARROW)) {
- if ((tattr & ATTR_WIDE) == 0 &&
- char_width(ctx, (tchar | tattr) & 0xFFFF) == 2)
- tattr |= ATTR_NARROW;
- } else if (term->disptext[idx]&ATTR_NARROW)
- tattr |= ATTR_NARROW;
+ if (!ATTR_EQUAL(ATTR_OR(tchar, tattr),
+ ATTR_OFF(term->disptext[idx], ATTR_NARROW))) {
+ if (!ATTR_STATE(tattr, ATTR_WIDE) &&
+ char_width(ctx, ATTR_AND(ATTR_OR(tchar, tattr), ATTR_WRAP(0xFFFF)).attr) == 2)
+ tattr = ATTR_ON(tattr, ATTR_NARROW);
+ } else if (ATTR_STATE(term->disptext[idx], ATTR_NARROW))
+ tattr = ATTR_ON(tattr, ATTR_NARROW);
/* Cursor here ? Save the 'background' */
if (i == our_curs_y && j == our_curs_x) {
- cursor_background = tattr | tchar;
+ cursor_background = ATTR_OR(tattr, tchar);
term->dispcurs = term->disptext + idx;
}
- if ((term->disptext[idx] ^ tattr) & ATTR_WIDE)
+ if (ATTR_STATE( ATTR_XOR(term->disptext[idx], tattr), ATTR_WIDE))
dirty_line = TRUE;
- break_run = (((tattr ^ attr) & term->attr_mask) ||
- j - start >= sizeof(ch));
+ break_run = (!(ATTR_ZERO(ATTR_AND(ATTR_XOR(tattr, attr), term->attr_mask)))) ||
+ j - start >= sizeof(ch);
/* Special hack for VT100 Linedraw glyphs */
// GrP vt100 horizontal linedraw causes break_run to be set? (why?)
- if ((attr & CSET_MASK) == 0x2300 && tchar >= 0xBA && tchar <= 0xBD)
+ if (ATTR_EQUAL(ATTR_AND(attr, ATTR_WRAP(CSET_MASK)), ATTR_WRAP(0x2300)) &&
+ tchar.attr >= 0xBA && tchar.attr <= 0xBD)
{
break_run = TRUE;
}
if (!term->ucsdata->dbcs_screenfont && !dirty_line) {
- if ((tchar | tattr) == term->disptext[idx])
+ if (ATTR_EQUAL(ATTR_OR(tchar, tattr), term->disptext[idx]))
break_run = TRUE;
else if (!dirty_run && ccount == 1)
break_run = TRUE;
dirty_run = dirty_line;
}
- if ((tchar | tattr) != term->disptext[idx])
+ if (!ATTR_EQUAL(ATTR_OR(tchar, tattr), term->disptext[idx]))
dirty_run = TRUE;
- ch[ccount++] = (char) tchar;
- term->disptext[idx] = tchar | tattr;
+ ch[ccount++] = (char) tchar.attr;
+ term->disptext[idx] = ATTR_OR(tchar, tattr);
/* If it's a wide char step along to the next one. */
- if (tattr & ATTR_WIDE) {
+ if (ATTR_STATE(tattr, ATTR_WIDE)) {
if (++j < term->cols) {
idx++;
d++;
* Ever.
*/
assert(!(i == our_curs_y && j == our_curs_x));
- if (term->disptext[idx] != *d)
+ if (!ATTR_EQUAL(term->disptext[idx], *d))
dirty_run = TRUE;
term->disptext[idx] = *d;
}
/* Cursor on this line ? (and changed) */
if (i == our_curs_y && (term->curstype != cursor || updated_line)) {
- ch[0] = (char) (cursor_background & CHAR_MASK);
- attr = (cursor_background & ATTR_MASK) | cursor;
+ ch[0] = (char) ATTR_CHAR(cursor_background).attr;
+ attr = ATTR_OR(ATTR_ATTRS(cursor_background), ATTR_WRAP(cursor));
do_cursor(ctx, our_curs_x, i, ch, 1, attr, lattr);
term->curstype = cursor;
}
if (bottom >= term->rows) bottom = term->rows-1;
for (i = top; i <= bottom && i < term->rows; i++) {
- if ((term->disptext[i * (term->cols + 1) + term->cols] &
+ if ((term->disptext[i * (term->cols + 1)].attr & /* abstraction violation */
LATTR_MODE) == LATTR_NORM)
for (j = left; j <= right && j < term->cols; j++)
term->disptext[i * (term->cols + 1) + j] = ATTR_INVALID;
while (poslt(top, bottom)) {
int nl = FALSE;
- unsigned long *ldata = lineptr(top.y);
+ struct attr_tag *ldata = lineptr(top.y);
pos nlpos;
/*
* because in normal selection mode this means we need a
* newline at the end)...
*/
- if (!(ldata[term->cols] & LATTR_WRAPPED)) {
- while (((ldata[nlpos.x - 1] & 0xFF) == 0x20 ||
- (DIRECT_CHAR(ldata[nlpos.x - 1]) &&
- (ldata[nlpos.x - 1] & CHAR_MASK) == 0x20))
+ if (!(LINE_ATTRS(ldata-1) & LATTR_WRAPPED)) {
+ while (((ldata[nlpos.x - 1].attr & 0xFF) == 0x20 ||
+ (DIRECT_CHAR(ldata[nlpos.x - 1].attr) &&
+ (ldata[nlpos.x - 1].attr & CHAR_MASK) == 0x20))
&& poslt(top, nlpos))
decpos(nlpos);
if (poslt(nlpos, bottom))
nl = TRUE;
- } else if (ldata[term->cols] & LATTR_WRAPPED2) {
+ } else if (LINE_ATTRS(ldata-1) & LATTR_WRAPPED2) {
/* Ignore the last char on the line in a WRAPPED2 line. */
decpos(nlpos);
}
}
while (poslt(top, bottom) && poslt(top, nlpos)) {
- unsigned int uc = (ldata[top.x] & 0xFFFF);
+ unsigned int uc = (ldata[top.x].attr & 0xFFFF);
if (uc == UCSWIDE) {
top.x++;
* The wordness array is mainly for deciding the disposition of the
* US-ASCII characters.
*/
-static int wordtype(Terminal *term, uint32_t uc)
+static int wordtype(Terminal *term, struct attr_tag uc_in)
{
struct ucsword {
unsigned int start, end, ctype;
0, 0, 0}
};
const struct ucsword *wptr;
+ unsigned long uc = uc_in.attr;
uc &= (CSET_MASK | CHAR_MASK);
*/
static pos sel_spread_half(Terminal *term, pos p, int dir)
{
- unsigned long *ldata;
+ struct attr_tag *ldata;
short wvalue;
int topy = -sblines(term);
* In this mode, every character is a separate unit, except
* for runs of spaces at the end of a non-wrapping line.
*/
- if (!(ldata[term->cols] & LATTR_WRAPPED)) {
- unsigned long *q = ldata + term->cols;
- while (q > ldata && (q[-1] & CHAR_MASK) == 0x20)
+ if (!(LINE_ATTRS(ldata-1) & LATTR_WRAPPED)) {
+ struct attr_tag *q = ldata + term->cols;
+ while (q > ldata && (q[-1].attr & CHAR_MASK) == 0x20)
q--;
if (q == ldata + term->cols)
q--;
wvalue = wordtype(term, UCSGET(ldata, p.x));
if (dir == +1) {
while (1) {
- int maxcols = (ldata[term->cols] & LATTR_WRAPPED2 ?
+ int maxcols = (LINE_ATTRS(ldata-1) & LATTR_WRAPPED2 ?
term->cols-1 : term->cols);
if (p.x < maxcols-1) {
if (wordtype(term, UCSGET(ldata, p.x + 1)) == wvalue)
else
break;
} else {
- if (ldata[term->cols] & LATTR_WRAPPED) {
- unsigned long *ldata2;
+ if (LINE_ATTRS(ldata-1) & LATTR_WRAPPED) {
+ struct attr_tag *ldata2;
ldata2 = lineptr(p.y+1);
if (wordtype(term, UCSGET(ldata2, 0)) == wvalue) {
p.x = 0;
else
break;
} else {
- unsigned long *ldata2;
+ struct attr_tag *ldata2;
int maxcols;
if (p.y <= topy)
break;
ldata2 = lineptr(p.y-1);
- maxcols = (ldata2[term->cols] & LATTR_WRAPPED2 ?
+ maxcols = (LINE_ATTRS(ldata2-1) & LATTR_WRAPPED2 ?
term->cols-1 : term->cols);
- if (ldata2[term->cols] & LATTR_WRAPPED) {
+ if (LINE_ATTRS(ldata2-1) & LATTR_WRAPPED) {
if (wordtype(term, UCSGET(ldata2, maxcols-1))
== wvalue) {
p.x = maxcols-1;
Mouse_Action a, int x, int y, int shift, int ctrl, int alt)
{
pos selpoint;
- unsigned long *ldata;
+ struct attr_tag *ldata;
int raw_mouse = (term->xterm_mouse &&
!term->cfg.no_mouse_rep &&
!(term->cfg.mouse_override && shift));
selpoint.y = y + term->disptop;
selpoint.x = x;
ldata = lineptr(selpoint.y);
- if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM)
+ if ((LINE_ATTRS(ldata-1) & LATTR_MODE) != LATTR_NORM)
selpoint.x /= 2;
if (raw_mouse) {
int tempsblines; /* number of lines in temporary
scrollback */
- unsigned long *cpos; /* cursor position (convenience) */
+ struct attr_tag *cpos; /* cursor position (convenience) */
- unsigned long *disptext; /* buffer of text on real screen */
- unsigned long *dispcurs; /* location of cursor on real screen */
+ struct attr_tag *disptext; /* buffer of text on real screen */
+ struct attr_tag *dispcurs; /* location of cursor on real screen */
unsigned long curstype; /* type of cursor on real screen */
#define VBELL_TIMEOUT (TICKSPERSEC/10) /* visual bell lasts 1/10 sec */
int beep_overloaded;
long lastbeep;
-#define TTYPE unsigned long
+#define TTYPE struct attr_tag
#define TSIZE (sizeof(TTYPE))
#define fix_cpos do { \
term->cpos = lineptr(term->curs.y) + term->curs.x; \
struct scrollregion *scrollhead, *scrolltail;
#endif /* OPTIMISE_SCROLL */
- unsigned long default_attr, curr_attr, save_attr;
- unsigned long erase_char;
+ struct attr_tag default_attr, curr_attr, save_attr;
+ struct attr_tag erase_char;
bufchain inbuf; /* terminal input buffer */
pos curs; /* cursor */
int wrap, wrapnext; /* wrap flags */
int insert; /* insert-mode flag */
int cset; /* 0 or 1: which char set */
- int save_cset, save_csattr; /* saved with cursor position */
+ int save_cset; /* saved with cursor position */
+ struct attr_tag save_csattr; /* saved with cursor position */
int save_utf, save_wnext; /* saved with cursor position */
int rvideo; /* global reverse video flag */
unsigned long rvbell_startpoint; /* for ESC[?5hESC[?5l vbell */
int xterm_mouse; /* send mouse messages to app */
int mouse_is_down; /* used while tracking mouse buttons */
- unsigned long cset_attr[2];
+ struct attr_tag cset_attr[2];
/*
* Saved settings on the alternate screen.
short wordness[256];
/* Mask of attributes to pay attention to when painting. */
- unsigned long attr_mask;
+ struct attr_tag attr_mask;
wchar_t *paste_buffer;
int paste_len, paste_pos, paste_hold;
fg_color = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormForeColorListID));
bg_color = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormBackColorListID));
- set_palm_color(fg_color * 2, bg_color * 2);
+ set_palm_color(fg_color, bg_color);
if (PrvGetControlValue(DisplayPrefsFormSmallFontCheckboxID)) {
FntSetFont(font_for_screen(font4x6));