summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-format1
-rw-r--r--.travis.yml6
-rw-r--r--configure.ac1
-rw-r--r--i3lock.c14
-rw-r--r--i3lock.h9
-rw-r--r--travis/Dockerfile4
-rw-r--r--unlock_indicator.c61
-rw-r--r--unlock_indicator.h5
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
8PointerBindsToType: false 8PointerBindsToType: false
9ColumnLimit: 0 9ColumnLimit: 0
10SpaceBeforeParens: ControlStatements 10SpaceBeforeParens: ControlStatements
11SortIncludes: 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
7compiler: 7compiler:
8 - gcc 8 - gcc
9 - clang 9 - clang
10addons:
11 apt:
12 packages:
13 - clang-format-3.5
14script: 10script:
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
66AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK 66AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
67AC_FUNC_STRNLEN 67AC_FUNC_STRNLEN
68AC_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])]) 68AC_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])])
69AC_CHECK_FUNCS([explicit_bzero])
69 70
70# Checks for libraries. 71# Checks for libraries.
71 72
diff --git a/i3lock.c b/i3lock.c
index 4ef0f73..f7c5bdc 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -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 */
156void u8_dec(char *s, int *i) { 155static 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 */
225static void clear_password_memory(void) { 224static 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 */
667void handle_screen_resize(void) { 666static 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
diff --git a/i3lock.h b/i3lock.h
index 57190e5..6cf7694 100644
--- a/i3lock.h
+++ b/i3lock.h
@@ -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)
17RUN apt-get update && \ 17RUN 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
25WORKDIR /usr/src 25WORKDIR /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
57extern bool debug_mode; 57extern 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. */
101extern int failed_attempts; 101extern 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. */
108extern xcb_screen_t *screen; 108extern 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. */
115static xcb_visualtype_t *vistype; 115static 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 */
127xcb_pixmap_t draw_image(uint32_t *resolution) { 127void 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
401static 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 */
408void 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 */
404void redraw_screen(void) { 417void 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
4typedef enum { 6typedef 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
22xcb_pixmap_t draw_image(uint32_t* resolution); 24void free_bg_pixmap(void);
25void draw_image(xcb_pixmap_t bg_pixmap, uint32_t* resolution);
23void redraw_screen(void); 26void redraw_screen(void);
24void clear_indicator(void); 27void clear_indicator(void);
25 28