aboutsummaryrefslogtreecommitdiffstats
path: root/src/window-xlib.c
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 /src/window-xlib.c
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
Diffstat (limited to 'src/window-xlib.c')
-rw-r--r--src/window-xlib.c183
1 files changed, 106 insertions, 77 deletions
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(