Use 32bit-deep drawables to allow setting a color with alpha channel as background
This commit is contained in:
parent
d9fcd23c19
commit
0da5cdb447
6
i3lock.1
6
i3lock.1
|
@ -108,9 +108,9 @@ You can also use it to resize images to the screen ratio:
|
||||||
Note that $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/') gets you the current screen dimensions in the wxh (e.g. 1920x1080) format.
|
Note that $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/') gets you the current screen dimensions in the wxh (e.g. 1920x1080) format.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI \-c\ rrggbb \fR,\ \fB\-\-color= rrggbb
|
.BI \-c\ rrggbbaa \fR,\ \fB\-\-color= rrggbbaa
|
||||||
Turn the screen into the given color instead of white. Color must be given in 3-byte
|
Turn the screen into the given color instead of white. Color must be given in 4-byte
|
||||||
format: rrggbb (i.e. ff0000 is red).
|
format: rrggbbaa (i.e. ff0000ff is opaque red).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-t, \-\-tiling
|
.B \-t, \-\-tiling
|
||||||
|
|
41
i3lock.c
41
i3lock.c
|
@ -70,7 +70,7 @@
|
||||||
typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents);
|
typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents);
|
||||||
static void input_done(void);
|
static void input_done(void);
|
||||||
|
|
||||||
char color[7] = "ffffff";
|
char color[9] = "ffffffff";
|
||||||
|
|
||||||
/* options for unlock indicator colors */
|
/* options for unlock indicator colors */
|
||||||
char insidevercolor[9] = "006effbf";
|
char insidevercolor[9] = "006effbf";
|
||||||
|
@ -1497,6 +1497,13 @@ int main(int argc, char *argv[]) {
|
||||||
char *optstring = "hvnbdc:p:ui:teI:frsS:kB:m";
|
char *optstring = "hvnbdc:p:ui:teI:frsS:kB:m";
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
|
|
||||||
|
#define parse_color(acolor)\
|
||||||
|
arg = optarg;\
|
||||||
|
if (arg[0] == '#') arg++;\
|
||||||
|
if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", acolor) != 1)\
|
||||||
|
errx(1, #acolor " is invalid, color must be given in 4-byte format: rrggbbaa\n");
|
||||||
|
|
||||||
while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) {
|
while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) {
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case 'v':
|
case 'v':
|
||||||
|
@ -1514,18 +1521,6 @@ int main(int argc, char *argv[]) {
|
||||||
fprintf(stderr, "Inactivity timeout only makes sense with DPMS, which was removed. Please see the manpage i3lock(1).\n");
|
fprintf(stderr, "Inactivity timeout only makes sense with DPMS, which was removed. Please see the manpage i3lock(1).\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'c': {
|
|
||||||
arg = optarg;
|
|
||||||
|
|
||||||
/* Skip # if present */
|
|
||||||
if (arg[0] == '#')
|
|
||||||
arg++;
|
|
||||||
|
|
||||||
if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) != 1)
|
|
||||||
errx(EXIT_FAILURE, "color is invalid, it must be given in 3-byte hexadecimal format: rrggbb");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'u':
|
case 'u':
|
||||||
unlock_indicator = false;
|
unlock_indicator = false;
|
||||||
break;
|
break;
|
||||||
|
@ -1575,11 +1570,9 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Begin colors
|
// Begin colors
|
||||||
#define parse_color(color)\
|
case 'c':
|
||||||
arg = optarg;\
|
parse_color(color);
|
||||||
if (arg[0] == '#') arg++;\
|
break;
|
||||||
if (strlen(arg) != 8 || sscanf(arg, "%08[0-9a-fA-F]", color) != 1)\
|
|
||||||
errx(1, #color " is invalid, color must be given in 4-byte format: rrggbbaa\n");
|
|
||||||
case 300:
|
case 300:
|
||||||
parse_color(insidevercolor);
|
parse_color(insidevercolor);
|
||||||
break;
|
break;
|
||||||
|
@ -2206,14 +2199,16 @@ int main(int argc, char *argv[]) {
|
||||||
cairo_surface_destroy(xcb_img);
|
cairo_surface_destroy(xcb_img);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pixmap on which the image is rendered to (if any) */
|
|
||||||
xcb_pixmap_t bg_pixmap = draw_image(last_resolution);
|
|
||||||
|
|
||||||
xcb_window_t stolen_focus = find_focused_window(conn, screen->root);
|
xcb_window_t stolen_focus = find_focused_window(conn, screen->root);
|
||||||
|
|
||||||
/* Open the fullscreen window, already with the correct pixmap in place */
|
/* Open the fullscreen window, already with the correct pixmap in place */
|
||||||
win = open_fullscreen_window(conn, screen, color, bg_pixmap);
|
win = open_fullscreen_window(conn, screen, color);
|
||||||
xcb_free_pixmap(conn, bg_pixmap);
|
|
||||||
|
xcb_pixmap_t pixmap = create_bg_pixmap(conn, win, last_resolution, color);
|
||||||
|
draw_image(last_resolution, pixmap);
|
||||||
|
xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[]){pixmap});
|
||||||
|
|
||||||
|
xcb_free_pixmap(conn, pixmap);
|
||||||
if (blur_pixmap) {
|
if (blur_pixmap) {
|
||||||
xcb_free_pixmap(conn, *blur_pixmap);
|
xcb_free_pixmap(conn, *blur_pixmap);
|
||||||
free(blur_pixmap);
|
free(blur_pixmap);
|
||||||
|
|
|
@ -71,7 +71,7 @@ unsigned long lastCheck;
|
||||||
/* Whether the image should be tiled. */
|
/* Whether the image should be tiled. */
|
||||||
extern bool tile;
|
extern bool tile;
|
||||||
/* The background color to use (in hex). */
|
/* The background color to use (in hex). */
|
||||||
extern char color[7];
|
extern char color[9];
|
||||||
/* indicator color options */
|
/* indicator color options */
|
||||||
extern char insidevercolor[9];
|
extern char insidevercolor[9];
|
||||||
extern char insidewrongcolor[9];
|
extern char insidewrongcolor[9];
|
||||||
|
@ -675,7 +675,7 @@ static void draw_elements(cairo_t *const ctx, DrawData const *const draw_data) {
|
||||||
* resolution and returns it.
|
* resolution and returns it.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
xcb_pixmap_t draw_image(uint32_t *resolution) {
|
void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
||||||
const double scaling_factor = get_dpi_value() / 96.0;
|
const double scaling_factor = get_dpi_value() / 96.0;
|
||||||
xcb_pixmap_t bg_pixmap = XCB_NONE;
|
xcb_pixmap_t bg_pixmap = XCB_NONE;
|
||||||
int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER);
|
int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER);
|
||||||
|
@ -683,7 +683,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
|
||||||
scaling_factor, button_diameter_physical);
|
scaling_factor, button_diameter_physical);
|
||||||
|
|
||||||
if (!vistype)
|
if (!vistype)
|
||||||
vistype = get_root_visual_type(screen);
|
vistype = get_visualtype_by_depth(32, screen);
|
||||||
bg_pixmap = create_bg_pixmap(conn, screen, resolution, color);
|
bg_pixmap = create_bg_pixmap(conn, screen, resolution, color);
|
||||||
/* Initialize cairo: Create one in-memory surface to render the unlock
|
/* Initialize cairo: Create one in-memory surface to render the unlock
|
||||||
* indicator on, create one XCB surface to actually draw (one or more,
|
* indicator on, create one XCB surface to actually draw (one or more,
|
||||||
|
@ -696,7 +696,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
|
||||||
|
|
||||||
// cairo_set_font_face(ctx, get_font_face(0));
|
// cairo_set_font_face(ctx, get_font_face(0));
|
||||||
|
|
||||||
cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]);
|
cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, drawable, vistype, resolution[0], resolution[1]);
|
||||||
cairo_t *xcb_ctx = cairo_create(xcb_output);
|
cairo_t *xcb_ctx = cairo_create(xcb_output);
|
||||||
|
|
||||||
/*update image according to the slideshow_interval*/
|
/*update image according to the slideshow_interval*/
|
||||||
|
@ -1073,12 +1073,11 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
|
||||||
*/
|
*/
|
||||||
void redraw_screen(void) {
|
void redraw_screen(void) {
|
||||||
DEBUG("redraw_screen(unlock_state = %d, auth_state = %d) @ [%lu]\n", unlock_state, auth_state, (unsigned long)time(NULL));
|
DEBUG("redraw_screen(unlock_state = %d, auth_state = %d) @ [%lu]\n", unlock_state, auth_state, (unsigned long)time(NULL));
|
||||||
xcb_pixmap_t bg_pixmap = draw_image(last_resolution);
|
xcb_pixmap_t pixmap = create_bg_pixmap(conn, win, last_resolution, color);
|
||||||
xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap});
|
draw_image(last_resolution, pixmap);
|
||||||
/* XXX: Possible optimization: Only update the area in the middle of the
|
xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){pixmap});
|
||||||
* screen instead of the whole screen. */
|
|
||||||
xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]);
|
xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]);
|
||||||
xcb_free_pixmap(conn, bg_pixmap);
|
xcb_free_pixmap(conn, pixmap);
|
||||||
xcb_flush(conn);
|
xcb_flush(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ typedef struct {
|
||||||
double bar_offset;
|
double bar_offset;
|
||||||
} DrawData;
|
} DrawData;
|
||||||
|
|
||||||
xcb_pixmap_t draw_image(uint32_t* resolution);
|
void draw_image(uint32_t* resolution, xcb_drawable_t drawable);
|
||||||
void init_colors_once(void);
|
void init_colors_once(void);
|
||||||
void redraw_screen(void);
|
void redraw_screen(void);
|
||||||
void clear_indicator(void);
|
void clear_indicator(void);
|
||||||
|
|
68
xcb.c
68
xcb.c
|
@ -82,16 +82,37 @@ static unsigned char mask_windows_bits[] = {
|
||||||
0x80, 0x01};
|
0x80, 0x01};
|
||||||
|
|
||||||
static uint32_t get_colorpixel(char *hex) {
|
static uint32_t get_colorpixel(char *hex) {
|
||||||
char strgroups[3][3] = {{hex[0], hex[1], '\0'},
|
char strgroups[4][3] = {{hex[0], hex[1], '\0'},
|
||||||
{hex[2], hex[3], '\0'},
|
{hex[2], hex[3], '\0'},
|
||||||
{hex[4], hex[5], '\0'}};
|
{hex[4], hex[5], '\0'},
|
||||||
uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)),
|
{hex[6], hex[4], '\0'}};
|
||||||
|
uint32_t rgb16[4] = {(strtol(strgroups[0], NULL, 16)),
|
||||||
(strtol(strgroups[1], NULL, 16)),
|
(strtol(strgroups[1], NULL, 16)),
|
||||||
(strtol(strgroups[2], NULL, 16))};
|
(strtol(strgroups[2], NULL, 16)),
|
||||||
|
(strtol(strgroups[3], NULL, 16))};
|
||||||
|
|
||||||
return (rgb16[0] << 16) + (rgb16[1] << 8) + rgb16[2];
|
return (rgb16[3] << 24) + (rgb16[0] << 16) + (rgb16[1] << 8) + rgb16[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xcb_visualtype_t *get_visualtype_by_depth(uint16_t depth, xcb_screen_t *root_screen) {
|
||||||
|
xcb_depth_iterator_t depth_iter;
|
||||||
|
|
||||||
|
depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
|
||||||
|
for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
|
||||||
|
if (depth_iter.data->depth != depth)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
xcb_visualtype_iterator_t visual_iter;
|
||||||
|
|
||||||
|
visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
|
||||||
|
if (!visual_iter.rem)
|
||||||
|
continue;
|
||||||
|
return visual_iter.data;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
xcb_visualtype_t *get_root_visual_type(xcb_screen_t *screen) {
|
xcb_visualtype_t *get_root_visual_type(xcb_screen_t *screen) {
|
||||||
xcb_visualtype_t *visual_type = NULL;
|
xcb_visualtype_t *visual_type = NULL;
|
||||||
xcb_depth_iterator_t depth_iter;
|
xcb_depth_iterator_t depth_iter;
|
||||||
|
@ -114,10 +135,9 @@ xcb_visualtype_t *get_root_visual_type(xcb_screen_t *screen) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t *resolution, char *color) {
|
xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_drawable_t win, u_int32_t *resolution, char *color) {
|
||||||
xcb_pixmap_t bg_pixmap = xcb_generate_id(conn);
|
xcb_pixmap_t bg_pixmap = xcb_generate_id(conn);
|
||||||
xcb_create_pixmap(conn, scr->root_depth, bg_pixmap, scr->root,
|
xcb_create_pixmap(conn, 32, bg_pixmap, win, resolution[0], resolution[1]);
|
||||||
resolution[0], resolution[1]);
|
|
||||||
|
|
||||||
/* Generate a Graphics Context and fill the pixmap with background color
|
/* Generate a Graphics Context and fill the pixmap with background color
|
||||||
* (for images that are smaller than your screen) */
|
* (for images that are smaller than your screen) */
|
||||||
|
@ -131,9 +151,9 @@ xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32
|
||||||
return bg_pixmap;
|
return bg_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap) {
|
xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color) {
|
||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t values[3];
|
uint32_t values[5];
|
||||||
xcb_window_t win = xcb_generate_id(conn);
|
xcb_window_t win = xcb_generate_id(conn);
|
||||||
xcb_window_t parent_win = scr->root;
|
xcb_window_t parent_win = scr->root;
|
||||||
|
|
||||||
|
@ -161,26 +181,32 @@ xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmap == XCB_NONE) {
|
|
||||||
mask |= XCB_CW_BACK_PIXEL;
|
xcb_visualid_t visual = get_visualtype_by_depth(32, scr)->visual_id;
|
||||||
values[0] = get_colorpixel(color);
|
xcb_colormap_t win_colormap = xcb_generate_id(conn);
|
||||||
} else {
|
xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, win_colormap, scr->root, visual);
|
||||||
mask |= XCB_CW_BACK_PIXMAP;
|
|
||||||
values[0] = pixmap;
|
mask |= XCB_CW_BACK_PIXEL;
|
||||||
}
|
values[0] = get_colorpixel(color);
|
||||||
|
|
||||||
|
mask |= XCB_CW_BORDER_PIXEL;
|
||||||
|
values[1] = 0x00000000;
|
||||||
|
|
||||||
mask |= XCB_CW_OVERRIDE_REDIRECT;
|
mask |= XCB_CW_OVERRIDE_REDIRECT;
|
||||||
values[1] = 1;
|
values[2] = 1;
|
||||||
|
|
||||||
mask |= XCB_CW_EVENT_MASK;
|
mask |= XCB_CW_EVENT_MASK;
|
||||||
values[2] = XCB_EVENT_MASK_EXPOSURE |
|
values[3] = XCB_EVENT_MASK_EXPOSURE |
|
||||||
XCB_EVENT_MASK_KEY_PRESS |
|
XCB_EVENT_MASK_KEY_PRESS |
|
||||||
XCB_EVENT_MASK_KEY_RELEASE |
|
XCB_EVENT_MASK_KEY_RELEASE |
|
||||||
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
|
|
||||||
|
mask |= XCB_CW_COLORMAP;
|
||||||
|
values[4] = win_colormap;
|
||||||
|
|
||||||
xcb_create_window(conn,
|
xcb_create_window(conn,
|
||||||
XCB_COPY_FROM_PARENT,
|
32,
|
||||||
win, /* the window id */
|
win, /* the window id */
|
||||||
parent_win,
|
parent_win,
|
||||||
0, 0,
|
0, 0,
|
||||||
|
@ -188,7 +214,7 @@ xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, c
|
||||||
scr->height_in_pixels, /* dimensions */
|
scr->height_in_pixels, /* dimensions */
|
||||||
0, /* border = 0, we draw our own */
|
0, /* border = 0, we draw our own */
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
|
visual, /* copy visual from parent */
|
||||||
mask,
|
mask,
|
||||||
values);
|
values);
|
||||||
|
|
||||||
|
|
5
xcb.h
5
xcb.h
|
@ -24,8 +24,9 @@ extern xcb_connection_t *conn;
|
||||||
extern xcb_screen_t *screen;
|
extern xcb_screen_t *screen;
|
||||||
|
|
||||||
xcb_visualtype_t *get_root_visual_type(xcb_screen_t *s);
|
xcb_visualtype_t *get_root_visual_type(xcb_screen_t *s);
|
||||||
xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t *resolution, char *color);
|
xcb_visualtype_t* get_visualtype_by_depth(uint16_t depth, xcb_screen_t* root_screen);
|
||||||
xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap);
|
xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_drawable_t drawable, u_int32_t *resolution, char *color);
|
||||||
|
xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color);
|
||||||
bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor, int tries);
|
bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor, int tries);
|
||||||
xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice);
|
xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice);
|
||||||
xcb_window_t find_focused_window(xcb_connection_t *conn, const xcb_window_t root);
|
xcb_window_t find_focused_window(xcb_connection_t *conn, const xcb_window_t root);
|
||||||
|
|
Loading…
Reference in New Issue