diff --git a/README.md b/README.md index eea54ea..c6450ac 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,24 @@ -i3lock - improved screen locker -=============================== -i3lock is a simple screen locker like slock. After starting it, you will -see a white screen (you can configure the color/an image). You can return -to your screen by entering your password. +i3lock-color +============ -Many little improvements have been made to i3lock over time: +*making i3lock's typing indicator color scheme configurable* -- i3lock forks, so you can combine it with an alias to suspend to RAM - (run "i3lock && echo mem > /sys/power/state" to get a locked screen - after waking up your computer from suspend to RAM) +I added the following command line options: +* `--insidevercolor=rrggbbaa` -- Inside of the circle while the password is being verified +* `--insidewrongcolor=rrggbbaa` -- Inside of the circle when a wrong password was entered +* `--insidecolor=rrggbbaa` -- Inside of the circle while typing/idle +* `--ringvercolor=rrggbbaa` -- Outer ring while the password is being +* `--ringwrongcolor=rrggbbaa` -- Outer ring when a wrong password was entered +* `--ringcolor=rrggbbaa` -- Outer ring while typing/idle +* `--linecolor=rrggbbaa` -- Line separating outer ring from inside of the circle and delimiting the highlight segments +* `--textcolor=rrggbbaa` -- Text ("verifying", "wrong!") +* `--keyhlcolor=rrggbbaa` -- Keypress highlight segments +* `--bshlcolor=rrggbbaa` -- Backspace highlight segments -- You can specify either a background color or a PNG image which will be - displayed while your screen is locked. +All the colors have an alpha channel now. Please keep in mind that this was not intended when the program was originally written, so making thing transparent that weren't before can make it look strange. -- You can specify whether i3lock should bell upon a wrong password. +### Examples: -- i3lock uses PAM and therefore is compatible with LDAP etc. +i3lock --insidevercolor=0000a0bf --insidewrongcolor=ff8000bf --insidecolor=ffffffbf --ringvercolor=0020ffff --ringwrongcolor=4040ffff --ringcolor=404090ff --textcolor=ffffffff --linecolor=aaaaaaff --keyhlcolor=30ccccff --bshlcolor=ff8000ff -Requirements ------------- -- pkg-config -- libxcb -- libxcb-util -- libpam-dev -- libcairo-dev -- libxcb-xinerama -- libev -- libx11-dev -- libx11-xcb-dev -- libxkbcommon >= 0.5.0 -- libxkbcommon-x11 >= 0.5.0 - -Running i3lock -------------- -Simply invoke the 'i3lock' command. To get out of it, enter your password and -press enter. - -Upstream --------- -Please submit pull requests to https://github.com/i3/i3lock +Refer to the original README file for general information and libraries you need. diff --git a/README.md.old b/README.md.old new file mode 100644 index 0000000..eea54ea --- /dev/null +++ b/README.md.old @@ -0,0 +1,41 @@ +i3lock - improved screen locker +=============================== +i3lock is a simple screen locker like slock. After starting it, you will +see a white screen (you can configure the color/an image). You can return +to your screen by entering your password. + +Many little improvements have been made to i3lock over time: + +- i3lock forks, so you can combine it with an alias to suspend to RAM + (run "i3lock && echo mem > /sys/power/state" to get a locked screen + after waking up your computer from suspend to RAM) + +- You can specify either a background color or a PNG image which will be + displayed while your screen is locked. + +- You can specify whether i3lock should bell upon a wrong password. + +- i3lock uses PAM and therefore is compatible with LDAP etc. + +Requirements +------------ +- pkg-config +- libxcb +- libxcb-util +- libpam-dev +- libcairo-dev +- libxcb-xinerama +- libev +- libx11-dev +- libx11-xcb-dev +- libxkbcommon >= 0.5.0 +- libxkbcommon-x11 >= 0.5.0 + +Running i3lock +------------- +Simply invoke the 'i3lock' command. To get out of it, enter your password and +press enter. + +Upstream +-------- +Please submit pull requests to https://github.com/i3/i3lock diff --git a/i3lock.c b/i3lock.c index df5d952..fef03ae 100644 --- a/i3lock.c +++ b/i3lock.c @@ -45,6 +45,19 @@ typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents); char color[7] = "ffffff"; + +/* options for unlock indicator colors */ +char insidevercolor[9] = "006effbf"; +char insidewrongcolor[9] = "fa0000bf"; +char insidecolor[9] = "000000bf"; +char ringvercolor[9] = "3300faff"; +char ringwrongcolor[9] = "7d3300ff"; +char ringcolor[9] = "337d00ff"; +char linecolor[9] = "000000ff"; +char textcolor[9] = "000000ff"; +char keyhlcolor[9] = "33db00ff"; +char bshlcolor[9] = "db3300ff"; + int inactivity_timeout = 30; uint32_t last_resolution[2]; xcb_window_t win; @@ -756,6 +769,20 @@ int main(int argc, char *argv[]) { {"no-unlock-indicator", no_argument, NULL, 'u'}, {"image", required_argument, NULL, 'i'}, {"tiling", no_argument, NULL, 't'}, + + /* options for unlock indicator colors */ + // defining a lot of different chars here for the options -- TODO find a nicer way for this, maybe not offering single character options at all + {"insidevercolor", required_argument, NULL, 0}, + {"insidewrongcolor", required_argument, NULL, 0}, + {"insidecolor", required_argument, NULL, 0}, + {"ringvercolor", required_argument, NULL, 0}, + {"ringwrongcolor", required_argument, NULL, 0}, + {"ringcolor", required_argument, NULL, 0}, + {"linecolor", required_argument, NULL, 0}, + {"textcolor", required_argument, NULL, 0}, + {"keyhlcolor", required_argument, NULL, 0}, + {"bshlcolor", required_argument, NULL, 0}, + {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, @@ -823,6 +850,106 @@ int main(int argc, char *argv[]) { case 0: if (strcmp(longopts[optind].name, "debug") == 0) debug_mode = true; + else if (strcmp(longopts[optind].name, "insidevercolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", insidevercolor) != 1) + errx(1, "insidevercolor is invalid, color must be given in 8-byte format: rrggbbaa\n"); + } + else if (strcmp(longopts[optind].name, "insidewrongcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", insidewrongcolor) != 1) + errx(1, "insidewrongcolor is invalid, color must be given in 8-byte format: rrggbbaa\n"); + } + else if (strcmp(longopts[optind].name, "insidecolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", insidecolor) != 1) + errx(1, "insidecolor is invalid, color must be given in 8-byte format: rrggbbaa\n"); + } + else if (strcmp(longopts[optind].name, "ringvercolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", ringvercolor) != 1) + errx(1, "ringvercolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "ringwrongcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", ringwrongcolor) != 1) + errx(1, "ringwrongcolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "ringcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", ringcolor) != 1) + errx(1, "ringcolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "linecolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", linecolor) != 1) + errx(1, "linecolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "textcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", textcolor) != 1) + errx(1, "textcolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "keyhlcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", keyhlcolor) != 1) + errx(1, "keyhlcolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } + else if (strcmp(longopts[optind].name, "bshlcolor") == 0) { + char *arg = optarg; + + /* Skip # if present */ + if (arg[0] == '#') + arg++; + + if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", bshlcolor) != 1) + errx(1, "bshlcolor is invalid, color must be given in 8-byte format: rrggbb\n"); + } break; case 'f': show_failed_attempts = true; diff --git a/unlock_indicator.c b/unlock_indicator.c index 3b94d17..44c1119 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -55,6 +55,17 @@ extern cairo_surface_t *img; extern bool tile; /* The background color to use (in hex). */ extern char color[7]; +/* indicator color options */ +extern char insidevercolor[9]; +extern char insidewrongcolor[9]; +extern char insidecolor[9]; +extern char ringvercolor[9]; +extern char ringwrongcolor[9]; +extern char ringcolor[9]; +extern char linecolor[9]; +extern char textcolor[9]; +extern char keyhlcolor[9]; +extern char bshlcolor[9]; /* Whether the failed attempts should be displayed. */ extern bool show_failed_attempts; @@ -140,6 +151,88 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_fill(xcb_ctx); } + /* build indicator color arrays */ + char strgroupsiv[4][3] = {{insidevercolor[0], insidevercolor[1], '\0'}, + {insidevercolor[2], insidevercolor[3], '\0'}, + {insidevercolor[4], insidevercolor[5], '\0'}, + {insidevercolor[6], insidevercolor[7], '\0'}}; + uint32_t insidever16[4] = {(strtol(strgroupsiv[0], NULL, 16)), + (strtol(strgroupsiv[1], NULL, 16)), + (strtol(strgroupsiv[2], NULL, 16)), + (strtol(strgroupsiv[3], NULL, 16))}; + char strgroupsiw[4][3] = {{insidewrongcolor[0], insidewrongcolor[1], '\0'}, + {insidewrongcolor[2], insidewrongcolor[3], '\0'}, + {insidewrongcolor[4], insidewrongcolor[5], '\0'}, + {insidewrongcolor[6], insidewrongcolor[7], '\0'}}; + uint32_t insidewrong16[4] = {(strtol(strgroupsiw[0], NULL, 16)), + (strtol(strgroupsiw[1], NULL, 16)), + (strtol(strgroupsiw[2], NULL, 16)), + (strtol(strgroupsiw[3], NULL, 16))}; + char strgroupsi[4][3] = {{insidecolor[0], insidecolor[1], '\0'}, + {insidecolor[2], insidecolor[3], '\0'}, + {insidecolor[4], insidecolor[5], '\0'}, + {insidecolor[6], insidecolor[7], '\0'}}; + uint32_t inside16[4] = {(strtol(strgroupsi[0], NULL, 16)), + (strtol(strgroupsi[1], NULL, 16)), + (strtol(strgroupsi[2], NULL, 16)), + (strtol(strgroupsi[3], NULL, 16))}; + char strgroupsrv[4][3] = {{ringvercolor[0], ringvercolor[1], '\0'}, + {ringvercolor[2], ringvercolor[3], '\0'}, + {ringvercolor[4], ringvercolor[5], '\0'}, + {ringvercolor[6], ringvercolor[7], '\0'}}; + uint32_t ringver16[4] = {(strtol(strgroupsrv[0], NULL, 16)), + (strtol(strgroupsrv[1], NULL, 16)), + (strtol(strgroupsrv[2], NULL, 16)), + (strtol(strgroupsrv[3], NULL, 16))}; + char strgroupsrw[4][3] = {{ringwrongcolor[0], ringwrongcolor[1], '\0'}, + {ringwrongcolor[2], ringwrongcolor[3], '\0'}, + {ringwrongcolor[4], ringwrongcolor[5], '\0'}, + {ringwrongcolor[6], ringwrongcolor[7], '\0'}}; + uint32_t ringwrong16[4] = {(strtol(strgroupsrw[0], NULL, 16)), + (strtol(strgroupsrw[1], NULL, 16)), + (strtol(strgroupsrw[2], NULL, 16)), + (strtol(strgroupsrw[3], NULL, 16))}; + char strgroupsr[4][3] = {{ringcolor[0], ringcolor[1], '\0'}, + {ringcolor[2], ringcolor[3], '\0'}, + {ringcolor[4], ringcolor[5], '\0'}, + {ringcolor[6], ringcolor[7], '\0'}}; + uint32_t ring16[4] = {(strtol(strgroupsr[0], NULL, 16)), + (strtol(strgroupsr[1], NULL, 16)), + (strtol(strgroupsr[2], NULL, 16)), + (strtol(strgroupsr[3], NULL, 16))}; + char strgroupsl[4][3] = {{linecolor[0], linecolor[1], '\0'}, + {linecolor[2], linecolor[3], '\0'}, + {linecolor[4], linecolor[5], '\0'}, + {linecolor[6], linecolor[7], '\0'}}; + uint32_t line16[4] = {(strtol(strgroupsl[0], NULL, 16)), + (strtol(strgroupsl[1], NULL, 16)), + (strtol(strgroupsl[2], NULL, 16)), + (strtol(strgroupsl[3], NULL, 16))}; + char strgroupst[4][3] = {{textcolor[0], textcolor[1], '\0'}, + {textcolor[2], textcolor[3], '\0'}, + {textcolor[4], textcolor[5], '\0'}, + {textcolor[6], textcolor[7], '\0'}}; + uint32_t text16[4] = {(strtol(strgroupst[0], NULL, 16)), + (strtol(strgroupst[1], NULL, 16)), + (strtol(strgroupst[2], NULL, 16)), + (strtol(strgroupst[3], NULL, 16))}; + char strgroupsk[4][3] = {{keyhlcolor[0], textcolor[1], '\0'}, + {keyhlcolor[2], textcolor[3], '\0'}, + {keyhlcolor[4], textcolor[5], '\0'}, + {keyhlcolor[6], textcolor[7], '\0'}}; + uint32_t keyhl16[4] = {(strtol(strgroupsk[0], NULL, 16)), + (strtol(strgroupsk[1], NULL, 16)), + (strtol(strgroupsk[2], NULL, 16)), + (strtol(strgroupsk[3], NULL, 16))}; + char strgroupsb[4][3] = {{bshlcolor[0], textcolor[1], '\0'}, + {bshlcolor[2], textcolor[3], '\0'}, + {bshlcolor[4], textcolor[5], '\0'}, + {bshlcolor[6], textcolor[7], '\0'}}; + uint32_t bshl16[4] = {(strtol(strgroupsb[0], NULL, 16)), + (strtol(strgroupsb[1], NULL, 16)), + (strtol(strgroupsb[2], NULL, 16)), + (strtol(strgroupsb[3], NULL, 16))}; + if (unlock_indicator && (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE)) { cairo_scale(ctx, scaling_factor(), scaling_factor()); @@ -156,32 +249,32 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: - cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75); + cairo_set_source_rgba(ctx, (double)insidever16[0]/255, (double)insidever16[1]/255, (double)insidever16[2]/255, (double)insidever16[3]/255); break; case STATE_PAM_WRONG: - cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75); + cairo_set_source_rgba(ctx, (double)insidewrong16[0]/255, (double)insidewrong16[1]/255, (double)insidewrong16[2]/255, (double)insidewrong16[3]/255); break; default: - cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); + cairo_set_source_rgba(ctx, (double)inside16[0]/255, (double)inside16[1]/255, (double)inside16[2]/255, (double)inside16[3]/255); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: - cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255); + cairo_set_source_rgba(ctx, (double)ringver16[0]/255, (double)ringver16[1]/255, (double)ringver16[2]/255, (double)ringver16[3]/255); break; case STATE_PAM_WRONG: - cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0); + cairo_set_source_rgba(ctx, (double)ringwrong16[0]/255, (double)ringwrong16[1]/255, (double)ringwrong16[2]/255, (double)ringwrong16[3]/255); break; case STATE_PAM_IDLE: - cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); + cairo_set_source_rgba(ctx, (double)ring16[0]/255, (double)ring16[1]/255, (double)ring16[2]/255, (double)ring16[3]/255); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ - cairo_set_source_rgb(ctx, 0, 0, 0); + cairo_set_source_rgba(ctx, (double)line16[0]/255, (double)line16[1]/255, (double)line16[2]/255, (double)line16[3]/255); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, @@ -198,7 +291,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { /* We don't want to show more than a 3-digit number. */ char buf[4]; - cairo_set_source_rgb(ctx, 0, 0, 0); + cairo_set_source_rgba(ctx, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); //this was moved up to here cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: @@ -263,17 +356,17 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { highlight_start, highlight_start + (M_PI / 3.0)); if (unlock_state == STATE_KEY_ACTIVE) { - /* For normal keys, we use a lighter green. */ - cairo_set_source_rgb(ctx, 51.0 / 255, 219.0 / 255, 0); + /* For normal keys, we use a lighter green. */ //lol no + cairo_set_source_rgba(ctx, (double)keyhl16[0]/255, (double)keyhl16[1]/255, (double)keyhl16[2]/255, (double)keyhl16[3]/255); } else { - /* For backspace, we use red. */ - cairo_set_source_rgb(ctx, 219.0 / 255, 51.0 / 255, 0); + /* For backspace, we use red. */ //lol no + cairo_set_source_rgba(ctx, (double)bshl16[0]/255, (double)bshl16[1]/255, (double)bshl16[2]/255, (double)bshl16[3]/255); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ - cairo_set_source_rgb(ctx, 0, 0, 0); + cairo_set_source_rgba(ctx, (double)line16[0]/255, (double)line16[1]/255, (double)line16[2]/255, (double)line16[3]/255); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */,