diff --git a/TODO.org b/TODO.org index de27202..df95bc0 100644 --- a/TODO.org +++ b/TODO.org @@ -32,7 +32,6 @@ ** basic: share mmapped pages correctly ** completion: fix electric behavior ** completion: add completion function to get the default value -** display: remove QECOLOR_XOR mess, use dpy_cursor_at for all devices ** files: check file date to detect asynchronous modifications on disk ** files: reload modified file upon change if untouched since load ** layout: kill buffer should delete popup and popleft window diff --git a/cfb.c b/cfb.c index c95eed1..9817737 100644 --- a/cfb.c +++ b/cfb.c @@ -59,42 +59,52 @@ static void cfb16_fill_rectangle(QEditScreen *s, col = (col << 16) | col; dest = cfb->base + y1 * cfb->wrap + x1 * 2; - if (color == QECOLOR_XOR) { - /* XXX: suppress this mess */ - for (y = 0; y < h; y++) { - d = dest; - for (n = w; n != 0; n--) { - ((uint16_t *)(void *)d)[0] ^= 0xffff; - d += 2; - } - dest += cfb->wrap; - } - } else { - for (y = 0; y < h; y++) { - d = dest; - n = w; + for (y = 0; y < h; y++) { + d = dest; + n = w; - if (((intptr_t)d & 3) != 0) { - ((uint16_t *)(void *)d)[0] = col; - d += 2; - n--; - } - - while (n >= 8) { - ((uint32_t *)(void *)d)[0] = col; - ((uint32_t *)(void *)d)[1] = col; - ((uint32_t *)(void *)d)[2] = col; - ((uint32_t *)(void *)d)[3] = col; - d += 16; - n -= 8; - } - while (n > 0) { - ((uint16_t *)(void *)d)[0] = col; - d += 2; - n--; - } - dest += cfb->wrap; + if (((intptr_t)d & 3) != 0) { + ((uint16_t *)(void *)d)[0] = col; + d += 2; + n--; } + + while (n >= 8) { + ((uint32_t *)(void *)d)[0] = col; + ((uint32_t *)(void *)d)[1] = col; + ((uint32_t *)(void *)d)[2] = col; + ((uint32_t *)(void *)d)[3] = col; + d += 16; + n -= 8; + } + while (n > 0) { + ((uint16_t *)(void *)d)[0] = col; + d += 2; + n--; + } + dest += cfb->wrap; + } +} + +static void cfb16_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + CFBContext *cfb = s->priv_data; + unsigned char *dest, *d; + int y, n; + unsigned int col; + + col = cfb->get_color(color); + col = (col << 16) | col; + + dest = cfb->base + y1 * cfb->wrap + x1 * 2; + for (y = 0; y < h; y++) { + d = dest; + for (n = w; n != 0; n--) { + ((uint16_t *)(void *)d)[0] ^= 0xffff; + d += 2; + } + dest += cfb->wrap; } } @@ -109,35 +119,44 @@ static void cfb32_fill_rectangle(QEditScreen *s, col = cfb->get_color(color); dest = cfb->base + y1 * cfb->wrap + x1 * 4; - if (color == QECOLOR_XOR) { - /* XXX: suppress this mess */ - for (y = 0; y < h; y++) { - d = dest; - for (n = w; n != 0; n--) { - ((uint32_t *)(void *)d)[0] ^= 0x00ffffff; - d += 4; - } - dest += cfb->wrap; + for (y = 0; y < h; y++) { + d = dest; + n = w; + while (n >= 4) { + ((uint32_t *)(void *)d)[0] = col; + ((uint32_t *)(void *)d)[1] = col; + ((uint32_t *)(void *)d)[2] = col; + ((uint32_t *)(void *)d)[3] = col; + d += 16; + n -= 4; } - } else { - for (y = 0; y < h; y++) { - d = dest; - n = w; - while (n >= 4) { - ((uint32_t *)(void *)d)[0] = col; - ((uint32_t *)(void *)d)[1] = col; - ((uint32_t *)(void *)d)[2] = col; - ((uint32_t *)(void *)d)[3] = col; - d += 16; - n -= 4; - } - while (n > 0) { - ((uint32_t *)(void *)d)[0] = col; - d += 4; - n--; - } - dest += cfb->wrap; + while (n > 0) { + ((uint32_t *)(void *)d)[0] = col; + d += 4; + n--; } + dest += cfb->wrap; + } +} + +static void cfb32_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + CFBContext *cfb = s->priv_data; + unsigned char *dest, *d; + int y, n; + unsigned int col; + + col = cfb->get_color(color); + + dest = cfb->base + y1 * cfb->wrap + x1 * 4; + for (y = 0; y < h; y++) { + d = dest; + for (n = w; n != 0; n--) { + ((uint32_t *)(void *)d)[0] ^= 0x00ffffff; + d += 4; + } + dest += cfb->wrap; } } @@ -332,11 +351,13 @@ int cfb_init(QEditScreen *s, switch (cfb->bpp) { case 2: s->dpy.dpy_fill_rectangle = cfb16_fill_rectangle; + s->dpy.dpy_xor_rectangle = cfb16_xor_rectangle; cfb->draw_glyph = cfb16_draw_glyph; break; default: case 4: s->dpy.dpy_fill_rectangle = cfb32_fill_rectangle; + s->dpy.dpy_xor_rectangle = cfb32_xor_rectangle; cfb->draw_glyph = cfb32_draw_glyph; break; } diff --git a/display.c b/display.c index 9359461..6d77643 100644 --- a/display.c +++ b/display.c @@ -52,6 +52,13 @@ static void dummy_dpy_fill_rectangle(qe__unused__ QEditScreen *s, { } +static void dummy_dpy_xor_rectangle(qe__unused__ QEditScreen *s, + qe__unused__ int x1, qe__unused__ int y1, + qe__unused__ int w, qe__unused__ int h, + qe__unused__ QEColor color) +{ +} + static QEFont *dummy_dpy_open_font(qe__unused__ QEditScreen *s, qe__unused__ int style, qe__unused__ int size) { @@ -91,12 +98,13 @@ static void dummy_dpy_set_clip(qe__unused__ QEditScreen *s, static QEDisplay const dummy_dpy = { "dummy", - NULL, + NULL, /* dpy_probe */ dummy_dpy_init, dummy_dpy_close, dummy_dpy_flush, dummy_dpy_is_user_input_pending, dummy_dpy_fill_rectangle, + dummy_dpy_xor_rectangle, dummy_dpy_open_font, dummy_dpy_close_font, dummy_dpy_text_metrics, @@ -147,10 +155,25 @@ void fill_rectangle(QEditScreen *s, s->dpy.dpy_fill_rectangle(s, x1, y1, x2 - x1, y2 - y1, color); } +void xor_rectangle(QEditScreen *s, + int x, int y, int w, int h, QEColor color) +{ + /* intersect with clip region */ + int x1 = max(s->clip_x1, x); + int y1 = max(s->clip_y1, y); + int x2 = min(s->clip_x2, x1 + w); + int y2 = min(s->clip_y2, y1 + h); + + if (x1 < x2 && y1 < y2) { + s->dpy.dpy_xor_rectangle(s, x1, y1, x2 - x1, y2 - y1, color); + } +} + /* set the clip rectangle (and does not clip by the previous one) */ void set_clip_rectangle(QEditScreen *s, CSSRect *r) { int x1, y1, x2, y2; + x1 = r->x1; y1 = r->y1; x2 = r->x2; @@ -322,6 +345,7 @@ QEBitmap *bmp_alloc(QEditScreen *s, int width, int height, int flags) if (!s->dpy.dpy_bmp_alloc) return NULL; + b = qe_mallocz(QEBitmap); if (!b) return NULL; diff --git a/display.h b/display.h index 3f4ab06..861b856 100644 --- a/display.h +++ b/display.h @@ -105,6 +105,8 @@ struct QEDisplay { int (*dpy_is_user_input_pending)(QEditScreen *s); void (*dpy_fill_rectangle)(QEditScreen *s, int x, int y, int w, int h, QEColor color); + void (*dpy_xor_rectangle)(QEditScreen *s, + int x, int y, int w, int h, QEColor color); QEFont *(*dpy_open_font)(QEditScreen *s, int style, int size); void (*dpy_close_font)(QEditScreen *s, QEFont **fontp); void (*dpy_text_metrics)(QEditScreen *s, QEFont *font, @@ -217,8 +219,10 @@ static inline void bmp_draw(QEditScreen *s, QEBitmap *b, int dst_x, int dst_y, int dst_w, int dst_h, int offset_x, int offset_y, int flags) { - s->dpy.dpy_bmp_draw(s, b, dst_x, dst_y, dst_w, dst_h, - offset_x, offset_y, flags); + if (s->dpy.dpy_bmp_draw) { + s->dpy.dpy_bmp_draw(s, b, dst_x, dst_y, dst_w, dst_h, + offset_x, offset_y, flags); + } } /* used to access the bitmap data. Return the necessary pointers to @@ -226,12 +230,26 @@ static inline void bmp_draw(QEditScreen *s, QEBitmap *b, static inline void bmp_lock(QEditScreen *s, QEBitmap *bitmap, QEPicture *pict, int x1, int y1, int w1, int h1) { - s->dpy.dpy_bmp_lock(s, bitmap, pict, x1, y1, w1, h1); + if (s->dpy.dpy_bmp_lock) + s->dpy.dpy_bmp_lock(s, bitmap, pict, x1, y1, w1, h1); } static inline void bmp_unlock(QEditScreen *s, QEBitmap *bitmap) { - s->dpy.dpy_bmp_unlock(s, bitmap); + if (s->dpy.dpy_bmp_unlock) + s->dpy.dpy_bmp_unlock(s, bitmap); +} + +static inline void dpy_full_screen(QEditScreen *s, int full_screen) +{ + if (s->dpy.dpy_full_screen) + s->dpy.dpy_full_screen(s, full_screen); +} + +static inline void dpy_describe(QEditScreen *s, EditBuffer *b) +{ + if (s->dpy.dpy_describe) + s->dpy.dpy_describe(s, b); } /* XXX: only needed for backward compatibility */ @@ -246,6 +264,8 @@ static inline int glyph_width(QEditScreen *s, QEFont *font, int ch) void fill_rectangle(QEditScreen *s, int x1, int y1, int w, int h, QEColor color); +void xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color); void set_clip_rectangle(QEditScreen *s, CSSRect *r); void push_clip_rectangle(QEditScreen *s, CSSRect *r0, CSSRect *r); diff --git a/extras.c b/extras.c index 31e4435..81398cc 100644 --- a/extras.c +++ b/extras.c @@ -1503,9 +1503,7 @@ static void do_describe_screen(EditState *e, int argval) eb_printf(b1, "%*s: %x << %d\n", w, "QE_TERM_FG_COLORS", QE_TERM_FG_COLORS, QE_TERM_FG_SHIFT); eb_printf(b1, "%*s: %x << %d\n\n", w, "QE_TERM_BG_COLORS", QE_TERM_BG_COLORS, QE_TERM_BG_SHIFT); - if (s->dpy.dpy_describe) { - s->dpy.dpy_describe(s, b1); - } + dpy_describe(s, b1); b1->flags |= BF_READONLY; show_popup(e, b1); diff --git a/haiku.cpp b/haiku.cpp index 4dfdfdc..c712dcd 100644 --- a/haiku.cpp +++ b/haiku.cpp @@ -638,27 +638,29 @@ static void haiku_fill_rectangle(QEditScreen *s, int x1, int y1, int w, int h, QEColor color) { WindowState *ctx = (WindowState *)s->priv_data; - //fprintf(stderr, "%s()\n", __FUNCTION__); - drawing_mode oldMode; BRect r(x1, y1, x1 + w - 1, y1 + h - 1); rgb_color c = { (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, 0xff }; ctx->v->LockLooper(); - - oldMode = ctx->v->DrawingMode(); - - /* XXX: suppress XOR mode */ - if (color == QECOLOR_XOR) - ctx->v->SetDrawingMode(B_OP_INVERT); - else - ctx->v->SetHighColor(c); + ctx->v->SetHighColor(c); ctx->v->FillRect(r); + ctx->v->UnlockLooper(); +} - /* XXX: suppress XOR mode */ - if (color == QECOLOR_XOR) - ctx->v->SetDrawingMode(oldMode); - +static void haiku_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + WindowState *ctx = (WindowState *)s->priv_data; + drawing_mode oldMode; + + BRect r(x1, y1, x1 + w - 1, y1 + h - 1); + + ctx->v->LockLooper(); + oldMode = ctx->v->DrawingMode(); + ctx->v->SetDrawingMode(B_OP_INVERT); + ctx->v->FillRect(r); + ctx->v->SetDrawingMode(oldMode); ctx->v->UnlockLooper(); } @@ -747,10 +749,6 @@ static void haiku_draw_text(QEditScreen *s, QEFont *font, int i; //fprintf(stderr, "%s()\n", __FUNCTION__); - /* XXX: suppress XOR mode */ - if (color == QECOLOR_XOR) - color = QERGB(0xff, 0xff, 0xff); - rgb_color c = { (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, 0xff }; ctx->v->LockLooper(); @@ -873,13 +871,14 @@ static QEDisplay haiku_dpy = { haiku_flush, haiku_is_user_input_pending, haiku_fill_rectangle, + haiku_xor_rectangle, haiku_open_font, haiku_close_font, haiku_text_metrics, haiku_draw_text, haiku_set_clip, - NULL, /* no selection handling */ - NULL, /* no selection handling */ + NULL, /* dpy_selection_activate */ + NULL, /* dpy_selection_request */ NULL, /* dpy_invalidate */ NULL, /* dpy_cursor_at */ haiku_bmp_alloc, /* dpy_bmp_alloc */ diff --git a/html.c b/html.c index e9bdad2..3d7f651 100644 --- a/html.c +++ b/html.c @@ -341,7 +341,7 @@ static void html_display(EditState *s) /* hardware cursor */ s->screen->dpy.dpy_cursor_at(s->screen, x, y, w, h); } else { - fill_rectangle(s->screen, x, y, w, h, QECOLOR_XOR); + xor_rectangle(s->screen, x, y, w, h, QERGB(0xFF, 0xFF, 0xFF)); /* invalidate rectangle modified by cursor */ css_set_rect(&rect, x, y, x + w, y + h); css_union_rect(&hs->invalid_rect, &rect); diff --git a/html2png.c b/html2png.c index ce9fd45..b4cf2c4 100644 --- a/html2png.c +++ b/html2png.c @@ -115,6 +115,7 @@ static QEDisplay ppm_dpy = { NULL, /* dpy_flush */ NULL, /* dpy_is_user_input_pending */ NULL, /* dpy_fill_rectangle */ + NULL, /* dpy_xor_rectangle */ NULL, /* dpy_open_font */ NULL, /* dpy_close_font */ NULL, /* dpy_text_metrics */ diff --git a/qe.c b/qe.c index 1801626..35fa55e 100644 --- a/qe.c +++ b/qe.c @@ -2974,8 +2974,7 @@ void do_toggle_full_screen(EditState *s) QEditScreen *screen = s->screen; qs->is_full_screen = !qs->is_full_screen; - if (screen->dpy.dpy_full_screen) - screen->dpy.dpy_full_screen(screen, qs->is_full_screen); + dpy_full_screen(screen, qs->is_full_screen); if (qs->is_full_screen) s->flags &= ~WF_MODELINE; else @@ -4355,10 +4354,9 @@ static void generic_text_display(EditState *s) x += w; w = -w; } - fill_rectangle(s->screen, x, y, w, h, QECOLOR_XOR); + xor_rectangle(s->screen, x, y, w, h, QERGB(0xFF, 0xFF, 0xFF)); /* invalidate line so that the cursor will be erased next time */ - memset(&s->line_shadow[m->linec], 0xff, - sizeof(QELineShadow)); + memset(&s->line_shadow[m->linec], 0xff, sizeof(QELineShadow)); } } s->cur_rtl = (m->dirc == DIR_RTL); diff --git a/qe.h b/qe.h index 03422bf..8674684 100644 --- a/qe.h +++ b/qe.h @@ -206,7 +206,6 @@ typedef unsigned int QEColor; #define QERGB(r,g,b) QEARGB(0xff, r, g, b) #define QERGB25(r,g,b) QEARGB(1, r, g, b) #define COLOR_TRANSPARENT 0 -#define QECOLOR_XOR 1 /* A qemacs style is a named set of attributes including: * - colors for foreground and background diff --git a/tty.c b/tty.c index c43ac4b..1e2c473 100644 --- a/tty.c +++ b/tty.c @@ -144,20 +144,21 @@ typedef struct TTYState { unsigned int comb_cache[COMB_CACHE_SIZE]; } TTYState; -static void tty_term_invalidate(QEditScreen *s); -static void tty_resize(int sig); +static QEditScreen *tty_screen; /* for tty_term_exit and tty_term_resize */ + +static void tty_dpy_invalidate(QEditScreen *s); + +static void tty_term_resize(int sig); static void tty_term_exit(void); static void tty_read_handler(void *opaque); -static QEditScreen *tty_screen; /* for tty_term_exit and tty_resize */ - -static int tty_term_probe(void) +static int tty_dpy_probe(void) { return 1; } -static int tty_term_init(QEditScreen *s, - qe__unused__ int w, qe__unused__ int h) +static int tty_dpy_init(QEditScreen *s, + qe__unused__ int w, qe__unused__ int h) { TTYState *ts; struct termios tty; @@ -320,7 +321,7 @@ static int tty_term_init(QEditScreen *s, atexit(tty_term_exit); - sig.sa_handler = tty_resize; + sig.sa_handler = tty_term_resize; sigemptyset(&sig.sa_mask); sig.sa_flags = 0; sigaction(SIGWINCH, &sig, NULL); @@ -333,7 +334,7 @@ static int tty_term_init(QEditScreen *s, set_read_handler(fileno(s->STDIN), tty_read_handler, s); - tty_term_invalidate(s); + tty_dpy_invalidate(s); if (ts->term_flags & KBS_CONTROL_H) { do_toggle_control_h(NULL, 1); @@ -342,7 +343,7 @@ static int tty_term_init(QEditScreen *s, return 0; } -static void tty_term_close(QEditScreen *s) +static void tty_dpy_close(QEditScreen *s) { TTYState *ts = s->priv_data; @@ -371,23 +372,29 @@ static void tty_term_close(QEditScreen *s) static void tty_term_exit(void) { QEditScreen *s = tty_screen; - TTYState *ts = s->priv_data; - tcsetattr(fileno(s->STDIN), TCSANOW, &ts->oldtty); + if (s) { + TTYState *ts = s->priv_data; + if (ts) { + tcsetattr(fileno(s->STDIN), TCSANOW, &ts->oldtty); + } + } } -static void tty_resize(qe__unused__ int sig) +static void tty_term_resize(qe__unused__ int sig) { QEditScreen *s = tty_screen; - tty_term_invalidate(s); + if (s) { + tty_dpy_invalidate(s); - //fprintf(stderr, "tty_resize: width=%d, height=%d\n", s->width, s->height); + //fprintf(stderr, "tty_term_resize: width=%d, height=%d\n", s->width, s->height); - url_redisplay(); + url_redisplay(); + } } -static void tty_term_invalidate(QEditScreen *s) +static void tty_dpy_invalidate(QEditScreen *s) { TTYState *ts; struct winsize ws; @@ -435,15 +442,15 @@ static void tty_term_invalidate(QEditScreen *s) s->clip_y2 = s->height; } -static void tty_term_cursor_at(QEditScreen *s, int x1, int y1, - qe__unused__ int w, qe__unused__ int h) +static void tty_dpy_cursor_at(QEditScreen *s, int x1, int y1, + qe__unused__ int w, qe__unused__ int h) { TTYState *ts = s->priv_data; ts->cursor_x = x1; ts->cursor_y = y1; } -static int tty_term_is_user_input_pending(QEditScreen *s) +static int tty_dpy_is_user_input_pending(QEditScreen *s) { fd_set rfds; struct timeval tv; @@ -538,7 +545,7 @@ static void tty_read_handler(void *opaque) } } if (ch == '\033') { - if (!tty_term_is_user_input_pending(s)) { + if (!tty_dpy_is_user_input_pending(s)) { /* Trick to distinguish the ESC key from function and meta * keys transmitting escape sequences starting with \033 * but followed immediately by more characters. @@ -556,7 +563,7 @@ static void tty_read_handler(void *opaque) goto the_end; } if (ch == '[') { - if (!tty_term_is_user_input_pending(s)) { + if (!tty_dpy_is_user_input_pending(s)) { ch = KEY_META('['); ts->input_state = IS_NORM; goto the_end; @@ -685,44 +692,54 @@ static void tty_read_handler(void *opaque) } } -static void tty_term_fill_rectangle(QEditScreen *s, - int x1, int y1, int w, int h, QEColor color) +static void tty_dpy_fill_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) { TTYState *ts = s->priv_data; + int x, y; int x2 = x1 + w; int y2 = y1 + h; - int x, y; - TTYChar *ptr; int wrap = s->width - w; + TTYChar *ptr; unsigned int bgcolor; ptr = ts->screen + y1 * s->width + x1; - if (color == QECOLOR_XOR) { - for (y = y1; y < y2; y++) { - ts->line_updated[y] = 1; - for (x = x1; x < x2; x++) { - /* XXX: should reverse fg and bg */ - *ptr ^= TTY_CHAR(0, 7, 7); - ptr++; - } - ptr += wrap; + bgcolor = qe_map_color(color, ts->tty_colors, ts->tty_bg_colors_count, NULL); + for (y = y1; y < y2; y++) { + ts->line_updated[y] = 1; + for (x = x1; x < x2; x++) { + *ptr = TTY_CHAR(' ', 7, bgcolor); + ptr++; } - } else { - bgcolor = qe_map_color(color, ts->tty_colors, ts->tty_bg_colors_count, NULL); - for (y = y1; y < y2; y++) { - ts->line_updated[y] = 1; - for (x = x1; x < x2; x++) { - *ptr = TTY_CHAR(' ', 7, bgcolor); - ptr++; - } - ptr += wrap; + ptr += wrap; + } +} + +static void tty_dpy_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + TTYState *ts = s->priv_data; + int x, y; + int x2 = x1 + w; + int y2 = y1 + h; + int wrap = s->width - w; + TTYChar *ptr; + + ptr = ts->screen + y1 * s->width + x1; + for (y = y1; y < y2; y++) { + ts->line_updated[y] = 1; + for (x = x1; x < x2; x++) { + /* XXX: should reverse fg and bg */ + *ptr ^= TTY_CHAR(0, 7, 7); + ptr++; } + ptr += wrap; } } /* XXX: could alloc font in wrapper */ -static QEFont *tty_term_open_font(qe__unused__ QEditScreen *s, - qe__unused__ int style, qe__unused__ int size) +static QEFont *tty_dpy_open_font(qe__unused__ QEditScreen *s, + qe__unused__ int style, qe__unused__ int size) { QEFont *font; @@ -736,7 +753,7 @@ static QEFont *tty_term_open_font(qe__unused__ QEditScreen *s, return font; } -static void tty_term_close_font(qe__unused__ QEditScreen *s, QEFont **fontp) +static void tty_dpy_close_font(qe__unused__ QEditScreen *s, QEFont **fontp) { qe_free(fontp); } @@ -750,9 +767,9 @@ static inline int tty_term_glyph_width(qe__unused__ QEditScreen *s, unsigned int return unicode_tty_glyph_width(ucs); } -static void tty_term_text_metrics(QEditScreen *s, qe__unused__ QEFont *font, - QECharMetrics *metrics, - const unsigned int *str, int len) +static void tty_dpy_text_metrics(QEditScreen *s, qe__unused__ QEFont *font, + QECharMetrics *metrics, + const unsigned int *str, int len) { int i, x; @@ -879,9 +896,9 @@ static void comb_cache_describe(QEditScreen *s, EditBuffer *b) { #define comb_cache_describe(s, b) #endif -static void tty_term_draw_text(QEditScreen *s, QEFont *font, - int x, int y, const unsigned int *str0, int len, - QEColor color) +static void tty_dpy_draw_text(QEditScreen *s, QEFont *font, + int x, int y, const unsigned int *str0, int len, + QEColor color) { TTYState *ts = s->priv_data; TTYChar *ptr; @@ -972,13 +989,13 @@ static void tty_term_draw_text(QEditScreen *s, QEFont *font, } } -static void tty_term_set_clip(qe__unused__ QEditScreen *s, - qe__unused__ int x, qe__unused__ int y, - qe__unused__ int w, qe__unused__ int h) +static void tty_dpy_set_clip(qe__unused__ QEditScreen *s, + qe__unused__ int x, qe__unused__ int y, + qe__unused__ int w, qe__unused__ int h) { } -static void tty_term_flush(QEditScreen *s) +static void tty_dpy_flush(QEditScreen *s) { TTYState *ts = s->priv_data; TTYChar *ptr, *ptr1, *ptr2, *ptr3, *ptr4, cc, blankcc; @@ -1292,34 +1309,36 @@ static void tty_term_flush(QEditScreen *s) comb_cache_clean(ts, ts->screen, ts->screen_size); } -static void tty_term_describe(QEditScreen *s, EditBuffer *b) { +static void tty_dpy_describe(QEditScreen *s, EditBuffer *b) +{ comb_cache_describe(s, b); } static QEDisplay tty_dpy = { "vt100", - tty_term_probe, - tty_term_init, - tty_term_close, - tty_term_flush, - tty_term_is_user_input_pending, - tty_term_fill_rectangle, - tty_term_open_font, - tty_term_close_font, - tty_term_text_metrics, - tty_term_draw_text, - tty_term_set_clip, + tty_dpy_probe, + tty_dpy_init, + tty_dpy_close, + tty_dpy_flush, + tty_dpy_is_user_input_pending, + tty_dpy_fill_rectangle, + tty_dpy_xor_rectangle, + tty_dpy_open_font, + tty_dpy_close_font, + tty_dpy_text_metrics, + tty_dpy_draw_text, + tty_dpy_set_clip, NULL, /* dpy_selection_activate */ NULL, /* dpy_selection_request */ - tty_term_invalidate, - tty_term_cursor_at, + tty_dpy_invalidate, + tty_dpy_cursor_at, NULL, /* dpy_bmp_alloc */ NULL, /* dpy_bmp_free */ NULL, /* dpy_bmp_draw */ NULL, /* dpy_bmp_lock */ NULL, /* dpy_bmp_unlock */ NULL, /* dpy_full_screen */ - tty_term_describe, + tty_dpy_describe, NULL, /* next */ }; diff --git a/win32.c b/win32.c index 358db80..f75776c 100644 --- a/win32.c +++ b/win32.c @@ -431,13 +431,26 @@ static void win_fill_rectangle(QEditScreen *s, HBRUSH hbr; COLORREF col; - /* XXX: suppress XOR mode */ - if (color == QECOLOR_XOR) - color = QERGB(0xff, 0xff, 0xff); + SetRect(&rc, x1, y1, x1 + w, y1 + h); + col = RGB((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + hbr = CreateSolidBrush(col); + FillRect(win_ctx.hdc, &rc, hbr); + DeleteObject(hbr); +} + +static void win_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + RECT rc; + HBRUSH hbr; + COLORREF col; + + color = QERGB(0xff, 0xff, 0xff); SetRect(&rc, x1, y1, x1 + w, y1 + h); col = RGB((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); hbr = CreateSolidBrush(col); + // XXX: set XOR rop? FillRect(win_ctx.hdc, &rc, hbr); DeleteObject(hbr); } @@ -505,6 +518,7 @@ static QEDisplay win32_dpy = { win_flush, win_is_user_input_pending, win_fill_rectangle, + win_xor_rectangle, win_open_font, win_close_font, win_text_metrics, diff --git a/x11.c b/x11.c index cffe3d9..11eee07 100644 --- a/x11.c +++ b/x11.c @@ -499,20 +499,6 @@ static unsigned long get_x11_color(X11State *xs, QEColor color) } } -static void xor_rectangle(QEditScreen *s, int x, int y, int w, int h) -{ - X11State *xs = s->priv_data; - int fg; - - fg = WhitePixel(xs->display, xs->xscreen); - XSetForeground(xs->display, xs->gc, fg); - XSetFunction(xs->display, xs->gc, GXxor); - - XFillRectangle(xs->display, xs->dbuffer, xs->gc, x, y, w, h); - - XSetFunction(xs->display, xs->gc, GXcopy); -} - /* Print the unicode string 'str' with baseline at position (x,y). The higher bits of each char may contain attributes. */ #ifdef CONFIG_XFT @@ -524,11 +510,6 @@ static void x11_dpy_fill_rectangle(QEditScreen *s, XftColor col; int r, g, b, a; - if (color == QECOLOR_XOR) { - xor_rectangle(s, x1, y1, w, h); - return; - } - a = (color >> 24) & 0xff; r = (color >> 16) & 0xff; g = (color >> 8) & 0xff; @@ -542,6 +523,19 @@ static void x11_dpy_fill_rectangle(QEditScreen *s, XftDrawRect(xs->renderDraw, &col, x1, y1, w, h); } +static void x11_dpy_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + X11State *xs = s->priv_data; + int fg; + + fg = WhitePixel(xs->display, xs->xscreen); + XSetForeground(xs->display, xs->gc, fg); + XSetFunction(xs->display, xs->gc, GXxor); + XFillRectangle(xs->display, xs->dbuffer, xs->gc, x1, y1, w, h); + XSetFunction(xs->display, xs->gc, GXcopy); +} + static QEFont *x11_dpy_open_font(QEditScreen *s, int style, int size) { X11State *xs = s->priv_data; @@ -650,16 +644,26 @@ static void x11_dpy_fill_rectangle(QEditScreen *s, update_rect(xs, x1, y1, x1 + w, y1 + h); - if (color == QECOLOR_XOR) { - xor_rectangle(s, x1, y1, w, h); - return; - } - xcolor = get_x11_color(xs, color); XSetForeground(xs->display, xs->gc, xcolor); XFillRectangle(xs->display, xs->dbuffer, xs->gc, x1, y1, w, h); } +static void x11_dpy_xor_rectangle(QEditScreen *s, + int x1, int y1, int w, int h, QEColor color) +{ + X11State *xs = s->priv_data; + int fg; + + update_rect(xs, x1, y1, x1 + w, y1 + h); + + fg = WhitePixel(xs->display, xs->xscreen); + XSetForeground(xs->display, xs->gc, fg); + XSetFunction(xs->display, xs->gc, GXxor); + XFillRectangle(xs->display, xs->dbuffer, xs->gc, x1, y1, w, h); + XSetFunction(xs->display, xs->gc, GXcopy); +} + static void get_entry(char *buf, int buf_size, const char **pp) { const char *p, *r; @@ -1887,6 +1891,7 @@ static QEDisplay x11_dpy = { x11_dpy_flush, x11_dpy_is_user_input_pending, x11_dpy_fill_rectangle, + x11_dpy_xor_rectangle, x11_dpy_open_font, x11_dpy_close_font, x11_dpy_text_metrics,