├── config.mk ├── man ├── Makefile └── chwbb.1 ├── util.h ├── Makefile ├── LICENSE ├── README.md ├── arg.h ├── util.c ├── chbr.c ├── chwbb.c ├── chbpresel.c └── chwbn.c /config.mk: -------------------------------------------------------------------------------- 1 | PREFIX = /usr 2 | MANPREFIX = $(PREFIX)/share/man 3 | 4 | CC = cc 5 | LD = $(CC) 6 | 7 | CFLAGS += -std=c99 -pedantic -Wall -Os 8 | LDFLAGS += -lxcb -lxcb-util 9 | -------------------------------------------------------------------------------- /man/Makefile: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | MAN = \ 4 | chwbb.1 5 | 6 | .POSIX: 7 | 8 | install: $(MAN) 9 | mkdir -p $(DESTDIR)$(MANPREFIX)/man1/ 10 | cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1/ 11 | 12 | uninstall: 13 | @echo "uninstalling manpages" 14 | @for page in $(MAN); do \ 15 | rm -f $(DESTDIR)$(MANPREFIX)/man1/$$page; \ 16 | done 17 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H__ 2 | #define UTIL_H__ 3 | 4 | void init_xcb(xcb_connection_t **); 5 | void kill_xcb(xcb_connection_t **); 6 | 7 | void get_screen(xcb_connection_t *, xcb_screen_t **); 8 | int get_windows(xcb_connection_t *, xcb_window_t, xcb_window_t **); 9 | 10 | int exists(xcb_connection_t *, xcb_window_t); 11 | int mapped(xcb_connection_t *, xcb_window_t); 12 | int ignore(xcb_connection_t *, xcb_window_t); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include config.mk 2 | 3 | HDR = arg.h util.h 4 | SRC = \ 5 | chwbb.c \ 6 | chwbn.c \ 7 | chbr.c \ 8 | chbpresel.c 9 | 10 | OBJ = $(SRC:.c=.o) 11 | BIN = $(SRC:.c=) 12 | 13 | .POSIX: 14 | 15 | all: binutils 16 | 17 | binutils: $(BIN) 18 | 19 | manpages: 20 | cd man; $(MAKE) $(MFLAGS) 21 | 22 | $(OBJ): $(HDR) util.o 23 | 24 | .o: 25 | @echo "LD $@" 26 | @$(LD) $< -o $@ $(LDFLAGS) util.o 27 | 28 | .c.o: 29 | @echo "CC $<" 30 | @$(CC) -c $< -o $@ $(CFLAGS) 31 | 32 | install: $(BIN) 33 | mkdir -p $(DESTDIR)$(PREFIX)/bin/ 34 | cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin/ 35 | cd man; $(MAKE) $(MFLAGS) install 36 | 37 | uninstall: 38 | @echo "uninstalling binaries" 39 | @for util in $(BIN); do \ 40 | rm -f $(DESTDIR)$(PREFIX)/bin/$$util; \ 41 | done 42 | cd man; $(MAKE) $(MFLAGS) uninstall 43 | 44 | clean: 45 | rm -f $(OBJ) $(BIN) util.o 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2014-2016 brosephs , 4 | 5 | 2017 6 | 7 | Permission to use, copy, modify, and distribute this software for any 8 | purpose with or without fee is hereby granted, provided that the above 9 | copyright notice and this permission notice appear in all copies. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 12 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 13 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 14 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 16 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 | PERFORMANCE OF THIS SOFTWARE. 18 | -------------------------------------------------------------------------------- /man/chwbb.1: -------------------------------------------------------------------------------- 1 | .Dd February 3, 2017 2 | .Dt CHWBB 1 3 | .Os wmutils 4 | .Sh NAME 5 | .Nm chwbb 6 | .Nd change window bevel borders 7 | .Sh SYNOPSIS 8 | .Nm chwbb 9 | .Op Fl c Ar base color 10 | .Op Fl i Ar inner border size 11 | .Op Fl o Ar outer border size 12 | .Op Fl m Ar middle border size 13 | .Ar wid Op Ar ... 14 | .Sh DESCRIPTION 15 | .Nm 16 | applies a bevel pixmap border to 17 | .Ar wid . 18 | .Bl -tag -width Ds 19 | .It Fl c Ar base color 20 | Set the base color that will be multiplied for 21 | .Ar wid 22 | . 23 | Colors should be passed as a hex triplet without the '#' prefix (see 24 | .Xr strtoul 3 ) 25 | in RGB format. 26 | .It Fl i Ar size 27 | .It Fl o Ar size 28 | .It Fl m Ar size 29 | Sets the inner/outer/middle border width of 30 | .Ar wid 31 | to 32 | .Ar size . 33 | .El 34 | .Sh ENVIRONMENT 35 | .Nm 36 | acts on the X display specified by the 37 | .Ev DISPLAY 38 | variable. 39 | .Sh EXAMPLES 40 | Set a bevel border based on 777777 with total width of 8 on the current window: 41 | .Dl $ chwbb -c 777777 -I ffff00 -i 2 -m 4 -o 2 $(pfw) 42 | .Sh SEE ALSO 43 | .Xr strtoul 3 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | neeasade's border opt 2 | ============= 3 | 4 | wmutils-like border programs. 5 | 6 | utilities 7 | --------- 8 | 9 | * chwbb - make 'bevel' style borders 10 | * chwbr - make rounded borders on windows that already have 32-bit color depth 11 | * chbpresel - make preselection indications 12 | * chwbn - give infinite borders to programs 13 | 14 | For more information, refer to the programs manpages. 15 | 16 | reference 17 | --------- 18 | 19 | ``` 20 | +=================+====+----+ 21 | # Client area, | ri # le | 22 | # invisible | gh # ft | 23 | # | t # | 24 | +-----------------+----+----+ 25 | # bottom border | br # bl | 26 | +=================+====+----+ 27 | | top border | tr | tl | 28 | +-----------------+----+----+ 29 | ``` 30 | 31 | license 32 | ------- 33 | 34 | This project and all its code is licensed under the [ISC](http://www.openbsd.org/policy.html) 35 | license. See the LICENSE file. 36 | 37 | build & install 38 | --------------- 39 | 40 | $ make 41 | # make install 42 | 43 | In the file config.mk you can override build options, 44 | such as the compiler flags or the installation path. 45 | -------------------------------------------------------------------------------- /arg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copy me if you can. 3 | * by 20h 4 | */ 5 | 6 | #ifndef ARG_H__ 7 | #define ARG_H__ 8 | 9 | extern char *argv0; 10 | 11 | /* use main(int argc, char *argv[]) */ 12 | #define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ 13 | argv[0] && argv[0][1]\ 14 | && argv[0][0] == '-';\ 15 | argc--, argv++) {\ 16 | char argc_;\ 17 | char **argv_;\ 18 | int brk_;\ 19 | if (argv[0][1] == '-' && argv[0][2] == '\0') {\ 20 | argv++;\ 21 | argc--;\ 22 | break;\ 23 | }\ 24 | for (brk_ = 0, argv[0]++, argv_ = argv;\ 25 | argv[0][0] && !brk_;\ 26 | argv[0]++) {\ 27 | if (argv_ != argv)\ 28 | break;\ 29 | argc_ = argv[0][0];\ 30 | switch (argc_) 31 | 32 | /* Handles obsolete -NUM syntax */ 33 | #define ARGNUM case '0':\ 34 | case '1':\ 35 | case '2':\ 36 | case '3':\ 37 | case '4':\ 38 | case '5':\ 39 | case '6':\ 40 | case '7':\ 41 | case '8':\ 42 | case '9' 43 | 44 | #define ARGEND }\ 45 | } 46 | 47 | #define ARGC() argc_ 48 | 49 | #define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) 50 | 51 | #define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ 52 | ((x), abort(), (char *)0) :\ 53 | (brk_ = 1, (argv[0][1] != '\0')?\ 54 | (&argv[0][1]) :\ 55 | (argc--, argv++, argv[0]))) 56 | 57 | #define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ 58 | (char *)0 :\ 59 | (brk_ = 1, (argv[0][1] != '\0')?\ 60 | (&argv[0][1]) :\ 61 | (argc--, argv++, argv[0]))) 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "util.h" 6 | 7 | void 8 | init_xcb(xcb_connection_t **con) 9 | { 10 | *con = xcb_connect(NULL, NULL); 11 | if (xcb_connection_has_error(*con)) 12 | errx(1, "unable connect to the X server"); 13 | } 14 | 15 | void 16 | kill_xcb(xcb_connection_t **con) 17 | { 18 | if (*con) 19 | xcb_disconnect(*con); 20 | } 21 | 22 | void 23 | get_screen(xcb_connection_t *con, xcb_screen_t **scr) 24 | { 25 | *scr = xcb_setup_roots_iterator(xcb_get_setup(con)).data; 26 | if (*scr == NULL) 27 | errx(1, "unable to retrieve screen informations"); 28 | } 29 | 30 | int 31 | exists(xcb_connection_t *con, xcb_window_t w) 32 | { 33 | xcb_get_window_attributes_cookie_t c; 34 | xcb_get_window_attributes_reply_t *r; 35 | 36 | c = xcb_get_window_attributes(con, w); 37 | r = xcb_get_window_attributes_reply(con, c, NULL); 38 | 39 | if (r == NULL) 40 | return 0; 41 | 42 | return 1; 43 | } 44 | 45 | int 46 | mapped(xcb_connection_t *con, xcb_window_t w) 47 | { 48 | int ms; 49 | xcb_get_window_attributes_cookie_t c; 50 | xcb_get_window_attributes_reply_t *r; 51 | 52 | c = xcb_get_window_attributes(con, w); 53 | r = xcb_get_window_attributes_reply(con, c, NULL); 54 | 55 | if (r == NULL) 56 | return 0; 57 | 58 | ms = r->map_state; 59 | 60 | free(r); 61 | return ms == XCB_MAP_STATE_VIEWABLE; 62 | } 63 | 64 | int 65 | ignore(xcb_connection_t *con, xcb_window_t w) 66 | { 67 | int or; 68 | xcb_get_window_attributes_cookie_t c; 69 | xcb_get_window_attributes_reply_t *r; 70 | 71 | c = xcb_get_window_attributes(con, w); 72 | r = xcb_get_window_attributes_reply(con, c, NULL); 73 | 74 | if (r == NULL) 75 | return 0; 76 | 77 | or = r->override_redirect; 78 | 79 | free(r); 80 | return or; 81 | } 82 | 83 | int 84 | get_windows(xcb_connection_t *con, xcb_window_t w, xcb_window_t **l) 85 | { 86 | int childnum = 0; 87 | xcb_query_tree_cookie_t c; 88 | xcb_query_tree_reply_t *r; 89 | 90 | c = xcb_query_tree(con, w); 91 | r = xcb_query_tree_reply(con, c, NULL); 92 | if (r == NULL) 93 | errx(1, "0x%08x: no such window", w); 94 | 95 | *l = xcb_query_tree_children(r); 96 | 97 | childnum = r->children_len; 98 | free(r); 99 | 100 | return childnum; 101 | } 102 | -------------------------------------------------------------------------------- /chbr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017, neeasade 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include "arg.h" 27 | #include "util.h" 28 | 29 | char *argv0; 30 | static xcb_connection_t *conn; 31 | static xcb_screen_t *scr; 32 | 33 | static void usage (char *name); 34 | static void set2border (xcb_window_t, int, int); 35 | 36 | static void 37 | usage (char *name) 38 | { 39 | fprintf(stderr, "usage: %s -c -s [wid...]\n", name); 40 | exit(1); 41 | } 42 | 43 | static void 44 | set2border (win, color, size) 45 | xcb_window_t win; 46 | int color; 47 | int size; 48 | { 49 | uint32_t values[1]; 50 | short w, h, b; 51 | 52 | xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, 53 | xcb_get_geometry(conn, win), NULL); 54 | 55 | if (geom == NULL) 56 | return; 57 | 58 | //if (size > geom->border_width) 59 | //warnx("warning: pixmap is greater than border size"); 60 | 61 | w = (short)geom->width; 62 | h = (short)geom->height; 63 | b = (unsigned short)size; 64 | 65 | xcb_rectangle_t regular[] = { 66 | {w, 0, b*2, h}, 67 | {0, h, w, b*2}, 68 | }; 69 | 70 | xcb_rectangle_t transparent[] = { 71 | {w, h, b*2, b*2}, 72 | }; 73 | 74 | xcb_arc_t arcs[] = { 75 | { w-b-1, h-b-1, b*2, b*2, 270<<6, 90 << 6 }, 76 | { w+b, h+b, b*2, b*2, 90 << 6, 360 << 6 }, 77 | { w+b, h-b-1, b*2, b*2, 180 << 6, 90 << 6 }, 78 | { w-b-1, h+b, b*2, b*2, 0, 90 << 6 }, 79 | }; 80 | 81 | xcb_pixmap_t pmap = xcb_generate_id(conn); 82 | 83 | // the issue.. 84 | 85 | //printf("%i", scr->root_depth); 86 | /* 87 | xcb_create_pixmap(conn, scr->root_depth, pmap, win, 88 | geom->width + (b*2), 89 | geom->height + (b*2)); 90 | */ 91 | 92 | xcb_create_pixmap(conn, 32, pmap, win, 93 | geom->width + (b*2), 94 | geom->height + (b*2)); 95 | 96 | 97 | xcb_gcontext_t gc = xcb_generate_id(conn); 98 | xcb_create_gc(conn, gc, pmap, 0, NULL); 99 | 100 | values[0] = color; 101 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 102 | xcb_poly_fill_rectangle(conn, pmap, gc, 2, regular); 103 | 104 | // todo here: transparent color 105 | 106 | // transparent 107 | values[0] = 0x00000000U; 108 | //values[0] = 0x000000U; 109 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 110 | xcb_poly_fill_rectangle(conn, pmap, gc, 1, transparent); 111 | 112 | xcb_aux_sync(conn); 113 | 114 | values[0] = color; 115 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 116 | xcb_poly_fill_arc(conn, pmap, gc, 4, arcs); 117 | 118 | xcb_aux_sync(conn); 119 | 120 | values[0] = pmap; 121 | 122 | xcb_change_window_attributes(conn, win, XCB_CW_BORDER_PIXMAP, values); 123 | 124 | xcb_free_pixmap(conn, pmap); 125 | xcb_free_gc(conn, gc); 126 | } 127 | 128 | int 129 | main (int argc, char **argv) 130 | { 131 | int color, size; 132 | 133 | if (argc < 2) 134 | usage(argv[0]); 135 | 136 | color = size = -1; 137 | ARGBEGIN { 138 | case 'c': 139 | color = strtoul(EARGF(usage(argv0)), NULL, 16); 140 | break; 141 | case 's': 142 | size = strtoul(EARGF(usage(argv0)), NULL, 16); 143 | break; 144 | case 'h': 145 | usage(argv0); 146 | /* NOTREACHED */ 147 | } ARGEND 148 | 149 | init_xcb(&conn); 150 | get_screen(conn, &scr); 151 | 152 | /* assume remaining arguments are windows */ 153 | while (*argv) 154 | set2border(strtoul(*argv++, NULL, 16), color, size); 155 | 156 | xcb_aux_sync(conn); 157 | 158 | kill_xcb(&conn); 159 | 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /chwbb.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "arg.h" 10 | #include "util.h" 11 | 12 | #define MAX(A, B) ((A) > (B) ? (A) : (B)) 13 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 14 | 15 | static xcb_connection_t *conn; 16 | 17 | static void usage(char *name); 18 | static void set_border(long, xcb_window_t); 19 | static unsigned long multiplycolor(unsigned long col, double fact); 20 | 21 | static const double bevelfacts[] = { 1.25, 1.0, 0.5 }; /* multiply outer/middle/inner bordercolor with x */ 22 | static unsigned int borders[] = { 2, 4, 2 }; /* outer, middle, inner border */ 23 | static long colbase, colaccent, colflat; 24 | 25 | static xcb_screen_t *scr; 26 | 27 | unsigned long 28 | multiplycolor(unsigned long col, double fact) { 29 | int r = (int)(((0xFF0000 & col) >> 16) * fact); 30 | int g = (int)(((0x00FF00 & col) >> 8) * fact); 31 | int b = (int)(((0x0000FF & col) >> 0) * fact); 32 | r = r > 255 ? 255 : r; 33 | g = g > 255 ? 255 : g; 34 | b = b > 255 ? 255 : b; 35 | return (0xFF000000 & col) | (r << 16) | (g << 8) | (b << 0); 36 | } 37 | 38 | static void 39 | usage(char *name) 40 | { 41 | fprintf(stderr, "usage: %s <-sc ...> [wid...]\n", name); 42 | exit(1); 43 | } 44 | 45 | static void 46 | set_border(long color, xcb_window_t win) 47 | { 48 | uint32_t values[1]; 49 | short w, h, b, x, y, z; 50 | 51 | xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, 52 | xcb_get_geometry(conn, win), NULL); 53 | 54 | if (geom == NULL) 55 | return; 56 | 57 | 58 | w = (short)geom->width; 59 | h = (short)geom->height; 60 | x = (short)borders[2]; 61 | y = (short)borders[1]; 62 | z = (short)borders[0]; 63 | b = (unsigned short)x+y+z; 64 | 65 | xcb_rectangle_t base[] = { 66 | {0, h+x,w+x+y,y}, 67 | {w+x, 0, y,h+x}, 68 | {0,h+b+z,w+x+y,y}, 69 | {w+x,h+b+z+y,y,x}, 70 | {w+b+z,0,y,h+x+y}, 71 | {w+b+z+y,h+x,x,y}, 72 | {w+b+z, h+b+z,y+x,y}, 73 | {w+b+z,h+b+z+y,y,x}, 74 | }; 75 | 76 | xcb_rectangle_t accent[] = { 77 | {w,0,x,h}, 78 | {0,h,w+x,x}, 79 | {0,h+b,w+2*b,z}, 80 | {w+b,0,z,h+2*b}, 81 | }; 82 | 83 | xcb_rectangle_t flat[] = { 84 | {0,h+x+y,w+b,z}, 85 | {w+x+y,0,z,h+y+x}, 86 | {0,(h+2*b)-x,w+x,x}, 87 | {w+x+y,h+b+z,z,x+y}, 88 | {w+b+z+y,0,x,h+x}, 89 | {w+b+z,h+x+y,y+x,z}, 90 | {(w+2*b)-x,(h+2*b)-x,x,x}, 91 | }; 92 | 93 | xcb_pixmap_t pmap = xcb_generate_id(conn); 94 | xcb_create_pixmap(conn, scr->root_depth, pmap, win, 95 | geom->width + (b*2), 96 | geom->height + (b*2)); 97 | 98 | xcb_gcontext_t gc = xcb_generate_id(conn); 99 | xcb_create_gc(conn, gc, pmap, 0, NULL); 100 | 101 | values[0] = colbase; 102 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 103 | xcb_poly_fill_rectangle(conn, pmap, gc, 8, base); 104 | 105 | values[0] = colaccent; 106 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 107 | xcb_poly_fill_rectangle(conn, pmap, gc, 4, accent); 108 | 109 | values[0] = colflat; 110 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 111 | xcb_poly_fill_rectangle(conn, pmap, gc, 7, flat); 112 | 113 | values[0] = pmap; 114 | xcb_change_window_attributes(conn, win, XCB_CW_BORDER_PIXMAP, values); 115 | 116 | xcb_free_pixmap(conn, pmap); 117 | xcb_free_gc(conn, gc); 118 | } 119 | 120 | int 121 | main(int argc, char **argv) 122 | { 123 | char *argv0; 124 | int color; 125 | 126 | color = -1; 127 | 128 | if (argc < 2) 129 | usage(argv[0]); 130 | 131 | ARGBEGIN { 132 | case 'i': 133 | borders[2] = strtoul(EARGF(usage(argv0)), NULL, 10); 134 | break; 135 | case 'o': 136 | borders[0] = strtoul(EARGF(usage(argv0)), NULL, 10); 137 | break; 138 | case 'm': 139 | borders[1] = strtoul(EARGF(usage(argv0)), NULL, 10); 140 | break; 141 | case 'c': 142 | color = strtoul(EARGF(usage(argv0)), NULL, 16); 143 | break; 144 | default: 145 | usage(argv0); 146 | /* NOTREACHED */ 147 | } ARGEND 148 | 149 | init_xcb(&conn); 150 | get_screen(conn, &scr); 151 | 152 | colaccent = multiplycolor(color, bevelfacts[0]); 153 | colbase = multiplycolor(color, bevelfacts[1]); 154 | colflat = multiplycolor(color, bevelfacts[2]); 155 | 156 | /* assume remaining arguments are windows */ 157 | while (*argv) 158 | set_border(color, strtoul(*argv++, NULL, 16)); 159 | 160 | xcb_aux_sync(conn); 161 | 162 | kill_xcb(&conn); 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /chbpresel.c: -------------------------------------------------------------------------------- 1 | /** * Copyright (c) 2014, Broseph * * Permission to use, copy, modify, and/or distribute this software for any 2 | * purpose with or without fee is hereby granted, provided that the above 3 | * copyright notice and this permission notice appear in all copies. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 6 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 7 | * MERCHANTABILITY AND FITNESS IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 8 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 9 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 10 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 11 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | **/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "arg.h" 21 | #include "util.h" 22 | 23 | char *argv0; 24 | static xcb_connection_t *conn; 25 | static xcb_screen_t *scr; 26 | 27 | static void usage (char *name); 28 | static void set2border (xcb_window_t, int, int, int); 29 | 30 | static void 31 | usage (char *name) 32 | { 33 | fprintf(stderr, "usage: %s <-I color> <-O color> <-i size> <-o size> [wid...]\n", name); 34 | exit(1); 35 | } 36 | 37 | static void 38 | set2border (win, c, C, direction) 39 | xcb_window_t win; 40 | int c; /* back color */ 41 | int C; /* forward color */ 42 | int direction; /* direction tlbr - 1 2 3 4 */ 43 | { 44 | //if (os < 0 || oc < 0 || is < 0 || ic < 0) 45 | //return; 46 | 47 | uint32_t values[1]; 48 | short w, h, b; 49 | 50 | xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, 51 | xcb_get_geometry(conn, win), NULL); 52 | 53 | if (geom == NULL) 54 | return; 55 | 56 | //if (is + os > geom->border_width) 57 | //warnx("warning: pixmap is greater than border size"); 58 | 59 | w = (short)geom->width; 60 | h = (short)geom->height; 61 | b = (short)geom->border_width; 62 | 63 | xcb_rectangle_t left[] = { 64 | { w + b, 0, b, h +b + b }, 65 | { 0, h, w/2, b}, 66 | { 0, h+b, w/2, b} 67 | }; 68 | 69 | xcb_rectangle_t right[] = { 70 | { w, 0, b, h +b + b }, 71 | { w/2, h, w/2, b}, 72 | { w/2, h + b, w/2, b} 73 | }; 74 | 75 | xcb_rectangle_t up[] = { 76 | { 0, h + b, w + b + b, b}, 77 | { w, 0, b, h/2}, 78 | { w+b, 0, b, h/2} 79 | }; 80 | 81 | xcb_rectangle_t down[] = { 82 | { 0, h, w + b + b, b}, 83 | { w, h/2, b, h/2}, 84 | { w+b, h/2, b, h/2} 85 | }; 86 | 87 | xcb_pixmap_t pmap = xcb_generate_id(conn); 88 | xcb_create_pixmap(conn, scr->root_depth, pmap, win, 89 | geom->width + (b*2), 90 | geom->height + (b*2)); 91 | xcb_gcontext_t gc = xcb_generate_id(conn); 92 | xcb_create_gc(conn, gc, pmap, 0, NULL); 93 | 94 | // focus direction 95 | values[0] = C; 96 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 97 | switch(direction) 98 | { 99 | case 1: xcb_poly_fill_rectangle(conn, pmap, gc, 3, up); break; 100 | case 2: xcb_poly_fill_rectangle(conn, pmap, gc, 3, left); break; 101 | case 3: xcb_poly_fill_rectangle(conn, pmap, gc, 3, down); break; 102 | case 4: xcb_poly_fill_rectangle(conn, pmap, gc, 3, right); break; 103 | default: break; 104 | } 105 | 106 | // behind 107 | values[0] = c; 108 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 109 | switch(direction) 110 | { 111 | case 1: xcb_poly_fill_rectangle(conn, pmap, gc, 3, down); break; 112 | case 2: xcb_poly_fill_rectangle(conn, pmap, gc, 3, right); break; 113 | case 3: xcb_poly_fill_rectangle(conn, pmap, gc, 3, up); break; 114 | case 4: xcb_poly_fill_rectangle(conn, pmap, gc, 3, left); break; 115 | default: break; 116 | } 117 | 118 | values[0] = pmap; 119 | xcb_change_window_attributes(conn, win, XCB_CW_BORDER_PIXMAP, values); 120 | 121 | xcb_free_pixmap(conn, pmap); 122 | xcb_free_gc(conn, gc); 123 | } 124 | 125 | int 126 | main (int argc, char **argv) 127 | { 128 | int C, c, d; 129 | 130 | if (argc < 2) 131 | usage(argv[0]); 132 | 133 | C = c = d = -1; 134 | ARGBEGIN { 135 | case 'C': 136 | C = strtoul(EARGF(usage(argv0)), NULL, 16); 137 | break; 138 | case 'c': 139 | c = strtoul(EARGF(usage(argv0)), NULL, 16); 140 | break; 141 | case 'd': 142 | d = strtoul(EARGF(usage(argv0)), NULL, 10); 143 | break; 144 | case 'h': 145 | usage(argv0); 146 | /* NOTREACHED */ 147 | } ARGEND 148 | 149 | init_xcb(&conn); 150 | get_screen(conn, &scr); 151 | 152 | /* assume remaining arguments are windows */ 153 | while (*argv) 154 | set2border(strtoul(*argv++, NULL, 16), c, C, d); 155 | 156 | xcb_aux_sync(conn); 157 | 158 | kill_xcb(&conn); 159 | 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /chwbn.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "arg.h" 10 | #include "util.h" 11 | 12 | #define MAX(A, B) ((A) > (B) ? (A) : (B)) 13 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 14 | 15 | static xcb_connection_t *conn; 16 | 17 | static void usage(char *name); 18 | static void set_border(xcb_window_t); 19 | 20 | static unsigned int borders[100]; /* widths */ 21 | static unsigned int colors[100]; /* colors */ 22 | static unsigned int num_borders; 23 | static int border_width; 24 | 25 | static int border_index; 26 | static int color_index; 27 | 28 | static xcb_screen_t *scr; 29 | 30 | static void 31 | usage(char *name) 32 | { 33 | fprintf(stderr, "usage: %s <-sc ...> [wid...]\n", name); 34 | exit(1); 35 | } 36 | 37 | static void 38 | get_rectangles(xcb_rectangle_t rectangles[], short offset, short cbw, short bw, short h, short w) 39 | { 40 | /* outside in */ 41 | /* right, bottom, left, top */ 42 | rectangles[0] = (xcb_rectangle_t){ w + bw - offset - cbw, 0, cbw, h + bw - offset }; 43 | rectangles[1] = (xcb_rectangle_t){ 0, h + bw - offset - cbw, w + bw - offset, cbw}; 44 | rectangles[2] = (xcb_rectangle_t){ w + bw + offset, 0, cbw, h + bw - offset }; 45 | rectangles[3] = (xcb_rectangle_t){ 0, h+bw+offset, w + bw - offset, cbw }; 46 | 47 | /* lower left corner fix */ 48 | rectangles[6] = (xcb_rectangle_t){ w + bw + offset, h + bw -offset-cbw, bw-offset, cbw}; 49 | /* upper right corner fix */ 50 | rectangles[7] = (xcb_rectangle_t){ w + bw - offset -cbw, h+bw+offset, cbw, bw - offset }; 51 | 52 | /* corner */ 53 | rectangles[4] = (xcb_rectangle_t){ w + bw + offset, h + bw + offset, cbw, h + bw + bw - (h + bw + offset) }; 54 | rectangles[5] = (xcb_rectangle_t){ w + bw + offset, h + bw + offset, w + bw + bw - (w + bw + offset), cbw }; 55 | } 56 | 57 | static void 58 | set_border(xcb_window_t win) 59 | { 60 | uint32_t values[1]; 61 | short w, h, bw, cbw; 62 | 63 | xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, 64 | xcb_get_geometry(conn, win), NULL); 65 | 66 | if (geom == NULL) 67 | return; 68 | 69 | w = (short)geom->width; 70 | h = (short)geom->height; 71 | bw = border_width; 72 | 73 | xcb_pixmap_t pmap = xcb_generate_id(conn); 74 | xcb_create_pixmap(conn, scr->root_depth, pmap, win, 75 | geom->width + (bw*2), 76 | geom->height + (bw*2)); 77 | 78 | xcb_gcontext_t gc = xcb_generate_id(conn); 79 | xcb_create_gc(conn, gc, pmap, 0, NULL); 80 | 81 | short offset = 0; 82 | 83 | xcb_rectangle_t rectangles[] = 84 | { 85 | {-1, -1, -1, -1}, 86 | {-1, -1, -1, -1}, 87 | {-1, -1, -1, -1}, 88 | {-1, -1, -1, -1}, 89 | {-1, -1, -1, -1}, 90 | {-1, -1, -1, -1}, 91 | {-1, -1, -1, -1}, 92 | {-1, -1, -1, -1} 93 | }; 94 | 95 | for (int i = 0; i < num_borders; i++ ) 96 | { 97 | cbw = borders[i]; 98 | if (cbw != -1) 99 | { 100 | values[0] = colors[i]; 101 | 102 | get_rectangles(rectangles, offset, cbw, bw, h, w); 103 | 104 | short rects_length = 8; // todo 105 | xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); 106 | xcb_poly_fill_rectangle(conn, pmap, gc, rects_length, rectangles); 107 | 108 | xcb_aux_sync(conn); 109 | offset += cbw; 110 | } 111 | } 112 | 113 | /* values[0] = colbase; */ 114 | /* xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, values); */ 115 | /* xcb_poly_fill_rectangle(conn, pmap, gc, 8, base); */ 116 | 117 | 118 | values[0] = pmap; 119 | xcb_change_window_attributes(conn, win, XCB_CW_BORDER_PIXMAP, values); 120 | 121 | xcb_free_pixmap(conn, pmap); 122 | xcb_free_gc(conn, gc); 123 | } 124 | 125 | int 126 | main(int argc, char **argv) 127 | { 128 | char *argv0; 129 | num_borders = 100; 130 | border_width = 0; 131 | 132 | // init 133 | for (int i =0; i< num_borders;i++) 134 | { 135 | colors[i] = -1; 136 | borders[i] = -1; 137 | } 138 | 139 | border_index = 0; 140 | color_index = 0; 141 | 142 | int temp; 143 | 144 | if (argc < 2) 145 | usage(argv[0]); 146 | 147 | ARGBEGIN { 148 | /* 149 | case 'n': 150 | count = strtoul(EARGF(usage(argv0)), NULL, 10); 151 | num_borders = count; 152 | borders = new int[count]; 153 | colors = new long[count]; 154 | break; 155 | */ 156 | case 'b': 157 | temp = strtoul(EARGF(usage(argv0)), NULL, 10); 158 | border_width += temp; 159 | 160 | borders[border_index++] = temp; 161 | break; 162 | case 'c': 163 | colors[color_index++] = strtoul(EARGF(usage(argv0)), NULL, 16); 164 | break; 165 | default: 166 | usage(argv0); 167 | /* NOTREACHED */ 168 | } ARGEND 169 | 170 | init_xcb(&conn); 171 | get_screen(conn, &scr); 172 | 173 | /* assume remaining arguments are windows */ 174 | while (*argv) 175 | set_border(strtoul(*argv++, NULL, 16)); 176 | 177 | xcb_aux_sync(conn); 178 | 179 | kill_xcb(&conn); 180 | 181 | return 0; 182 | } 183 | --------------------------------------------------------------------------------