aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Magahern <james@magahern.com>2019-01-16 10:52:37 -0800
committerJames Magahern <james@magahern.com>2019-01-16 10:52:37 -0800
commit39c1761380ed3f25eaf639e899ef1f710bcb83d3 (patch)
treeb953778405c499dd9b3c323adcbb9973f95133ba
parentHygiene (diff)
Some organization and fading cursor
-rw-r--r--buzzsaver.c165
1 files 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 <X11/Xlib.h>
#include <X11/Xutil.h>
+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;
}