From 64f8f68a3434e883bb672f5e484e72845765da4d Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 25 Oct 2018 18:44:04 +0100 Subject: [PATCH] Remove the 'Frontend' type and replace it with a vtable. After the recent Seat and LogContext revamps, _nearly_ all the remaining uses of the type 'Frontend' were in terminal.c, which needs all sorts of interactions with the GUI window the terminal lives in, from the obvious (actually drawing text on the window, reading and writing the clipboard) to the obscure (minimising, maximising and moving the window in response to particular escape sequences). All of those functions are now provided by an abstraction called TermWin. The few remaining uses of Frontend after _that_ are internal to a particular platform directory, so as to spread the implementation of that particular kind of Frontend between multiple source files; so I've renamed all of those so that they take a more specifically named type that refers to the particular implementation rather than the general abstraction. So now the name 'Frontend' no longer exists in the code base at all, and everywhere one used to be used, it's completely clear whether it was operating in one of Frontend's three abstract roles (and if so, which), or whether it was specific to a particular implementation. Another type that's disappeared is 'Context', which used to be a typedef defined to something different on each platform, describing whatever short-lived resources were necessary to draw on the terminal window: the front end would provide a ready-made one when calling term_paint, and the terminal could request one with get_ctx/free_ctx if it wanted to do proactive window updates. Now that drawing context lives inside the TermWin itself, because there was never any need to have two of those contexts live at the same time. (Another minor API change is that the window-title functions - both reading and writing - have had a missing 'const' added to their char * parameters / return values.) I don't expect this change to enable any particularly interesting new functionality (in particular, I have no plans that need more than one implementation of TermWin in the same application). But it completes the tidying-up that began with the Seat and LogContext rework. --- defs.h | 3 +- fuzzterm.c | 105 +++++--- putty.h | 165 +++++++++--- terminal.c | 165 ++++++------ terminal.h | 2 +- unix/gtkapp.c | 4 +- unix/gtkmain.c | 2 +- unix/gtkwin.c | 630 ++++++++++++++++++++++++--------------------- unix/unix.h | 8 +- windows/windlg.c | 2 +- windows/window.c | 317 +++++++++++++++-------- windows/winstuff.h | 4 +- 12 files changed, 839 insertions(+), 568 deletions(-) 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)