diff options
| -rw-r--r-- | .clang-format | 1 | ||||
| -rw-r--r-- | .travis.yml | 6 | ||||
| -rw-r--r-- | configure.ac | 1 | ||||
| -rw-r--r-- | i3lock.c | 14 | ||||
| -rw-r--r-- | i3lock.h | 9 | ||||
| -rw-r--r-- | travis/Dockerfile | 4 | ||||
| -rw-r--r-- | unlock_indicator.c | 61 | ||||
| -rw-r--r-- | unlock_indicator.h | 5 |
8 files changed, 61 insertions, 40 deletions
diff --git a/.clang-format b/.clang-format index 1d84013..6e49d83 100644 --- a/.clang-format +++ b/.clang-format | |||
| @@ -8,3 +8,4 @@ IndentWidth: 4 | |||
| 8 | PointerBindsToType: false | 8 | PointerBindsToType: false |
| 9 | ColumnLimit: 0 | 9 | ColumnLimit: 0 |
| 10 | SpaceBeforeParens: ControlStatements | 10 | SpaceBeforeParens: ControlStatements |
| 11 | SortIncludes: false | ||
diff --git a/.travis.yml b/.travis.yml index 15ad1e4..6e929e6 100644 --- a/.travis.yml +++ b/.travis.yml | |||
| @@ -7,11 +7,7 @@ language: c | |||
| 7 | compiler: | 7 | compiler: |
| 8 | - gcc | 8 | - gcc |
| 9 | - clang | 9 | - clang |
| 10 | addons: | ||
| 11 | apt: | ||
| 12 | packages: | ||
| 13 | - clang-format-3.5 | ||
| 14 | script: | 10 | script: |
| 15 | - clang-format-3.5 -i *.[ch] && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false) | ||
| 16 | - docker build --pull --no-cache --rm -t=i3lock -f travis/Dockerfile . | 11 | - docker build --pull --no-cache --rm -t=i3lock -f travis/Dockerfile . |
| 12 | - docker run -e CC=$CC -v $PWD:/usr/src:rw i3lock /bin/sh -c 'clang-format-9 -i *.[ch] && git diff --exit-code || (echo "Code was not formatted using clang-format!"; false)' | ||
| 17 | - docker run -e CC=$CC -v $PWD:/usr/src:rw i3lock /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j V=1 CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror"' | 13 | - docker run -e CC=$CC -v $PWD:/usr/src:rw i3lock /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j V=1 CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror"' |
diff --git a/configure.ac b/configure.ac index 79f23a9..699e5a6 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -66,6 +66,7 @@ AC_FUNC_FORK | |||
| 66 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK | 66 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK |
| 67 | AC_FUNC_STRNLEN | 67 | AC_FUNC_STRNLEN |
| 68 | AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strndup strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3lock requires])]) | 68 | AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strndup strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3lock requires])]) |
| 69 | AC_CHECK_FUNCS([explicit_bzero]) | ||
| 69 | 70 | ||
| 70 | # Checks for libraries. | 71 | # Checks for libraries. |
| 71 | 72 | ||
| @@ -46,7 +46,6 @@ | |||
| 46 | #include <security/pam_appl.h> | 46 | #include <security/pam_appl.h> |
| 47 | #endif | 47 | #endif |
| 48 | #include <getopt.h> | 48 | #include <getopt.h> |
| 49 | #include <string.h> | ||
| 50 | #include <ev.h> | 49 | #include <ev.h> |
| 51 | #include <sys/mman.h> | 50 | #include <sys/mman.h> |
| 52 | #include <xkbcommon/xkbcommon.h> | 51 | #include <xkbcommon/xkbcommon.h> |
| @@ -54,7 +53,7 @@ | |||
| 54 | #include <xkbcommon/xkbcommon-x11.h> | 53 | #include <xkbcommon/xkbcommon-x11.h> |
| 55 | #include <cairo.h> | 54 | #include <cairo.h> |
| 56 | #include <cairo/cairo-xcb.h> | 55 | #include <cairo/cairo-xcb.h> |
| 57 | #ifdef __OpenBSD__ | 56 | #ifdef HAVE_EXPLICIT_BZERO |
| 58 | #include <strings.h> /* explicit_bzero(3) */ | 57 | #include <strings.h> /* explicit_bzero(3) */ |
| 59 | #endif | 58 | #endif |
| 60 | #include <xcb/xcb_aux.h> | 59 | #include <xcb/xcb_aux.h> |
| @@ -153,7 +152,7 @@ bool skip_repeated_empty_password = false; | |||
| 153 | * Decrements i to point to the previous unicode glyph | 152 | * Decrements i to point to the previous unicode glyph |
| 154 | * | 153 | * |
| 155 | */ | 154 | */ |
| 156 | void u8_dec(char *s, int *i) { | 155 | static void u8_dec(char *s, int *i) { |
| 157 | (void)(isutf(s[--(*i)]) || isutf(s[--(*i)]) || isutf(s[--(*i)]) || --(*i)); | 156 | (void)(isutf(s[--(*i)]) || isutf(s[--(*i)]) || isutf(s[--(*i)]) || --(*i)); |
| 158 | } | 157 | } |
| 159 | 158 | ||
| @@ -223,7 +222,7 @@ static bool load_compose_table(const char *locale) { | |||
| 223 | * | 222 | * |
| 224 | */ | 223 | */ |
| 225 | static void clear_password_memory(void) { | 224 | static void clear_password_memory(void) { |
| 226 | #ifdef __OpenBSD__ | 225 | #ifdef HAVE_EXPLICIT_BZERO |
| 227 | /* Use explicit_bzero(3) which was explicitly designed not to be | 226 | /* Use explicit_bzero(3) which was explicitly designed not to be |
| 228 | * optimized out by the compiler. */ | 227 | * optimized out by the compiler. */ |
| 229 | explicit_bzero(password, strlen(password)); | 228 | explicit_bzero(password, strlen(password)); |
| @@ -664,7 +663,7 @@ static void process_xkb_event(xcb_generic_event_t *gevent) { | |||
| 664 | * and also redraw the image, if any. | 663 | * and also redraw the image, if any. |
| 665 | * | 664 | * |
| 666 | */ | 665 | */ |
| 667 | void handle_screen_resize(void) { | 666 | static void handle_screen_resize(void) { |
| 668 | xcb_get_geometry_cookie_t geomc; | 667 | xcb_get_geometry_cookie_t geomc; |
| 669 | xcb_get_geometry_reply_t *geom; | 668 | xcb_get_geometry_reply_t *geom; |
| 670 | geomc = xcb_get_geometry(conn, screen->root); | 669 | geomc = xcb_get_geometry(conn, screen->root); |
| @@ -1119,6 +1118,8 @@ int main(int argc, char *argv[]) { | |||
| 1119 | err(EXIT_FAILURE, "getpwuid() failed"); | 1118 | err(EXIT_FAILURE, "getpwuid() failed"); |
| 1120 | if ((username = pw->pw_name) == NULL) | 1119 | if ((username = pw->pw_name) == NULL) |
| 1121 | errx(EXIT_FAILURE, "pw->pw_name is NULL."); | 1120 | errx(EXIT_FAILURE, "pw->pw_name is NULL."); |
| 1121 | if (getenv("WAYLAND_DISPLAY") != NULL) | ||
| 1122 | errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead"); | ||
| 1122 | 1123 | ||
| 1123 | #ifdef EXTRAS | 1124 | #ifdef EXTRAS |
| 1124 | char *optstring = "hvnbDdELc:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f"; | 1125 | char *optstring = "hvnbDdELc:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f"; |
| @@ -1497,7 +1498,8 @@ int main(int argc, char *argv[]) { | |||
| 1497 | free(image_raw_format); | 1498 | free(image_raw_format); |
| 1498 | 1499 | ||
| 1499 | /* Pixmap on which the image is rendered to (if any) */ | 1500 | /* Pixmap on which the image is rendered to (if any) */ |
| 1500 | xcb_pixmap_t bg_pixmap = draw_image(last_resolution); | 1501 | xcb_pixmap_t bg_pixmap = create_bg_pixmap(conn, screen, last_resolution, color); |
| 1502 | draw_image(bg_pixmap, last_resolution); | ||
| 1501 | 1503 | ||
| 1502 | xcb_window_t stolen_focus = find_focused_window(conn, screen->root); | 1504 | xcb_window_t stolen_focus = find_focused_window(conn, screen->root); |
| 1503 | 1505 | ||
| @@ -5,10 +5,11 @@ | |||
| 5 | * This is important because xautolock (for example) closes stdout/stderr by | 5 | * This is important because xautolock (for example) closes stdout/stderr by |
| 6 | * default, so just printing something to stdout will lead to the data ending | 6 | * default, so just printing something to stdout will lead to the data ending |
| 7 | * up on the X11 socket (!). */ | 7 | * up on the X11 socket (!). */ |
| 8 | #define DEBUG(fmt, ...) \ | 8 | #define DEBUG(fmt, ...) \ |
| 9 | do { \ | 9 | do { \ |
| 10 | if (debug_mode) \ | 10 | if (debug_mode) { \ |
| 11 | printf("[i3lock-debug] " fmt, ##__VA_ARGS__); \ | 11 | fprintf(stderr, "[i3lock-extended-debug] " fmt, ##__VA_ARGS__); \ |
| 12 | } \ | ||
| 12 | } while (0) | 13 | } while (0) |
| 13 | 14 | ||
| 14 | #endif | 15 | #endif |
diff --git a/travis/Dockerfile b/travis/Dockerfile index 5381276..cc2dd7d 100644 --- a/travis/Dockerfile +++ b/travis/Dockerfile | |||
| @@ -11,7 +11,7 @@ RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry | |||
| 11 | # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. | 11 | # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. |
| 12 | 12 | ||
| 13 | # Install mk-build-deps (for installing the i3 build dependencies), | 13 | # Install mk-build-deps (for installing the i3 build dependencies), |
| 14 | # clang and clang-format-3.8 (for checking formatting and building with clang), | 14 | # clang and clang-format-9 (for checking formatting and building with clang), |
| 15 | # lintian (for checking spelling errors), | 15 | # lintian (for checking spelling errors), |
| 16 | # test suite dependencies (for running tests) | 16 | # test suite dependencies (for running tests) |
| 17 | RUN apt-get update && \ | 17 | RUN apt-get update && \ |
| @@ -19,7 +19,7 @@ RUN apt-get update && \ | |||
| 19 | build-essential clang git autoconf automake libxcb-randr0-dev pkg-config libpam0g-dev \ | 19 | build-essential clang git autoconf automake libxcb-randr0-dev pkg-config libpam0g-dev \ |
| 20 | libcairo2-dev libxcb1-dev libxcb-dpms0-dev libxcb-image0-dev libxcb-util0-dev \ | 20 | libcairo2-dev libxcb1-dev libxcb-dpms0-dev libxcb-image0-dev libxcb-util0-dev \ |
| 21 | libxcb-xrm-dev libev-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ | 21 | libxcb-xrm-dev libev-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ |
| 22 | libxkbcommon-x11-dev && \ | 22 | libxkbcommon-x11-dev clang-format-9 && \ |
| 23 | rm -rf /var/lib/apt/lists/* | 23 | rm -rf /var/lib/apt/lists/* |
| 24 | 24 | ||
| 25 | WORKDIR /usr/src | 25 | WORKDIR /usr/src |
diff --git a/unlock_indicator.c b/unlock_indicator.c index 3d98a5f..73320cb 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c | |||
| @@ -50,9 +50,9 @@ | |||
| 50 | #define BUTTON_CENTER (BUTTON_RADIUS + 5) | 50 | #define BUTTON_CENTER (BUTTON_RADIUS + 5) |
| 51 | #define BUTTON_DIAMETER (2 * BUTTON_SPACE) | 51 | #define BUTTON_DIAMETER (2 * BUTTON_SPACE) |
| 52 | 52 | ||
| 53 | /****************************************************************************** | 53 | /******************************************************************************* |
| 54 | * Variables defined in i3lock.c. | 54 | * Variables defined in i3lock.c. |
| 55 | *****************************************************************************/ | 55 | ******************************************************************************/ |
| 56 | 56 | ||
| 57 | extern bool debug_mode; | 57 | extern bool debug_mode; |
| 58 | 58 | ||
| @@ -100,16 +100,16 @@ extern bool show_failed_attempts; | |||
| 100 | /* Number of failed unlock attempts. */ | 100 | /* Number of failed unlock attempts. */ |
| 101 | extern int failed_attempts; | 101 | extern int failed_attempts; |
| 102 | 102 | ||
| 103 | /****************************************************************************** | 103 | /******************************************************************************* |
| 104 | * Variables defined in xcb.c. | 104 | * Variables defined in xcb.c. |
| 105 | *****************************************************************************/ | 105 | ******************************************************************************/ |
| 106 | 106 | ||
| 107 | /* The root screen, to determine the DPI. */ | 107 | /* The root screen, to determine the DPI. */ |
| 108 | extern xcb_screen_t *screen; | 108 | extern xcb_screen_t *screen; |
| 109 | 109 | ||
| 110 | /****************************************************************************** | 110 | /******************************************************************************* |
| 111 | * Local variables. | 111 | * Local variables. |
| 112 | *****************************************************************************/ | 112 | ******************************************************************************/ |
| 113 | 113 | ||
| 114 | /* Cache the screen’s visual, necessary for creating a Cairo context. */ | 114 | /* Cache the screen’s visual, necessary for creating a Cairo context. */ |
| 115 | static xcb_visualtype_t *vistype; | 115 | static xcb_visualtype_t *vistype; |
| @@ -124,8 +124,7 @@ auth_state_t auth_state; | |||
| 124 | * resolution and returns it. | 124 | * resolution and returns it. |
| 125 | * | 125 | * |
| 126 | */ | 126 | */ |
| 127 | xcb_pixmap_t draw_image(uint32_t *resolution) { | 127 | void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) { |
| 128 | xcb_pixmap_t bg_pixmap = XCB_NONE; | ||
| 129 | const double scaling_factor = get_dpi_value() / 96.0; | 128 | const double scaling_factor = get_dpi_value() / 96.0; |
| 130 | int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER); | 129 | int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER); |
| 131 | DEBUG("scaling_factor is %.f, physical diameter is %d px\n", | 130 | DEBUG("scaling_factor is %.f, physical diameter is %d px\n", |
| @@ -133,7 +132,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 133 | 132 | ||
| 134 | if (!vistype) | 133 | if (!vistype) |
| 135 | vistype = get_root_visual_type(screen); | 134 | vistype = get_root_visual_type(screen); |
| 136 | bg_pixmap = create_bg_pixmap(conn, screen, resolution, color); | 135 | |
| 137 | /* Initialize cairo: Create one in-memory surface to render the unlock | 136 | /* Initialize cairo: Create one in-memory surface to render the unlock |
| 138 | * indicator on, create one XCB surface to actually draw (one or more, | 137 | * indicator on, create one XCB surface to actually draw (one or more, |
| 139 | * depending on the amount of screens) unlock indicators on. */ | 138 | * depending on the amount of screens) unlock indicators on. */ |
| @@ -143,6 +142,19 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 143 | cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); | 142 | cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); |
| 144 | cairo_t *xcb_ctx = cairo_create(xcb_output); | 143 | cairo_t *xcb_ctx = cairo_create(xcb_output); |
| 145 | 144 | ||
| 145 | /* After the first iteration, the pixmap will still contain the previous | ||
| 146 | * contents. Explicitly clear the entire pixmap with the background color | ||
| 147 | * first to get back into a defined state: */ | ||
| 148 | char strgroups[3][3] = {{color[0], color[1], '\0'}, | ||
| 149 | {color[2], color[3], '\0'}, | ||
| 150 | {color[4], color[5], '\0'}}; | ||
| 151 | uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), | ||
| 152 | (strtol(strgroups[1], NULL, 16)), | ||
| 153 | (strtol(strgroups[2], NULL, 16))}; | ||
| 154 | cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); | ||
| 155 | cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); | ||
| 156 | cairo_fill(xcb_ctx); | ||
| 157 | |||
| 146 | if (img) { | 158 | if (img) { |
| 147 | if (!tile) { | 159 | if (!tile) { |
| 148 | cairo_set_source_surface(xcb_ctx, img, 0, 0); | 160 | cairo_set_source_surface(xcb_ctx, img, 0, 0); |
| @@ -157,16 +169,6 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 157 | cairo_fill(xcb_ctx); | 169 | cairo_fill(xcb_ctx); |
| 158 | cairo_pattern_destroy(pattern); | 170 | cairo_pattern_destroy(pattern); |
| 159 | } | 171 | } |
| 160 | } else { | ||
| 161 | char strgroups[3][3] = {{color[0], color[1], '\0'}, | ||
| 162 | {color[2], color[3], '\0'}, | ||
| 163 | {color[4], color[5], '\0'}}; | ||
| 164 | uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), | ||
| 165 | (strtol(strgroups[1], NULL, 16)), | ||
| 166 | (strtol(strgroups[2], NULL, 16))}; | ||
| 167 | cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); | ||
| 168 | cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); | ||
| 169 | cairo_fill(xcb_ctx); | ||
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | if (unlock_indicator && | 174 | if (unlock_indicator && |
| @@ -394,7 +396,18 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 394 | cairo_surface_destroy(output); | 396 | cairo_surface_destroy(output); |
| 395 | cairo_destroy(ctx); | 397 | cairo_destroy(ctx); |
| 396 | cairo_destroy(xcb_ctx); | 398 | cairo_destroy(xcb_ctx); |
| 397 | return bg_pixmap; | 399 | } |
| 400 | |||
| 401 | static xcb_pixmap_t bg_pixmap = XCB_NONE; | ||
| 402 | |||
| 403 | /* | ||
| 404 | * Releases the current background pixmap so that the next redraw_screen() call | ||
| 405 | * will allocate a new one with the updated resolution. | ||
| 406 | * | ||
| 407 | */ | ||
| 408 | void free_bg_pixmap(void) { | ||
| 409 | xcb_free_pixmap(conn, bg_pixmap); | ||
| 410 | bg_pixmap = XCB_NONE; | ||
| 398 | } | 411 | } |
| 399 | 412 | ||
| 400 | /* | 413 | /* |
| @@ -403,12 +416,16 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 403 | */ | 416 | */ |
| 404 | void redraw_screen(void) { | 417 | void redraw_screen(void) { |
| 405 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); | 418 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); |
| 406 | xcb_pixmap_t bg_pixmap = draw_image(last_resolution); | 419 | if (bg_pixmap == XCB_NONE) { |
| 420 | DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]); | ||
| 421 | bg_pixmap = create_bg_pixmap(conn, screen, last_resolution, color); | ||
| 422 | } | ||
| 423 | |||
| 424 | draw_image(bg_pixmap, last_resolution); | ||
| 407 | xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap}); | 425 | xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap}); |
| 408 | /* XXX: Possible optimization: Only update the area in the middle of the | 426 | /* XXX: Possible optimization: Only update the area in the middle of the |
| 409 | * screen instead of the whole screen. */ | 427 | * screen instead of the whole screen. */ |
| 410 | xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]); | 428 | xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]); |
| 411 | xcb_free_pixmap(conn, bg_pixmap); | ||
| 412 | xcb_flush(conn); | 429 | xcb_flush(conn); |
| 413 | } | 430 | } |
| 414 | 431 | ||
diff --git a/unlock_indicator.h b/unlock_indicator.h index 93c1de8..581d028 100644 --- a/unlock_indicator.h +++ b/unlock_indicator.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef _UNLOCK_INDICATOR_H | 1 | #ifndef _UNLOCK_INDICATOR_H |
| 2 | #define _UNLOCK_INDICATOR_H | 2 | #define _UNLOCK_INDICATOR_H |
| 3 | 3 | ||
| 4 | #include <xcb/xcb.h> | ||
| 5 | |||
| 4 | typedef enum { | 6 | typedef enum { |
| 5 | STATE_STARTED = 0, /* default state */ | 7 | STATE_STARTED = 0, /* default state */ |
| 6 | STATE_KEY_PRESSED = 1, /* key was pressed, show unlock indicator */ | 8 | STATE_KEY_PRESSED = 1, /* key was pressed, show unlock indicator */ |
| @@ -19,7 +21,8 @@ typedef enum { | |||
| 19 | STATE_I3LOCK_LOCK_FAILED = 4, /* i3lock failed to load */ | 21 | STATE_I3LOCK_LOCK_FAILED = 4, /* i3lock failed to load */ |
| 20 | } auth_state_t; | 22 | } auth_state_t; |
| 21 | 23 | ||
| 22 | xcb_pixmap_t draw_image(uint32_t* resolution); | 24 | void free_bg_pixmap(void); |
| 25 | void draw_image(xcb_pixmap_t bg_pixmap, uint32_t* resolution); | ||
| 23 | void redraw_screen(void); | 26 | void redraw_screen(void); |
| 24 | void clear_indicator(void); | 27 | void clear_indicator(void); |
| 25 | 28 | ||
