aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2016-05-10 17:25:12 -0400
committerJesse Luehrs <doy@tozt.net>2016-05-10 17:31:39 -0400
commitec77a7037586864ece6505c448ab5c15bf8a57d9 (patch)
treead23ca8d2ded6ffc0a9d9c6c5320e457c37ece32
parent9118ead5ae15548c8a5b96340f9a0a24b3104e32 (diff)
downloadrunes-ec77a7037586864ece6505c448ab5c15bf8a57d9.tar.gz
runes-ec77a7037586864ece6505c448ab5c15bf8a57d9.zip
refactor how submodules are handled
let them own their own memory, so that they can free themselves once they exit the loop. also split out the parts of the terminal that we only want to initialize once, even if we open multiple terminal windows
-rw-r--r--src/config.c11
-rw-r--r--src/config.h4
-rw-r--r--src/display.c11
-rw-r--r--src/display.h4
-rw-r--r--src/loop.c11
-rw-r--r--src/loop.h4
-rw-r--r--src/pty-unix.c16
-rw-r--r--src/pty-unix.h4
-rw-r--r--src/runes.c18
-rw-r--r--src/runes.h1
-rw-r--r--src/runesd.c21
-rw-r--r--src/socket.c19
-rw-r--r--src/socket.h5
-rw-r--r--src/term.c70
-rw-r--r--src/term.h5
-rw-r--r--src/window-xlib.c183
-rw-r--r--src/window-xlib.h15
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
diff --git a/src/loop.c b/src/loop.c
index 0eeb0ea..be3b3ba 100644
--- a/src/loop.c
+++ b/src/loop.c
@@ -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)
diff --git a/src/loop.h b/src/loop.h
index 6151033..a825fc5 100644
--- a/src/loop.h
+++ b/src/loop.h
@@ -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))
diff --git a/src/term.c b/src/term.c
index fe79cc5..49d214f 100644
--- a/src/term.c
+++ b/src/term.c
@@ -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);
}
diff --git a/src/term.h b/src/term.h
index 51fc327..10bff11 100644
--- a/src/term.h
+++ b/src/term.h
@@ -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