diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.c | 11 | ||||
-rw-r--r-- | src/config.h | 4 | ||||
-rw-r--r-- | src/display.c | 11 | ||||
-rw-r--r-- | src/display.h | 4 | ||||
-rw-r--r-- | src/loop.c | 11 | ||||
-rw-r--r-- | src/loop.h | 4 | ||||
-rw-r--r-- | src/pty-unix.c | 16 | ||||
-rw-r--r-- | src/pty-unix.h | 4 | ||||
-rw-r--r-- | src/runes.c | 18 | ||||
-rw-r--r-- | src/runes.h | 1 | ||||
-rw-r--r-- | src/runesd.c | 21 | ||||
-rw-r--r-- | src/socket.c | 19 | ||||
-rw-r--r-- | src/socket.h | 5 | ||||
-rw-r--r-- | src/term.c | 70 | ||||
-rw-r--r-- | src/term.h | 5 | ||||
-rw-r--r-- | src/window-xlib.c | 183 | ||||
-rw-r--r-- | src/window-xlib.h | 15 |
17 files changed, 234 insertions, 168 deletions
diff --git a/src/config.c b/src/config.c index e1c93bd..9d947ee 100644 --- a/src/config.c +++ b/src/config.c @@ -17,14 +17,19 @@ 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(RunesConfig *config, int argc, char *argv[]) +RunesConfig *runes_config_new(int argc, char *argv[]) { + RunesConfig *config; + + config = calloc(1, sizeof(RunesConfig)); runes_config_set_defaults(config); runes_config_process_config_file(config, runes_config_get_config_file()); runes_config_process_args(config, argc, argv); + + return config; } -void runes_config_cleanup(RunesConfig *config) +void runes_config_delete(RunesConfig *config) { int i; @@ -36,6 +41,8 @@ void runes_config_cleanup(RunesConfig *config) for (i = 0; i < 256; ++i) { cairo_pattern_destroy(config->colors[i]); } + + free(config); } static void runes_config_set_defaults(RunesConfig *config) diff --git a/src/config.h b/src/config.h index 709a13a..aa0fba7 100644 --- a/src/config.h +++ b/src/config.h @@ -28,7 +28,7 @@ struct runes_config { char audible_bell: 1; }; -void runes_config_init(RunesConfig *config, int argc, char *argv[]); -void runes_config_cleanup(RunesConfig *config); +RunesConfig *runes_config_new(int argc, char *argv[]); +void runes_config_delete(RunesConfig *config); #endif diff --git a/src/display.c b/src/display.c index 5558725..20487ff 100644 --- a/src/display.c +++ b/src/display.c @@ -28,9 +28,14 @@ static int runes_display_loc_is_between( struct vt100_loc loc, struct vt100_loc start, struct vt100_loc end); -void runes_display_init(RunesDisplay *display, char *font_name) +RunesDisplay *runes_display_new(char *font_name) { + RunesDisplay *display; + + display = calloc(1, sizeof(RunesDisplay)); runes_display_recalculate_font_metrics(display, font_name); + + return display; } void runes_display_set_context(RunesTerm *t, cairo_t *cr) @@ -157,10 +162,12 @@ void runes_display_draw_cursor(RunesTerm *t) } } -void runes_display_cleanup(RunesDisplay *display) +void runes_display_delete(RunesDisplay *display) { cairo_pattern_destroy(display->buffer); g_object_unref(display->layout); + + free(display); } static void runes_display_recalculate_font_metrics( diff --git a/src/display.h b/src/display.h index 97247ab..b3fa0ee 100644 --- a/src/display.h +++ b/src/display.h @@ -25,10 +25,10 @@ struct runes_display { char dirty: 1; }; -void runes_display_init(RunesDisplay *display, char *font_name); +RunesDisplay *runes_display_new(char *font_name); void runes_display_set_context(RunesTerm *t, cairo_t *cr); void runes_display_draw_screen(RunesTerm *t); void runes_display_draw_cursor(RunesTerm *t); -void runes_display_cleanup(RunesDisplay *display); +void runes_display_delete(RunesDisplay *display); #endif @@ -21,9 +21,14 @@ static void runes_loop_do_after_work(uv_work_t *req, int status); static void runes_loop_timer_cb(uv_timer_t *handle); static void runes_loop_free_handle(uv_handle_t *handle); -void runes_loop_init(RunesLoop *loop) +RunesLoop *runes_loop_new() { + RunesLoop *loop; + + loop = calloc(1, sizeof(RunesLoop)); loop->loop = uv_default_loop(); + + return loop; } void runes_loop_run(RunesLoop *loop) @@ -63,9 +68,11 @@ void runes_loop_timer_set(RunesLoop *loop, int timeout, int repeat, uv_timer_start(timer_req, runes_loop_timer_cb, timeout, repeat); } -void runes_loop_cleanup(RunesLoop *loop) +void runes_loop_delete(RunesLoop *loop) { uv_loop_close(loop->loop); + + free(loop); } static void runes_loop_do_work(uv_work_t *req) @@ -7,13 +7,13 @@ struct runes_loop { uv_loop_t *loop; }; -void runes_loop_init(RunesLoop *loop); +RunesLoop *runes_loop_new(); void runes_loop_run(RunesLoop *loop); void runes_loop_start_work(RunesLoop *loop, void *t, void (*work_cb)(void*), int (*after_work_cb)(void*)); void runes_loop_timer_set(RunesLoop *loop, int timeout, int repeat, void *t, void (*cb)(void*)); -void runes_loop_cleanup(RunesLoop *loop); +void runes_loop_delete(RunesLoop *loop); #endif diff --git a/src/pty-unix.c b/src/pty-unix.c index 27419ce..2430cd2 100644 --- a/src/pty-unix.c +++ b/src/pty-unix.c @@ -19,11 +19,16 @@ static void runes_pty_backend_read(void *t); static int runes_pty_backend_got_data(void *t); -void runes_pty_backend_init(RunesPtyBackend *pty) +RunesPtyBackend *runes_pty_backend_new() { + RunesPtyBackend *pty; + + pty = calloc(1, sizeof(RunesPtyBackend)); pty->master = posix_openpt(O_RDWR); grantpt(pty->master); unlockpt(pty->master); + + return pty; } void runes_pty_backend_spawn_subprocess(RunesTerm *t) @@ -94,12 +99,11 @@ void runes_pty_backend_spawn_subprocess(RunesTerm *t) fprintf(old_stderr, "Couldn't run %s: %s\n", cmd, strerror(errno)); exit(1); } - - runes_term_refcnt_inc(t); } void runes_pty_backend_init_loop(RunesTerm *t, RunesLoop *loop) { + runes_term_refcnt_inc(t); runes_loop_start_work(loop, t, runes_pty_backend_read, runes_pty_backend_got_data); } @@ -128,9 +132,11 @@ void runes_pty_backend_request_close(RunesTerm *t) kill(pty->child_pid, SIGHUP); } -void runes_pty_backend_cleanup(RunesPtyBackend *pty) +void runes_pty_backend_delete(RunesPtyBackend *pty) { close(pty->master); + + free(pty); } static void runes_pty_backend_read(void *t) @@ -157,8 +163,6 @@ static int runes_pty_backend_got_data(void *t) return 1; } else { - runes_pty_backend_cleanup(pty); - free(pty); runes_window_backend_request_close(t); runes_term_refcnt_dec(t); diff --git a/src/pty-unix.h b/src/pty-unix.h index ea131ca..364f9ad 100644 --- a/src/pty-unix.h +++ b/src/pty-unix.h @@ -13,13 +13,13 @@ struct runes_pty { int remaininglen; }; -void runes_pty_backend_init(RunesPtyBackend *pty); +RunesPtyBackend *runes_pty_backend_new(); 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(RunesPtyBackend *pty); +void runes_pty_backend_delete(RunesPtyBackend *pty); #endif diff --git a/src/runes.c b/src/runes.c index af32778..46aaf41 100644 --- a/src/runes.c +++ b/src/runes.c @@ -1,27 +1,27 @@ #include <locale.h> -#include <stdlib.h> #include "runes.h" #include "loop.h" #include "term.h" +#include "window-xlib.h" int main (int argc, char *argv[]) { - RunesLoop loop; - RunesTerm *t; + RunesLoop *loop; + RunesWindowBackendGlobal *wg; setlocale(LC_ALL, ""); - runes_loop_init(&loop); + loop = runes_loop_new(); + wg = runes_window_backend_global_init(); + runes_term_register_with_loop(runes_term_new(argc, argv, wg), loop); - t = calloc(1, sizeof(RunesTerm)); - runes_term_init(t, &loop, argc, argv); - - runes_loop_run(&loop); + runes_loop_run(loop); #ifdef RUNES_VALGRIND - runes_loop_cleanup(&loop); + runes_loop_cleanup(loop); + runes_window_backend_global_cleanup(wg); #endif return 0; diff --git a/src/runes.h b/src/runes.h index a5ed4a4..ad33725 100644 --- a/src/runes.h +++ b/src/runes.h @@ -11,6 +11,7 @@ struct runes_socket; typedef struct runes_term RunesTerm; typedef struct runes_window RunesWindowBackend; +typedef struct runes_window_global RunesWindowBackendGlobal; typedef struct runes_pty RunesPtyBackend; typedef struct runes_config RunesConfig; typedef struct runes_display RunesDisplay; diff --git a/src/runesd.c b/src/runesd.c index 2ba6ba0..344e834 100644 --- a/src/runesd.c +++ b/src/runesd.c @@ -4,11 +4,13 @@ #include "loop.h" #include "socket.h" +#include "window-xlib.h" int main (int argc, char *argv[]) { - RunesLoop loop; - RunesSocket socket; + RunesLoop *loop; + RunesSocket *socket; + RunesWindowBackendGlobal *wg; UNUSED(argv); @@ -18,13 +20,18 @@ int main (int argc, char *argv[]) setlocale(LC_ALL, ""); - runes_loop_init(&loop); - runes_socket_init(&socket, &loop); + loop = runes_loop_new(); + wg = runes_window_backend_global_init(); + socket = runes_socket_new(loop, wg); + UNUSED(socket); - runes_loop_run(&loop); + runes_loop_run(loop); - runes_socket_cleanup(&socket); - runes_loop_cleanup(&loop); +#ifdef RUNES_VALGRIND + runes_socket_delete(socket); + runes_window_backend_global_cleanup(wg); + runes_loop_delete(loop); +#endif return 0; } diff --git a/src/socket.c b/src/socket.c index e2aef89..5758ab0 100644 --- a/src/socket.c +++ b/src/socket.c @@ -17,24 +17,32 @@ static void runes_socket_close(RunesSocket *sock); static void runes_socket_accept(void *t); static int runes_socket_handle_request(void *t); -void runes_socket_init(RunesSocket *sock, RunesLoop *loop) +RunesSocket *runes_socket_new(RunesLoop *loop, RunesWindowBackendGlobal *wg) { + RunesSocket *sock; + + sock = calloc(1, sizeof(RunesSocket)); sock->loop = loop; + sock->wg = wg; sock->name = runes_get_socket_name(); sock->sock = runes_socket_open(sock); runes_socket_init_loop(sock, loop); + + return sock; } void runes_socket_init_loop(RunesSocket *sock, RunesLoop *loop) { - runes_loop_start_work(loop, (RunesTerm *)sock, runes_socket_accept, + runes_loop_start_work(loop, sock, runes_socket_accept, runes_socket_handle_request); } -void runes_socket_cleanup(RunesSocket *sock) +void runes_socket_delete(RunesSocket *sock) { runes_socket_close(sock); free(sock->name); + + free(sock); } static int runes_socket_open(RunesSocket *sock) @@ -160,7 +168,6 @@ static int runes_socket_handle_request(void *t) if (argc > 0) { size_t offset = 0; int i; - RunesTerm *t; for (i = 0; i < (int)argc; ++i) { char *next_null; @@ -176,8 +183,8 @@ static int runes_socket_handle_request(void *t) offset = next_null - argv_buf + 1; } - t = calloc(1, sizeof(RunesTerm)); - runes_term_init(t, sock->loop, argc, argv); + runes_term_register_with_loop( + runes_term_new(argc, argv, sock->wg), sock->loop); } free(argv); diff --git a/src/socket.h b/src/socket.h index e0c5955..a2d453a 100644 --- a/src/socket.h +++ b/src/socket.h @@ -5,15 +5,16 @@ struct runes_socket { RunesLoop *loop; + RunesWindowBackendGlobal *wg; char *name; int sock; int client_sock; }; -void runes_socket_init(RunesSocket *sock, RunesLoop *loop); +RunesSocket *runes_socket_new(RunesLoop *loop, RunesWindowBackendGlobal *wg); void runes_socket_init_loop(RunesSocket *sock, RunesLoop *loop); void runes_socket_send_client_message(int argc, char **argv); -void runes_socket_cleanup(RunesSocket *sock); +void runes_socket_delete(RunesSocket *sock); #define MAX_SOCKET_PATH_LEN \ (sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path)) @@ -9,26 +9,18 @@ #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[]) +RunesTerm *runes_term_new(int argc, char *argv[], RunesWindowBackendGlobal *wg) { + RunesTerm *t; int width, height; - 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); + t = calloc(1, sizeof(RunesTerm)); - t->scr = calloc(1, sizeof(VT100Screen)); - vt100_screen_init(t->scr); + t->config = runes_config_new(argc, argv); + t->display = runes_display_new(t->config->font_name); + t->w = runes_window_backend_new(wg); + t->pty = runes_pty_backend_new(); + t->scr = vt100_screen_new(t->config->default_cols, t->config->default_rows); vt100_screen_set_scrollback_length(t->scr, t->config->scrollback_length); runes_window_backend_create_window(t, argc, argv); @@ -38,22 +30,14 @@ void runes_term_init(RunesTerm *t, RunesLoop *loop, int argc, char *argv[]) runes_window_backend_get_size(t, &width, &height); runes_term_set_window_size(t, width, height); - t->loop = loop; - runes_term_init_loop(t, loop); + return t; } -void runes_term_refcnt_inc(RunesTerm *t) +void runes_term_register_with_loop(RunesTerm *t, RunesLoop *loop) { - t->refcnt++; -} - -void runes_term_refcnt_dec(RunesTerm *t) -{ - t->refcnt--; - if (t->refcnt <= 0) { - runes_term_cleanup(t); - free(t); - } + t->loop = loop; + runes_window_backend_init_loop(t, loop); + runes_pty_backend_init_loop(t, loop); } void runes_term_set_window_size(RunesTerm *t, int xpixel, int ypixel) @@ -64,20 +48,26 @@ void runes_term_set_window_size(RunesTerm *t, int xpixel, int ypixel) vt100_screen_set_window_size(t->scr, row, col); } -void runes_term_cleanup(RunesTerm *t) +void runes_term_refcnt_inc(RunesTerm *t) { - vt100_screen_cleanup(t->scr); - free(t->scr); - - runes_display_cleanup(t->display); - free(t->display); + t->refcnt++; +} - runes_config_cleanup(t->config); - free(t->config); +void runes_term_refcnt_dec(RunesTerm *t) +{ + t->refcnt--; + if (t->refcnt <= 0) { + runes_term_delete(t); + } } -static void runes_term_init_loop(RunesTerm *t, RunesLoop *loop) +void runes_term_delete(RunesTerm *t) { - runes_window_backend_init_loop(t, loop); - runes_pty_backend_init_loop(t, loop); + vt100_screen_delete(t->scr); + runes_pty_backend_delete(t->pty); + runes_window_backend_delete(t->w); + runes_display_delete(t->display); + runes_config_delete(t->config); + + free(t); } @@ -15,10 +15,11 @@ struct runes_term { int refcnt; }; -void runes_term_init(RunesTerm *t, RunesLoop *loop, int argc, char *argv[]); +RunesTerm *runes_term_new(int argc, char *argv[], RunesWindowBackendGlobal *wg); +void runes_term_register_with_loop(RunesTerm *t, RunesLoop *loop); void runes_term_set_window_size(RunesTerm *t, int xpixel, int ypixel); void runes_term_refcnt_inc(RunesTerm *t); void runes_term_refcnt_dec(RunesTerm *t); -void runes_term_cleanup(RunesTerm *t); +void runes_term_delete(RunesTerm *t); #endif diff --git a/src/window-xlib.c b/src/window-xlib.c index ecfc6cb..dce54ef 100644 --- a/src/window-xlib.c +++ b/src/window-xlib.c @@ -135,12 +135,27 @@ 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) +RunesWindowBackendGlobal *runes_window_backend_global_init() { + RunesWindowBackendGlobal *wg; + + wg = calloc(1, sizeof(RunesWindowBackendGlobal)); XInitThreads(); XSetLocaleModifiers(""); - w->dpy = XOpenDisplay(NULL); - XInternAtoms(w->dpy, atom_names, RUNES_NUM_ATOMS, False, w->atoms); + wg->dpy = XOpenDisplay(NULL); + XInternAtoms(wg->dpy, atom_names, RUNES_NUM_ATOMS, False, wg->atoms); + + return wg; +} + +RunesWindowBackend *runes_window_backend_new(RunesWindowBackendGlobal *wg) +{ + RunesWindowBackend *w; + + w = calloc(1, sizeof(RunesWindowBackend)); + w->wg = wg; + + return w; } void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) @@ -178,17 +193,18 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) bgcolor.blue = bg_b * 65535; XAllocColor( - w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)), &bgcolor); + w->wg->dpy, DefaultColormap(w->wg->dpy, DefaultScreen(w->wg->dpy)), + &bgcolor); w->border_w = XCreateSimpleWindow( - w->dpy, DefaultRootWindow(w->dpy), + w->wg->dpy, DefaultRootWindow(w->wg->dpy), 0, 0, normal_hints.base_width, normal_hints.base_height, 0, bgcolor.pixel, bgcolor.pixel); w->w = XCreateSimpleWindow( - w->dpy, w->border_w, + w->wg->dpy, w->border_w, 2, 2, normal_hints.base_width - 4, normal_hints.base_height - 4, 0, bgcolor.pixel, bgcolor.pixel); - im = XOpenIM(w->dpy, NULL, NULL, NULL); + im = XOpenIM(w->wg->dpy, NULL, NULL, NULL); w->ic = XCreateIC( im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, @@ -200,21 +216,22 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) runes_die("failed"); } - XSetWMProtocols(w->dpy, w->border_w, w->atoms, RUNES_NUM_PROTOCOL_ATOMS); + XSetWMProtocols( + w->wg->dpy, w->border_w, w->wg->atoms, RUNES_NUM_PROTOCOL_ATOMS); Xutf8SetWMProperties( - w->dpy, w->border_w, "runes", "runes", argv, argc, + w->wg->dpy, w->border_w, "runes", "runes", argv, argc, &normal_hints, &wm_hints, &class_hints); pid = getpid(); XChangeProperty( - w->dpy, w->border_w, w->atoms[RUNES_ATOM_NET_WM_PID], + w->wg->dpy, w->border_w, w->wg->atoms[RUNES_ATOM_NET_WM_PID], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1); runes_window_backend_set_icon_name(t, "runes", 5); runes_window_backend_set_window_title(t, "runes", 5); - cursor = XCreateFontCursor(w->dpy, XC_xterm); + cursor = XCreateFontCursor(w->wg->dpy, XC_xterm); cairo_pattern_get_rgba( t->config->mousecursorcolor, &mouse_r, &mouse_g, &mouse_b, NULL); cursor_fg.red = (unsigned short)(mouse_r * 65535); @@ -226,17 +243,18 @@ void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) else { cursor_bg.red = cursor_bg.green = cursor_bg.blue = 65535; } - XRecolorCursor(w->dpy, cursor, &cursor_fg, &cursor_bg); - XDefineCursor(w->dpy, w->w, cursor); + XRecolorCursor(w->wg->dpy, cursor, &cursor_fg, &cursor_bg); + XDefineCursor(w->wg->dpy, w->w, cursor); - vis = DefaultVisual(w->dpy, DefaultScreen(w->dpy)); + vis = DefaultVisual(w->wg->dpy, DefaultScreen(w->wg->dpy)); surface = cairo_xlib_surface_create( - w->dpy, w->w, vis, normal_hints.base_width, normal_hints.base_height); + w->wg->dpy, w->w, vis, normal_hints.base_width, + normal_hints.base_height); w->backend_cr = cairo_create(surface); cairo_surface_destroy(surface); - XMapWindow(w->dpy, w->w); - XMapWindow(w->dpy, w->border_w); + XMapWindow(w->wg->dpy, w->w); + XMapWindow(w->wg->dpy, w->border_w); runes_term_refcnt_inc(t); } @@ -255,13 +273,13 @@ void runes_window_backend_init_loop(RunesTerm *t, RunesLoop *loop) /* the top level window is the only one that needs to worry about window * size and focus changes */ XSelectInput( - w->dpy, w->border_w, + w->wg->dpy, w->border_w, xim_mask|common_mask|StructureNotifyMask|FocusChangeMask); /* we only care about mouse events if they are over the actual terminal * area, and the terminal area is the only area we need to redraw, so it's * the only thing we care about exposure events for */ XSelectInput( - w->dpy, w->w, + w->wg->dpy, w->w, xim_mask|common_mask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|ExposureMask); XSetICFocus(w->ic); @@ -271,34 +289,36 @@ void runes_window_backend_init_loop(RunesTerm *t, RunesLoop *loop) void runes_window_backend_request_flush(RunesTerm *t) { + RunesWindowBackend *w = t->w; XEvent e; e.xclient.type = ClientMessage; - e.xclient.window = t->w->w; + e.xclient.window = w->w; e.xclient.format = 32; - e.xclient.data.l[0] = t->w->atoms[RUNES_ATOM_RUNES_FLUSH]; + e.xclient.data.l[0] = w->wg->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(w->wg->dpy, w->w, False, NoEventMask, &e); + XLockDisplay(w->wg->dpy); + XFlush(w->wg->dpy); + XUnlockDisplay(w->wg->dpy); } void runes_window_backend_request_close(RunesTerm *t) { + RunesWindowBackend *w = t->w; 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 = w->w; + e.xclient.message_type = w->wg->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] = w->wg->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(w->wg->dpy, w->w, False, NoEventMask, &e); + XLockDisplay(w->wg->dpy); + XFlush(w->wg->dpy); + XUnlockDisplay(w->wg->dpy); } unsigned long runes_window_backend_get_window_id(RunesTerm *t) @@ -323,12 +343,12 @@ void runes_window_backend_set_icon_name(RunesTerm *t, char *name, size_t len) RunesWindowBackend *w = t->w; XChangeProperty( - w->dpy, w->border_w, XA_WM_ICON_NAME, - w->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, + w->wg->dpy, w->border_w, XA_WM_ICON_NAME, + w->wg->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, (unsigned char *)name, len); XChangeProperty( - w->dpy, w->border_w, w->atoms[RUNES_ATOM_NET_WM_ICON_NAME], - w->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, + w->wg->dpy, w->border_w, w->wg->atoms[RUNES_ATOM_NET_WM_ICON_NAME], + w->wg->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, (unsigned char *)name, len); } @@ -338,16 +358,16 @@ void runes_window_backend_set_window_title( RunesWindowBackend *w = t->w; XChangeProperty( - w->dpy, w->border_w, XA_WM_NAME, - w->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, + w->wg->dpy, w->border_w, XA_WM_NAME, + w->wg->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, (unsigned char *)name, len); XChangeProperty( - w->dpy, w->border_w, w->atoms[RUNES_ATOM_NET_WM_NAME], - w->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, + w->wg->dpy, w->border_w, w->wg->atoms[RUNES_ATOM_NET_WM_NAME], + w->wg->atoms[RUNES_ATOM_UTF8_STRING], 8, PropModeReplace, (unsigned char *)name, len); } -void runes_window_backend_cleanup(RunesWindowBackend *w) +void runes_window_backend_delete(RunesWindowBackend *w) { XIM im; @@ -355,16 +375,23 @@ void runes_window_backend_cleanup(RunesWindowBackend *w) im = XIMOfIC(w->ic); XDestroyIC(w->ic); XCloseIM(im); - XDestroyWindow(w->dpy, w->w); - XDestroyWindow(w->dpy, w->border_w); - XCloseDisplay(w->dpy); + XDestroyWindow(w->wg->dpy, w->w); + XDestroyWindow(w->wg->dpy, w->border_w); + + free(w); +} + +void runes_window_backend_global_cleanup(RunesWindowBackendGlobal *wg) +{ + XCloseDisplay(wg->dpy); + free(wg); } static void runes_window_backend_get_next_event(void *t) { RunesWindowBackend *w = ((RunesTerm *)t)->w; - XNextEvent(w->dpy, &w->event); + XNextEvent(w->wg->dpy, &w->event); } static int runes_window_backend_process_event(void *t) @@ -410,23 +437,23 @@ static int runes_window_backend_process_event(void *t) break; case ClientMessage: { Atom a = e->xclient.data.l[0]; - if (a == w->atoms[RUNES_ATOM_WM_DELETE_WINDOW]) { + if (a == w->wg->atoms[RUNES_ATOM_WM_DELETE_WINDOW]) { should_close = 1; } - else if (a == w->atoms[RUNES_ATOM_NET_WM_PING]) { - e->xclient.window = DefaultRootWindow(w->dpy); + else if (a == w->wg->atoms[RUNES_ATOM_NET_WM_PING]) { + e->xclient.window = DefaultRootWindow(w->wg->dpy); XSendEvent( - w->dpy, e->xclient.window, False, + w->wg->dpy, e->xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, e ); } - else if (a == w->atoms[RUNES_ATOM_RUNES_FLUSH]) { + else if (a == w->wg->atoms[RUNES_ATOM_RUNES_FLUSH]) { Bool res = True; while (res) { res = XCheckIfEvent( - w->dpy, e, runes_window_backend_find_flush_events, + w->wg->dpy, e, runes_window_backend_find_flush_events, (XPointer)w); } runes_window_backend_flush(t); @@ -439,8 +466,6 @@ static int runes_window_backend_process_event(void *t) } if (should_close) { - runes_window_backend_cleanup(w); - free(w); runes_pty_backend_request_close(t); runes_term_refcnt_dec(t); } @@ -457,7 +482,7 @@ static Bool runes_window_backend_find_flush_events( if (e->type == ClientMessage) { Atom a = e->xclient.data.l[0]; - return a == w->atoms[RUNES_ATOM_RUNES_FLUSH] ? True : False; + return a == w->wg->atoms[RUNES_ATOM_RUNES_FLUSH] ? True : False; } else { return False; @@ -481,7 +506,7 @@ static void runes_window_backend_resize_window( if (width != t->display->xpixel || height != t->display->ypixel) { int dwidth = width - 4, dheight = height - 4; - XResizeWindow(w->dpy, w->w, dwidth, dheight); + XResizeWindow(w->wg->dpy, w->w, dwidth, dheight); cairo_xlib_surface_set_size( cairo_get_target(w->backend_cr), dwidth, dheight); runes_term_set_window_size(t, dwidth, dheight); @@ -619,7 +644,7 @@ static void runes_window_backend_visual_bell(RunesTerm *t) 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); + XFlush(w->wg->dpy); runes_loop_timer_set(t->loop, 20, 0, t, runes_window_backend_reset_visual_bell); @@ -645,7 +670,7 @@ static void runes_window_backend_audible_bell(RunesTerm *t) if (t->config->bell_is_urgent) { runes_window_backend_set_urgent(t); } - XBell(w->dpy, 0); + XBell(w->wg->dpy, 0); } else { runes_window_backend_visual_bell(t); @@ -654,21 +679,23 @@ static void runes_window_backend_audible_bell(RunesTerm *t) static void runes_window_backend_set_urgent(RunesTerm *t) { + RunesWindowBackend *w = t->w; XWMHints *hints; - hints = XGetWMHints(t->w->dpy, t->w->border_w); + hints = XGetWMHints(w->wg->dpy, w->border_w); hints->flags |= XUrgencyHint; - XSetWMHints(t->w->dpy, t->w->border_w, hints); + XSetWMHints(w->wg->dpy, w->border_w, hints); XFree(hints); } static void runes_window_backend_clear_urgent(RunesTerm *t) { + RunesWindowBackend *w = t->w; XWMHints *hints; - hints = XGetWMHints(t->w->dpy, t->w->border_w); + hints = XGetWMHints(w->wg->dpy, t->w->border_w); hints->flags &= ~XUrgencyHint; - XSetWMHints(t->w->dpy, t->w->border_w, hints); + XSetWMHints(w->wg->dpy, t->w->border_w, hints); XFree(hints); } @@ -677,8 +704,8 @@ static void runes_window_backend_paste(RunesTerm *t, Time time) RunesWindowBackend *w = t->w; XConvertSelection( - w->dpy, XA_PRIMARY, w->atoms[RUNES_ATOM_UTF8_STRING], - w->atoms[RUNES_ATOM_RUNES_SELECTION], w->w, time); + w->wg->dpy, XA_PRIMARY, w->wg->atoms[RUNES_ATOM_UTF8_STRING], + w->wg->atoms[RUNES_ATOM_RUNES_SELECTION], w->w, time); } static void runes_window_backend_start_selection( @@ -691,8 +718,8 @@ static void runes_window_backend_start_selection( *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); + XSetSelectionOwner(w->wg->dpy, XA_PRIMARY, w->w, time); + t->display->has_selection = (XGetSelectionOwner(w->wg->dpy, XA_PRIMARY) == w->w); t->display->dirty = 1; runes_window_backend_request_flush(t); @@ -736,7 +763,7 @@ static void runes_window_backend_clear_selection(RunesTerm *t) { RunesWindowBackend *w = t->w; - XSetSelectionOwner(w->dpy, XA_PRIMARY, None, CurrentTime); + XSetSelectionOwner(w->wg->dpy, XA_PRIMARY, None, CurrentTime); t->display->has_selection = 0; if (w->selection_contents) { free(w->selection_contents); @@ -896,7 +923,7 @@ static void runes_window_backend_handle_configure_event( } while (XCheckTypedWindowEvent( - w->dpy, w->border_w, ConfigureNotify, (XEvent *)e)); + w->wg->dpy, w->border_w, ConfigureNotify, (XEvent *)e)); runes_window_backend_resize_window(t, e->width, e->height); } @@ -933,10 +960,10 @@ static void runes_window_backend_handle_selection_notify_event( RunesWindowBackend *w = t->w; if (e->property == None) { - if (e->target == w->atoms[RUNES_ATOM_UTF8_STRING]) { + if (e->target == w->wg->atoms[RUNES_ATOM_UTF8_STRING]) { XConvertSelection( - w->dpy, XA_PRIMARY, XA_STRING, - w->atoms[RUNES_ATOM_RUNES_SELECTION], w->w, e->time); + w->wg->dpy, XA_PRIMARY, XA_STRING, + w->wg->atoms[RUNES_ATOM_RUNES_SELECTION], w->w, e->time); } } else { @@ -946,7 +973,7 @@ static void runes_window_backend_handle_selection_notify_event( unsigned char *buf; XGetWindowProperty( - w->dpy, e->requestor, e->property, 0, 0x1fffffff, 0, + w->wg->dpy, e->requestor, e->property, 0, 0x1fffffff, 0, AnyPropertyType, &type, &format, &nitems, &left, &buf); if (t->scr->bracketed_paste) { runes_window_backend_write_to_pty(t, "\e[200~", 6); @@ -985,18 +1012,19 @@ static void runes_window_backend_handle_selection_request_event( selection.property = e->property; selection.time = e->time; - if (e->target == w->atoms[RUNES_ATOM_TARGETS]) { - Atom targets[2] = { XA_STRING, w->atoms[RUNES_ATOM_UTF8_STRING] }; + if (e->target == w->wg->atoms[RUNES_ATOM_TARGETS]) { + Atom targets[2] = { XA_STRING, w->wg->atoms[RUNES_ATOM_UTF8_STRING] }; XChangeProperty( - w->dpy, e->requestor, e->property, + w->wg->dpy, e->requestor, e->property, XA_ATOM, 32, PropModeReplace, (unsigned char *)&targets, 2); } - else if (e->target == XA_STRING || e->target == w->atoms[RUNES_ATOM_UTF8_STRING]) { + else if (e->target == XA_STRING + || e->target == w->wg->atoms[RUNES_ATOM_UTF8_STRING]) { if (w->selection_contents) { XChangeProperty( - w->dpy, e->requestor, e->property, + w->wg->dpy, e->requestor, e->property, e->target, 8, PropModeReplace, (unsigned char *)w->selection_contents, w->selection_len); } @@ -1005,7 +1033,8 @@ static void runes_window_backend_handle_selection_request_event( selection.property = None; } - XSendEvent(w->dpy, e->requestor, False, NoEventMask, (XEvent *)&selection); + XSendEvent( + w->wg->dpy, e->requestor, False, NoEventMask, (XEvent *)&selection); } static int runes_window_backend_handle_builtin_keypress( diff --git a/src/window-xlib.h b/src/window-xlib.h index dad4241..c84f251 100644 --- a/src/window-xlib.h +++ b/src/window-xlib.h @@ -21,7 +21,7 @@ enum runes_atoms { }; struct runes_window { - Display *dpy; + RunesWindowBackendGlobal *wg; Window w; Window border_w; XIC ic; @@ -32,13 +32,17 @@ struct runes_window { cairo_t *backend_cr; - Atom atoms[RUNES_NUM_ATOMS]; - char visual_bell_is_ringing: 1; char delaying: 1; }; -void runes_window_backend_init(RunesWindowBackend *w); +struct runes_window_global { + Display *dpy; + Atom atoms[RUNES_NUM_ATOMS]; +}; + +RunesWindowBackendGlobal *runes_window_backend_global_init(); +RunesWindowBackend *runes_window_backend_new(); 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); @@ -48,6 +52,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); void runes_window_backend_set_window_title( RunesTerm *t, char *name, size_t len); -void runes_window_backend_cleanup(RunesWindowBackend *w); +void runes_window_backend_delete(RunesWindowBackend *w); +void runes_window_backend_global_cleanup(RunesWindowBackendGlobal *wg); #endif |