From e9b4d14df7a175c8451563d9b383568190304494 Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 9 Sep 2021 21:54:16 +0200 Subject: Prepared handler and main to separate layouting from drawing --- text.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/text.c b/text.c index 8ad0d75..c0bd004 100644 --- a/text.c +++ b/text.c @@ -44,10 +44,17 @@ struct State cairo_surface_t * surface; }; +enum Actions +{ + ACTION_REDRAW = 1 << 0, + ACTION_RELAYOUT = 1 << 1, + ACTION_CLOSE = 1 << 2, +}; + int setup(struct State *); void finalize(struct State *); int handle(struct State *, xcb_generic_event_t *); -void draw_body(struct State *, union Command *); +void draw(struct State *, union Command *); xcb_visualtype_t * find_visual(xcb_screen_t *); static const int MARGIN = 20; @@ -78,9 +85,13 @@ int main(int argc, const char ** argv) } for (;;) { - xcb_generic_event_t * e = xcb_wait_for_event(state.c); // TODO: Change it to poll-like behaviour. - if (handle(&state, e)) + xcb_generic_event_t * e = xcb_wait_for_event(state.c); // TODO: All events first, then flagged actions. + int actions = handle(&state, e); // Obviously, right now this may have at most one action. + if (ACTION_CLOSE & actions) break; + // if (ACTION_RELAYOUT & actions) TODO: Implement separate layouting. + if (ACTION_REDRAW & actions) + draw(&state, body); } finalize(&state); } @@ -122,20 +133,18 @@ void finalize(struct State * state) int handle(struct State * state, xcb_generic_event_t * e) { + int actions = 0; switch (XCB_EVENT_RESPONSE_TYPE(e)) { case XCB_KEY_PRESS: - free(e); - return 1; + actions = ACTION_CLOSE; + break; case XCB_EXPOSE: - cairo_set_source_rgb(state->ctx, 1., 1., 1.); - cairo_paint(state->ctx); - draw_body(state, body); // TODO: Redraw outside of handler and don't use global body. - cairo_surface_flush(state->surface); - xcb_flush(state->c); + actions |= ACTION_REDRAW; break; case XCB_CONFIGURE_NOTIFY: ; + actions |= ACTION_RELAYOUT; xcb_configure_notify_event_t * conf = (xcb_configure_notify_event_t *) e; if (state->width != conf->width || state->height != conf->height) { @@ -148,7 +157,7 @@ int handle(struct State * state, xcb_generic_event_t * e) break; } free(e); - return 0; + return actions; } @@ -166,12 +175,14 @@ xcb_visualtype_t * find_visual(xcb_screen_t * screen) } -void draw_body(struct State * state, union Command * body) +void draw(struct State * state, union Command * body) { + cairo_set_source_rgb(state->ctx, 1., 1., 1.); + cairo_paint(state->ctx); PangoFontDescription * desc = pango_font_description_from_string(FONT); cairo_set_source_rgb(state->ctx, 0., 0., 0.); int y = MARGIN; - PangoAttrList * attrs = pango_attr_list_new(); // TODO-maybe: Don't recreate attributes lists each redraw? + PangoAttrList * attrs = pango_attr_list_new(); // TODO: Store layouts and only relayout if needed. for (union Command * command = body; COMMAND_DONE != command->type; ++command) { switch (command->type) @@ -206,4 +217,6 @@ void draw_body(struct State * state, union Command * body) } pango_attr_list_unref(attrs); pango_font_description_free(desc); + cairo_surface_flush(state->surface); + xcb_flush(state->c); } -- cgit v1.1