aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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