aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-04-30 03:28:42 -0400
committerJesse Luehrs <doy@tozt.net>2014-04-30 03:28:42 -0400
commit21c4112cf12e3aa0e83170ca87100917eeeb3374 (patch)
tree2f1e0b965eb5cf329eeef8127c900964163e2bff
parent59be0a78dff68ee4a2fc29e33705fbc0c8b6c850 (diff)
downloadrunes-21c4112cf12e3aa0e83170ca87100917eeeb3374.tar.gz
runes-21c4112cf12e3aa0e83170ca87100917eeeb3374.zip
implement window resizing (again)
-rw-r--r--src/display.c7
-rw-r--r--src/screen.c53
-rw-r--r--src/screen.h2
-rw-r--r--src/window-xlib.c12
4 files changed, 65 insertions, 9 deletions
diff --git a/src/display.c b/src/display.c
index ad4253d..a8c24bf 100644
--- a/src/display.c
+++ b/src/display.c
@@ -32,12 +32,6 @@ void runes_display_set_window_size(RunesTerm *t)
t->xpixel = width;
t->ypixel = height;
- t->scr.max.row = t->ypixel / t->fonty;
- t->scr.max.col = t->xpixel / t->fontx;
-
- t->scr.scroll_top = 0;
- t->scr.scroll_bottom = t->scr.max.row - 1;
-
old_cr = t->cr;
/* XXX this should really use cairo_surface_create_similar_image, but when
@@ -84,6 +78,7 @@ void runes_display_set_window_size(RunesTerm *t)
cairo_destroy(old_cr);
}
+ runes_screen_set_window_size(t);
runes_pty_backend_set_window_size(t);
}
diff --git a/src/screen.c b/src/screen.c
index fa7182b..6fb4c4f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6,14 +6,64 @@
void runes_screen_init(RunesTerm *t)
{
+ UNUSED(t);
+ /* nothing (for now?) */
+}
+
+void runes_screen_set_window_size(RunesTerm *t)
+{
RunesScreen *scr = &t->scr;
+ struct runes_row *old_rows = scr->rows;
+ struct runes_loc old_size;
int i;
+ old_size.row = scr->max.row;
+ old_size.col = scr->max.col;
+
+ scr->max.row = t->ypixel / t->fonty;
+ scr->max.col = t->xpixel / t->fontx;
+
+ if (scr->max.row == 0) {
+ scr->max.row = 1;
+ }
+ if (scr->max.col == 0) {
+ scr->max.col = 1;
+ }
+
+ if (scr->max.row == old_size.row && scr->max.col == old_size.col) {
+ return;
+ }
+
+ if (scr->cur.row >= scr->max.row) {
+ scr->cur.row = scr->max.row - 1;
+ }
+ if (scr->cur.col > scr->max.col) {
+ scr->cur.col = scr->max.col;
+ }
+
+ scr->scroll_top = 0;
+ scr->scroll_bottom = scr->max.row - 1;
+
scr->rows = calloc(scr->max.row, sizeof(struct runes_row));
for (i = 0; i < scr->max.row; ++i) {
scr->rows[i].cells = calloc(
scr->max.col, sizeof(struct runes_cell));
}
+
+ if (old_rows) {
+ struct runes_loc overlap = {
+ scr->max.row < old_size.row ? scr->max.row : old_size.row,
+ scr->max.col < old_size.col ? scr->max.col : old_size.col
+ };
+
+ for (i = 0; i < overlap.row; ++i) {
+ memcpy(
+ scr->rows[i].cells, old_rows[i].cells,
+ overlap.col * sizeof(struct runes_cell));
+ free(old_rows[i].cells);
+ }
+ free(old_rows);
+ }
}
void runes_screen_process_string(RunesTerm *t, char *buf, size_t len)
@@ -496,6 +546,7 @@ void runes_screen_use_alternate_buffer(RunesTerm *t)
runes_screen_save_cursor(t);
scr->alternate = scr->rows;
+ scr->alternate_max = scr->max;
scr->rows = calloc(scr->max.row, sizeof(struct runes_row));
for (i = 0; i < scr->max.row; ++i) {
@@ -519,9 +570,11 @@ void runes_screen_use_normal_buffer(RunesTerm *t)
free(scr->rows);
scr->rows = scr->alternate;
+ scr->max = scr->alternate_max;
scr->alternate = NULL;
runes_screen_restore_cursor(t);
+ runes_screen_set_window_size(t);
}
void runes_screen_save_cursor(RunesTerm *t)
diff --git a/src/screen.h b/src/screen.h
index 38368a3..3296764 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -60,6 +60,7 @@ struct runes_row {
struct runes_screen {
struct runes_loc cur;
struct runes_loc max;
+ struct runes_loc alternate_max;
struct runes_loc saved;
int scroll_top;
@@ -88,6 +89,7 @@ struct runes_screen {
};
void runes_screen_init(RunesTerm *t);
+void runes_screen_set_window_size(RunesTerm *t);
void runes_screen_process_string(RunesTerm *t, char *buf, size_t len);
void runes_screen_audible_bell(RunesTerm *t);
void runes_screen_visual_bell(RunesTerm *t);
diff --git a/src/window-xlib.c b/src/window-xlib.c
index fc6f0f0..7325595 100644
--- a/src/window-xlib.c
+++ b/src/window-xlib.c
@@ -215,7 +215,7 @@ void runes_window_backend_start_loop(RunesTerm *t)
void *data;
XGetICValues(w->ic, XNFilterEvents, &mask, NULL);
- XSelectInput(w->dpy, w->border_w, mask|KeyPressMask);
+ XSelectInput(w->dpy, w->border_w, mask|KeyPressMask|StructureNotifyMask);
XSelectInput(
w->dpy, w->w,
mask|KeyPressMask|ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|PointerMotionHintMask|EnterWindowMask|LeaveWindowMask|StructureNotifyMask|ExposureMask|FocusChangeMask);
@@ -414,8 +414,9 @@ static void runes_window_backend_resize_window(
}
if (width != t->xpixel || height != t->ypixel) {
+ XResizeWindow(w->dpy, w->w, width - 4, height - 4);
cairo_xlib_surface_set_size(
- cairo_get_target(w->backend_cr), width, height);
+ cairo_get_target(w->backend_cr), width - 4, height - 4);
runes_display_set_window_size(t);
}
}
@@ -738,7 +739,12 @@ static void runes_window_backend_handle_configure_event(
{
RunesWindowBackend *w = &t->w;
- while (XCheckTypedWindowEvent(w->dpy, w->w, ConfigureNotify, (XEvent *)e));
+ if (e->window != w->border_w) {
+ return;
+ }
+
+ while (XCheckTypedWindowEvent(
+ w->dpy, w->border_w, ConfigureNotify, (XEvent *)e));
runes_window_backend_resize_window(t, e->width, e->height);
}