From 39c1761380ed3f25eaf639e899ef1f710bcb83d3 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Wed, 16 Jan 2019 10:52:37 -0800 Subject: Some organization and fading cursor --- buzzsaver.c | 165 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 40 deletions(-) diff --git a/buzzsaver.c b/buzzsaver.c index 7f24f5b..163c95e 100644 --- a/buzzsaver.c +++ b/buzzsaver.c @@ -14,6 +14,19 @@ #include #include +int __width, __height; +static Window __window = { 0 }; +static Display *__display = NULL; + +static const double kLogoBackgroundWidth = 300.0; + +typedef struct { + cairo_t *ctx; + + double cursor_opacity; + double cursor_fade_direction; +} saver_state_t; + int poll_events(Display *display, Window window) { const bool block_for_next_event = false; @@ -42,43 +55,134 @@ int poll_events(Display *display, Window window) } } +/* + * Scene specific stuff + */ + +void draw_logo(saver_state_t *state) +{ + cairo_t *cr = state->ctx; + cairo_set_source_rgb(cr, (208.0 / 255.0), (69.0 / 255.0), (255.0 / 255.0)); + cairo_rectangle(cr, 0, 0, kLogoBackgroundWidth, __height); + cairo_fill(cr); +} + +void draw_password_field(saver_state_t *state) +{ + cairo_t *cr = state->ctx; + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, state->cursor_opacity); + + const double cursor_height = 50.0; + const double cursor_width = 30.0; + cairo_rectangle(cr, kLogoBackgroundWidth + 50.0, (__height - cursor_height) / 2.0, cursor_width, cursor_height); + + cairo_fill(cr); +} + +/* + * Main drawing/update routines + */ + +void update(saver_state_t *state) +{ + const double cursor_fade_speed = 0.007; + if (state->cursor_fade_direction > 0) { + state->cursor_opacity += cursor_fade_speed; + if (state->cursor_opacity > 1.0) { + state->cursor_fade_direction *= -1; + } + } else { + state->cursor_opacity -= cursor_fade_speed; + if (state->cursor_opacity <= 0.0) { + state->cursor_fade_direction *= -1; + } + } + + + poll_events(__display, __window); +} + +void draw(saver_state_t *state) +{ + // Draw background + cairo_t *cr = state->ctx; + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); + cairo_paint(cr); + + draw_logo(state); + draw_password_field(state); +} + +int runloop(cairo_surface_t *surface) +{ + cairo_t *cr = cairo_create(surface); + + saver_state_t state = { 0 }; + state.ctx = cr; + state.cursor_opacity = 1.0; + state.cursor_fade_direction = -1.0; + + // Main run loop + struct timespec sleep_time = { 0, 5000000 }; + for (;;) { + update(&state); + + cairo_push_group(cr); + + draw(&state); + + cairo_pop_group_to_source(cr); + + cairo_paint(cr); + cairo_surface_flush(surface); + + nanosleep(&sleep_time, NULL); + } + + // Cleanup + cairo_destroy(cr); + + return EXIT_SUCCESS; +} + int main(int argc, char **argv) { - int width = 300; - int height = 300; + __width = 800; + __height = 600; - Display *display = XOpenDisplay(NULL); - if (display == NULL) { + __display = XOpenDisplay(NULL); + if (__display == NULL) { fprintf(stderr, "Error opening display\n"); exit(1); } - Window root_window = DefaultRootWindow(display); - Window window = XCreateSimpleWindow( - display, // display + Window root_window = DefaultRootWindow(__display); + __window = XCreateSimpleWindow( + __display, // display root_window, // parent window 0, 0, // x, y - width, height, // width, height + __width, // width + __height, // height 0, // border_width 0, // border 0 // background ); // Enable key events - XSelectInput(display, window, ButtonPressMask | KeyPressMask | StructureNotifyMask); + XSelectInput(__display, __window, ButtonPressMask | KeyPressMask | StructureNotifyMask); // Map window to display - XMapWindow(display, window); + XMapWindow(__display, __window); // Create cairo surface - int screen = DefaultScreen(display); - Visual *visual = DefaultVisual(display, screen); + int screen = DefaultScreen(__display); + Visual *visual = DefaultVisual(__display, screen); cairo_surface_t *surface = cairo_xlib_surface_create( - display, - window, + __display, + __window, visual, - width, - height + __width, + __height ); if (surface == NULL) { @@ -87,32 +191,13 @@ int main(int argc, char **argv) } // Docs say this must be called whenever the size of the window changes - cairo_xlib_surface_set_size(surface, width, height); + cairo_xlib_surface_set_size(surface, __width, __height); + + int result = runloop(surface); - // Create cairo surface - cairo_t *cr = cairo_create(surface); - - // Main run loop - struct timespec sleep_time = { 0, 5000000 }; - for (;;) { - cairo_push_group(cr); - cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0); - cairo_fill_preserve(cr); - cairo_paint(cr); - cairo_pop_group_to_source(cr); - - cairo_paint(cr); - cairo_surface_flush(surface); - - poll_events(display, window); - nanosleep(&sleep_time, NULL); - } - - // Cleanup - cairo_destroy(cr); cairo_surface_destroy(surface); - XCloseDisplay(display); + XCloseDisplay(__display); - return 0; + return result; } -- cgit v1.2.3