diff --git a/defs.h b/defs.h index bf257117..74aca8b1 100644 --- a/defs.h +++ b/defs.h @@ -57,7 +57,8 @@ typedef struct LogPolicyVtable LogPolicyVtable; typedef struct Seat Seat; typedef struct SeatVtable SeatVtable; -typedef struct Frontend Frontend; +typedef struct TermWin TermWin; +typedef struct TermWinVtable TermWinVtable; typedef struct Ssh Ssh; diff --git a/fuzzterm.c b/fuzzterm.c index 32608d9f..d6a8337f 100644 --- a/fuzzterm.c +++ b/fuzzterm.c @@ -9,6 +9,8 @@ /* For Unix in particular, but harmless if this main() is reused elsewhere */ const int buildinfo_gtk_relevant = FALSE; +static const TermWinVtable fuzz_termwin_vt; + int main(int argc, char **argv) { char blk[512]; @@ -16,6 +18,9 @@ int main(int argc, char **argv) Terminal *term; Conf *conf; struct unicode_data ucsdata; + TermWin termwin; + + termwin.vt = &fuzz_termwin_vt; conf = conf_new(); do_defaults(NULL, conf); @@ -23,7 +28,7 @@ int main(int argc, char **argv) conf_get_int(conf, CONF_utf8_override), CS_NONE, conf_get_int(conf, CONF_vtmode)); - term = term_init(conf, &ucsdata, NULL); + term = term_init(conf, &ucsdata, &termwin); term_size(term, 24, 80, 10000); term->ldisc = NULL; /* Tell american fuzzy lop that this is a good place to fork. */ @@ -39,10 +44,10 @@ int main(int argc, char **argv) } /* functions required by terminal.c */ - -void request_resize(Frontend *frontend, int x, int y) { } -void do_text(Context ctx, int x, int y, wchar_t * text, int len, - unsigned long attr, int lattr, truecolour tc) +static int fuzz_setup_draw_ctx(TermWin *tw) { return TRUE; } +static void fuzz_draw_text( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour tc) { int i; @@ -52,8 +57,9 @@ void do_text(Context ctx, int x, int y, wchar_t * text, int len, } printf("\n"); } -void do_cursor(Context ctx, int x, int y, wchar_t * text, int len, - unsigned long attr, int lattr, truecolour tc) +static void fuzz_draw_cursor( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour tc) { int i; @@ -63,38 +69,69 @@ void do_cursor(Context ctx, int x, int y, wchar_t * text, int len, } printf("\n"); } -int char_width(Context ctx, int uc) { return 1; } -void set_title(Frontend *frontend, char *t) { } -void set_icon(Frontend *frontend, char *t) { } -void set_sbar(Frontend *frontend, int a, int b, int c) { } +static int fuzz_char_width(TermWin *tw, int uc) { return 1; } +static void fuzz_free_draw_ctx(TermWin *tw) {} +static void fuzz_set_cursor_pos(TermWin *tw, int x, int y) {} +static void fuzz_set_raw_mouse_mode(TermWin *tw, int enable) {} +static void fuzz_set_scrollbar(TermWin *tw, int total, int start, int page) {} +static void fuzz_bell(TermWin *tw, int mode) {} +static void fuzz_clip_write( + TermWin *tw, int clipboard, wchar_t *text, int *attrs, + truecolour *colours, int len, int must_deselect) {} +static void fuzz_clip_request_paste(TermWin *tw, int clipboard) {} +static void fuzz_refresh(TermWin *tw) {} +static void fuzz_request_resize(TermWin *tw, int w, int h) {} +static void fuzz_set_title(TermWin *tw, const char *title) {} +static void fuzz_set_icon_title(TermWin *tw, const char *icontitle) {} +static void fuzz_set_minimised(TermWin *tw, int minimised) {} +static int fuzz_is_minimised(TermWin *tw) { return FALSE; } +static void fuzz_set_maximised(TermWin *tw, int maximised) {} +static void fuzz_move(TermWin *tw, int x, int y) {} +static void fuzz_set_zorder(TermWin *tw, int top) {} +static int fuzz_palette_get(TermWin *tw, int n, int *r, int *g, int *b) +{ return FALSE; } +static void fuzz_palette_set(TermWin *tw, int n, int r, int g, int b) {} +static void fuzz_palette_reset(TermWin *tw) {} +static void fuzz_get_pos(TermWin *tw, int *x, int *y) { *x = *y = 0; } +static void fuzz_get_pixels(TermWin *tw, int *x, int *y) { *x = *y = 0; } +static const char *fuzz_get_title(TermWin *tw, int icon) { return "moo"; } +static int fuzz_is_utf8(TermWin *tw) { return TRUE; } + +static const TermWinVtable fuzz_termwin_vt = { + fuzz_setup_draw_ctx, + fuzz_draw_text, + fuzz_draw_cursor, + fuzz_char_width, + fuzz_free_draw_ctx, + fuzz_set_cursor_pos, + fuzz_set_raw_mouse_mode, + fuzz_set_scrollbar, + fuzz_bell, + fuzz_clip_write, + fuzz_clip_request_paste, + fuzz_refresh, + fuzz_request_resize, + fuzz_set_title, + fuzz_set_icon_title, + fuzz_set_minimised, + fuzz_is_minimised, + fuzz_set_maximised, + fuzz_move, + fuzz_set_zorder, + fuzz_palette_get, + fuzz_palette_set, + fuzz_palette_reset, + fuzz_get_pos, + fuzz_get_pixels, + fuzz_get_title, + fuzz_is_utf8, +}; void ldisc_send(Ldisc *ldisc, const void *buf, int len, int interactive) {} void ldisc_echoedit_update(Ldisc *ldisc) {} -Context get_ctx(Frontend *frontend) { return NULL; } -void free_ctx(Context ctx) { } -void palette_set(Frontend *frontend, int a, int b, int c, int d) { } -void palette_reset(Frontend *frontend) { } -int palette_get(Frontend *frontend, int n, int *r, int *g, int *b) {return FALSE;} -void write_clip(Frontend *frontend, int clipboard, - wchar_t *a, int *b, truecolour *c, int d, int e) { } -void set_raw_mouse_mode(Frontend *frontend, int m) { } -void frontend_request_paste(Frontend *frontend, int clipboard) { } -void do_beep(Frontend *frontend, int a) { } -void sys_cursor(Frontend *frontend, int x, int y) { } void modalfatalbox(const char *fmt, ...) { exit(0); } void nonfatal(const char *fmt, ...) { } -void set_iconic(Frontend *frontend, int iconic) { } -void move_window(Frontend *frontend, int x, int y) { } -void set_zorder(Frontend *frontend, int top) { } -void refresh_window(Frontend *frontend) { } -void set_zoomed(Frontend *frontend, int zoomed) { } -int is_iconic(Frontend *frontend) { return 0; } -void get_window_pos(Frontend *frontend, int *x, int *y) { *x = 0; *y = 0; } -void get_window_pixels(Frontend *frontend, int *x, int *y) { *x = 0; *y = 0; } -char *get_window_title(Frontend *frontend, int icon) { return "moo"; } -int frontend_is_utf8(Frontend *frontend) { return TRUE; } - /* needed by timing.c */ void timer_change_notify(unsigned long next) { } @@ -173,5 +210,3 @@ char *x_get_default(const char *key) { return NULL; /* this is a stub */ } - - diff --git a/putty.h b/putty.h index da6a175e..010935a7 100644 --- a/putty.h +++ b/putty.h @@ -1012,46 +1012,139 @@ int console_confirm_weak_cached_hostkey( int filexfer_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input); /* - * Exports from the front end. + * Data type 'TermWin', which is a vtable encapsulating all the + * functionality that Terminal expects from its containing terminal + * window. + */ +struct TermWin { + const struct TermWinVtable *vt; +}; +struct TermWinVtable { + /* + * All functions listed here between setup_draw_ctx and + * free_draw_ctx expect to be _called_ between them too, so that + * the TermWin has a drawing context currently available. + * + * (Yes, even char_width, because e.g. the Windows implementation + * of TermWin handles it by loading the currently configured font + * into the HDC and doing a GDI query.) + */ + int (*setup_draw_ctx)(TermWin *); + /* Draw text in the window, during a painting operation */ + void (*draw_text)(TermWin *, int x, int y, wchar_t *text, int len, + unsigned long attrs, int line_attrs, truecolour tc); + /* Draw the visible cursor. Expects you to have called do_text + * first (because it might just draw an underline over a character + * presumed to exist already), but also expects you to pass in all + * the details of the character under the cursor (because it might + * redraw it in different colours). */ + void (*draw_cursor)(TermWin *, int x, int y, wchar_t *text, int len, + unsigned long attrs, int line_attrs, truecolour tc); + int (*char_width)(TermWin *, int uc); + void (*free_draw_ctx)(TermWin *); + + void (*set_cursor_pos)(TermWin *, int x, int y); + + void (*set_raw_mouse_mode)(TermWin *, int enable); + + void (*set_scrollbar)(TermWin *, int total, int start, int page); + + void (*bell)(TermWin *, int mode); + + void (*clip_write)(TermWin *, int clipboard, wchar_t *text, int *attrs, + truecolour *colours, int len, int must_deselect); + void (*clip_request_paste)(TermWin *, int clipboard); + + void (*refresh)(TermWin *); + + void (*request_resize)(TermWin *, int w, int h); + + void (*set_title)(TermWin *, const char *title); + void (*set_icon_title)(TermWin *, const char *icontitle); + /* set_minimised and set_maximised are assumed to set two + * independent settings, rather than a single three-way + * {min,normal,max} switch. The idea is that when you un-minimise + * the window it remembers whether to go back to normal or + * maximised. */ + void (*set_minimised)(TermWin *, int minimised); + int (*is_minimised)(TermWin *); + void (*set_maximised)(TermWin *, int maximised); + void (*move)(TermWin *, int x, int y); + void (*set_zorder)(TermWin *, int top); + + int (*palette_get)(TermWin *, int n, int *r, int *g, int *b); + void (*palette_set)(TermWin *, int n, int r, int g, int b); + void (*palette_reset)(TermWin *); + + void (*get_pos)(TermWin *, int *x, int *y); + void (*get_pixels)(TermWin *, int *x, int *y); + const char *(*get_title)(TermWin *, int icon); + int (*is_utf8)(TermWin *); +}; + +#define win_setup_draw_ctx(win) \ + ((win)->vt->setup_draw_ctx(win)) +#define win_draw_text(win, x, y, text, len, attrs, lattrs, tc) \ + ((win)->vt->draw_text(win, x, y, text, len, attrs, lattrs, tc)) +#define win_draw_cursor(win, x, y, text, len, attrs, lattrs, tc) \ + ((win)->vt->draw_cursor(win, x, y, text, len, attrs, lattrs, tc)) +#define win_char_width(win, uc) \ + ((win)->vt->char_width(win, uc)) +#define win_free_draw_ctx(win) \ + ((win)->vt->free_draw_ctx(win)) +#define win_set_cursor_pos(win, x, y) \ + ((win)->vt->set_cursor_pos(win, x, y)) +#define win_set_raw_mouse_mode(win, enable) \ + ((win)->vt->set_raw_mouse_mode(win, enable)) +#define win_set_scrollbar(win, total, start, page) \ + ((win)->vt->set_scrollbar(win, total, start, page)) +#define win_bell(win, mode) \ + ((win)->vt->bell(win, mode)) +#define win_clip_write(win, clipboard, text, attrs, colours, len, desel) \ + ((win)->vt->clip_write(win, clipboard, text, attrs, colours, len, desel)) +#define win_clip_request_paste(win, clipboard) \ + ((win)->vt->clip_request_paste(win, clipboard)) +#define win_refresh(win) \ + ((win)->vt->refresh(win)) +#define win_request_resize(win, w, h) \ + ((win)->vt->request_resize(win, w, h)) +#define win_set_title(win, title) \ + ((win)->vt->set_title(win, title)) +#define win_set_icon_title(win, ititle) \ + ((win)->vt->set_icon_title(win, ititle)) +#define win_set_minimised(win, minimised) \ + ((win)->vt->set_minimised(win, minimised)) +#define win_is_minimised(win) \ + ((win)->vt->is_minimised(win)) +#define win_set_maximised(win, maximised) \ + ((win)->vt->set_maximised(win, maximised)) +#define win_move(win, x, y) \ + ((win)->vt->move(win, x, y)) +#define win_set_zorder(win, top) \ + ((win)->vt->set_zorder(win, top)) +#define win_palette_get(win, n, r, g, b) \ + ((win)->vt->palette_get(win, n, r, g, b)) +#define win_palette_set(win, n, r, g, b) \ + ((win)->vt->palette_set(win, n, r, g, b)) +#define win_palette_reset(win) \ + ((win)->vt->palette_reset(win)) +#define win_get_pos(win, x, y) \ + ((win)->vt->get_pos(win, x, y)) +#define win_get_pixels(win, x, y) \ + ((win)->vt->get_pixels(win, x, y)) +#define win_get_title(win, icon) \ + ((win)->vt->get_title(win, icon)) +#define win_is_utf8(win) \ + ((win)->vt->is_utf8(win)) + +/* + * Global functions not specific to a connection instance. */ -void request_resize(Frontend *frontend, int, int); -void do_text(Context, int, int, wchar_t *, int, unsigned long, int, - truecolour); -void do_cursor(Context, int, int, wchar_t *, int, unsigned long, int, - truecolour); -int char_width(Context ctx, int uc); -void set_title(Frontend *frontend, char *); -void set_icon(Frontend *frontend, char *); -void set_sbar(Frontend *frontend, int, int, int); -Context get_ctx(Frontend *frontend); -void free_ctx(Context); -void palette_set(Frontend *frontend, int, int, int, int); -void palette_reset(Frontend *frontend); -int palette_get(Frontend *frontend, int n, int *r, int *g, int *b); -void write_clip(Frontend *frontend, int clipboard, wchar_t *, int *, - truecolour *, int, int); -void optimised_move(Frontend *frontend, int, int, int); -void set_raw_mouse_mode(Frontend *frontend, int); void nonfatal(const char *, ...); void modalfatalbox(const char *, ...); #ifdef macintosh #pragma noreturn(modalfatalbox) #endif -void do_beep(Frontend *frontend, int); -void sys_cursor(Frontend *frontend, int x, int y); -void frontend_request_paste(Frontend *frontend, int clipboard); - -void set_iconic(Frontend *frontend, int iconic); -void move_window(Frontend *frontend, int x, int y); -void set_zorder(Frontend *frontend, int top); -void refresh_window(Frontend *frontend); -void set_zoomed(Frontend *frontend, int zoomed); -int is_iconic(Frontend *frontend); -void get_window_pos(Frontend *frontend, int *x, int *y); -void get_window_pixels(Frontend *frontend, int *x, int *y); -char *get_window_title(Frontend *frontend, int icon); -int frontend_is_utf8(Frontend *frontend); - void cleanup_exit(int); /* @@ -1407,10 +1500,10 @@ FontSpec *platform_default_fontspec(const char *name); * Exports from terminal.c. */ -Terminal *term_init(Conf *, struct unicode_data *, Frontend *); +Terminal *term_init(Conf *, struct unicode_data *, TermWin *); void term_free(Terminal *); void term_size(Terminal *, int, int, int); -void term_paint(Terminal *, Context, int, int, int, int, int); +void term_paint(Terminal *, int, int, int, int, int); void term_scroll(Terminal *, int, int); void term_scroll_to_selection(Terminal *, int); void term_pwron(Terminal *, int); diff --git a/terminal.c b/terminal.c index 01fd8da0..6708c61a 100644 --- a/terminal.c +++ b/terminal.c @@ -101,7 +101,7 @@ static void resizeline(Terminal *, termline *, int); static termline *lineptr(Terminal *, int, int, int); static void unlineptr(termline *); static void check_line_size(Terminal *, termline *); -static void do_paint(Terminal *, Context); +static void do_paint(Terminal *); static void erase_lots(Terminal *, int, int, int); static int find_last_nonempty_line(Terminal *, tree234 *); static void swap_screen(Terminal *, int, int, int); @@ -1317,7 +1317,7 @@ static void power_on(Terminal *term, int clear) term->xterm_mouse = 0; term->xterm_extended_mouse = 0; term->urxvt_extended_mouse = 0; - set_raw_mouse_mode(term->frontend, FALSE); + win_set_raw_mouse_mode(term->win, FALSE); term->bracketed_paste = FALSE; { int i; @@ -1348,12 +1348,9 @@ static void power_on(Terminal *term, int clear) */ void term_update(Terminal *term) { - Context ctx; - term->window_update_pending = FALSE; - ctx = get_ctx(term->frontend); - if (ctx) { + if (win_setup_draw_ctx(term->win)) { int need_sbar_update = term->seen_disp_event; if (term->seen_disp_event && term->scroll_on_disp) { term->disptop = 0; /* return to main screen */ @@ -1363,9 +1360,10 @@ void term_update(Terminal *term) if (need_sbar_update) update_sbar(term); - do_paint(term, ctx); - sys_cursor(term->frontend, term->curs.x, term->curs.y - term->disptop); - free_ctx(ctx); + do_paint(term); + win_set_cursor_pos( + term->win, term->curs.x, term->curs.y - term->disptop); + win_free_draw_ctx(term->win); } } @@ -1568,7 +1566,7 @@ void term_reconfig(Terminal *term, Conf *conf) swap_screen(term, 0, FALSE, FALSE); if (conf_get_int(term->conf, CONF_no_mouse_rep)) { term->xterm_mouse = 0; - set_raw_mouse_mode(term->frontend, 0); + win_set_raw_mouse_mode(term->win, 0); } if (conf_get_int(term->conf, CONF_no_remote_charset)) { term->cset_attr[0] = term->cset_attr[1] = CSET_ASCII; @@ -1635,8 +1633,7 @@ const optionalrgb optionalrgb_none = {0, 0, 0, 0}; /* * Initialise the terminal. */ -Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, - Frontend *frontend) +Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win) { Terminal *term; @@ -1645,7 +1642,7 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, * that need it. */ term = snew(Terminal); - term->frontend = frontend; + term->win = win; term->ucsdata = ucsdata; term->conf = conf_copy(myconf); term->logctx = NULL; @@ -1712,8 +1709,8 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, term->last_selected_attr = NULL; term->last_selected_tc = NULL; term->last_selected_len = 0; - /* frontends will typically extend these with clipboard ids they - * know about */ + /* TermWin implementations will typically extend these with + * clipboard ids they know about */ term->mouse_select_clipboards[0] = CLIP_LOCAL; term->n_mouse_select_clipboards = 1; term->mouse_paste_clipboard = CLIP_NULL; @@ -2097,8 +2094,8 @@ static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos) static void update_sbar(Terminal *term) { int nscroll = sblines(term); - set_sbar(term->frontend, nscroll + term->rows, - nscroll + term->disptop, term->rows); + win_set_scrollbar(term->win, nscroll + term->rows, + nscroll + term->disptop, term->rows); } /* @@ -2533,7 +2530,7 @@ static void toggle_mode(Terminal *term, int mode, int query, int state) case 3: /* DECCOLM: 80/132 columns */ deselect(term); if (!term->no_remote_resize) - request_resize(term->frontend, state ? 132 : 80, term->rows); + win_request_resize(term->win, state ? 132 : 80, term->rows); term->reset_132 = state; term->alt_t = term->marg_t = 0; term->alt_b = term->marg_b = term->rows - 1; @@ -2585,11 +2582,11 @@ static void toggle_mode(Terminal *term, int mode, int query, int state) break; case 1000: /* xterm mouse 1 (normal) */ term->xterm_mouse = state ? 1 : 0; - set_raw_mouse_mode(term->frontend, state); + win_set_raw_mouse_mode(term->win, state); break; case 1002: /* xterm mouse 2 (inc. button drags) */ term->xterm_mouse = state ? 2 : 0; - set_raw_mouse_mode(term->frontend, state); + win_set_raw_mouse_mode(term->win, state); break; case 1006: /* xterm extended mouse */ term->xterm_extended_mouse = state ? 1 : 0; @@ -2659,20 +2656,20 @@ static void do_osc(Terminal *term) case 0: case 1: if (!term->no_remote_wintitle) - set_icon(term->frontend, term->osc_string); + win_set_icon_title(term->win, term->osc_string); if (term->esc_args[0] == 1) break; /* fall through: parameter 0 means set both */ case 2: case 21: if (!term->no_remote_wintitle) - set_title(term->frontend, term->osc_string); + win_set_title(term->win, term->osc_string); break; case 4: if (term->ldisc && !strcmp(term->osc_string, "?")) { int r, g, b; - if (palette_get(term->frontend, toint(term->esc_args[1]), - &r, &g, &b)) { + if (win_palette_get(term->win, toint(term->esc_args[1]), + &r, &g, &b)) { char *reply_buf = dupprintf( "\033]4;%u;rgb:%04x/%04x/%04x\007", term->esc_args[1], @@ -3182,7 +3179,7 @@ static void term_out(Terminal *term) * Perform an actual beep if we're not overloaded. */ if (!term->bellovl || !term->beep_overloaded) { - do_beep(term->frontend, term->beep); + win_bell(term->win, term->beep); if (term->beep == BELL_VISUAL) { term_schedule_vbell(term, FALSE, 0); @@ -3383,7 +3380,7 @@ static void term_out(Terminal *term) ldisc_echoedit_update(term->ldisc); if (term->reset_132) { if (!term->no_remote_resize) - request_resize(term->frontend, 80, term->rows); + win_request_resize(term->win, 80, term->rows); term->reset_132 = 0; } if (term->scroll_on_disp) @@ -4027,8 +4024,8 @@ static void term_out(Terminal *term) term->esc_args[0] >= 24)) { compatibility(VT340TEXT); if (!term->no_remote_resize) - request_resize(term->frontend, term->cols, - def(term->esc_args[0], 24)); + win_request_resize(term->win, term->cols, + def(term->esc_args[0], 24)); deselect(term); } else if (term->esc_nargs >= 1 && term->esc_args[0] >= 1 && @@ -4040,17 +4037,17 @@ static void term_out(Terminal *term) char buf[80]; const char *p; case 1: - set_iconic(term->frontend, FALSE); + win_set_minimised(term->win, FALSE); break; case 2: - set_iconic(term->frontend, TRUE); + win_set_minimised(term->win, TRUE); break; case 3: if (term->esc_nargs >= 3) { if (!term->no_remote_resize) - move_window(term->frontend, - def(term->esc_args[1], 0), - def(term->esc_args[2], 0)); + win_move(term->win, + def(term->esc_args[1], 0), + def(term->esc_args[2], 0)); } break; case 4: @@ -4061,38 +4058,41 @@ static void term_out(Terminal *term) break; case 5: /* move to top */ - set_zorder(term->frontend, TRUE); + win_set_zorder(term->win, TRUE); break; case 6: /* move to bottom */ - set_zorder(term->frontend, FALSE); + win_set_zorder(term->win, FALSE); break; case 7: - refresh_window(term->frontend); + win_refresh(term->win); break; case 8: if (term->esc_nargs >= 3) { if (!term->no_remote_resize) - request_resize(term->frontend, - def(term->esc_args[2], term->conf_width), - def(term->esc_args[1], term->conf_height)); + win_request_resize( + term->win, + def(term->esc_args[2], + term->conf_width), + def(term->esc_args[1], + term->conf_height)); } break; case 9: if (term->esc_nargs >= 2) - set_zoomed(term->frontend, - term->esc_args[1] ? - TRUE : FALSE); + win_set_maximised( + term->win, + term->esc_args[1] ? TRUE : FALSE); break; case 11: if (term->ldisc) ldisc_send(term->ldisc, - is_iconic(term->frontend) ? + win_is_minimised(term->win) ? "\033[2t" : "\033[1t", 4, 0); break; case 13: if (term->ldisc) { - get_window_pos(term->frontend, &x, &y); + win_get_pos(term->win, &x, &y); len = sprintf(buf, "\033[3;%u;%ut", (unsigned)x, (unsigned)y); @@ -4101,7 +4101,7 @@ static void term_out(Terminal *term) break; case 14: if (term->ldisc) { - get_window_pixels(term->frontend, &x, &y); + win_get_pixels(term->win, &x, &y); len = sprintf(buf, "\033[4;%d;%dt", y, x); ldisc_send(term->ldisc, buf, len, 0); } @@ -4134,7 +4134,7 @@ static void term_out(Terminal *term) if (term->ldisc && term->remote_qtitle_action != TITLE_NONE) { if(term->remote_qtitle_action == TITLE_REAL) - p = get_window_title(term->frontend, TRUE); + p = win_get_title(term->win, TRUE); else p = EMPTY_WINDOW_TITLE; len = strlen(p); @@ -4148,7 +4148,7 @@ static void term_out(Terminal *term) if (term->ldisc && term->remote_qtitle_action != TITLE_NONE) { if(term->remote_qtitle_action == TITLE_REAL) - p = get_window_title(term->frontend, FALSE); + p = win_get_title(term->win, FALSE); else p = EMPTY_WINDOW_TITLE; len = strlen(p); @@ -4187,9 +4187,9 @@ static void term_out(Terminal *term) compatibility(VT420); if (term->esc_nargs == 1 && term->esc_args[0] > 0) { if (!term->no_remote_resize) - request_resize(term->frontend, term->cols, - def(term->esc_args[0], - term->conf_height)); + win_request_resize(term->win, term->cols, + def(term->esc_args[0], + term->conf_height)); deselect(term); } break; @@ -4202,10 +4202,10 @@ static void term_out(Terminal *term) compatibility(VT340TEXT); if (term->esc_nargs <= 1) { if (!term->no_remote_resize) - request_resize(term->frontend, - def(term->esc_args[0], - term->conf_width), - term->rows); + win_request_resize( + term->win, + def(term->esc_args[0], term->conf_width), + term->rows); deselect(term); } break; @@ -4413,9 +4413,9 @@ static void term_out(Terminal *term) if (!has_compat(VT420) && has_compat(VT100)) { if (!term->no_remote_resize) { if (term->reset_132) - request_resize(132, 24); + win_request_resize(term->win, 132, 24); else - request_resize(80, 24); + win_request_resize(term->win, 80, 24); } } #endif @@ -4430,7 +4430,7 @@ static void term_out(Terminal *term) term->osc_strlen = 0; break; case 'R': /* Linux palette reset */ - palette_reset(term->frontend); + win_palette_reset(term->win); term_invalidate(term); term->termstate = TOPLEVEL; break; @@ -4528,10 +4528,11 @@ static void term_out(Terminal *term) } term->osc_string[term->osc_strlen++] = val; if (term->osc_strlen >= 7) { - palette_set(term->frontend, term->osc_string[0], - term->osc_string[1] * 16 + term->osc_string[2], - term->osc_string[3] * 16 + term->osc_string[4], - term->osc_string[5] * 16 + term->osc_string[6]); + win_palette_set( + term->win, term->osc_string[0], + term->osc_string[1] * 16 + term->osc_string[2], + term->osc_string[3] * 16 + term->osc_string[4], + term->osc_string[5] * 16 + term->osc_string[6]); term_invalidate(term); term->termstate = TOPLEVEL; } @@ -5024,7 +5025,7 @@ static termchar *term_bidi_line(Terminal *term, struct termline *ldata, /* * Given a context, update the window. */ -static void do_paint(Terminal *term, Context ctx) +static void do_paint(Terminal *term) { int i, j, our_curs_y, our_curs_x; int rv, cursor; @@ -5209,7 +5210,8 @@ static void do_paint(Terminal *term, Context ctx) if (tchar != term->disptext[i]->chars[j].chr || tattr != (term->disptext[i]->chars[j].attr &~ (ATTR_NARROW | DATTR_MASK))) { - if ((tattr & ATTR_WIDE) == 0 && char_width(ctx, tchar) == 2) + if ((tattr & ATTR_WIDE) == 0 && + win_char_width(term->win, tchar) == 2) tattr |= ATTR_NARROW; } else if (term->disptext[i]->chars[j].attr & ATTR_NARROW) tattr |= ATTR_NARROW; @@ -5324,10 +5326,11 @@ static void do_paint(Terminal *term, Context ctx) if (break_run) { if ((dirty_run || last_run_dirty) && ccount > 0) { - do_text(ctx, start, i, ch, ccount, attr, ldata->lattr, tc); + win_draw_text(term->win, start, i, ch, ccount, + attr, ldata->lattr, tc); if (attr & (TATTR_ACTCURS | TATTR_PASCURS)) - do_cursor(ctx, start, i, ch, ccount, attr, - ldata->lattr, tc); + win_draw_cursor(term->win, start, i, ch, ccount, attr, + ldata->lattr, tc); } start = j; ccount = 0; @@ -5423,9 +5426,11 @@ static void do_paint(Terminal *term, Context ctx) } } if (dirty_run && ccount > 0) { - do_text(ctx, start, i, ch, ccount, attr, ldata->lattr, tc); + win_draw_text(term->win, start, i, ch, ccount, + attr, ldata->lattr, tc); if (attr & (TATTR_ACTCURS | TATTR_PASCURS)) - do_cursor(ctx, start, i, ch, ccount, attr, ldata->lattr, tc); + win_draw_cursor(term->win, start, i, ch, ccount, + attr, ldata->lattr, tc); } unlineptr(ldata); @@ -5452,7 +5457,7 @@ void term_invalidate(Terminal *term) /* * Paint the window in response to a WM_PAINT message. */ -void term_paint(Terminal *term, Context ctx, +void term_paint(Terminal *term, int left, int top, int right, int bottom, int immediately) { int i, j; @@ -5471,7 +5476,7 @@ void term_paint(Terminal *term, Context ctx, } if (immediately) { - do_paint (term, ctx); + do_paint(term); } else { term_schedule_update(term); } @@ -5722,9 +5727,9 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel, if (clipboards[i] == CLIP_LOCAL) { clip_local = TRUE; } else if (clipboards[i] != CLIP_NULL) { - write_clip(term->frontend, clipboards[i], - buf.textbuf, buf.attrbuf, buf.tcbuf, buf.bufpos, - desel); + win_clip_write( + term->win, clipboards[i], buf.textbuf, buf.attrbuf, + buf.tcbuf, buf.bufpos, desel); } } if (clip_local) { @@ -5767,12 +5772,10 @@ void term_request_copy(Terminal *term, const int *clipboards, int n_clipboards) for (i = 0; i < n_clipboards; i++) { assert(clipboards[i] != CLIP_LOCAL); if (clipboards[i] != CLIP_NULL) { - write_clip(term->frontend, clipboards[i], - term->last_selected_text, - term->last_selected_attr, - term->last_selected_tc, - term->last_selected_len, - FALSE); + win_clip_write(term->win, clipboards[i], + term->last_selected_text, term->last_selected_attr, + term->last_selected_tc, term->last_selected_len, + FALSE); } } } @@ -5787,7 +5790,7 @@ void term_request_paste(Terminal *term, int clipboard) queue_toplevel_callback(paste_from_clip_local, term); break; default: - frontend_request_paste(term->frontend, clipboard); + win_clip_request_paste(term->win, clipboard); break; } } @@ -6582,7 +6585,7 @@ char *term_get_ttymode(Terminal *term, const char *mode) if (strcmp(mode, "ERASE") == 0) { val = term->bksp_is_delete ? "^?" : "^H"; } else if (strcmp(mode, "IUTF8") == 0) { - val = frontend_is_utf8(term->frontend) ? "yes" : "no"; + val = win_is_utf8(term->win) ? "yes" : "no"; } /* FIXME: perhaps we should set ONLCR based on lfhascr as well? */ /* FIXME: or ECHO and friends based on local echo state? */ diff --git a/terminal.h b/terminal.h index 5129149c..b63d42e9 100644 --- a/terminal.h +++ b/terminal.h @@ -218,7 +218,7 @@ struct terminal_tag { Ldisc *ldisc; - Frontend *frontend; + TermWin *win; LogContext *logctx; diff --git a/unix/gtkapp.c b/unix/gtkapp.c index f79e5e9a..2629e684 100644 --- a/unix/gtkapp.c +++ b/unix/gtkapp.c @@ -99,7 +99,7 @@ int main(int argc, char **argv) fprintf(stderr, "GtkApplication frontend doesn't work pre-GTK3\n"); return 1; } -GtkWidget *make_gtk_toplevel_window(Frontend *frontend) { return NULL; } +GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend) { return NULL; } void launch_duplicate_session(Conf *conf) {} void launch_new_session(void) {} void launch_saved_session(const char *str) {} @@ -204,7 +204,7 @@ WIN_ACTION_LIST(WIN_ACTION_ENTRY) }; static GtkApplication *app; -GtkWidget *make_gtk_toplevel_window(Frontend *frontend) +GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend) { GtkWidget *win = gtk_application_window_new(app); g_action_map_add_action_entries(G_ACTION_MAP(win), diff --git a/unix/gtkmain.c b/unix/gtkmain.c index a97f7415..8829dbfa 100644 --- a/unix/gtkmain.c +++ b/unix/gtkmain.c @@ -549,7 +549,7 @@ int do_cmdline(int argc, char **argv, int do_everything, Conf *conf) return err; } -GtkWidget *make_gtk_toplevel_window(Frontend *frontend) +GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend) { return gtk_window_new(GTK_WINDOW_TOPLEVEL); } diff --git a/unix/gtkwin.c b/unix/gtkwin.c index c364afe2..0868d2fd 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -76,7 +76,7 @@ struct clipboard_data_instance { #endif struct clipboard_state { - Frontend *inst; + GtkFrontend *inst; int clipboard; GdkAtom atom; #ifdef JUST_USE_GTK_CLIPBOARD_UTF8 @@ -88,7 +88,7 @@ struct clipboard_state { #endif }; -struct Frontend { +struct GtkFrontend { GtkWidget *window, *area, *sbar; gboolean sbar_visible; gboolean drawing_area_got_size, drawing_area_realised; @@ -143,7 +143,7 @@ struct Frontend { struct clipboard_state clipstates[N_CLIPBOARDS]; #ifdef JUST_USE_GTK_CLIPBOARD_UTF8 /* Remember all clipboard_data_instance structures currently - * associated with this gui_data, in case they're still around + * associated with this GtkFrontend, in case they're still around * when it gets destroyed */ struct clipboard_data_instance cdi_headtail; #endif @@ -180,12 +180,14 @@ struct Frontend { #ifdef OSX_META_KEY_CONFIG int system_mod_mask; #endif + unifont_drawctx uctx; Seat seat; + TermWin termwin; LogPolicy logpolicy; }; -static void cache_conf_values(Frontend *inst) +static void cache_conf_values(GtkFrontend *inst) { inst->bold_style = conf_get_int(inst->conf, CONF_bold_style); inst->window_border = conf_get_int(inst->conf, CONF_window_border); @@ -202,33 +204,28 @@ static void cache_conf_values(Frontend *inst) #endif } -struct draw_ctx { - Frontend *inst; - unifont_drawctx uctx; -}; - static int send_raw_mouse; -static void start_backend(Frontend *inst); +static void start_backend(GtkFrontend *inst); static void exit_callback(void *vinst); -static void destroy_inst_connection(Frontend *inst); -static void delete_inst(Frontend *inst); +static void destroy_inst_connection(GtkFrontend *inst); +static void delete_inst(GtkFrontend *inst); static void post_fatal_message_box_toplevel(void *vctx) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; gtk_widget_destroy(inst->window); } static void post_fatal_message_box(void *vctx, int result) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; unregister_dialog(&inst->seat, DIALOG_SLOT_CONNECTION_FATAL); queue_toplevel_callback(post_fatal_message_box_toplevel, inst); } static void common_connfatal_message_box( - Frontend *inst, const char *msg, post_dialog_fn_t postfn) + GtkFrontend *inst, const char *msg, post_dialog_fn_t postfn) { char *title = dupcat(appname, " Fatal Error", NULL); GtkWidget *dialog = create_message_box( @@ -239,26 +236,26 @@ static void common_connfatal_message_box( sfree(title); } -void fatal_message_box(Frontend *inst, const char *msg) +void fatal_message_box(GtkFrontend *inst, const char *msg) { common_connfatal_message_box(inst, msg, post_fatal_message_box); } static void connection_fatal_callback(void *vctx) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; destroy_inst_connection(inst); } static void post_nonfatal_message_box(void *vctx, int result) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; unregister_dialog(&inst->seat, DIALOG_SLOT_CONNECTION_FATAL); } static void gtk_seat_connection_fatal(Seat *seat, const char *msg) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); if (conf_get_int(inst->conf, CONF_close_on_exit) == FORCE_ON) { fatal_message_box(inst, msg); } else { @@ -306,27 +303,27 @@ int platform_default_i(const char *name, int def) static char *gtk_seat_get_ttymode(Seat *seat, const char *mode) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); return term_get_ttymode(inst->term, mode); } static int gtk_seat_output(Seat *seat, int is_stderr, const void *data, int len) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); return term_data(inst->term, is_stderr, data, len); } static int gtk_seat_eof(Seat *seat) { - /* Frontend *inst = container_of(seat, Frontend, seat); */ + /* GtkFrontend *inst = container_of(seat, GtkFrontend, seat); */ return TRUE; /* do respond to incoming EOF with outgoing */ } static int gtk_seat_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); int ret; ret = cmdline_get_passwd_input(p); if (ret == -1) @@ -336,14 +333,14 @@ static int gtk_seat_get_userpass_input(Seat *seat, prompts_t *p, static int gtk_seat_is_utf8(Seat *seat) { - Frontend *inst = container_of(seat, Frontend, seat); - return frontend_is_utf8(inst); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); + return win_is_utf8(&inst->termwin); } static int gtk_seat_get_window_pixel_size(Seat *seat, int *w, int *h) { - Frontend *inst = container_of(seat, Frontend, seat); - get_window_pixels(inst, w, h); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); + win_get_pixels(&inst->termwin, w, h); return TRUE; } @@ -380,20 +377,20 @@ static const SeatVtable gtk_seat_vt = { static void gtk_eventlog(LogPolicy *lp, const char *string) { - Frontend *inst = container_of(lp, Frontend, logpolicy); + GtkFrontend *inst = container_of(lp, GtkFrontend, logpolicy); logevent_dlg(inst->eventlogstuff, string); } static int gtk_askappend(LogPolicy *lp, Filename *filename, void (*callback)(void *ctx, int result), void *ctx) { - Frontend *inst = container_of(lp, Frontend, logpolicy); + GtkFrontend *inst = container_of(lp, GtkFrontend, logpolicy); return gtkdlg_askappend(&inst->seat, filename, callback, ctx); } static void gtk_logging_error(LogPolicy *lp, const char *event) { - Frontend *inst = container_of(lp, Frontend, logpolicy); + GtkFrontend *inst = container_of(lp, GtkFrontend, logpolicy); /* Send 'can't open log file' errors to the terminal window. * (Marked as stderr, although terminal.c won't care.) */ @@ -433,7 +430,7 @@ static Mouse_Button translate_button(Mouse_Button button) */ GtkWidget *gtk_seat_get_window(Seat *seat) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); return inst->window; } @@ -444,18 +441,18 @@ GtkWidget *gtk_seat_get_window(Seat *seat) */ void register_dialog(Seat *seat, enum DialogSlot slot, GtkWidget *dialog) { - Frontend *inst; + GtkFrontend *inst; assert(seat->vt == >k_seat_vt); - inst = container_of(seat, Frontend, seat); + inst = container_of(seat, GtkFrontend, seat); assert(slot < DIALOG_SLOT_LIMIT); assert(!inst->dialogs[slot]); inst->dialogs[slot] = dialog; } void unregister_dialog(Seat *seat, enum DialogSlot slot) { - Frontend *inst; + GtkFrontend *inst; assert(seat->vt == >k_seat_vt); - inst = container_of(seat, Frontend, seat); + inst = container_of(seat, GtkFrontend, seat); assert(slot < DIALOG_SLOT_LIMIT); assert(inst->dialogs[slot]); inst->dialogs[slot] = NULL; @@ -465,13 +462,14 @@ void unregister_dialog(Seat *seat, enum DialogSlot slot) * Minimise or restore the window in response to a server-side * request. */ -void set_iconic(Frontend *inst, int iconic) +static void gtkwin_set_minimised(TermWin *tw, int minimised) { /* * GTK 1.2 doesn't know how to do this. */ #if GTK_CHECK_VERSION(2,0,0) - if (iconic) + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); + if (minimised) gtk_window_iconify(GTK_WINDOW(inst->window)); else gtk_window_deiconify(GTK_WINDOW(inst->window)); @@ -481,8 +479,9 @@ void set_iconic(Frontend *inst, int iconic) /* * Move the window in response to a server-side request. */ -void move_window(Frontend *inst, int x, int y) +static void gtkwin_move(TermWin *tw, int x, int y) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -501,8 +500,9 @@ void move_window(Frontend *inst, int x, int y) * Move the window to the top or bottom of the z-order in response * to a server-side request. */ -void set_zorder(Frontend *inst, int top) +static void gtkwin_set_zorder(TermWin *tw, int top) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); if (top) gdk_window_raise(gtk_widget_get_window(inst->window)); else @@ -512,8 +512,9 @@ void set_zorder(Frontend *inst, int top) /* * Refresh the window in response to a server-side request. */ -void refresh_window(Frontend *inst) +static void gtkwin_refresh(TermWin *tw) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); term_invalidate(inst->term); } @@ -521,13 +522,14 @@ void refresh_window(Frontend *inst) * Maximise or restore the window in response to a server-side * request. */ -void set_zoomed(Frontend *inst, int zoomed) +static void gtkwin_set_maximised(TermWin *tw, int maximised) { /* * GTK 1.2 doesn't know how to do this. */ #if GTK_CHECK_VERSION(2,0,0) - if (zoomed) + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); + if (maximised) gtk_window_maximize(GTK_WINDOW(inst->window)); else gtk_window_unmaximize(GTK_WINDOW(inst->window)); @@ -535,18 +537,20 @@ void set_zoomed(Frontend *inst, int zoomed) } /* - * Report whether the window is iconic, for terminal reports. + * Report whether the window is minimised, for terminal reports. */ -int is_iconic(Frontend *inst) +static int gtkwin_is_minimised(TermWin *tw) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); return !gdk_window_is_viewable(gtk_widget_get_window(inst->window)); } /* * Report the window's position, for terminal reports. */ -void get_window_pos(Frontend *inst, int *x, int *y) +static void gtkwin_get_pos(TermWin *tw, int *x, int *y) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -562,8 +566,9 @@ void get_window_pos(Frontend *inst, int *x, int *y) /* * Report the window's pixel size, for terminal reports. */ -void get_window_pixels(Frontend *inst, int *x, int *y) +static void gtkwin_get_pixels(TermWin *tw, int *x, int *y) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); /* * I assume that when the GTK version of this call is available * we should use it. Not sure how it differs from the GDK one, @@ -582,7 +587,7 @@ void get_window_pixels(Frontend *inst, int *x, int *y) * raise it, so that the user realises they've already been asked this * question. */ -static int find_and_raise_dialog(Frontend *inst, enum DialogSlot slot) +static int find_and_raise_dialog(GtkFrontend *inst, enum DialogSlot slot) { GtkWidget *dialog = inst->dialogs[slot]; if (!dialog) @@ -598,14 +603,15 @@ static int find_and_raise_dialog(Frontend *inst, enum DialogSlot slot) /* * Return the window or icon title. */ -char *get_window_title(Frontend *inst, int icon) +static const char *gtkwin_get_title(TermWin *tw, int icon) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); return icon ? inst->icontitle : inst->wintitle; } static void warn_on_close_callback(void *vctx, int result) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; unregister_dialog(&inst->seat, DIALOG_SLOT_WARN_ON_CLOSE); if (result) gtk_widget_destroy(inst->window); @@ -621,7 +627,7 @@ static void warn_on_close_callback(void *vctx, int result) * handler need not do anything', i.e. 'suppress default handler', * i.e. 'do not close the window'.) */ -gint delete_window(GtkWidget *widget, GdkEvent *event, Frontend *inst) +gint delete_window(GtkWidget *widget, GdkEvent *event, GtkFrontend *inst) { if (!inst->exited && conf_get_int(inst->conf, CONF_warn_on_close)) { /* @@ -644,7 +650,7 @@ gint delete_window(GtkWidget *widget, GdkEvent *event, Frontend *inst) return FALSE; } -static void update_mouseptr(Frontend *inst) +static void update_mouseptr(GtkFrontend *inst) { switch (inst->busy_status) { case BUSY_NOT: @@ -670,7 +676,7 @@ static void update_mouseptr(Frontend *inst) } } -static void show_mouseptr(Frontend *inst, int show) +static void show_mouseptr(GtkFrontend *inst, int show) { if (!conf_get_int(inst->conf, CONF_hide_mouseptr)) show = 1; @@ -678,9 +684,9 @@ static void show_mouseptr(Frontend *inst, int show) update_mouseptr(inst); } -static void draw_backing_rect(Frontend *inst); +static void draw_backing_rect(GtkFrontend *inst); -static void drawing_area_setup(Frontend *inst, int width, int height) +static void drawing_area_setup(GtkFrontend *inst, int width, int height) { int w, h, new_scale, need_size = 0; @@ -769,7 +775,7 @@ static void drawing_area_setup(Frontend *inst, int width, int height) #endif } -static void drawing_area_setup_simple(Frontend *inst) +static void drawing_area_setup_simple(GtkFrontend *inst) { /* * Wrapper on drawing_area_setup which fetches the width and @@ -786,7 +792,7 @@ static void drawing_area_setup_simple(Frontend *inst) drawing_area_setup(inst, alloc.width, alloc.height); } -static void area_realised(GtkWidget *widget, Frontend *inst) +static void area_realised(GtkWidget *widget, GtkFrontend *inst) { inst->drawing_area_realised = TRUE; if (inst->drawing_area_realised && inst->drawing_area_got_size && @@ -795,7 +801,7 @@ static void area_realised(GtkWidget *widget, Frontend *inst) } static void area_size_allocate( - GtkWidget *widget, GdkRectangle *alloc, Frontend *inst) + GtkWidget *widget, GdkRectangle *alloc, GtkFrontend *inst) { inst->drawing_area_got_size = TRUE; if (inst->drawing_area_realised && inst->drawing_area_got_size) @@ -803,7 +809,7 @@ static void area_size_allocate( } #if GTK_CHECK_VERSION(3,10,0) -static void area_check_scale(Frontend *inst) +static void area_check_scale(GtkFrontend *inst) { if (!inst->drawing_area_setup_needed && inst->scale != gtk_widget_get_scale_factor(inst->area)) { @@ -820,32 +826,32 @@ static void area_check_scale(Frontend *inst) static gboolean area_configured( GtkWidget *widget, GdkEventConfigure *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; area_check_scale(inst); return FALSE; } #endif #ifdef DRAW_TEXT_CAIRO -static void cairo_setup_dctx(struct draw_ctx *dctx) +static void cairo_setup_draw_ctx(GtkFrontend *inst) { - cairo_get_matrix(dctx->uctx.u.cairo.cr, - &dctx->uctx.u.cairo.origmatrix); - cairo_set_line_width(dctx->uctx.u.cairo.cr, 1.0); - cairo_set_line_cap(dctx->uctx.u.cairo.cr, CAIRO_LINE_CAP_SQUARE); - cairo_set_line_join(dctx->uctx.u.cairo.cr, CAIRO_LINE_JOIN_MITER); + cairo_get_matrix(inst->uctx.u.cairo.cr, + &inst->uctx.u.cairo.origmatrix); + cairo_set_line_width(inst->uctx.u.cairo.cr, 1.0); + cairo_set_line_cap(inst->uctx.u.cairo.cr, CAIRO_LINE_CAP_SQUARE); + cairo_set_line_join(inst->uctx.u.cairo.cr, CAIRO_LINE_JOIN_MITER); /* This antialiasing setting appears to be ignored for Pango * font rendering but honoured for stroking and filling paths; * I don't quite understand the logic of that, but I won't * complain since it's exactly what I happen to want */ - cairo_set_antialias(dctx->uctx.u.cairo.cr, CAIRO_ANTIALIAS_NONE); + cairo_set_antialias(inst->uctx.u.cairo.cr, CAIRO_ANTIALIAS_NONE); } #endif #if GTK_CHECK_VERSION(3,0,0) static gint draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; #if GTK_CHECK_VERSION(3,10,0) /* @@ -908,7 +914,7 @@ static gint draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) #else gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; #ifndef NO_BACKING_PIXMAPS /* @@ -958,12 +964,12 @@ char *dup_keyval_name(guint keyval) } #endif -static void change_font_size(Frontend *inst, int increment); -static void key_pressed(Frontend *inst); +static void change_font_size(GtkFrontend *inst, int increment); +static void key_pressed(GtkFrontend *inst); gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; char output[256]; wchar_t ucsoutput[2]; int ucsval, start, end, special, output_charset, use_ucsoutput; @@ -2200,7 +2206,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) #if GTK_CHECK_VERSION(2,0,0) void input_method_commit_event(GtkIMContext *imc, gchar *str, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; #ifdef KEY_EVENT_DIAGNOSTICS char *string_string = dupstr(""); @@ -2228,7 +2234,7 @@ void input_method_commit_event(GtkIMContext *imc, gchar *str, gpointer data) #define SCROLL_INCREMENT_LINES 5 #if GTK_CHECK_VERSION(3,4,0) -gboolean scroll_internal(Frontend *inst, gdouble delta, guint state, +gboolean scroll_internal(GtkFrontend *inst, gdouble delta, guint state, gdouble ex, gdouble ey) { int shift, ctrl, alt, x, y, raw_mouse_mode; @@ -2280,7 +2286,7 @@ gboolean scroll_internal(Frontend *inst, gdouble delta, guint state, } #endif -static gboolean button_internal(Frontend *inst, GdkEventButton *event) +static gboolean button_internal(GtkFrontend *inst, GdkEventButton *event) { int shift, ctrl, alt, x, y, button, act, raw_mouse_mode; @@ -2353,7 +2359,7 @@ static gboolean button_internal(Frontend *inst, GdkEventButton *event) gboolean button_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; return button_internal(inst, event); } @@ -2365,7 +2371,7 @@ gboolean button_event(GtkWidget *widget, GdkEventButton *event, gpointer data) */ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; #if GTK_CHECK_VERSION(3,4,0) gdouble dx, dy; @@ -2406,7 +2412,7 @@ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; int shift, ctrl, alt, x, y, button; /* Remember the timestamp. */ @@ -2435,7 +2441,7 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) return TRUE; } -static void key_pressed(Frontend *inst) +static void key_pressed(GtkFrontend *inst) { /* * If our child process has exited but not closed, terminate on @@ -2456,7 +2462,7 @@ static void key_pressed(Frontend *inst) static void exit_callback(void *vctx) { - Frontend *inst = (Frontend *)vctx; + GtkFrontend *inst = (GtkFrontend *)vctx; int exitcode, close_on_exit; if (!inst->exited && @@ -2473,11 +2479,11 @@ static void exit_callback(void *vctx) static void gtk_seat_notify_remote_exit(Seat *seat) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); queue_toplevel_callback(exit_callback, inst); } -static void destroy_inst_connection(Frontend *inst) +static void destroy_inst_connection(GtkFrontend *inst) { inst->exited = TRUE; if (inst->ldisc) { @@ -2496,7 +2502,7 @@ static void destroy_inst_connection(Frontend *inst) } } -static void delete_inst(Frontend *inst) +static void delete_inst(GtkFrontend *inst) { int dialog_slot; for (dialog_slot = 0; dialog_slot < DIALOG_SLOT_LIMIT; dialog_slot++) { @@ -2559,7 +2565,7 @@ static void delete_inst(Frontend *inst) void destroy(GtkWidget *widget, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; inst->window = NULL; delete_inst(inst); session_window_closed(); @@ -2567,7 +2573,7 @@ void destroy(GtkWidget *widget, gpointer data) gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; term_set_focus(inst->term, event->in); term_update(inst->term); show_mouseptr(inst, 1); @@ -2576,7 +2582,7 @@ gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) static void gtk_seat_set_busy_status(Seat *seat, BusyStatus status) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); inst->busy_status = status; update_mouseptr(inst); } @@ -2584,21 +2590,24 @@ static void gtk_seat_set_busy_status(Seat *seat, BusyStatus status) /* * set or clear the "raw mouse message" mode */ -void set_raw_mouse_mode(Frontend *inst, int activate) +static void gtkwin_set_raw_mouse_mode(TermWin *tw, int activate) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); activate = activate && !conf_get_int(inst->conf, CONF_no_mouse_rep); send_raw_mouse = activate; update_mouseptr(inst); } #if GTK_CHECK_VERSION(2,0,0) -static void compute_whole_window_size(Frontend *inst, +static void compute_whole_window_size(GtkFrontend *inst, int wchars, int hchars, int *wpix, int *hpix); #endif -void request_resize(Frontend *inst, int w, int h) +static void gtkwin_request_resize(TermWin *tw, int w, int h) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); + #if !GTK_CHECK_VERSION(3,0,0) int large_x, large_y; @@ -2684,7 +2693,7 @@ void request_resize(Frontend *inst, int w, int h) } -static void real_palette_set(Frontend *inst, int n, int r, int g, int b) +static void real_palette_set(GtkFrontend *inst, int n, int r, int g, int b) { inst->cols[n].red = r * 0x0101; inst->cols[n].green = g * 0x0101; @@ -2738,7 +2747,7 @@ void set_gtk_widget_background(GtkWidget *widget, const GdkColor *col) #endif } -void set_window_background(Frontend *inst) +void set_window_background(GtkFrontend *inst) { if (inst->area) set_gtk_widget_background(GTK_WIDGET(inst->area), &inst->cols[258]); @@ -2746,8 +2755,9 @@ void set_window_background(Frontend *inst) set_gtk_widget_background(GTK_WIDGET(inst->window), &inst->cols[258]); } -void palette_set(Frontend *inst, int n, int r, int g, int b) +static void gtkwin_palette_set(TermWin *tw, int n, int r, int g, int b) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); if (n >= 16) n += 256 - 16; if (n >= NALLCOLOURS) @@ -2762,8 +2772,9 @@ void palette_set(Frontend *inst, int n, int r, int g, int b) } } -int palette_get(Frontend *inst, int n, int *r, int *g, int *b) +static int gtkwin_palette_get(TermWin *tw, int n, int *r, int *g, int *b) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); if (n < 0 || n >= NALLCOLOURS) return FALSE; *r = inst->cols[n].red >> 8; @@ -2772,8 +2783,9 @@ int palette_get(Frontend *inst, int n, int *r, int *g, int *b) return TRUE; } -void palette_reset(Frontend *inst) +static void gtkwin_palette_reset(TermWin *tw) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); /* This maps colour indices in inst->conf to those used in inst->cols. */ static const int ww[] = { 256, 257, 258, 259, 260, 261, @@ -2841,7 +2853,7 @@ void palette_reset(Frontend *inst) } static struct clipboard_state *clipboard_from_atom( - Frontend *inst, GdkAtom atom) + GtkFrontend *inst, GdkAtom atom) { int i; @@ -2863,7 +2875,7 @@ static struct clipboard_state *clipboard_from_atom( * formats it feels like. */ -void set_clipboard_atom(Frontend *inst, int clipboard, GdkAtom atom) +void set_clipboard_atom(GtkFrontend *inst, int clipboard, GdkAtom atom) { struct clipboard_state *state = &inst->clipstates[clipboard]; @@ -2880,7 +2892,7 @@ void set_clipboard_atom(Frontend *inst, int clipboard, GdkAtom atom) } } -int init_clipboard(Frontend *inst) +int init_clipboard(GtkFrontend *inst) { set_clipboard_atom(inst, CLIP_PRIMARY, GDK_SELECTION_PRIMARY); set_clipboard_atom(inst, CLIP_CLIPBOARD, clipboard_atom); @@ -2918,10 +2930,11 @@ static void clipboard_clear(GtkClipboard *clipboard, gpointer data) sfree(cdi); } -void write_clip(Frontend *inst, int clipboard, - wchar_t *data, int *attr, truecolour *truecolour, int len, - int must_deselect) +static void gtkwin_clip_write( + TermWin *tw, int clipboard, wchar_t *data, int *attr, + truecolour *truecolour, int len, int must_deselect) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); struct clipboard_state *state = &inst->clipstates[clipboard]; struct clipboard_data_instance *cdi; @@ -2978,7 +2991,7 @@ void write_clip(Frontend *inst, int clipboard, static void clipboard_text_received(GtkClipboard *clipboard, const gchar *text, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; wchar_t *paste; int paste_len; int length; @@ -2996,8 +3009,9 @@ static void clipboard_text_received(GtkClipboard *clipboard, sfree(paste); } -void frontend_request_paste(Frontend *inst, int clipboard) +static void gtkwin_clip_request_paste(TermWin *tw, int clipboard) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); struct clipboard_state *state = &inst->clipstates[clipboard]; if (!state->gtkclipboard) @@ -3030,7 +3044,7 @@ void frontend_request_paste(Frontend *inst, int clipboard) */ /* Store the data in a cut-buffer. */ -static void store_cutbuffer(Frontend *inst, char *ptr, int len) +static void store_cutbuffer(GtkFrontend *inst, char *ptr, int len) { #ifndef NOT_X_WINDOWS if (inst->disp) { @@ -3044,7 +3058,7 @@ static void store_cutbuffer(Frontend *inst, char *ptr, int len) /* Retrieve data from a cut-buffer. * Returned data needs to be freed with XFree(). */ -static char *retrieve_cutbuffer(Frontend *inst, int *nbytes) +static char *retrieve_cutbuffer(GtkFrontend *inst, int *nbytes) { #ifndef NOT_X_WINDOWS char *ptr; @@ -3064,10 +3078,11 @@ static char *retrieve_cutbuffer(Frontend *inst, int *nbytes) #endif } -void write_clip(Frontend *inst, int clipboard, - wchar_t *data, int *attr, truecolour *truecolour, int len, - int must_deselect) +static void gtkwin_clip_write( + TermWin *tw, int clipboard, wchar_t *data, int *attr, + truecolour *truecolour, int len, int must_deselect) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); struct clipboard_state *state = &inst->clipstates[clipboard]; if (state->pasteout_data) @@ -3169,7 +3184,7 @@ void write_clip(Frontend *inst, int clipboard, static void selection_get(GtkWidget *widget, GtkSelectionData *seldata, guint info, guint time_stamp, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; GdkAtom target = gtk_selection_data_get_target(seldata); struct clipboard_state *state = clipboard_from_atom( inst, gtk_selection_data_get_selection(seldata)); @@ -3194,7 +3209,7 @@ static void selection_get(GtkWidget *widget, GtkSelectionData *seldata, static gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; struct clipboard_state *state = clipboard_from_atom( inst, seldata->selection); @@ -3217,8 +3232,9 @@ static gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata, return TRUE; } -void frontend_request_paste(Frontend *inst, int clipboard) +static void gtkwin_clip_request_paste(TermWin *tw, int clipboard) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); struct clipboard_state *state = &inst->clipstates[clipboard]; /* @@ -3251,7 +3267,7 @@ void frontend_request_paste(Frontend *inst, int clipboard) static void selection_received(GtkWidget *widget, GtkSelectionData *seldata, guint time, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; char *text; int length; #ifndef NOT_X_WINDOWS @@ -3373,7 +3389,7 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata, #endif } -static void init_one_clipboard(Frontend *inst, int clipboard) +static void init_one_clipboard(GtkFrontend *inst, int clipboard) { struct clipboard_state *state = &inst->clipstates[clipboard]; @@ -3381,7 +3397,7 @@ static void init_one_clipboard(Frontend *inst, int clipboard) state->clipboard = clipboard; } -void set_clipboard_atom(Frontend *inst, int clipboard, GdkAtom atom) +void set_clipboard_atom(GtkFrontend *inst, int clipboard, GdkAtom atom) { struct clipboard_state *state = &inst->clipstates[clipboard]; @@ -3391,7 +3407,7 @@ void set_clipboard_atom(Frontend *inst, int clipboard, GdkAtom atom) state->atom = atom; } -void init_clipboard(Frontend *inst) +void init_clipboard(GtkFrontend *inst) { #ifndef NOT_X_WINDOWS /* @@ -3447,7 +3463,7 @@ void init_clipboard(Frontend *inst) #endif /* JUST_USE_GTK_CLIPBOARD_UTF8 */ -static void set_window_titles(Frontend *inst) +static void set_window_titles(GtkFrontend *inst) { /* * We must always call set_icon_name after calling set_title, @@ -3460,21 +3476,23 @@ static void set_window_titles(Frontend *inst) inst->icontitle); } -void set_title(Frontend *inst, char *title) +static void gtkwin_set_title(TermWin *tw, const char *title) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); sfree(inst->wintitle); inst->wintitle = dupstr(title); set_window_titles(inst); } -void set_icon(Frontend *inst, char *title) +static void gtkwin_set_icon_title(TermWin *tw, const char *title) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); sfree(inst->icontitle); inst->icontitle = dupstr(title); set_window_titles(inst); } -void set_title_and_icon(Frontend *inst, char *title, char *icon) +void set_title_and_icon(GtkFrontend *inst, char *title, char *icon) { sfree(inst->wintitle); inst->wintitle = dupstr(title); @@ -3483,8 +3501,9 @@ void set_title_and_icon(Frontend *inst, char *title, char *icon) set_window_titles(inst); } -void set_sbar(Frontend *inst, int total, int start, int page) +static void gtkwin_set_scrollbar(TermWin *tw, int total, int start, int page) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); if (!conf_get_int(inst->conf, CONF_scrollbar)) return; inst->ignore_sbar = TRUE; @@ -3500,7 +3519,7 @@ void set_sbar(Frontend *inst, int total, int start, int page) inst->ignore_sbar = FALSE; } -void scrollbar_moved(GtkAdjustment *adj, Frontend *inst) +void scrollbar_moved(GtkAdjustment *adj, GtkFrontend *inst) { if (!conf_get_int(inst->conf, CONF_scrollbar)) return; @@ -3508,7 +3527,7 @@ void scrollbar_moved(GtkAdjustment *adj, Frontend *inst) term_scroll(inst->term, 1, (int)gtk_adjustment_get_value(adj)); } -static void show_scrollbar(Frontend *inst, gboolean visible) +static void show_scrollbar(GtkFrontend *inst, gboolean visible) { inst->sbar_visible = visible; if (visible) @@ -3517,7 +3536,7 @@ static void show_scrollbar(Frontend *inst, gboolean visible) gtk_widget_hide(inst->sbar); } -void sys_cursor(Frontend *frontend, int x, int y) +static void gtkwin_set_cursor_pos(TermWin *tw, int x, int y) { /* * This is meaningless under X. @@ -3530,13 +3549,14 @@ void sys_cursor(Frontend *frontend, int x, int y) * may want to perform additional actions on any kind of bell (for * example, taskbar flashing in Windows). */ -void do_beep(Frontend *frontend, int mode) +static void gtkwin_bell(TermWin *tw, int mode) { + /* GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); */ if (mode == BELL_DEFAULT) gdk_display_beep(gdk_display_get_default()); } -int char_width(Context ctx, int uc) +static int gtkwin_char_width(TermWin *tw, int uc) { /* * In this front end, double-width characters are handled using a @@ -3545,66 +3565,63 @@ int char_width(Context ctx, int uc) return 1; } -Context get_ctx(Frontend *inst) +static int gtkwin_setup_draw_ctx(TermWin *tw) { - struct draw_ctx *dctx; + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); if (!gtk_widget_get_window(inst->area)) - return NULL; + return FALSE; - dctx = snew(struct draw_ctx); - dctx->inst = inst; - dctx->uctx.type = inst->drawtype; + inst->uctx.type = inst->drawtype; #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { + if (inst->uctx.type == DRAWTYPE_GDK) { /* If we're doing GDK-based drawing, then we also expect * inst->pixmap to exist. */ - dctx->uctx.u.gdk.target = inst->pixmap; - dctx->uctx.u.gdk.gc = gdk_gc_new(gtk_widget_get_window(inst->area)); + inst->uctx.u.gdk.target = inst->pixmap; + inst->uctx.u.gdk.gc = gdk_gc_new(gtk_widget_get_window(inst->area)); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - dctx->uctx.u.cairo.widget = GTK_WIDGET(inst->area); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + inst->uctx.u.cairo.widget = GTK_WIDGET(inst->area); /* If we're doing Cairo drawing, we expect inst->surface to * exist, and we draw to that first, regardless of whether we * subsequently copy the results to inst->pixmap. */ - dctx->uctx.u.cairo.cr = cairo_create(inst->surface); - cairo_scale(dctx->uctx.u.cairo.cr, inst->scale, inst->scale); - cairo_setup_dctx(dctx); + inst->uctx.u.cairo.cr = cairo_create(inst->surface); + cairo_scale(inst->uctx.u.cairo.cr, inst->scale, inst->scale); + cairo_setup_draw_ctx(inst); } #endif - return dctx; + return TRUE; } -void free_ctx(Context dctx) +static void gtkwin_free_draw_ctx(TermWin *tw) { - /* Frontend *inst = dctx->inst; */ + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { - gdk_gc_unref(dctx->uctx.u.gdk.gc); + if (inst->uctx.type == DRAWTYPE_GDK) { + gdk_gc_unref(inst->uctx.u.gdk.gc); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_destroy(dctx->uctx.u.cairo.cr); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_destroy(inst->uctx.u.cairo.cr); } #endif - sfree(dctx); } -static void draw_update(struct draw_ctx *dctx, int x, int y, int w, int h) +static void draw_update(GtkFrontend *inst, int x, int y, int w, int h) { #if defined DRAW_TEXT_CAIRO && !defined NO_BACKING_PIXMAPS - if (dctx->uctx.type == DRAWTYPE_CAIRO) { + if (inst->uctx.type == DRAWTYPE_CAIRO) { /* * If inst->surface and inst->pixmap both exist, then we've * just drawn new content to the former which we must copy to * the latter. */ - cairo_t *cr = gdk_cairo_create(dctx->inst->pixmap); - cairo_set_source_surface(cr, dctx->inst->surface, 0, 0); + cairo_t *cr = gdk_cairo_create(inst->pixmap); + cairo_set_source_surface(cr, inst->surface, 0, 0); cairo_rectangle(cr, x, y, w, h); cairo_fill(cr); cairo_destroy(cr); @@ -3620,7 +3637,7 @@ static void draw_update(struct draw_ctx *dctx, int x, int y, int w, int h) * Amazingly, this one API call is actually valid in all versions * of GTK :-) */ - gtk_widget_queue_draw_area(dctx->inst->area, x, y, w, h); + gtk_widget_queue_draw_area(inst->area, x, y, w, h); } #ifdef DRAW_TEXT_CAIRO @@ -3634,41 +3651,40 @@ static void cairo_set_source_rgb_dim(cairo_t *cr, double r, double g, double b, } #endif -static void draw_set_colour(struct draw_ctx *dctx, int col, int dim) +static void draw_set_colour(GtkFrontend *inst, int col, int dim) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { + if (inst->uctx.type == DRAWTYPE_GDK) { if (dim) { #if GTK_CHECK_VERSION(2,0,0) GdkColor color; - color.red = dctx->inst->cols[col].red * 2 / 3; - color.green = dctx->inst->cols[col].green * 2 / 3; - color.blue = dctx->inst->cols[col].blue * 2 / 3; - gdk_gc_set_rgb_fg_color(dctx->uctx.u.gdk.gc, &color); + color.red = inst->cols[col].red * 2 / 3; + color.green = inst->cols[col].green * 2 / 3; + color.blue = inst->cols[col].blue * 2 / 3; + gdk_gc_set_rgb_fg_color(inst->uctx.u.gdk.gc, &color); #else /* Poor GTK1 fallback */ - gdk_gc_set_foreground(dctx->uctx.u.gdk.gc, &dctx->inst->cols[col]); + gdk_gc_set_foreground(inst->uctx.u.gdk.gc, &inst->cols[col]); #endif } else { - gdk_gc_set_foreground(dctx->uctx.u.gdk.gc, &dctx->inst->cols[col]); + gdk_gc_set_foreground(inst->uctx.u.gdk.gc, &inst->cols[col]); } } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_set_source_rgb_dim(dctx->uctx.u.cairo.cr, - dctx->inst->cols[col].red / 65535.0, - dctx->inst->cols[col].green / 65535.0, - dctx->inst->cols[col].blue / 65535.0, dim); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_set_source_rgb_dim(inst->uctx.u.cairo.cr, + inst->cols[col].red / 65535.0, + inst->cols[col].green / 65535.0, + inst->cols[col].blue / 65535.0, dim); } #endif } -static void draw_set_colour_rgb(struct draw_ctx *dctx, optionalrgb orgb, - int dim) +static void draw_set_colour_rgb(GtkFrontend *inst, optionalrgb orgb, int dim) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { + if (inst->uctx.type == DRAWTYPE_GDK) { #if GTK_CHECK_VERSION(2,0,0) GdkColor color; color.red = orgb.r * 256; @@ -3679,50 +3695,50 @@ static void draw_set_colour_rgb(struct draw_ctx *dctx, optionalrgb orgb, color.green = color.green * 2 / 3; color.blue = color.blue * 2 / 3; } - gdk_gc_set_rgb_fg_color(dctx->uctx.u.gdk.gc, &color); + gdk_gc_set_rgb_fg_color(inst->uctx.u.gdk.gc, &color); #else /* Poor GTK1 fallback */ - gdk_gc_set_foreground(dctx->uctx.u.gdk.gc, &dctx->inst->cols[256]); + gdk_gc_set_foreground(inst->uctx.u.gdk.gc, &inst->cols[256]); #endif } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_set_source_rgb_dim(dctx->uctx.u.cairo.cr, orgb.r / 255.0, + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_set_source_rgb_dim(inst->uctx.u.cairo.cr, orgb.r / 255.0, orgb.g / 255.0, orgb.b / 255.0, dim); } #endif } -static void draw_rectangle(struct draw_ctx *dctx, int filled, +static void draw_rectangle(GtkFrontend *inst, int filled, int x, int y, int w, int h) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { - gdk_draw_rectangle(dctx->uctx.u.gdk.target, dctx->uctx.u.gdk.gc, + if (inst->uctx.type == DRAWTYPE_GDK) { + gdk_draw_rectangle(inst->uctx.u.gdk.target, inst->uctx.u.gdk.gc, filled, x, y, w, h); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_new_path(dctx->uctx.u.cairo.cr); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_new_path(inst->uctx.u.cairo.cr); if (filled) { - cairo_rectangle(dctx->uctx.u.cairo.cr, x, y, w, h); - cairo_fill(dctx->uctx.u.cairo.cr); + cairo_rectangle(inst->uctx.u.cairo.cr, x, y, w, h); + cairo_fill(inst->uctx.u.cairo.cr); } else { - cairo_rectangle(dctx->uctx.u.cairo.cr, + cairo_rectangle(inst->uctx.u.cairo.cr, x + 0.5, y + 0.5, w, h); - cairo_close_path(dctx->uctx.u.cairo.cr); - cairo_stroke(dctx->uctx.u.cairo.cr); + cairo_close_path(inst->uctx.u.cairo.cr); + cairo_stroke(inst->uctx.u.cairo.cr); } } #endif } -static void draw_clip(struct draw_ctx *dctx, int x, int y, int w, int h) +static void draw_clip(GtkFrontend *inst, int x, int y, int w, int h) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { + if (inst->uctx.type == DRAWTYPE_GDK) { GdkRectangle r; r.x = x; @@ -3730,59 +3746,59 @@ static void draw_clip(struct draw_ctx *dctx, int x, int y, int w, int h) r.width = w; r.height = h; - gdk_gc_set_clip_rectangle(dctx->uctx.u.gdk.gc, &r); + gdk_gc_set_clip_rectangle(inst->uctx.u.gdk.gc, &r); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_reset_clip(dctx->uctx.u.cairo.cr); - cairo_new_path(dctx->uctx.u.cairo.cr); - cairo_rectangle(dctx->uctx.u.cairo.cr, x, y, w, h); - cairo_clip(dctx->uctx.u.cairo.cr); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_reset_clip(inst->uctx.u.cairo.cr); + cairo_new_path(inst->uctx.u.cairo.cr); + cairo_rectangle(inst->uctx.u.cairo.cr, x, y, w, h); + cairo_clip(inst->uctx.u.cairo.cr); } #endif } -static void draw_point(struct draw_ctx *dctx, int x, int y) +static void draw_point(GtkFrontend *inst, int x, int y) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { - gdk_draw_point(dctx->uctx.u.gdk.target, dctx->uctx.u.gdk.gc, x, y); + if (inst->uctx.type == DRAWTYPE_GDK) { + gdk_draw_point(inst->uctx.u.gdk.target, inst->uctx.u.gdk.gc, x, y); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_new_path(dctx->uctx.u.cairo.cr); - cairo_rectangle(dctx->uctx.u.cairo.cr, x, y, 1, 1); - cairo_fill(dctx->uctx.u.cairo.cr); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_new_path(inst->uctx.u.cairo.cr); + cairo_rectangle(inst->uctx.u.cairo.cr, x, y, 1, 1); + cairo_fill(inst->uctx.u.cairo.cr); } #endif } -static void draw_line(struct draw_ctx *dctx, int x0, int y0, int x1, int y1) +static void draw_line(GtkFrontend *inst, int x0, int y0, int x1, int y1) { #ifdef DRAW_TEXT_GDK - if (dctx->uctx.type == DRAWTYPE_GDK) { - gdk_draw_line(dctx->uctx.u.gdk.target, dctx->uctx.u.gdk.gc, + if (inst->uctx.type == DRAWTYPE_GDK) { + gdk_draw_line(inst->uctx.u.gdk.target, inst->uctx.u.gdk.gc, x0, y0, x1, y1); } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_new_path(dctx->uctx.u.cairo.cr); - cairo_move_to(dctx->uctx.u.cairo.cr, x0 + 0.5, y0 + 0.5); - cairo_line_to(dctx->uctx.u.cairo.cr, x1 + 0.5, y1 + 0.5); - cairo_stroke(dctx->uctx.u.cairo.cr); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_new_path(inst->uctx.u.cairo.cr); + cairo_move_to(inst->uctx.u.cairo.cr, x0 + 0.5, y0 + 0.5); + cairo_line_to(inst->uctx.u.cairo.cr, x1 + 0.5, y1 + 0.5); + cairo_stroke(inst->uctx.u.cairo.cr); } #endif } -static void draw_stretch_before(struct draw_ctx *dctx, int x, int y, +static void draw_stretch_before(GtkFrontend *inst, int x, int y, int w, int wdouble, int h, int hdouble, int hbothalf) { #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { + if (inst->uctx.type == DRAWTYPE_CAIRO) { cairo_matrix_t matrix; matrix.xy = 0; @@ -3807,18 +3823,18 @@ static void draw_stretch_before(struct draw_ctx *dctx, int x, int y, matrix.yy = 1; matrix.y0 = 0; } - cairo_transform(dctx->uctx.u.cairo.cr, &matrix); + cairo_transform(inst->uctx.u.cairo.cr, &matrix); } #endif } -static void draw_stretch_after(struct draw_ctx *dctx, int x, int y, +static void draw_stretch_after(GtkFrontend *inst, int x, int y, int w, int wdouble, int h, int hdouble, int hbothalf) { #ifdef DRAW_TEXT_GDK #ifndef NO_BACKING_PIXMAPS - if (dctx->uctx.type == DRAWTYPE_GDK) { + if (inst->uctx.type == DRAWTYPE_GDK) { /* * I can't find any plausible StretchBlt equivalent in the X * server, so I'm going to do this the slow and painful way. @@ -3830,9 +3846,9 @@ static void draw_stretch_after(struct draw_ctx *dctx, int x, int y, int i; if (wdouble) { for (i = 0; i < w; i++) { - gdk_draw_pixmap(dctx->uctx.u.gdk.target, - dctx->uctx.u.gdk.gc, - dctx->uctx.u.gdk.target, + gdk_draw_pixmap(inst->uctx.u.gdk.target, + inst->uctx.u.gdk.gc, + inst->uctx.u.gdk.target, x + 2*i, y, x + 2*i+1, y, w - i, h); @@ -3848,9 +3864,9 @@ static void draw_stretch_after(struct draw_ctx *dctx, int x, int y, else dt = 1, db = 0; for (i = 0; i < h; i += 2) { - gdk_draw_pixmap(dctx->uctx.u.gdk.target, - dctx->uctx.u.gdk.gc, - dctx->uctx.u.gdk.target, + gdk_draw_pixmap(inst->uctx.u.gdk.target, + inst->uctx.u.gdk.gc, + inst->uctx.u.gdk.target, x, y + dt*i + db, x, y + dt*(i+1), w, h-i-1); @@ -3862,27 +3878,26 @@ static void draw_stretch_after(struct draw_ctx *dctx, int x, int y, #endif #endif /* DRAW_TEXT_GDK */ #ifdef DRAW_TEXT_CAIRO - if (dctx->uctx.type == DRAWTYPE_CAIRO) { - cairo_set_matrix(dctx->uctx.u.cairo.cr, - &dctx->uctx.u.cairo.origmatrix); + if (inst->uctx.type == DRAWTYPE_CAIRO) { + cairo_set_matrix(inst->uctx.u.cairo.cr, + &inst->uctx.u.cairo.origmatrix); } #endif } -static void draw_backing_rect(Frontend *inst) +static void draw_backing_rect(GtkFrontend *inst) { int w, h; - struct draw_ctx *dctx = get_ctx(inst); - if (!dctx) + if (!win_setup_draw_ctx(&inst->termwin)) return; w = inst->width * inst->font_width + 2*inst->window_border; h = inst->height * inst->font_height + 2*inst->window_border; - draw_set_colour(dctx, 258, FALSE); - draw_rectangle(dctx, 1, 0, 0, w, h); - draw_update(dctx, 0, 0, w, h); - free_ctx(dctx); + draw_set_colour(inst, 258, FALSE); + draw_rectangle(inst, 1, 0, 0, w, h); + draw_update(inst, 0, 0, w, h); + win_free_draw_ctx(&inst->termwin); } /* @@ -3891,10 +3906,10 @@ static void draw_backing_rect(Frontend *inst) * * We are allowed to fiddle with the contents of `text'. */ -void do_text_internal(Context dctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void do_text_internal( + GtkFrontend *inst, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { - Frontend *inst = dctx->inst; int ncombining; int nfg, nbg, t, fontid, shadow, rlen, widefactor, bold; int monochrome = @@ -3980,14 +3995,14 @@ void do_text_internal(Context dctx, int x, int y, wchar_t *text, int len, } else rlen = len; - draw_clip(dctx, + draw_clip(inst, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, rlen*widefactor*inst->font_width, inst->font_height); if ((lattr & LATTR_MODE) != LATTR_NORM) { - draw_stretch_before(dctx, + draw_stretch_before(inst, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, rlen*widefactor*inst->font_width, TRUE, @@ -3997,28 +4012,28 @@ void do_text_internal(Context dctx, int x, int y, wchar_t *text, int len, } if (truecolour.bg.enabled) - draw_set_colour_rgb(dctx, truecolour.bg, attr & ATTR_DIM); + draw_set_colour_rgb(inst, truecolour.bg, attr & ATTR_DIM); else - draw_set_colour(dctx, nbg, attr & ATTR_DIM); - draw_rectangle(dctx, TRUE, + draw_set_colour(inst, nbg, attr & ATTR_DIM); + draw_rectangle(inst, TRUE, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, rlen*widefactor*inst->font_width, inst->font_height); if (truecolour.fg.enabled) - draw_set_colour_rgb(dctx, truecolour.fg, attr & ATTR_DIM); + draw_set_colour_rgb(inst, truecolour.fg, attr & ATTR_DIM); else - draw_set_colour(dctx, nfg, attr & ATTR_DIM); + draw_set_colour(inst, nfg, attr & ATTR_DIM); if (ncombining > 1) { assert(len == 1); - unifont_draw_combining(&dctx->uctx, inst->fonts[fontid], + unifont_draw_combining(&inst->uctx, inst->fonts[fontid], x*inst->font_width+inst->window_border, (y*inst->font_height+inst->window_border+ inst->fonts[0]->ascent), text, ncombining, widefactor > 1, bold, inst->font_width); } else { - unifont_draw_text(&dctx->uctx, inst->fonts[fontid], + unifont_draw_text(&inst->uctx, inst->fonts[fontid], x*inst->font_width+inst->window_border, (y*inst->font_height+inst->window_border+ inst->fonts[0]->ascent), @@ -4030,14 +4045,14 @@ void do_text_internal(Context dctx, int x, int y, wchar_t *text, int len, int uheight = inst->fonts[0]->ascent + 1; if (uheight >= inst->font_height) uheight = inst->font_height - 1; - draw_line(dctx, x*inst->font_width+inst->window_border, + draw_line(inst, x*inst->font_width+inst->window_border, y*inst->font_height + uheight + inst->window_border, (x+len)*widefactor*inst->font_width-1+inst->window_border, y*inst->font_height + uheight + inst->window_border); } if ((lattr & LATTR_MODE) != LATTR_NORM) { - draw_stretch_after(dctx, + draw_stretch_after(inst, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, rlen*widefactor*inst->font_width, TRUE, @@ -4047,13 +4062,14 @@ void do_text_internal(Context dctx, int x, int y, wchar_t *text, int len, } } -void do_text(Context dctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void gtkwin_draw_text( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { - Frontend *inst = dctx->inst; + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); int widefactor; - do_text_internal(dctx, x, y, text, len, attr, lattr, truecolour); + do_text_internal(inst, x, y, text, len, attr, lattr, truecolour); if (attr & ATTR_WIDE) { widefactor = 2; @@ -4070,17 +4086,17 @@ void do_text(Context dctx, int x, int y, wchar_t *text, int len, len *= 2; } - draw_update(dctx, + draw_update(inst, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, len*widefactor*inst->font_width, inst->font_height); } -void do_cursor(Context dctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void gtkwin_draw_cursor( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { - Frontend *inst = dctx->inst; - + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); int active, passive, widefactor; if (attr & TATTR_PASCURS) { @@ -4093,7 +4109,7 @@ void do_cursor(Context dctx, int x, int y, wchar_t *text, int len, active = 1; } else active = 0; - do_text_internal(dctx, x, y, text, len, attr, lattr, truecolour); + do_text_internal(inst, x, y, text, len, attr, lattr, truecolour); if (attr & TATTR_COMBINING) len = 1; @@ -4120,8 +4136,8 @@ void do_cursor(Context dctx, int x, int y, wchar_t *text, int len, * if it's passive. */ if (passive) { - draw_set_colour(dctx, 261, FALSE); - draw_rectangle(dctx, FALSE, + draw_set_colour(inst, 261, FALSE); + draw_rectangle(inst, FALSE, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, len*widefactor*inst->font_width-1, @@ -4159,22 +4175,22 @@ void do_cursor(Context dctx, int x, int y, wchar_t *text, int len, length = inst->font_height; } - draw_set_colour(dctx, 261, FALSE); + draw_set_colour(inst, 261, FALSE); if (passive) { for (i = 0; i < length; i++) { if (i % 2 == 0) { - draw_point(dctx, startx, starty); + draw_point(inst, startx, starty); } startx += dx; starty += dy; } } else if (active) { - draw_line(dctx, startx, starty, + draw_line(inst, startx, starty, startx + (length-1) * dx, starty + (length-1) * dy); } /* else no cursor (e.g., blinked off) */ } - draw_update(dctx, + draw_update(inst, x*inst->font_width+inst->window_border, y*inst->font_height+inst->window_border, len*widefactor*inst->font_width, inst->font_height); @@ -4191,7 +4207,7 @@ void do_cursor(Context dctx, int x, int y, wchar_t *text, int len, #endif } -GdkCursor *make_mouse_ptr(Frontend *inst, int cursor_val) +GdkCursor *make_mouse_ptr(GtkFrontend *inst, int cursor_val) { if (cursor_val == -1) { #if GTK_CHECK_VERSION(2,16,0) @@ -4236,7 +4252,7 @@ static const char *gtk_seat_get_x_display(Seat *seat) #ifndef NOT_X_WINDOWS static int gtk_seat_get_windowid(Seat *seat, long *id) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); GdkWindow *window = gtk_widget_get_window(inst->area); if (!GDK_IS_X11_WINDOW(window)) return FALSE; @@ -4245,12 +4261,13 @@ static int gtk_seat_get_windowid(Seat *seat, long *id) } #endif -int frontend_is_utf8(Frontend *inst) +static int gtkwin_is_utf8(TermWin *tw) { + GtkFrontend *inst = container_of(tw, GtkFrontend, termwin); return inst->ucsdata.line_codepage == CS_UTF8; } -char *setup_fonts_ucs(Frontend *inst) +char *setup_fonts_ucs(GtkFrontend *inst) { int shadowbold = conf_get_int(inst->conf, CONF_shadowbold); int shadowboldoffset = conf_get_int(inst->conf, CONF_shadowboldoffset); @@ -4353,7 +4370,7 @@ static void find_app_menu_bar(GtkWidget *widget, gpointer data) } #endif -static void compute_geom_hints(Frontend *inst, GdkGeometry *geom) +static void compute_geom_hints(GtkFrontend *inst, GdkGeometry *geom) { /* * Unused fields in geom. @@ -4454,7 +4471,7 @@ static void compute_geom_hints(Frontend *inst, GdkGeometry *geom) #endif } -void set_geom_hints(Frontend *inst) +void set_geom_hints(GtkFrontend *inst) { GdkGeometry geom; gint flags = GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC; @@ -4468,7 +4485,7 @@ void set_geom_hints(Frontend *inst) } #if GTK_CHECK_VERSION(2,0,0) -static void compute_whole_window_size(Frontend *inst, +static void compute_whole_window_size(GtkFrontend *inst, int wchars, int hchars, int *wpix, int *hpix) { @@ -4481,13 +4498,13 @@ static void compute_whole_window_size(Frontend *inst, void clear_scrollback_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; term_clrsb(inst->term); } void reset_terminal_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; term_pwron(inst->term, TRUE); if (inst->ldisc) ldisc_echoedit_update(inst->ldisc); @@ -4495,27 +4512,27 @@ void reset_terminal_menuitem(GtkMenuItem *item, gpointer data) void copy_clipboard_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; static const int clips[] = { MENU_CLIPBOARD }; term_request_copy(inst->term, clips, lenof(clips)); } void paste_clipboard_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; term_request_paste(inst->term, MENU_CLIPBOARD); } void copy_all_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; static const int clips[] = { COPYALL_CLIPBOARDS }; term_copyall(inst->term, clips, lenof(clips)); } void special_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; SessionSpecial *sc = g_object_get_data(G_OBJECT(item), "user-data"); if (inst->backend) @@ -4524,17 +4541,17 @@ void special_menuitem(GtkMenuItem *item, gpointer data) void about_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; about_box(inst->window); } void event_log_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; showeventlog(inst->eventlogstuff, inst->window); } -void setup_clipboards(Frontend *inst, Terminal *term, Conf *conf) +void setup_clipboards(GtkFrontend *inst, Terminal *term, Conf *conf) { assert(term->mouse_select_clipboards[0] == CLIP_LOCAL); @@ -4596,7 +4613,7 @@ void setup_clipboards(Frontend *inst, Terminal *term, Conf *conf) } struct after_change_settings_dialog_ctx { - Frontend *inst; + GtkFrontend *inst; Conf *newconf; }; @@ -4604,7 +4621,7 @@ static void after_change_settings_dialog(void *vctx, int retval); void change_settings_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; struct after_change_settings_dialog_ctx *ctx; GtkWidget *dialog; char *title; @@ -4637,7 +4654,7 @@ static void after_change_settings_dialog(void *vctx, int retval) }; struct after_change_settings_dialog_ctx ctx = *(struct after_change_settings_dialog_ctx *)vctx; - Frontend *inst = ctx.inst; + GtkFrontend *inst = ctx.inst; Conf *oldconf = inst->conf, *newconf = ctx.newconf; int i, j, need_size; @@ -4730,7 +4747,8 @@ static void after_change_settings_dialog(void *vctx, int retval) */ if (strcmp(conf_get_str(oldconf, CONF_wintitle), conf_get_str(newconf, CONF_wintitle))) - set_title(inst, conf_get_str(newconf, CONF_wintitle)); + win_set_title(&inst->termwin, + conf_get_str(newconf, CONF_wintitle)); set_window_titles(inst); /* @@ -4782,8 +4800,9 @@ static void after_change_settings_dialog(void *vctx, int retval) conf_get_int(newconf, CONF_window_border) || need_size) { set_geom_hints(inst); - request_resize(inst, conf_get_int(newconf, CONF_width), - conf_get_int(newconf, CONF_height)); + win_request_resize(&inst->termwin, + conf_get_int(newconf, CONF_width), + conf_get_int(newconf, CONF_height)); } else { /* * The above will have caused a call to term_size() for @@ -4812,7 +4831,7 @@ static void after_change_settings_dialog(void *vctx, int retval) } } -static void change_font_size(Frontend *inst, int increment) +static void change_font_size(GtkFrontend *inst, int increment) { static const int conf_keys[lenof(inst->fonts)] = { CONF_font, CONF_boldfont, CONF_widefont, CONF_wideboldfont, @@ -4856,8 +4875,8 @@ static void change_font_size(Frontend *inst, int increment) } set_geom_hints(inst); - request_resize(inst, conf_get_int(inst->conf, CONF_width), - conf_get_int(inst->conf, CONF_height)); + win_request_resize(&inst->termwin, conf_get_int(inst->conf, CONF_width), + conf_get_int(inst->conf, CONF_height)); term_invalidate(inst->term); gtk_widget_queue_draw(inst->area); @@ -4875,7 +4894,7 @@ static void change_font_size(Frontend *inst, int increment) void dup_session_menuitem(GtkMenuItem *item, gpointer gdata) { - Frontend *inst = (Frontend *)gdata; + GtkFrontend *inst = (GtkFrontend *)gdata; launch_duplicate_session(inst->conf); } @@ -4887,7 +4906,7 @@ void new_session_menuitem(GtkMenuItem *item, gpointer data) void restart_session_menuitem(GtkMenuItem *item, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; if (!inst->backend) { logevent(inst->logctx, "----- Session restarted -----"); @@ -4911,9 +4930,9 @@ void saved_session_freedata(GtkMenuItem *item, gpointer data) sfree(str); } -void app_menu_action(Frontend *frontend, enum MenuAction action) +void app_menu_action(GtkFrontend *frontend, enum MenuAction action) { - Frontend *inst = (Frontend *)frontend; + GtkFrontend *inst = (GtkFrontend *)frontend; switch (action) { case MA_COPY: copy_clipboard_menuitem(NULL, inst); @@ -4947,7 +4966,7 @@ void app_menu_action(Frontend *frontend, enum MenuAction action) static void update_savedsess_menu(GtkMenuItem *menuitem, gpointer data) { - Frontend *inst = (Frontend *)data; + GtkFrontend *inst = (GtkFrontend *)data; struct sesslist sesslist; int i; @@ -5020,7 +5039,7 @@ static void free_special_cmd(gpointer data) { sfree(data); } static void gtk_seat_update_specials_menu(Seat *seat) { - Frontend *inst = container_of(seat, Frontend, seat); + GtkFrontend *inst = container_of(seat, GtkFrontend, seat); const SessionSpecial *specials; if (inst->backend) @@ -5086,7 +5105,7 @@ static void gtk_seat_update_specials_menu(Seat *seat) } } -static void start_backend(Frontend *inst) +static void start_backend(GtkFrontend *inst) { const struct BackendVtable *vt; char *realhost; @@ -5156,16 +5175,46 @@ static void get_monitor_geometry(GtkWidget *widget, GdkRectangle *geometry) } #endif +static const TermWinVtable gtk_termwin_vt = { + gtkwin_setup_draw_ctx, + gtkwin_draw_text, + gtkwin_draw_cursor, + gtkwin_char_width, + gtkwin_free_draw_ctx, + gtkwin_set_cursor_pos, + gtkwin_set_raw_mouse_mode, + gtkwin_set_scrollbar, + gtkwin_bell, + gtkwin_clip_write, + gtkwin_clip_request_paste, + gtkwin_refresh, + gtkwin_request_resize, + gtkwin_set_title, + gtkwin_set_icon_title, + gtkwin_set_minimised, + gtkwin_is_minimised, + gtkwin_set_maximised, + gtkwin_move, + gtkwin_set_zorder, + gtkwin_palette_get, + gtkwin_palette_set, + gtkwin_palette_reset, + gtkwin_get_pos, + gtkwin_get_pixels, + gtkwin_get_title, + gtkwin_is_utf8, +}; + void new_session_window(Conf *conf, const char *geometry_string) { - Frontend *inst; + GtkFrontend *inst; prepare_session(conf); /* * Create an instance structure and initialise to zeroes */ - inst = snew(Frontend); + inst = snew(GtkFrontend); memset(inst, 0, sizeof(*inst)); #ifdef JUST_USE_GTK_CLIPBOARD_UTF8 inst->cdi_headtail.next = inst->cdi_headtail.prev = &inst->cdi_headtail; @@ -5180,6 +5229,7 @@ void new_session_window(Conf *conf, const char *geometry_string) #endif inst->drawing_area_setup_needed = TRUE; + inst->termwin.vt = >k_termwin_vt; inst->seat.vt = >k_seat_vt; inst->logpolicy.vt = >k_logpolicy_vt; @@ -5264,7 +5314,7 @@ void new_session_window(Conf *conf, const char *geometry_string) /* * Set up the colour map. */ - palette_reset(inst); + win_palette_reset(&inst->termwin); inst->width = conf_get_int(inst->conf, CONF_width); inst->height = conf_get_int(inst->conf, CONF_height); @@ -5499,7 +5549,7 @@ void new_session_window(Conf *conf, const char *geometry_string) inst->eventlogstuff = eventlogstuff_new(); - inst->term = term_init(inst->conf, &inst->ucsdata, inst); + inst->term = term_init(inst->conf, &inst->ucsdata, &inst->termwin); setup_clipboards(inst, inst->term, inst->conf); inst->logctx = log_init(&inst->logpolicy, inst->conf); term_provide_logctx(inst->term, inst->logctx); diff --git a/unix/unix.h b/unix/unix.h index 521c5a87..11f9b51d 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -65,8 +65,6 @@ struct FontSpec { }; struct FontSpec *fontspec_new(const char *name); -typedef struct draw_ctx *Context; - extern const struct BackendVtable pty_backend; #define BROKEN_PIPE_ERROR_CODE EPIPE /* used in sshshare.c */ @@ -158,7 +156,7 @@ unsigned long getticks(void); #endif /* The per-session frontend structure managed by gtkwin.c */ -struct gui_data; +typedef struct GtkFrontend GtkFrontend; /* Callback when a dialog box finishes, and a no-op implementation of it */ typedef void (*post_dialog_fn_t)(void *ctx, int result); @@ -175,7 +173,7 @@ void launch_saved_session(const char *str); void session_window_closed(void); void window_setup_error(const char *errmsg); #ifdef MAY_REFER_TO_GTK_IN_HEADERS -GtkWidget *make_gtk_toplevel_window(Frontend *frontend); +GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend); #endif const struct BackendVtable *select_backend(Conf *conf); @@ -189,7 +187,7 @@ enum MenuAction { MA_RESTART_SESSION, MA_CHANGE_SETTINGS, MA_CLEAR_SCROLLBACK, MA_RESET_TERMINAL, MA_EVENT_LOG }; -void app_menu_action(Frontend *frontend, enum MenuAction); +void app_menu_action(GtkFrontend *frontend, enum MenuAction); /* Things gtkdlg.c needs from pterm.c */ #ifdef MAY_REFER_TO_GTK_IN_HEADERS diff --git a/windows/windlg.c b/windows/windlg.c index 6dd8bf98..6dae33f9 100644 --- a/windows/windlg.c +++ b/windows/windlg.c @@ -156,7 +156,7 @@ static INT_PTR CALLBACK LogProc(HWND hwnd, UINT msg, memcpy(p, sel_nl, sizeof(sel_nl)); p += sizeof(sel_nl); } - write_aclip(NULL, CLIP_SYSTEM, clipdata, size, TRUE); + write_aclip(CLIP_SYSTEM, clipdata, size, TRUE); sfree(clipdata); } sfree(selitems); diff --git a/windows/window.c b/windows/window.c index 613c1fdc..5a6ddb7a 100644 --- a/windows/window.c +++ b/windows/window.c @@ -227,17 +227,87 @@ static UINT wm_mousewheel = WM_MOUSEWHEEL; (((wch) >= 0x180B && (wch) <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR */ \ ((wch) >= 0xFE00 && (wch) <= 0xFE0F)) /* VARIATION SELECTOR 1-16 */ +static int wintw_setup_draw_ctx(TermWin *); +static void wintw_draw_text(TermWin *, int x, int y, wchar_t *text, int len, + unsigned long attrs, int lattrs, truecolour tc); +static void wintw_draw_cursor(TermWin *, int x, int y, wchar_t *text, int len, + unsigned long attrs, int lattrs, truecolour tc); +static int wintw_char_width(TermWin *, int uc); +static void wintw_free_draw_ctx(TermWin *); +static void wintw_set_cursor_pos(TermWin *, int x, int y); +static void wintw_set_raw_mouse_mode(TermWin *, int enable); +static void wintw_set_scrollbar(TermWin *, int total, int start, int page); +static void wintw_bell(TermWin *, int mode); +static void wintw_clip_write( + TermWin *, int clipboard, wchar_t *text, int *attrs, + truecolour *colours, int len, int must_deselect); +static void wintw_clip_request_paste(TermWin *, int clipboard); +static void wintw_refresh(TermWin *); +static void wintw_request_resize(TermWin *, int w, int h); +static void wintw_set_title(TermWin *, const char *title); +static void wintw_set_icon_title(TermWin *, const char *icontitle); +static void wintw_set_minimised(TermWin *, int minimised); +static int wintw_is_minimised(TermWin *); +static void wintw_set_maximised(TermWin *, int maximised); +static void wintw_move(TermWin *, int x, int y); +static void wintw_set_zorder(TermWin *, int top); +static int wintw_palette_get(TermWin *, int n, int *r, int *g, int *b); +static void wintw_palette_set(TermWin *, int n, int r, int g, int b); +static void wintw_palette_reset(TermWin *); +static void wintw_get_pos(TermWin *, int *x, int *y); +static void wintw_get_pixels(TermWin *, int *x, int *y); +static const char *wintw_get_title(TermWin *, int icon); +static int wintw_is_utf8(TermWin *); + +static const TermWinVtable windows_termwin_vt = { + wintw_setup_draw_ctx, + wintw_draw_text, + wintw_draw_cursor, + wintw_char_width, + wintw_free_draw_ctx, + wintw_set_cursor_pos, + wintw_set_raw_mouse_mode, + wintw_set_scrollbar, + wintw_bell, + wintw_clip_write, + wintw_clip_request_paste, + wintw_refresh, + wintw_request_resize, + wintw_set_title, + wintw_set_icon_title, + wintw_set_minimised, + wintw_is_minimised, + wintw_set_maximised, + wintw_move, + wintw_set_zorder, + wintw_palette_get, + wintw_palette_set, + wintw_palette_reset, + wintw_get_pos, + wintw_get_pixels, + wintw_get_title, + wintw_is_utf8, +}; + +static TermWin wintw[1]; +static HDC wintw_hdc; + const int share_can_be_downstream = TRUE; const int share_can_be_upstream = TRUE; -int frontend_is_utf8(Frontend *frontend) +static int is_utf8(void) { return ucsdata.line_codepage == CP_UTF8; } +static int wintw_is_utf8(TermWin *tw) +{ + return is_utf8(); +} + static int win_seat_is_utf8(Seat *seat) { - return frontend_is_utf8(NULL); + return is_utf8(); } char *win_seat_get_ttymode(Seat *seat, const char *mode) @@ -247,7 +317,7 @@ char *win_seat_get_ttymode(Seat *seat, const char *mode) int win_seat_get_window_pixel_size(Seat *seat, int *x, int *y) { - get_window_pixels(NULL, x, y); + win_get_pixels(wintw, x, y); return TRUE; } @@ -322,8 +392,8 @@ static void start_backend(void) title = msg; } sfree(realhost); - set_title(NULL, title); - set_icon(NULL, title); + win_set_title(wintw, title); + win_set_icon_title(wintw, title); /* * Connect the terminal to the backend for resize purposes. @@ -356,8 +426,8 @@ static void close_session(void *ignored_context) session_closed = TRUE; sprintf(morestuff, "%.70s (inactive)", appname); - set_icon(NULL, morestuff); - set_title(NULL, morestuff); + win_set_icon_title(wintw, morestuff); + win_set_title(wintw, morestuff); if (ldisc) { ldisc_free(ldisc); @@ -667,7 +737,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * which will call schedule_timer(), which will in turn call * timer_change_notify() which will expect hwnd to exist.) */ - term = term_init(conf, &ucsdata, NULL); + wintw->vt = &windows_termwin_vt; + term = term_init(conf, &ucsdata, wintw); setup_clipboards(term, conf); logctx = log_init(default_logpolicy, conf); term_provide_logctx(term, logctx); @@ -1095,7 +1166,7 @@ static void win_seat_set_busy_status(Seat *seat, BusyStatus status) /* * set or clear the "raw mouse message" mode */ -void set_raw_mouse_mode(Frontend *frontend, int activate) +static void wintw_set_raw_mouse_mode(TermWin *tw, int activate) { activate = activate && !conf_get_int(conf, CONF_no_mouse_rep); send_raw_mouse = activate; @@ -1651,7 +1722,7 @@ static void deinit_fonts(void) } } -void request_resize(Frontend *frontend, int w, int h) +static void wintw_request_resize(TermWin *tw, int w, int h) { int width, height; @@ -2046,6 +2117,28 @@ static void conf_cache_data(void) static const int clips_system[] = { CLIP_SYSTEM }; +static HDC make_hdc(void) +{ + HDC hdc; + + if (!hwnd) + return NULL; + + hdc = GetDC(hwnd); + if (!hdc) + return NULL; + + SelectPalette(hdc, pal, FALSE); + return hdc; +} + +static void free_hdc(HDC hdc) +{ + assert(hwnd); + SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE); + ReleaseDC(hwnd, hdc); +} + static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -2348,7 +2441,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, init_lvl = 2; } - set_title(NULL, conf_get_str(conf, CONF_wintitle)); + win_set_title(wintw, conf_get_str(conf, CONF_wintitle)); if (IsIconic(hwnd)) { SetWindowText(hwnd, conf_get_int(conf, CONF_win_name_always) ? @@ -2671,12 +2764,15 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * current terminal appearance so that WM_PAINT becomes * completely trivial. However, this should do for now. */ - term_paint(term, hdc, + assert(!wintw_hdc); + wintw_hdc = hdc; + term_paint(term, (p.rcPaint.left-offset_width)/font_width, (p.rcPaint.top-offset_height)/font_height, (p.rcPaint.right-offset_width-1)/font_width, (p.rcPaint.bottom-offset_height-1)/font_height, !term->window_update_pending); + wintw_hdc = NULL; if (p.fErase || p.rcPaint.left < offset_width || @@ -3043,21 +3139,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; case WM_PALETTECHANGED: if ((HWND) wParam != hwnd && pal != NULL) { - HDC hdc = get_ctx(NULL); + HDC hdc = make_hdc(); if (hdc) { if (RealizePalette(hdc) > 0) UpdateColors(hdc); - free_ctx(hdc); + free_hdc(hdc); } } break; case WM_QUERYNEWPALETTE: if (pal != NULL) { - HDC hdc = get_ctx(NULL); + HDC hdc = make_hdc(); if (hdc) { if (RealizePalette(hdc) > 0) UpdateColors(hdc); - free_ctx(hdc); + free_hdc(hdc); return TRUE; } } @@ -3308,7 +3404,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * helper software tracks the system caret, so we should arrange to * have one.) */ -void sys_cursor(Frontend *frontend, int x, int y) +static void wintw_set_cursor_pos(TermWin *tw, int x, int y) { int cx, cy; @@ -3362,12 +3458,12 @@ static void sys_cursor_update(void) * * We are allowed to fiddle with the contents of `text'. */ -void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void do_text_internal( + int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { COLORREF fg, bg, t; int nfg, nbg, nfont; - HDC hdc = ctx; RECT line_box; int force_manual_underline = 0; int fnt_width, char_width; @@ -3513,13 +3609,13 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, GetBValue(fg) * 2 / 3); } - SelectObject(hdc, fonts[nfont]); - SetTextColor(hdc, fg); - SetBkColor(hdc, bg); + SelectObject(wintw_hdc, fonts[nfont]); + SetTextColor(wintw_hdc, fg); + SetBkColor(wintw_hdc, bg); if (attr & TATTR_COMBINING) - SetBkMode(hdc, TRANSPARENT); + SetBkMode(wintw_hdc, TRANSPARENT); else - SetBkMode(hdc, OPAQUE); + SetBkMode(wintw_hdc, OPAQUE); line_box.left = x; line_box.top = y; line_box.right = x + char_width * len; @@ -3556,7 +3652,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, * generally reasonable results. */ xoffset = char_width / 2; - SetTextAlign(hdc, TA_TOP | TA_CENTER | TA_NOUPDATECP); + SetTextAlign(wintw_hdc, TA_TOP | TA_CENTER | TA_NOUPDATECP); lpDx_maybe = NULL; maxlen = 1; } else { @@ -3565,7 +3661,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, * in the normal way. */ xoffset = 0; - SetTextAlign(hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP); + SetTextAlign(wintw_hdc, TA_TOP | TA_LEFT | TA_NOUPDATECP); lpDx_maybe = lpDx; maxlen = len; } @@ -3652,14 +3748,14 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, if (nlen <= 0) return; /* Eeek! */ - ExtTextOutW(hdc, x + xoffset, + ExtTextOutW(wintw_hdc, x + xoffset, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), &line_box, uni_buf, nlen, lpDx_maybe); if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { - SetBkMode(hdc, TRANSPARENT); - ExtTextOutW(hdc, x + xoffset - 1, + SetBkMode(wintw_hdc, TRANSPARENT); + ExtTextOutW(wintw_hdc, x + xoffset - 1, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED, &line_box, uni_buf, nlen, lpDx_maybe); @@ -3678,12 +3774,12 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, for (i = 0; i < len; i++) directbuf[i] = text[i] & 0xFF; - ExtTextOut(hdc, x + xoffset, + ExtTextOut(wintw_hdc, x + xoffset, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), &line_box, directbuf, len, lpDx_maybe); if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { - SetBkMode(hdc, TRANSPARENT); + SetBkMode(wintw_hdc, TRANSPARENT); /* GRR: This draws the character outside its box and * can leave 'droppings' even with the clip box! I @@ -3694,7 +3790,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, * or -1 for this shift depending on if the leftmost * column is blank... */ - ExtTextOut(hdc, x + xoffset - 1, + ExtTextOut(wintw_hdc, x + xoffset - 1, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED, &line_box, directbuf, len, lpDx_maybe); @@ -3715,15 +3811,15 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, wbuf[i] = text[i]; /* print Glyphs as they are, without Windows' Shaping*/ - general_textout(hdc, x + xoffset, + general_textout(wintw_hdc, x + xoffset, y - font_height * (lattr==LATTR_BOT) + text_adjust, &line_box, wbuf, len, lpDx, opaque && !(attr & TATTR_COMBINING)); /* And the shadow bold hack. */ if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { - SetBkMode(hdc, TRANSPARENT); - ExtTextOutW(hdc, x + xoffset - 1, + SetBkMode(wintw_hdc, TRANSPARENT); + ExtTextOutW(wintw_hdc, x + xoffset - 1, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED, &line_box, wbuf, len, lpDx_maybe); @@ -3734,7 +3830,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, * If we're looping round again, stop erasing the background * rectangle. */ - SetBkMode(hdc, TRANSPARENT); + SetBkMode(wintw_hdc, TRANSPARENT); opaque = FALSE; } if (lattr != LATTR_TOP && (force_manual_underline || @@ -3745,10 +3841,10 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, if (lattr == LATTR_BOT) dec = dec * 2 - font_height; - oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, fg)); - MoveToEx(hdc, line_box.left, line_box.top + dec, NULL); - LineTo(hdc, line_box.right, line_box.top + dec); - oldpen = SelectObject(hdc, oldpen); + oldpen = SelectObject(wintw_hdc, CreatePen(PS_SOLID, 0, fg)); + MoveToEx(wintw_hdc, line_box.left, line_box.top + dec, NULL); + LineTo(wintw_hdc, line_box.right, line_box.top + dec); + oldpen = SelectObject(wintw_hdc, oldpen); DeleteObject(oldpen); } } @@ -3756,8 +3852,9 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, /* * Wrapper that handles combining characters. */ -void do_text(Context ctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void wintw_draw_text( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { if (attr & TATTR_COMBINING) { unsigned long a = 0; @@ -3767,13 +3864,13 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len, len0 = 2; if (len-len0 >= 1 && IS_LOW_VARSEL(text[len0])) { attr &= ~TATTR_COMBINING; - do_text_internal(ctx, x, y, text, len0+1, attr, lattr, truecolour); + do_text_internal(x, y, text, len0+1, attr, lattr, truecolour); text += len0+1; len -= len0+1; a = TATTR_COMBINING; } else if (len-len0 >= 2 && IS_HIGH_VARSEL(text[len0], text[len0+1])) { attr &= ~TATTR_COMBINING; - do_text_internal(ctx, x, y, text, len0+2, attr, lattr, truecolour); + do_text_internal(x, y, text, len0+2, attr, lattr, truecolour); text += len0+2; len -= len0+2; a = TATTR_COMBINING; @@ -3783,33 +3880,32 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len, while (len--) { if (len >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) { - do_text_internal(ctx, x, y, text, 2, attr | a, lattr, truecolour); + do_text_internal(x, y, text, 2, attr | a, lattr, truecolour); len--; text++; } else - do_text_internal(ctx, x, y, text, 1, attr | a, lattr, truecolour); + do_text_internal(x, y, text, 1, attr | a, lattr, truecolour); text++; a = TATTR_COMBINING; } } else - do_text_internal(ctx, x, y, text, len, attr, lattr, truecolour); + do_text_internal(x, y, text, len, attr, lattr, truecolour); } -void do_cursor(Context ctx, int x, int y, wchar_t *text, int len, - unsigned long attr, int lattr, truecolour truecolour) +static void wintw_draw_cursor( + TermWin *tw, int x, int y, wchar_t *text, int len, + unsigned long attr, int lattr, truecolour truecolour) { - int fnt_width; int char_width; - HDC hdc = ctx; int ctype = cursor_type; lattr &= LATTR_MODE; if ((attr & TATTR_ACTCURS) && (ctype == 0 || term->big_cursor)) { if (*text != UCSWIDE) { - do_text(ctx, x, y, text, len, attr, lattr, truecolour); + win_draw_text(tw, x, y, text, len, attr, lattr, truecolour); return; } ctype = 2; @@ -3831,9 +3927,9 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len, pts[2].x = pts[3].x = x + char_width - 1; pts[0].y = pts[3].y = pts[4].y = y; pts[1].y = pts[2].y = y + font_height - 1; - oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[261])); - Polyline(hdc, pts, 5); - oldpen = SelectObject(hdc, oldpen); + oldpen = SelectObject(wintw_hdc, CreatePen(PS_SOLID, 0, colours[261])); + Polyline(wintw_hdc, pts, 5); + oldpen = SelectObject(wintw_hdc, oldpen); DeleteObject(oldpen); } else if ((attr & (TATTR_ACTCURS | TATTR_PASCURS)) && ctype != 0) { int startx, starty, dx, dy, length, i; @@ -3856,15 +3952,15 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len, if (attr & TATTR_ACTCURS) { HPEN oldpen; oldpen = - SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[261])); - MoveToEx(hdc, startx, starty, NULL); - LineTo(hdc, startx + dx * length, starty + dy * length); - oldpen = SelectObject(hdc, oldpen); + SelectObject(wintw_hdc, CreatePen(PS_SOLID, 0, colours[261])); + MoveToEx(wintw_hdc, startx, starty, NULL); + LineTo(wintw_hdc, startx + dx * length, starty + dy * length); + oldpen = SelectObject(wintw_hdc, oldpen); DeleteObject(oldpen); } else { for (i = 0; i < length; i++) { if (i % 2 == 0) { - SetPixel(hdc, startx, starty, colours[261]); + SetPixel(wintw_hdc, startx, starty, colours[261]); } startx += dx; starty += dy; @@ -3875,8 +3971,8 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len, /* This function gets the actual width of a character in the normal font. */ -int char_width(Context ctx, int uc) { - HDC hdc = ctx; +static int wintw_char_width(TermWin *tw, int uc) +{ int ibuf = 0; /* If the font max is the same as the font ave width then this @@ -3903,26 +3999,28 @@ int char_width(Context ctx, int uc) { return 1; if ( (uc & CSET_MASK) == CSET_ACP ) { - SelectObject(hdc, fonts[FONT_NORMAL]); + SelectObject(wintw_hdc, fonts[FONT_NORMAL]); } else if ( (uc & CSET_MASK) == CSET_OEMCP ) { another_font(FONT_OEM); if (!fonts[FONT_OEM]) return 0; - SelectObject(hdc, fonts[FONT_OEM]); + SelectObject(wintw_hdc, fonts[FONT_OEM]); } else return 0; - if ( GetCharWidth32(hdc, uc&~CSET_MASK, uc&~CSET_MASK, &ibuf) != 1 && - GetCharWidth(hdc, uc&~CSET_MASK, uc&~CSET_MASK, &ibuf) != 1) + if (GetCharWidth32(wintw_hdc, uc & ~CSET_MASK, + uc & ~CSET_MASK, &ibuf) != 1 && + GetCharWidth(wintw_hdc, uc & ~CSET_MASK, + uc & ~CSET_MASK, &ibuf) != 1) return 0; } else { /* Speedup, I know of no font where ascii is the wrong width */ if (uc >= ' ' && uc <= '~') return 1; - SelectObject(hdc, fonts[FONT_NORMAL]); - if ( GetCharWidth32W(hdc, uc, uc, &ibuf) == 1 ) + SelectObject(wintw_hdc, fonts[FONT_NORMAL]); + if (GetCharWidth32W(wintw_hdc, uc, uc, &ibuf) == 1) /* Okay that one worked */ ; - else if ( GetCharWidthW(hdc, uc, uc, &ibuf) == 1 ) + else if (GetCharWidthW(wintw_hdc, uc, uc, &ibuf) == 1) /* This should work on 9x too, but it's "less accurate" */ ; else return 0; @@ -4844,7 +4942,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return -1; } -void set_title(Frontend *frontend, char *title) +static void wintw_set_title(TermWin *tw, const char *title) { sfree(window_name); window_name = snewn(1 + strlen(title), char); @@ -4853,7 +4951,7 @@ void set_title(Frontend *frontend, char *title) SetWindowText(hwnd, title); } -void set_icon(Frontend *frontend, char *title) +static void wintw_set_icon_title(TermWin *tw, const char *title) { sfree(icon_name); icon_name = snewn(1 + strlen(title), char); @@ -4862,7 +4960,7 @@ void set_icon(Frontend *frontend, char *title) SetWindowText(hwnd, title); } -void set_sbar(Frontend *frontend, int total, int start, int page) +static void wintw_set_scrollbar(TermWin *tw, int total, int start, int page) { SCROLLINFO si; @@ -4880,22 +4978,18 @@ void set_sbar(Frontend *frontend, int total, int start, int page) SetScrollInfo(hwnd, SB_VERT, &si, TRUE); } -Context get_ctx(Frontend *frontend) +static int wintw_setup_draw_ctx(TermWin *tw) { - HDC hdc; - if (hwnd) { - hdc = GetDC(hwnd); - if (hdc && pal) - SelectPalette(hdc, pal, FALSE); - return hdc; - } else - return NULL; + assert(!wintw_hdc); + wintw_hdc = make_hdc(); + return wintw_hdc != NULL; } -void free_ctx(Context ctx) +static void wintw_free_draw_ctx(TermWin *tw) { - SelectPalette(ctx, GetStockObject(DEFAULT_PALETTE), FALSE); - ReleaseDC(hwnd, ctx); + assert(wintw_hdc); + free_hdc(wintw_hdc); + wintw_hdc = NULL; } static void real_palette_set(int n, int r, int g, int b) @@ -4910,7 +5004,7 @@ static void real_palette_set(int n, int r, int g, int b) } } -int palette_get(Frontend *frontend, int n, int *r, int *g, int *b) +static int wintw_palette_get(TermWin *tw, int n, int *r, int *g, int *b) { if (n < 0 || n >= NALLCOLOURS) return FALSE; @@ -4920,7 +5014,7 @@ int palette_get(Frontend *frontend, int n, int *r, int *g, int *b) return TRUE; } -void palette_set(Frontend *frontend, int n, int r, int g, int b) +static void wintw_palette_set(TermWin *tw, int n, int r, int g, int b) { if (n >= 16) n += 256 - 16; @@ -4928,10 +5022,10 @@ void palette_set(Frontend *frontend, int n, int r, int g, int b) return; real_palette_set(n, r, g, b); if (pal) { - HDC hdc = get_ctx(frontend); + HDC hdc = make_hdc(); UnrealizeObject(pal); RealizePalette(hdc); - free_ctx(hdc); + free_hdc(hdc); } else { if (n == (ATTR_DEFBG>>ATTR_BGSHIFT)) /* If Default Background changes, we need to ensure any @@ -4941,7 +5035,7 @@ void palette_set(Frontend *frontend, int n, int r, int g, int b) } } -void palette_reset(Frontend *frontend) +static void wintw_palette_reset(TermWin *tw) { int i; @@ -4960,9 +5054,9 @@ void palette_reset(Frontend *frontend) if (pal) { HDC hdc; SetPaletteEntries(pal, 0, NALLCOLOURS, logpal->palPalEntry); - hdc = get_ctx(frontend); + hdc = make_hdc(); RealizePalette(hdc); - free_ctx(hdc); + free_hdc(hdc); } else { /* Default Background may have changed. Ensure any space between * text area and window border is redrawn. */ @@ -4970,8 +5064,7 @@ void palette_reset(Frontend *frontend) } } -void write_aclip(Frontend *frontend, int clipboard, - char *data, int len, int must_deselect) +void write_aclip(int clipboard, char *data, int len, int must_deselect) { HGLOBAL clipdata; void *lock; @@ -5018,9 +5111,9 @@ int cmpCOLORREF(void *va, void *vb) /* * Note: unlike write_aclip() this will not append a nul. */ -void write_clip(Frontend *frontend, int clipboard, - wchar_t *data, int *attr, truecolour *truecolour, int len, - int must_deselect) +static void wintw_clip_write( + TermWin *tw, int clipboard, wchar_t *data, int *attr, + truecolour *truecolour, int len, int must_deselect) { HGLOBAL clipdata, clipdata2, clipdata3; int len2; @@ -5489,7 +5582,7 @@ static void process_clipdata(HGLOBAL clipdata, int unicode) sfree(clipboard_contents); } -void frontend_request_paste(Frontend *frontend, int clipboard) +static void wintw_clip_request_paste(TermWin *tw, int clipboard) { assert(clipboard == CLIP_SYSTEM); @@ -5628,7 +5721,7 @@ static void flash_window(int mode) /* * Beep. */ -void do_beep(Frontend *frontend, int mode) +static void wintw_bell(TermWin *tw, int mode) { if (mode == BELL_DEFAULT) { /* @@ -5690,13 +5783,13 @@ void do_beep(Frontend *frontend, int mode) * Minimise or restore the window in response to a server-side * request. */ -void set_iconic(Frontend *frontend, int iconic) +static void wintw_set_minimised(TermWin *tw, int minimised) { if (IsIconic(hwnd)) { - if (!iconic) + if (!minimised) ShowWindow(hwnd, SW_RESTORE); } else { - if (iconic) + if (minimised) ShowWindow(hwnd, SW_MINIMIZE); } } @@ -5704,7 +5797,7 @@ void set_iconic(Frontend *frontend, int iconic) /* * Move the window in response to a server-side request. */ -void move_window(Frontend *frontend, int x, int y) +static void wintw_move(TermWin *tw, int x, int y) { int resize_action = conf_get_int(conf, CONF_resize_action); if (resize_action == RESIZE_DISABLED || @@ -5719,7 +5812,7 @@ void move_window(Frontend *frontend, int x, int y) * Move the window to the top or bottom of the z-order in response * to a server-side request. */ -void set_zorder(Frontend *frontend, int top) +static void wintw_set_zorder(TermWin *tw, int top) { if (conf_get_int(conf, CONF_alwaysontop)) return; /* ignore */ @@ -5730,7 +5823,7 @@ void set_zorder(Frontend *frontend, int top) /* * Refresh the window in response to a server-side request. */ -void refresh_window(Frontend *frontend) +static void wintw_refresh(TermWin *tw) { InvalidateRect(hwnd, NULL, TRUE); } @@ -5739,13 +5832,13 @@ void refresh_window(Frontend *frontend) * Maximise or restore the window in response to a server-side * request. */ -void set_zoomed(Frontend *frontend, int zoomed) +static void wintw_set_maximised(TermWin *tw, int maximised) { if (IsZoomed(hwnd)) { - if (!zoomed) + if (!maximised) ShowWindow(hwnd, SW_RESTORE); } else { - if (zoomed) + if (maximised) ShowWindow(hwnd, SW_MAXIMIZE); } } @@ -5753,7 +5846,7 @@ void set_zoomed(Frontend *frontend, int zoomed) /* * Report whether the window is iconic, for terminal reports. */ -int is_iconic(Frontend *frontend) +static int wintw_is_minimised(TermWin *tw) { return IsIconic(hwnd); } @@ -5761,7 +5854,7 @@ int is_iconic(Frontend *frontend) /* * Report the window's position, for terminal reports. */ -void get_window_pos(Frontend *frontend, int *x, int *y) +static void wintw_get_pos(TermWin *tw, int *x, int *y) { RECT r; GetWindowRect(hwnd, &r); @@ -5772,7 +5865,7 @@ void get_window_pos(Frontend *frontend, int *x, int *y) /* * Report the window's pixel size, for terminal reports. */ -void get_window_pixels(Frontend *frontend, int *x, int *y) +static void wintw_get_pixels(TermWin *tw, int *x, int *y) { RECT r; GetWindowRect(hwnd, &r); @@ -5783,7 +5876,7 @@ void get_window_pixels(Frontend *frontend, int *x, int *y) /* * Return the window or icon title. */ -char *get_window_title(Frontend *frontend, int icon) +static const char *wintw_get_title(TermWin *tw, int icon) { return icon ? icon_name : window_name; } diff --git a/windows/winstuff.h b/windows/winstuff.h index 3708e2e6..0a55be89 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -195,8 +195,6 @@ struct FontSpec *fontspec_new(const char *name, #define DEFAULT_CODEPAGE CP_ACP #define USES_VTLINE_HACK -typedef HDC Context; - #ifndef NO_GSSAPI /* * GSS-API stuff @@ -261,7 +259,7 @@ int win_seat_confirm_weak_cached_hostkey( * which takes the data string in the system code page instead of * Unicode. */ -void write_aclip(Frontend *frontend, int clipboard, char *, int, int); +void write_aclip(int clipboard, char *, int, int); #define WM_NETEVENT (WM_APP + 5)