From ff994379ef1b0df5b95265b3c66d2138d3d0e3c8 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 15 Apr 2014 21:44:24 -0400 Subject: reorganize initialization a bunch this way, we can create the window with the correct dimensions from the start, rather than creating it with arbitrary dimensions and then resizing it later --- display.c | 63 +++++++++++++----------------- display.h | 3 +- pty-unix.c | 6 +-- pty-unix.h | 4 +- term.c | 13 ++++--- window-xlib.c | 120 ++++++++++++++++++++++++++-------------------------------- window-xlib.h | 5 +-- 7 files changed, 95 insertions(+), 119 deletions(-) diff --git a/display.c b/display.c index 6d0441e..ec8e531 100644 --- a/display.c +++ b/display.c @@ -9,11 +9,12 @@ static void runes_display_scroll_down(RunesTerm *t, int rows); void runes_display_init(RunesTerm *t) { - t->backend_cr = cairo_create(runes_window_backend_surface_create(t)); - - t->cr = NULL; - t->alternate_cr = NULL; - t->alternate = 0; + t->font_name = "monospace"; + t->font_size = 14.0; + t->font_bold = 0; + t->font_italic = 0; + t->font_underline = 0; + runes_display_calculate_font_dimensions(t); t->colors[0] = cairo_pattern_create_rgb(0.0, 0.0, 0.0); t->colors[1] = cairo_pattern_create_rgb(1.0, 0.0, 0.0); @@ -23,43 +24,38 @@ void runes_display_init(RunesTerm *t) t->colors[5] = cairo_pattern_create_rgb(1.0, 0.0, 1.0); t->colors[6] = cairo_pattern_create_rgb(1.0, 1.0, 1.0); t->colors[7] = cairo_pattern_create_rgb(1.0, 1.0, 1.0); - t->fgcolor = t->colors[7]; - t->bgcolor = t->colors[0]; t->cursorcolor = cairo_pattern_create_rgba(0.0, 1.0, 0.0, 0.5); t->show_cursor = 1; t->focused = 1; - t->font_name = "monospace"; - t->font_size = 14.0; - t->font_bold = 0; - t->font_italic = 0; + t->fgcolor = t->colors[7]; + t->bgcolor = t->colors[0]; + t->font_bold = 0; + t->font_italic = 0; t->font_underline = 0; - runes_display_calculate_font_dimensions(t); -} - -void runes_display_post_init(RunesTerm *t) -{ - int x, y; - - runes_window_backend_get_size(t, &x, &y); + t->scroll_top = 0; + t->scroll_bottom = t->rows - 1; + t->row = 0; + t->col = 0; + t->saved_row = 0; + t->saved_col = 0; t->xpixel = -1; t->ypixel = -1; - runes_display_set_window_size(t, x, y); - - runes_display_reset_text_attributes(t); - t->scroll_top = 0; - t->scroll_bottom = t->rows - 1; - runes_display_move_to(t, 0, 0); - runes_display_save_cursor(t); + t->cr = NULL; + t->alternate_cr = NULL; + t->alternate = 0; } -void runes_display_set_window_size(RunesTerm *t, int width, int height) +void runes_display_set_window_size(RunesTerm *t) { + int width, height; cairo_t *old_cr = NULL; + runes_window_backend_get_size(t, &width, &height); + if (width == t->xpixel && height == t->ypixel) { return; } @@ -100,6 +96,8 @@ void runes_display_set_window_size(RunesTerm *t, int width, int height) if (old_cr) { cairo_destroy(old_cr); } + + runes_pty_backend_set_window_size(t); } /* note: this uses the backend cairo context because it should be redrawn every @@ -347,8 +345,6 @@ void runes_display_restore_cursor(RunesTerm *t) void runes_display_use_alternate_buffer(RunesTerm *t) { - int x, y; - if (t->alternate) { return; } @@ -357,17 +353,13 @@ void runes_display_use_alternate_buffer(RunesTerm *t) t->alternate = 1; t->alternate_cr = t->cr; t->cr = NULL; - x = t->xpixel; - y = t->ypixel; t->xpixel = -1; t->ypixel = -1; - runes_display_set_window_size(t, x, y); + runes_display_set_window_size(t); } void runes_display_use_normal_buffer(RunesTerm *t) { - int x, y; - if (!t->alternate) { return; } @@ -379,8 +371,7 @@ void runes_display_use_normal_buffer(RunesTerm *t) t->alternate_cr = NULL; t->xpixel = -1; t->ypixel = -1; - runes_window_backend_get_size(t, &x, &y); - runes_display_set_window_size(t, x, y); + runes_display_set_window_size(t); } void runes_display_set_scroll_region( diff --git a/display.h b/display.h index f0e30d9..a4076df 100644 --- a/display.h +++ b/display.h @@ -2,8 +2,7 @@ #define _RUNES_DISPLAY_H void runes_display_init(RunesTerm *t); -void runes_display_post_init(RunesTerm *t); -void runes_display_set_window_size(RunesTerm *t, int width, int height); +void runes_display_set_window_size(RunesTerm *t); void runes_display_draw_cursor(RunesTerm *t); void runes_display_focus_in(RunesTerm *t); void runes_display_focus_out(RunesTerm *t); diff --git a/pty-unix.c b/pty-unix.c index 25540d0..5ca8b8d 100644 --- a/pty-unix.c +++ b/pty-unix.c @@ -9,7 +9,7 @@ static void runes_pty_backend_read(uv_work_t *req); static void runes_pty_backend_got_data(uv_work_t *req, int status); -void runes_pty_backend_init(RunesTerm *t) +void runes_pty_backend_spawn_subprocess(RunesTerm *t) { RunesPtyBackend *pty; @@ -53,7 +53,7 @@ void runes_pty_backend_init(RunesTerm *t) } } -void runes_pty_backend_post_init(RunesTerm *t) +void runes_pty_backend_start_loop(RunesTerm *t) { void *data; @@ -61,8 +61,6 @@ void runes_pty_backend_post_init(RunesTerm *t) ((RunesLoopData *)data)->req.data = data; ((RunesLoopData *)data)->t = t; - runes_pty_backend_set_window_size(t); - uv_queue_work( t->loop, data, runes_pty_backend_read, runes_pty_backend_got_data); } diff --git a/pty-unix.h b/pty-unix.h index b431790..791ceab 100644 --- a/pty-unix.h +++ b/pty-unix.h @@ -15,8 +15,8 @@ typedef struct { char buf[RUNES_PTY_BUFFER_LENGTH]; } RunesPtyLoopData; -void runes_pty_backend_init(RunesTerm *t); -void runes_pty_backend_post_init(RunesTerm *t); +void runes_pty_backend_spawn_subprocess(RunesTerm *t); +void runes_pty_backend_start_loop(RunesTerm *t); void runes_pty_backend_set_window_size(RunesTerm *t); void runes_pty_backend_write(RunesTerm *t, char *buf, size_t len); void runes_pty_backend_request_close(RunesTerm *t); diff --git a/term.c b/term.c index 08618fd..e36802f 100644 --- a/term.c +++ b/term.c @@ -8,15 +8,16 @@ void runes_term_init(RunesTerm *t, int argc, char *argv[]) * libuv will set up a bunch of state (including potentially things like * spawning threads) when that is initialized, and i'm not really sure how * that interacts with forking */ - runes_pty_backend_init(t); - runes_window_backend_init(t); + runes_pty_backend_spawn_subprocess(t); runes_display_init(t); - t->loop = uv_default_loop(); + runes_window_backend_create_window(t, argc, argv); + + runes_display_set_window_size(t); - runes_pty_backend_post_init(t); - runes_window_backend_post_init(t, argc, argv); - runes_display_post_init(t); + t->loop = uv_default_loop(); + runes_window_backend_start_loop(t); + runes_pty_backend_start_loop(t); } void runes_term_cleanup(RunesTerm *t) diff --git a/window-xlib.c b/window-xlib.c index 622f5a3..fe839ad 100644 --- a/window-xlib.c +++ b/window-xlib.c @@ -60,31 +60,47 @@ static struct function_key keys[] = { }; #undef RUNES_KEY +static cairo_surface_t *runes_window_backend_surface_create(RunesTerm *t); static void runes_window_backend_get_next_event(uv_work_t *req); static void runes_window_backend_process_event(uv_work_t *req, int status); static void runes_window_backend_map_window(RunesTerm *t); -static void runes_window_backend_init_wm_properties( - RunesTerm *t, int argc, char *argv[]); static void runes_window_backend_resize_window( RunesTerm *t, int width, int height); static void runes_window_backend_flush(RunesTerm *t); -void runes_window_backend_init(RunesTerm *t) +void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]) { RunesWindowBackend *w = &t->w; + pid_t pid; + XClassHint class_hints = { "runes", "runes" }; + XWMHints wm_hints; + XSizeHints normal_hints; unsigned long white; XIM im; Cursor cursor; XColor cursor_fg, cursor_bg; + wm_hints.flags = InputHint | StateHint; + wm_hints.input = True; + wm_hints.initial_state = NormalState; + + normal_hints.flags = PMinSize | PResizeInc | PBaseSize; + + normal_hints.min_width = t->fontx; + normal_hints.min_height = t->fonty; + normal_hints.width_inc = t->fontx; + normal_hints.height_inc = t->fonty; + normal_hints.base_width = t->fontx * 80; + normal_hints.base_height = t->fonty * 24; + XInitThreads(); w->dpy = XOpenDisplay(NULL); white = WhitePixel(w->dpy, DefaultScreen(w->dpy)); w->w = XCreateSimpleWindow( w->dpy, DefaultRootWindow(w->dpy), - 0, 0, 240, 80, 0, white, white - ); + 0, 0, normal_hints.base_width, normal_hints.base_height, + 0, white, white); XSetLocaleModifiers(""); im = XOpenIM(w->dpy, NULL, NULL, NULL); @@ -100,22 +116,38 @@ void runes_window_backend_init(RunesTerm *t) exit(1); } + XInternAtoms(w->dpy, atom_names, RUNES_NUM_ATOMS, False, w->atoms); + XSetWMProtocols(w->dpy, w->w, w->atoms, RUNES_NUM_PROTOCOL_ATOMS); + + Xutf8SetWMProperties( + w->dpy, w->w, "runes", "runes", argv, argc, + &normal_hints, &wm_hints, &class_hints); + + pid = getpid(); + XChangeProperty( + w->dpy, w->w, w->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_fg.red = cursor_fg.green = cursor_fg.blue = 65535; cursor_bg.red = cursor_bg.green = cursor_bg.blue = 0; XRecolorCursor(w->dpy, cursor, &cursor_fg, &cursor_bg); XDefineCursor(w->dpy, w->w, cursor); + + t->backend_cr = cairo_create(runes_window_backend_surface_create(t)); + + runes_window_backend_map_window(t); } -void runes_window_backend_post_init(RunesTerm *t, int argc, char *argv[]) +void runes_window_backend_start_loop(RunesTerm *t) { RunesWindowBackend *w = &t->w; unsigned long mask; void *data; - runes_window_backend_init_wm_properties(t, argc, argv); - runes_window_backend_map_window(t); - XGetICValues(w->ic, XNFilterEvents, &mask, NULL); XSelectInput( w->dpy, w->w, @@ -132,18 +164,6 @@ void runes_window_backend_post_init(RunesTerm *t, int argc, char *argv[]) runes_window_backend_process_event); } -cairo_surface_t *runes_window_backend_surface_create(RunesTerm *t) -{ - RunesWindowBackend *w = &t->w; - Visual *vis; - XWindowAttributes attrs; - - XGetWindowAttributes(w->dpy, w->w, &attrs); - vis = DefaultVisual(w->dpy, DefaultScreen(w->dpy)); - return cairo_xlib_surface_create( - w->dpy, w->w, vis, attrs.width, attrs.height); -} - void runes_window_backend_request_flush(RunesTerm *t) { XEvent e; @@ -233,6 +253,18 @@ void runes_window_backend_cleanup(RunesTerm *t) XCloseDisplay(w->dpy); } +static cairo_surface_t *runes_window_backend_surface_create(RunesTerm *t) +{ + RunesWindowBackend *w = &t->w; + Visual *vis; + XWindowAttributes attrs; + + XGetWindowAttributes(w->dpy, w->w, &attrs); + vis = DefaultVisual(w->dpy, DefaultScreen(w->dpy)); + return cairo_xlib_surface_create( + w->dpy, w->w, vis, attrs.width, attrs.height); +} + static void runes_window_backend_get_next_event(uv_work_t *req) { RunesXlibLoopData *data; @@ -364,49 +396,6 @@ static void runes_window_backend_map_window(RunesTerm *t) } } -static void runes_window_backend_init_wm_properties( - RunesTerm *t, int argc, char *argv[]) -{ - RunesWindowBackend *w = &t->w; - pid_t pid; - XClassHint class_hints = { "runes", "runes" }; - XWMHints wm_hints; - XSizeHints normal_hints; - - wm_hints.flags = InputHint | StateHint; - wm_hints.input = True; - wm_hints.initial_state = NormalState; - - normal_hints.flags = PMinSize | PResizeInc | PBaseSize; - - normal_hints.min_width = t->fontx; - normal_hints.min_height = t->fonty; - normal_hints.width_inc = t->fontx; - normal_hints.height_inc = t->fonty; - normal_hints.base_width = t->fontx * 80; - normal_hints.base_height = t->fonty * 24; - - XResizeWindow( - w->dpy, w->w, normal_hints.base_width, normal_hints.base_height); - runes_window_backend_resize_window( - t, normal_hints.base_width, normal_hints.base_height); - - XInternAtoms(w->dpy, atom_names, RUNES_NUM_ATOMS, False, w->atoms); - XSetWMProtocols(w->dpy, w->w, w->atoms, RUNES_NUM_PROTOCOL_ATOMS); - - Xutf8SetWMProperties( - w->dpy, w->w, "runes", "runes", argv, argc, - &normal_hints, &wm_hints, &class_hints); - - pid = getpid(); - XChangeProperty( - w->dpy, w->w, w->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); -} - static void runes_window_backend_resize_window( RunesTerm *t, int width, int height) { @@ -422,8 +411,7 @@ static void runes_window_backend_resize_window( if (width != t->xpixel || height != t->ypixel) { cairo_xlib_surface_set_size( cairo_get_target(t->backend_cr), width, height); - runes_display_set_window_size(t, width, height); - runes_pty_backend_set_window_size(t); + runes_display_set_window_size(t); } } diff --git a/window-xlib.h b/window-xlib.h index 4537901..7c0aecf 100644 --- a/window-xlib.h +++ b/window-xlib.h @@ -29,9 +29,8 @@ typedef struct { XEvent e; } RunesXlibLoopData; -void runes_window_backend_init(RunesTerm *t); -void runes_window_backend_post_init(RunesTerm *t, int argc, char *argv[]); -cairo_surface_t *runes_window_backend_surface_create(RunesTerm *t); +void runes_window_backend_create_window(RunesTerm *t, int argc, char *argv[]); +void runes_window_backend_start_loop(RunesTerm *t); void runes_window_backend_request_flush(RunesTerm *t); 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); -- cgit v1.2.3-54-g00ecf