From 031c4891b0be5abaa4ce86c9cad45388c11f9293 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 7 May 2016 19:13:25 -0400 Subject: use pointer indirection to separate source files even more --- src/config.c | 49 ++++++----- src/config.h | 4 +- src/display.c | 89 ++++++++++---------- src/display.h | 4 +- src/pty-unix.c | 38 +++++---- src/pty-unix.h | 3 +- src/runes.c | 1 + src/runesc.c | 2 + src/runesd.c | 1 + src/socket.c | 1 + src/term.c | 60 ++++++++++---- src/term.h | 18 ++--- src/window-xlib.c | 238 ++++++++++++++++++++++++++++-------------------------- src/window-xlib.h | 3 +- 14 files changed, 278 insertions(+), 233 deletions(-) diff --git a/src/config.c b/src/config.c index 7b0cd6b..34ab1b4 100644 --- a/src/config.c +++ b/src/config.c @@ -5,41 +5,41 @@ #include "runes.h" #include "config.h" -static void runes_config_set_defaults(RunesTerm *t); +static void runes_config_set_defaults(RunesConfig *config); static FILE *runes_config_get_config_file(); -static void runes_config_process_config_file(RunesTerm *t, FILE *config_file); -static void runes_config_process_args(RunesTerm *t, int argc, char *argv[]); -static void runes_config_set(RunesTerm *t, char *key, char *value); +static void runes_config_process_config_file( + RunesConfig *config, FILE *config_file); +static void runes_config_process_args( + RunesConfig *config, int argc, char *argv[]); +static void runes_config_set(RunesConfig *config, char *key, char *value); static char runes_config_parse_bool(char *val); static int runes_config_parse_uint(char *val); static char *runes_config_parse_string(char *val); static cairo_pattern_t *runes_config_parse_color(char *val); -void runes_config_init(RunesTerm *t, int argc, char *argv[]) +void runes_config_init(RunesConfig *config, int argc, char *argv[]) { - runes_config_set_defaults(t); - runes_config_process_config_file(t, runes_config_get_config_file()); - runes_config_process_args(t, argc, argv); + runes_config_set_defaults(config); + runes_config_process_config_file(config, runes_config_get_config_file()); + runes_config_process_args(config, argc, argv); } -void runes_config_cleanup(RunesTerm *t) +void runes_config_cleanup(RunesConfig *config) { int i; - free(t->config.font_name); - cairo_pattern_destroy(t->config.cursorcolor); - cairo_pattern_destroy(t->config.mousecursorcolor); - cairo_pattern_destroy(t->config.fgdefault); - cairo_pattern_destroy(t->config.bgdefault); + free(config->font_name); + cairo_pattern_destroy(config->cursorcolor); + cairo_pattern_destroy(config->mousecursorcolor); + cairo_pattern_destroy(config->fgdefault); + cairo_pattern_destroy(config->bgdefault); for (i = 0; i < 256; ++i) { - cairo_pattern_destroy(t->config.colors[i]); + cairo_pattern_destroy(config->colors[i]); } } -static void runes_config_set_defaults(RunesTerm *t) +static void runes_config_set_defaults(RunesConfig *config) { - RunesConfig *config = &t->config; - config->font_name = strdup("monospace 10"); config->bold_is_bright = 1; config->bold_is_bold = 1; @@ -363,7 +363,8 @@ static FILE *runes_config_get_config_file() return NULL; } -static void runes_config_process_config_file(RunesTerm *t, FILE *config_file) +static void runes_config_process_config_file( + RunesConfig *config, FILE *config_file) { char line[1024]; @@ -398,18 +399,18 @@ static void runes_config_process_config_file(RunesTerm *t, FILE *config_file) *kend = '\0'; *vend = '\0'; - runes_config_set(t, kbegin, vbegin); + runes_config_set(config, kbegin, vbegin); } } -static void runes_config_process_args(RunesTerm *t, int argc, char *argv[]) +static void runes_config_process_args(RunesConfig *config, int argc, char *argv[]) { int i; for (i = 1; i < argc; ++i) { if (!strncmp(argv[i], "--", 2)) { if (i + 1 < argc) { - runes_config_set(t, &argv[i][2], argv[i + 1]); + runes_config_set(config, &argv[i][2], argv[i + 1]); i++; } else { @@ -422,10 +423,8 @@ static void runes_config_process_args(RunesTerm *t, int argc, char *argv[]) } } -static void runes_config_set(RunesTerm *t, char *key, char *val) +static void runes_config_set(RunesConfig *config, char *key, char *val) { - RunesConfig *config = &t->config; - if (!strcmp(key, "font")) { free(config->font_name); config->font_name = runes_config_parse_string(val); diff --git a/src/config.h b/src/config.h index 1da07a2..709a13a 100644 --- a/src/config.h +++ b/src/config.h @@ -28,7 +28,7 @@ struct runes_config { char audible_bell: 1; }; -void runes_config_init(RunesTerm *t, int argc, char *argv[]); -void runes_config_cleanup(RunesTerm *t); +void runes_config_init(RunesConfig *config, int argc, char *argv[]); +void runes_config_cleanup(RunesConfig *config); #endif diff --git a/src/display.c b/src/display.c index 49c9d27..f26026f 100644 --- a/src/display.c +++ b/src/display.c @@ -4,7 +4,10 @@ #include "runes.h" #include "display.h" -static void runes_display_recalculate_font_metrics(RunesTerm *t); +#include "config.h" + +static void runes_display_recalculate_font_metrics( + RunesDisplay *display, char *font_name); static int runes_display_draw_cell(RunesTerm *t, int row, int col); static void runes_display_paint_rectangle( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, @@ -13,14 +16,14 @@ static void runes_display_draw_glyph( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, struct vt100_cell_attrs attrs, char *buf, size_t len, int row, int col); -void runes_display_init(RunesTerm *t) +void runes_display_init(RunesDisplay *display, char *font_name) { - runes_display_recalculate_font_metrics(t); + runes_display_recalculate_font_metrics(display, font_name); } void runes_display_set_window_size(RunesTerm *t, int width, int height) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; cairo_t *old_cr = NULL; cairo_surface_t *surface; @@ -50,7 +53,7 @@ void runes_display_set_window_size(RunesTerm *t, int width, int height) PangoFontDescription *font_desc; attrs = pango_attr_list_new(); - font_desc = pango_font_description_from_string(t->config.font_name); + font_desc = pango_font_description_from_string(t->config->font_name); display->layout = pango_cairo_create_layout(display->cr); pango_layout_set_attributes(display->layout, attrs); @@ -67,7 +70,7 @@ void runes_display_set_window_size(RunesTerm *t, int width, int height) display->cr, cairo_get_target(old_cr), 0.0, 0.0); } else { - cairo_set_source(display->cr, t->config.bgdefault); + cairo_set_source(display->cr, t->config->bgdefault); } cairo_paint(display->cr); @@ -81,51 +84,51 @@ void runes_display_set_window_size(RunesTerm *t, int width, int height) void runes_display_draw_screen(RunesTerm *t) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; int r, rows; - if (!t->scr.dirty && !display->dirty) { + if (!t->scr->dirty && !display->dirty) { return; } - if (t->scr.dirty) { + if (t->scr->dirty) { display->has_selection = 0; } /* XXX quite inefficient */ - rows = t->scr.grid->max.row; + rows = t->scr->grid->max.row; for (r = 0; r < rows; ++r) { - int c = 0, cols = t->scr.grid->max.col; + int c = 0, cols = t->scr->grid->max.col; while (c < cols) { c += runes_display_draw_cell(t, r, c); } } - t->scr.dirty = 0; + t->scr->dirty = 0; display->dirty = 0; } void runes_display_draw_cursor(RunesTerm *t, cairo_t *cr) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; - if (!t->scr.hide_cursor) { - int row = t->scr.grid->cur.row, col = t->scr.grid->cur.col, width; + if (!t->scr->hide_cursor) { + int row = t->scr->grid->cur.row, col = t->scr->grid->cur.col, width; struct vt100_cell *cell; - if (col >= t->scr.grid->max.col) { - col = t->scr.grid->max.col - 1; + if (col >= t->scr->grid->max.col) { + col = t->scr->grid->max.col - 1; } - cell = &t->scr.grid->rows[t->scr.grid->row_top + row].cells[col]; + cell = &t->scr->grid->rows[t->scr->grid->row_top + row].cells[col]; width = display->fontx; if (cell->is_wide) { width *= 2; } cairo_save(cr); - cairo_set_source(cr, t->config.cursorcolor); + cairo_set_source(cr, t->config->cursorcolor); if (display->unfocused) { cairo_set_line_width(cr, 1); cairo_rectangle( @@ -143,7 +146,7 @@ void runes_display_draw_cursor(RunesTerm *t, cairo_t *cr) width, display->fonty); cairo_fill(cr); runes_display_draw_glyph( - t, cr, t->config.bgdefault, cell->attrs, + t, cr, t->config->bgdefault, cell->attrs, cell->contents, cell->len, row + display->row_visible_offset, col); } @@ -153,7 +156,7 @@ void runes_display_draw_cursor(RunesTerm *t, cairo_t *cr) int runes_display_loc_is_selected(RunesTerm *t, struct vt100_loc loc) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; struct vt100_loc start = display->selection_start; struct vt100_loc end = display->selection_end; @@ -164,18 +167,18 @@ int runes_display_loc_is_selected(RunesTerm *t, struct vt100_loc loc) if (loc.row == start.row) { int start_max_col; - start_max_col = vt100_screen_row_max_col(&t->scr, start.row); + start_max_col = vt100_screen_row_max_col(t->scr, start.row); if (start.col > start_max_col) { - start.col = t->scr.grid->max.col; + start.col = t->scr->grid->max.col; } } if (loc.row == end.row) { int end_max_col; - end_max_col = vt100_screen_row_max_col(&t->scr, end.row); + end_max_col = vt100_screen_row_max_col(t->scr, end.row); if (end.col > end_max_col) { - end.col = t->scr.grid->max.col; + end.col = t->scr->grid->max.col; } } @@ -211,17 +214,15 @@ int runes_display_loc_is_between( return 1; } -void runes_display_cleanup(RunesTerm *t) +void runes_display_cleanup(RunesDisplay *display) { - RunesDisplay *display = &t->display; - g_object_unref(display->layout); cairo_destroy(display->cr); } -static void runes_display_recalculate_font_metrics(RunesTerm *t) +static void runes_display_recalculate_font_metrics( + RunesDisplay *display, char *font_name) { - RunesDisplay *display = &t->display; PangoFontDescription *desc; PangoContext *context; PangoFontMetrics *metrics; @@ -233,7 +234,7 @@ static void runes_display_recalculate_font_metrics(RunesTerm *t) context = pango_layout_get_context(display->layout); } else { - desc = pango_font_description_from_string(t->config.font_name); + desc = pango_font_description_from_string(font_name); context = pango_font_map_create_context( pango_cairo_font_map_get_default()); } @@ -255,10 +256,10 @@ static void runes_display_recalculate_font_metrics(RunesTerm *t) static int runes_display_draw_cell(RunesTerm *t, int row, int col) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; struct vt100_loc loc = { - row + t->scr.grid->row_top - display->row_visible_offset, col }; - struct vt100_cell *cell = &t->scr.grid->rows[loc.row].cells[loc.col]; + row + t->scr->grid->row_top - display->row_visible_offset, col }; + struct vt100_cell *cell = &t->scr->grid->rows[loc.row].cells[loc.col]; cairo_pattern_t *bg = NULL, *fg = NULL; int bg_is_custom = 0, fg_is_custom = 0; int selected; @@ -267,10 +268,10 @@ static int runes_display_draw_cell(RunesTerm *t, int row, int col) switch (cell->attrs.bgcolor.type) { case VT100_COLOR_DEFAULT: - bg = t->config.bgdefault; + bg = t->config->bgdefault; break; case VT100_COLOR_IDX: - bg = t->config.colors[cell->attrs.bgcolor.idx]; + bg = t->config->colors[cell->attrs.bgcolor.idx]; break; case VT100_COLOR_RGB: bg = cairo_pattern_create_rgb( @@ -283,15 +284,15 @@ static int runes_display_draw_cell(RunesTerm *t, int row, int col) switch (cell->attrs.fgcolor.type) { case VT100_COLOR_DEFAULT: - fg = t->config.fgdefault; + fg = t->config->fgdefault; break; case VT100_COLOR_IDX: { unsigned char idx = cell->attrs.fgcolor.idx; - if (t->config.bold_is_bright && cell->attrs.bold && idx < 8) { + if (t->config->bold_is_bright && cell->attrs.bold && idx < 8) { idx += 8; } - fg = t->config.colors[idx]; + fg = t->config->colors[idx]; break; } case VT100_COLOR_RGB: @@ -305,8 +306,8 @@ static int runes_display_draw_cell(RunesTerm *t, int row, int col) if (cell->attrs.inverse ^ selected) { if (cell->attrs.fgcolor.id == cell->attrs.bgcolor.id) { - fg = t->config.bgdefault; - bg = t->config.fgdefault; + fg = t->config->bgdefault; + bg = t->config->fgdefault; } else { cairo_pattern_t *tmp = fg; @@ -339,7 +340,7 @@ static void runes_display_paint_rectangle( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, int row, int col, int width, int height) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; cairo_save(cr); cairo_set_source(cr, pattern); @@ -354,11 +355,11 @@ static void runes_display_draw_glyph( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, struct vt100_cell_attrs attrs, char *buf, size_t len, int row, int col) { - RunesDisplay *display = &t->display; + RunesDisplay *display = t->display; PangoAttrList *pango_attrs; pango_attrs = pango_layout_get_attributes(display->layout); - if (t->config.bold_is_bold) { + if (t->config->bold_is_bold) { pango_attr_list_change( pango_attrs, pango_attr_weight_new( attrs.bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL)); diff --git a/src/display.h b/src/display.h index ed25e19..ba2bb13 100644 --- a/src/display.h +++ b/src/display.h @@ -24,7 +24,7 @@ struct runes_display { char dirty: 1; }; -void runes_display_init(RunesTerm *t); +void runes_display_init(RunesDisplay *display, char *font_name); void runes_display_set_window_size(RunesTerm *t, int width, int height); void runes_display_draw_screen(RunesTerm *t); void runes_display_draw_cursor(RunesTerm *t, cairo_t *cr); @@ -32,6 +32,6 @@ int runes_display_loc_is_selected(RunesTerm *t, struct vt100_loc loc); int runes_display_loc_is_between( RunesTerm *t, struct vt100_loc loc, struct vt100_loc start, struct vt100_loc end); -void runes_display_cleanup(RunesTerm *t); +void runes_display_cleanup(RunesDisplay *display); #endif diff --git a/src/pty-unix.c b/src/pty-unix.c index 1351b90..e2b55a8 100644 --- a/src/pty-unix.c +++ b/src/pty-unix.c @@ -9,18 +9,26 @@ #include "runes.h" #include "pty-unix.h" + +#include "config.h" +#include "display.h" #include "loop.h" +#include "window-xlib.h" static void runes_pty_backend_read(RunesTerm *t); static int runes_pty_backend_got_data(RunesTerm *t); -void runes_pty_backend_spawn_subprocess(RunesTerm *t) +void runes_pty_backend_init(RunesPtyBackend *pty) { - RunesPtyBackend *pty = &t->pty; - pty->master = posix_openpt(O_RDWR); grantpt(pty->master); unlockpt(pty->master); +} + +void runes_pty_backend_spawn_subprocess(RunesTerm *t) +{ + RunesPtyBackend *pty = t->pty; + pty->slave = open(ptsname(pty->master), O_RDWR); pty->child_pid = fork(); @@ -48,7 +56,7 @@ void runes_pty_backend_spawn_subprocess(RunesTerm *t) close(pty->slave); - cmd = t->config.cmd; + cmd = t->config->cmd; if (!cmd) { cmd = getenv("SHELL"); } @@ -102,36 +110,34 @@ void runes_pty_backend_set_window_size(RunesTerm *t, int row, int col, size.ws_col = col; size.ws_xpixel = xpixel; size.ws_ypixel = ypixel; - ioctl(t->pty.master, TIOCSWINSZ, &size); + ioctl(t->pty->master, TIOCSWINSZ, &size); } void runes_pty_backend_write(RunesTerm *t, char *buf, size_t len) { - write(t->pty.master, buf, len); - if (t->display.row_visible_offset != 0) { - t->display.row_visible_offset = 0; - t->scr.dirty = 1; + write(t->pty->master, buf, len); + if (t->display->row_visible_offset != 0) { + t->display->row_visible_offset = 0; + t->scr->dirty = 1; runes_window_backend_request_flush(t); } } void runes_pty_backend_request_close(RunesTerm *t) { - RunesPtyBackend *pty = &t->pty; + RunesPtyBackend *pty = t->pty; kill(pty->child_pid, SIGHUP); } -void runes_pty_backend_cleanup(RunesTerm *t) +void runes_pty_backend_cleanup(RunesPtyBackend *pty) { - RunesPtyBackend *pty = &t->pty; - close(pty->master); } static void runes_pty_backend_read(RunesTerm *t) { - RunesPtyBackend *pty = &t->pty; + RunesPtyBackend *pty = t->pty; runes_window_backend_request_flush(t); pty->readlen = read( @@ -141,12 +147,12 @@ static void runes_pty_backend_read(RunesTerm *t) static int runes_pty_backend_got_data(RunesTerm *t) { - RunesPtyBackend *pty = &t->pty; + RunesPtyBackend *pty = t->pty; if (pty->readlen > 0) { int to_process = pty->readlen + pty->remaininglen; int processed = vt100_screen_process_string( - &t->scr, pty->readbuf, to_process); + t->scr, pty->readbuf, to_process); pty->remaininglen = to_process - processed; memmove(pty->readbuf, pty->readbuf + processed, pty->remaininglen); diff --git a/src/pty-unix.h b/src/pty-unix.h index a0c7bac..ea131ca 100644 --- a/src/pty-unix.h +++ b/src/pty-unix.h @@ -13,12 +13,13 @@ struct runes_pty { int remaininglen; }; +void runes_pty_backend_init(RunesPtyBackend *pty); void runes_pty_backend_spawn_subprocess(RunesTerm *t); void runes_pty_backend_init_loop(RunesTerm *t, RunesLoop *loop); void runes_pty_backend_set_window_size(RunesTerm *t, int row, int col, int xpixel, int ypixel); void runes_pty_backend_write(RunesTerm *t, char *buf, size_t len); void runes_pty_backend_request_close(RunesTerm *t); -void runes_pty_backend_cleanup(RunesTerm *t); +void runes_pty_backend_cleanup(RunesPtyBackend *pty); #endif diff --git a/src/runes.c b/src/runes.c index 5d0d2b7..9315ac7 100644 --- a/src/runes.c +++ b/src/runes.c @@ -1,6 +1,7 @@ #include #include "runes.h" + #include "loop.h" #include "term.h" diff --git a/src/runesc.c b/src/runesc.c index 51ea1f3..6abfac8 100644 --- a/src/runesc.c +++ b/src/runesc.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,6 +8,7 @@ #include #include "runes.h" + #include "socket.h" static int runes_socket_open_client(char *name); diff --git a/src/runesd.c b/src/runesd.c index 48a9e57..2ba6ba0 100644 --- a/src/runesd.c +++ b/src/runesd.c @@ -1,6 +1,7 @@ #include #include "runes.h" + #include "loop.h" #include "socket.h" diff --git a/src/socket.c b/src/socket.c index af7d52f..3638f74 100644 --- a/src/socket.c +++ b/src/socket.c @@ -8,6 +8,7 @@ #include "runes.h" #include "socket.h" + #include "loop.h" static int runes_socket_open(RunesSocket *sock); diff --git a/src/term.c b/src/term.c index b764ad0..1b038a4 100644 --- a/src/term.c +++ b/src/term.c @@ -1,44 +1,74 @@ +#include #include #include "runes.h" +#include "config.h" +#include "display.h" +#include "pty-unix.h" +#include "window-xlib.h" + +static void runes_term_init_loop(RunesTerm *t, RunesLoop *loop); + void runes_term_init(RunesTerm *t, RunesLoop *loop, int argc, char *argv[]) { int width, height; - memset((void *)t, 0, sizeof(*t)); + t->config = calloc(1, sizeof(RunesConfig)); + runes_config_init(t->config, argc, argv); + + t->display = calloc(1, sizeof(RunesDisplay)); + runes_display_init(t->display, t->config->font_name); + + t->w = calloc(1, sizeof(RunesWindowBackend)); + runes_window_backend_init(t->w); + + t->pty = calloc(1, sizeof(RunesPtyBackend)); + runes_pty_backend_init(t->pty); - runes_config_init(t, argc, argv); - runes_display_init(t); + t->scr = calloc(1, sizeof(VT100Screen)); + vt100_screen_init(t->scr); runes_window_backend_create_window(t, argc, argv); runes_pty_backend_spawn_subprocess(t); - - vt100_screen_init(&t->scr); - vt100_screen_set_scrollback_length(&t->scr, t->config.scrollback_length); + vt100_screen_set_scrollback_length(t->scr, t->config->scrollback_length); runes_window_backend_get_size(t, &width, &height); runes_term_set_window_size(t, width, height); t->loop = loop; - runes_window_backend_init_loop(t, loop); - runes_pty_backend_init_loop(t, loop); + runes_term_init_loop(t, loop); } void runes_term_set_window_size(RunesTerm *t, int xpixel, int ypixel) { - int row = ypixel / t->display.fonty, col = xpixel / t->display.fontx; + int row = ypixel / t->display->fonty, col = xpixel / t->display->fontx; runes_display_set_window_size(t, xpixel, ypixel); runes_pty_backend_set_window_size(t, row, col, xpixel, ypixel); - vt100_screen_set_window_size(&t->scr, row, col); + vt100_screen_set_window_size(t->scr, row, col); } void runes_term_cleanup(RunesTerm *t) { - runes_config_cleanup(t); - runes_display_cleanup(t); - vt100_screen_cleanup(&t->scr); - runes_window_backend_cleanup(t); - runes_pty_backend_cleanup(t); + vt100_screen_cleanup(t->scr); + free(t->scr); + + runes_pty_backend_cleanup(t->pty); + free(t->pty); + + runes_window_backend_cleanup(t->w); + free(t->w); + + runes_display_cleanup(t->display); + free(t->display); + + runes_config_cleanup(t->config); + free(t->config); +} + +static void runes_term_init_loop(RunesTerm *t, RunesLoop *loop) +{ + runes_window_backend_init_loop(t, loop); + runes_pty_backend_init_loop(t, loop); } diff --git a/src/term.h b/src/term.h index 2e43c6a..7da9ac1 100644 --- a/src/term.h +++ b/src/term.h @@ -1,19 +1,15 @@ #ifndef _RUNES_TERM_H #define _RUNES_TERM_H -#include - -#include "config.h" -#include "display.h" -#include "pty-unix.h" -#include "window-xlib.h" +struct vt100_screen; +typedef struct vt100_screen VT100Screen; struct runes_term { - RunesWindowBackend w; - RunesPtyBackend pty; - VT100Screen scr; - RunesConfig config; - RunesDisplay display; + RunesConfig *config; + RunesDisplay *display; + RunesWindowBackend *w; + RunesPtyBackend *pty; + VT100Screen *scr; RunesLoop *loop; }; diff --git a/src/window-xlib.c b/src/window-xlib.c index ffda703..51c19f3 100644 --- a/src/window-xlib.c +++ b/src/window-xlib.c @@ -9,7 +9,11 @@ #include "runes.h" #include "window-xlib.h" + +#include "config.h" +#include "display.h" #include "loop.h" +#include "pty-unix.h" static char *atom_names[RUNES_NUM_ATOMS] = { "WM_DELETE_WINDOW", @@ -126,9 +130,17 @@ static struct function_key *runes_window_backend_find_key_sequence( static struct vt100_loc runes_window_backend_get_mouse_position( RunesTerm *t, int xpixel, int ypixel); +void runes_window_backend_init(RunesWindowBackend *w) +{ + XInitThreads(); + XSetLocaleModifiers(""); + w->dpy = XOpenDisplay(NULL); + XInternAtoms(w->dpy, atom_names, RUNES_NUM_ATOMS, False, w->atoms); +} + void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; pid_t pid; XClassHint class_hints = { "runes", "runes" }; XWMHints wm_hints; @@ -148,21 +160,18 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) normal_hints.flags = PMinSize | PResizeInc | PBaseSize; - normal_hints.min_width = t->display.fontx + 4; - normal_hints.min_height = t->display.fonty + 4; - normal_hints.width_inc = t->display.fontx; - normal_hints.height_inc = t->display.fonty; - normal_hints.base_width = t->display.fontx * t->config.default_cols + 4; - normal_hints.base_height = t->display.fonty * t->config.default_rows + 4; + normal_hints.min_width = t->display->fontx + 4; + normal_hints.min_height = t->display->fonty + 4; + normal_hints.width_inc = t->display->fontx; + normal_hints.height_inc = t->display->fonty; + normal_hints.base_width = t->display->fontx * t->config->default_cols + 4; + normal_hints.base_height = t->display->fonty * t->config->default_rows + 4; - cairo_pattern_get_rgba(t->config.bgdefault, &bg_r, &bg_g, &bg_b, NULL); + cairo_pattern_get_rgba(t->config->bgdefault, &bg_r, &bg_g, &bg_b, NULL); bgcolor.red = bg_r * 65535; bgcolor.green = bg_g * 65535; bgcolor.blue = bg_b * 65535; - XInitThreads(); - - w->dpy = XOpenDisplay(NULL); XAllocColor( w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)), &bgcolor); w->border_w = XCreateSimpleWindow( @@ -174,7 +183,6 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) 2, 2, normal_hints.base_width - 4, normal_hints.base_height - 4, 0, bgcolor.pixel, bgcolor.pixel); - XSetLocaleModifiers(""); im = XOpenIM(w->dpy, NULL, NULL, NULL); w->ic = XCreateIC( im, @@ -187,7 +195,6 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) runes_die("failed"); } - XInternAtoms(w->dpy, atom_names, RUNES_NUM_ATOMS, False, w->atoms); XSetWMProtocols(w->dpy, w->border_w, w->atoms, RUNES_NUM_PROTOCOL_ATOMS); Xutf8SetWMProperties( @@ -204,7 +211,7 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) cursor = XCreateFontCursor(w->dpy, XC_xterm); cairo_pattern_get_rgba( - t->config.mousecursorcolor, &mouse_r, &mouse_g, &mouse_b, NULL); + t->config->mousecursorcolor, &mouse_r, &mouse_g, &mouse_b, NULL); cursor_fg.red = (unsigned short)(mouse_r * 65535); cursor_fg.green = (unsigned short)(mouse_g * 65535); cursor_fg.blue = (unsigned short)(mouse_b * 65535); @@ -229,7 +236,7 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) void runes_window_backend_init_loop(RunesTerm *t, RunesLoop *loop) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; unsigned long xim_mask, common_mask; XGetICValues(w->ic, XNFilterEvents, &xim_mask, NULL); @@ -260,14 +267,14 @@ void runes_window_backend_request_flush(RunesTerm *t) XEvent e; e.xclient.type = ClientMessage; - e.xclient.window = t->w.w; + e.xclient.window = t->w->w; e.xclient.format = 32; - e.xclient.data.l[0] = t->w.atoms[RUNES_ATOM_RUNES_FLUSH]; + e.xclient.data.l[0] = t->w->atoms[RUNES_ATOM_RUNES_FLUSH]; - XSendEvent(t->w.dpy, t->w.w, False, NoEventMask, &e); - XLockDisplay(t->w.dpy); - XFlush(t->w.dpy); - XUnlockDisplay(t->w.dpy); + XSendEvent(t->w->dpy, t->w->w, False, NoEventMask, &e); + XLockDisplay(t->w->dpy); + XFlush(t->w->dpy); + XUnlockDisplay(t->w->dpy); } void runes_window_backend_request_close(RunesTerm *t) @@ -275,28 +282,28 @@ void runes_window_backend_request_close(RunesTerm *t) XEvent e; e.xclient.type = ClientMessage; - e.xclient.window = t->w.w; - e.xclient.message_type = t->w.atoms[RUNES_ATOM_WM_PROTOCOLS]; + e.xclient.window = t->w->w; + e.xclient.message_type = t->w->atoms[RUNES_ATOM_WM_PROTOCOLS]; e.xclient.format = 32; - e.xclient.data.l[0] = t->w.atoms[RUNES_ATOM_WM_DELETE_WINDOW]; + e.xclient.data.l[0] = t->w->atoms[RUNES_ATOM_WM_DELETE_WINDOW]; e.xclient.data.l[1] = CurrentTime; - XSendEvent(t->w.dpy, t->w.w, False, NoEventMask, &e); - XLockDisplay(t->w.dpy); - XFlush(t->w.dpy); - XUnlockDisplay(t->w.dpy); + XSendEvent(t->w->dpy, t->w->w, False, NoEventMask, &e); + XLockDisplay(t->w->dpy); + XFlush(t->w->dpy); + XUnlockDisplay(t->w->dpy); } unsigned long runes_window_backend_get_window_id(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; return (unsigned long)w->w; } void runes_window_backend_get_size(RunesTerm *t, int *xpixel, int *ypixel) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; cairo_surface_t *surface; surface = cairo_get_target(w->backend_cr); @@ -306,7 +313,7 @@ void runes_window_backend_get_size(RunesTerm *t, int *xpixel, int *ypixel) void runes_window_backend_set_icon_name(RunesTerm *t, char *name, size_t len) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XChangeProperty( w->dpy, w->border_w, XA_WM_ICON_NAME, @@ -321,7 +328,7 @@ void runes_window_backend_set_icon_name(RunesTerm *t, char *name, size_t len) void runes_window_backend_set_window_title( RunesTerm *t, char *name, size_t len) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XChangeProperty( w->dpy, w->border_w, XA_WM_NAME, @@ -333,9 +340,8 @@ void runes_window_backend_set_window_title( (unsigned char *)name, len); } -void runes_window_backend_cleanup(RunesTerm *t) +void runes_window_backend_cleanup(RunesWindowBackend *w) { - RunesWindowBackend *w = &t->w; XIM im; cairo_destroy(w->backend_cr); @@ -349,14 +355,14 @@ void runes_window_backend_cleanup(RunesTerm *t) static void runes_window_backend_get_next_event(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XNextEvent(w->dpy, &w->event); } static int runes_window_backend_process_event(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XEvent *e = &w->event; int should_close = 0; @@ -451,7 +457,7 @@ static Bool runes_window_backend_find_flush_events( static void runes_window_backend_resize_window( RunesTerm *t, int width, int height) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; /* XXX no idea why shrinking the window dimensions to 0 makes xlib think * that the dimension is 65535 */ @@ -462,7 +468,7 @@ static void runes_window_backend_resize_window( height = 1; } - if (width != t->display.xpixel || height != t->display.ypixel) { + if (width != t->display->xpixel || height != t->display->ypixel) { int dwidth = width - 4, dheight = height - 4; XResizeWindow(w->dpy, w->w, dwidth, dheight); @@ -475,32 +481,32 @@ static void runes_window_backend_resize_window( static void runes_window_backend_flush(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; if (runes_window_backend_check_recent(t)) { return; } - if (t->scr.audible_bell) { + if (t->scr->audible_bell) { runes_window_backend_audible_bell(t); - t->scr.audible_bell = 0; + t->scr->audible_bell = 0; } - if (t->scr.visual_bell) { + if (t->scr->visual_bell) { runes_window_backend_visual_bell(t); - t->scr.visual_bell = 0; + t->scr->visual_bell = 0; } - if (t->scr.update_title) { + if (t->scr->update_title) { runes_window_backend_set_window_title( - t, t->scr.title, t->scr.title_len); - t->scr.update_title = 0; + t, t->scr->title, t->scr->title_len); + t->scr->update_title = 0; } - if (t->scr.update_icon_name) { + if (t->scr->update_icon_name) { runes_window_backend_set_icon_name( - t, t->scr.icon_name, t->scr.icon_name_len); - t->scr.update_icon_name = 0; + t, t->scr->icon_name, t->scr->icon_name_len); + t->scr->update_icon_name = 0; } if (w->visual_bell_is_ringing) { @@ -510,7 +516,7 @@ static void runes_window_backend_flush(RunesTerm *t) runes_display_draw_screen(t); cairo_set_source_surface( - w->backend_cr, cairo_get_target(t->display.cr), 0.0, 0.0); + w->backend_cr, cairo_get_target(t->display->cr), 0.0, 0.0); cairo_paint(w->backend_cr); runes_display_draw_cursor(t, w->backend_cr); cairo_surface_flush(cairo_get_target(w->backend_cr)); @@ -520,9 +526,9 @@ static void runes_window_backend_flush(RunesTerm *t) static int runes_window_backend_check_recent(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; struct timespec now; - int rate = t->config.redraw_rate; + int rate = t->config->redraw_rate; if (rate == 0) { return 0; @@ -550,7 +556,7 @@ static int runes_window_backend_check_recent(RunesTerm *t) static void runes_window_backend_delay_cb(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; w->delaying = 0; runes_window_backend_request_flush(t); @@ -558,36 +564,36 @@ static void runes_window_backend_delay_cb(RunesTerm *t) static void runes_window_backend_visible_scroll(RunesTerm *t, int count) { - int min = 0, max = t->scr.grid->row_count - t->scr.grid->max.row; - int old_offset = t->display.row_visible_offset; + int min = 0, max = t->scr->grid->row_count - t->scr->grid->max.row; + int old_offset = t->display->row_visible_offset; - t->display.row_visible_offset += count; - if (t->display.row_visible_offset < min) { - t->display.row_visible_offset = min; + t->display->row_visible_offset += count; + if (t->display->row_visible_offset < min) { + t->display->row_visible_offset = min; } - if (t->display.row_visible_offset > max) { - t->display.row_visible_offset = max; + if (t->display->row_visible_offset > max) { + t->display->row_visible_offset = max; } - if (t->display.row_visible_offset == old_offset) { + if (t->display->row_visible_offset == old_offset) { return; } - t->display.dirty = 1; + t->display->dirty = 1; runes_window_backend_flush(t); } static void runes_window_backend_visual_bell(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; - if (t->config.bell_is_urgent) { + if (t->config->bell_is_urgent) { runes_window_backend_set_urgent(t); } if (!w->visual_bell_is_ringing) { w->visual_bell_is_ringing = 1; - cairo_set_source(w->backend_cr, t->config.fgdefault); + cairo_set_source(w->backend_cr, t->config->fgdefault); cairo_paint(w->backend_cr); cairo_surface_flush(cairo_get_target(w->backend_cr)); XFlush(w->dpy); @@ -599,7 +605,7 @@ static void runes_window_backend_visual_bell(RunesTerm *t) static void runes_window_backend_reset_visual_bell(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; runes_window_backend_request_flush(t); w->visual_bell_is_ringing = 0; @@ -607,10 +613,10 @@ static void runes_window_backend_reset_visual_bell(RunesTerm *t) static void runes_window_backend_audible_bell(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; - if (t->config.audible_bell) { - if (t->config.bell_is_urgent) { + if (t->config->audible_bell) { + if (t->config->bell_is_urgent) { runes_window_backend_set_urgent(t); } XBell(w->dpy, 0); @@ -624,9 +630,9 @@ static void runes_window_backend_set_urgent(RunesTerm *t) { XWMHints *hints; - hints = XGetWMHints(t->w.dpy, t->w.border_w); + hints = XGetWMHints(t->w->dpy, t->w->border_w); hints->flags |= XUrgencyHint; - XSetWMHints(t->w.dpy, t->w.border_w, hints); + XSetWMHints(t->w->dpy, t->w->border_w, hints); XFree(hints); } @@ -634,15 +640,15 @@ static void runes_window_backend_clear_urgent(RunesTerm *t) { XWMHints *hints; - hints = XGetWMHints(t->w.dpy, t->w.border_w); + hints = XGetWMHints(t->w->dpy, t->w->border_w); hints->flags &= ~XUrgencyHint; - XSetWMHints(t->w.dpy, t->w.border_w, hints); + XSetWMHints(t->w->dpy, t->w->border_w, hints); XFree(hints); } static void runes_window_backend_paste(RunesTerm *t, Time time) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XConvertSelection( w->dpy, XA_PRIMARY, w->atoms[RUNES_ATOM_UTF8_STRING], @@ -652,29 +658,29 @@ static void runes_window_backend_paste(RunesTerm *t, Time time) static void runes_window_backend_start_selection( RunesTerm *t, int xpixel, int ypixel, Time time) { - RunesWindowBackend *w = &t->w; - struct vt100_loc *start = &t->display.selection_start; - struct vt100_loc *end = &t->display.selection_end; + RunesWindowBackend *w = t->w; + struct vt100_loc *start = &t->display->selection_start; + struct vt100_loc *end = &t->display->selection_end; *start = runes_window_backend_get_mouse_position(t, xpixel, ypixel); *end = *start; XSetSelectionOwner(w->dpy, XA_PRIMARY, w->w, time); - t->display.has_selection = (XGetSelectionOwner(w->dpy, XA_PRIMARY) == w->w); + t->display->has_selection = (XGetSelectionOwner(w->dpy, XA_PRIMARY) == w->w); - t->display.dirty = 1; + t->display->dirty = 1; runes_window_backend_request_flush(t); } static void runes_window_backend_update_selection( RunesTerm *t, int xpixel, int ypixel) { - RunesWindowBackend *w = &t->w; - struct vt100_loc *start = &t->display.selection_start; - struct vt100_loc *end = &t->display.selection_end; + RunesWindowBackend *w = t->w; + struct vt100_loc *start = &t->display->selection_start; + struct vt100_loc *end = &t->display->selection_end; struct vt100_loc orig_end = *end; - if (!t->display.has_selection) { + if (!t->display->has_selection) { return; } @@ -694,18 +700,18 @@ static void runes_window_backend_update_selection( w->selection_contents = NULL; } vt100_screen_get_string_plaintext( - &t->scr, start, end, &w->selection_contents, &w->selection_len); - t->display.dirty = 1; + t->scr, start, end, &w->selection_contents, &w->selection_len); + t->display->dirty = 1; runes_window_backend_request_flush(t); } } static void runes_window_backend_clear_selection(RunesTerm *t) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XSetSelectionOwner(w->dpy, XA_PRIMARY, None, CurrentTime); - t->display.has_selection = 0; + t->display->has_selection = 0; if (w->selection_contents) { free(w->selection_contents); w->selection_contents = NULL; @@ -714,7 +720,7 @@ static void runes_window_backend_clear_selection(RunesTerm *t) static void runes_window_backend_handle_key_event(RunesTerm *t, XKeyEvent *e) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; char *buf; size_t len = 8; KeySym sym; @@ -770,7 +776,7 @@ static void runes_window_backend_handle_button_event( } } - if (t->scr.mouse_reporting_press_release) { + if (t->scr->mouse_reporting_press_release) { char response[7]; char status = 0; struct vt100_loc loc; @@ -818,7 +824,7 @@ static void runes_window_backend_handle_button_event( ' ' + (status), ' ' + loc.col + 1, ' ' + loc.row + 1); runes_pty_backend_write(t, response, 6); } - else if (t->scr.mouse_reporting_press && e->type == ButtonPress) { + else if (t->scr->mouse_reporting_press && e->type == ButtonPress) { char response[7]; struct vt100_loc loc; @@ -854,7 +860,7 @@ static void runes_window_backend_handle_expose_event( static void runes_window_backend_handle_configure_event( RunesTerm *t, XConfigureEvent *e) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; if (e->window != w->border_w) { return; @@ -875,19 +881,19 @@ static void runes_window_backend_handle_focus_event( return; } - if (e->type == FocusIn && !t->display.unfocused) { + if (e->type == FocusIn && !t->display->unfocused) { return; } - if (e->type == FocusOut && t->display.unfocused) { + if (e->type == FocusOut && t->display->unfocused) { return; } runes_window_backend_clear_urgent(t); if (e->type == FocusIn) { - t->display.unfocused = 0; + t->display->unfocused = 0; } else { - t->display.unfocused = 1; + t->display->unfocused = 1; } runes_window_backend_flush(t); } @@ -895,7 +901,7 @@ static void runes_window_backend_handle_focus_event( static void runes_window_backend_handle_selection_notify_event( RunesTerm *t, XSelectionEvent *e) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; if (e->property == None) { if (e->target == w->atoms[RUNES_ATOM_UTF8_STRING]) { @@ -913,11 +919,11 @@ static void runes_window_backend_handle_selection_notify_event( XGetWindowProperty( w->dpy, e->requestor, e->property, 0, 0x1fffffff, 0, AnyPropertyType, &type, &format, &nitems, &left, &buf); - if (t->scr.bracketed_paste) { + if (t->scr->bracketed_paste) { runes_pty_backend_write(t, "\e[200~", 6); } runes_pty_backend_write(t, (char *)buf, nitems); - if (t->scr.bracketed_paste) { + if (t->scr->bracketed_paste) { runes_pty_backend_write(t, "\e[201~", 6); } XFree(buf); @@ -929,15 +935,15 @@ static void runes_window_backend_handle_selection_clear_event( { UNUSED(e); - t->display.has_selection = 0; - t->display.dirty = 1; + t->display->has_selection = 0; + t->display->dirty = 1; runes_window_backend_flush(t); } static void runes_window_backend_handle_selection_request_event( RunesTerm *t, XSelectionRequestEvent *e) { - RunesWindowBackend *w = &t->w; + RunesWindowBackend *w = t->w; XSelectionEvent selection; selection.type = SelectionNotify; @@ -986,14 +992,14 @@ static int runes_window_backend_handle_builtin_keypress( case XK_Page_Up: if (e->state & ShiftMask) { runes_window_backend_visible_scroll( - t, t->scr.grid->max.row - 1); + t, t->scr->grid->max.row - 1); return 1; } break; case XK_Page_Down: if (e->state & ShiftMask) { runes_window_backend_visible_scroll( - t, -(t->scr.grid->max.row - 1)); + t, -(t->scr->grid->max.row - 1)); return 1; } break; @@ -1018,11 +1024,11 @@ static int runes_window_backend_handle_builtin_button_press( return 1; break; case Button4: - runes_window_backend_visible_scroll(t, t->config.scroll_lines); + runes_window_backend_visible_scroll(t, t->config->scroll_lines); return 1; break; case Button5: - runes_window_backend_visible_scroll(t, -t->config.scroll_lines); + runes_window_backend_visible_scroll(t, -t->config->scroll_lines); return 1; break; default: @@ -1038,8 +1044,8 @@ static struct function_key *runes_window_backend_find_key_sequence( { struct function_key *key; - if (t->scr.application_keypad) { - if (t->scr.application_cursor) { + if (t->scr->application_keypad) { + if (t->scr->application_cursor) { key = &application_cursor_keys[0]; while (key->sym != XK_VoidSymbol) { if (key->sym == sym) { @@ -1072,17 +1078,17 @@ static struct vt100_loc runes_window_backend_get_mouse_position( { struct vt100_loc ret; - ret.row = ypixel / t->display.fonty; - ret.col = xpixel / t->display.fontx; + ret.row = ypixel / t->display->fonty; + ret.col = xpixel / t->display->fontx; - ret.row = ret.row < 0 ? 0 - : ret.row > t->scr.grid->max.row - 1 ? t->scr.grid->max.row - 1 - : ret.row; - ret.col = ret.col < 0 ? 0 - : ret.col > t->scr.grid->max.col ? t->scr.grid->max.col - : ret.col; + ret.row = ret.row < 0 ? 0 + : ret.row > t->scr->grid->max.row - 1 ? t->scr->grid->max.row - 1 + : ret.row; + ret.col = ret.col < 0 ? 0 + : ret.col > t->scr->grid->max.col ? t->scr->grid->max.col + : ret.col; - ret.row = ret.row - t->display.row_visible_offset + t->scr.grid->row_count - t->scr.grid->max.row; + ret.row = ret.row - t->display->row_visible_offset + t->scr->grid->row_count - t->scr->grid->max.row; return ret; } diff --git a/src/window-xlib.h b/src/window-xlib.h index c5d0a8c..dad4241 100644 --- a/src/window-xlib.h +++ b/src/window-xlib.h @@ -38,6 +38,7 @@ struct runes_window { char delaying: 1; }; +void runes_window_backend_init(RunesWindowBackend *w); void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]); void runes_window_backend_init_loop(RunesTerm *t, RunesLoop *loop); void runes_window_backend_request_flush(RunesTerm *t); @@ -47,6 +48,6 @@ void runes_window_backend_get_size(RunesTerm *t, int *xpixel, int *ypixel); void runes_window_backend_set_icon_name(RunesTerm *t, char *name, size_t len); void runes_window_backend_set_window_title( RunesTerm *t, char *name, size_t len); -void runes_window_backend_cleanup(RunesTerm *t); +void runes_window_backend_cleanup(RunesWindowBackend *w); #endif -- cgit v1.2.3-54-g00ecf