From 7043db5df26b89cb4050e5d1e1622f03b77da018 Mon Sep 17 00:00:00 2001 From: coast Date: Fri, 30 May 2025 00:26:18 +0330 Subject: [PATCH] fixed dots --- .suckless/README.md | 1 - .suckless/dmenu/LICENSE | 30 + .suckless/dmenu/Makefile | 58 + .suckless/dmenu/README | 24 + .suckless/dmenu/arg.h | 49 + .suckless/dmenu/config.def.h | 23 + .suckless/dmenu/config.h | 23 + .suckless/dmenu/config.mk | 32 + .suckless/dmenu/dmenu | Bin 0 -> 42928 bytes .suckless/dmenu/dmenu.1 | 194 ++ .suckless/dmenu/dmenu.c | 795 ++++++ .suckless/dmenu/dmenu.o | Bin 0 -> 31968 bytes .suckless/dmenu/dmenu_path | 13 + .suckless/dmenu/dmenu_run | 2 + .suckless/dmenu/drw.c | 448 ++++ .suckless/dmenu/drw.h | 58 + .suckless/dmenu/drw.o | Bin 0 -> 11296 bytes .suckless/dmenu/stest | Bin 0 -> 16408 bytes .suckless/dmenu/stest.1 | 90 + .suckless/dmenu/stest.c | 109 + .suckless/dmenu/stest.o | Bin 0 -> 5240 bytes .suckless/dmenu/util.c | 37 + .suckless/dmenu/util.h | 9 + .suckless/dmenu/util.o | Bin 0 -> 2400 bytes .suckless/dwm/dwm | Bin 0 -> 100176 bytes .suckless/{ => dwm}/patch/attachx.c | 0 .suckless/{ => dwm}/patch/attachx.h | 0 .suckless/{ => dwm}/patch/bar.c | 0 .suckless/{ => dwm}/patch/bar.h | 0 .suckless/{ => dwm}/patch/bar_alpha.c | 0 .suckless/{ => dwm}/patch/bar_alpha.h | 0 .suckless/{ => dwm}/patch/bar_indicators.c | 0 .suckless/{ => dwm}/patch/bar_indicators.h | 0 .suckless/{ => dwm}/patch/bar_ltsymbol.c | 0 .suckless/{ => dwm}/patch/bar_ltsymbol.h | 0 .suckless/{ => dwm}/patch/bar_status.c | 0 .suckless/{ => dwm}/patch/bar_status.h | 0 .suckless/{ => dwm}/patch/bar_tagicons.c | 0 .suckless/{ => dwm}/patch/bar_tagicons.h | 0 .suckless/{ => dwm}/patch/bar_tags.c | 0 .suckless/{ => dwm}/patch/bar_tags.h | 0 .suckless/{ => dwm}/patch/bar_wintitle.c | 0 .suckless/{ => dwm}/patch/bar_wintitle.h | 0 .suckless/{ => dwm}/patch/cool_autostart.c | 0 .suckless/{ => dwm}/patch/cool_autostart.h | 0 .../patch/dwm-alpha-20230401-348f655.diff | Bin .suckless/{ => dwm}/patch/dwmc | 0 .suckless/{ => dwm}/patch/dwmc.c | 0 .suckless/{ => dwm}/patch/dwmc.h | 0 .suckless/{ => dwm}/patch/fullscreen.c | 0 .suckless/{ => dwm}/patch/fullscreen.h | 0 .suckless/{ => dwm}/patch/include.c | 0 .suckless/{ => dwm}/patch/include.h | 0 .suckless/{ => dwm}/patch/ipc/IPCClient.h | 0 .suckless/{ => dwm}/patch/ipc/dwm-msg.c | 0 .suckless/{ => dwm}/patch/ipc/yajl_dumps.h | 0 .suckless/{ => dwm}/patch/layout_facts.c | 0 .suckless/{ => dwm}/patch/layout_tile.c | 0 .suckless/{ => dwm}/patch/layout_tile.h | 0 .suckless/{ => dwm}/patch/moveresize.c | 0 .suckless/{ => dwm}/patch/moveresize.h | 0 .suckless/{ => dwm}/patch/movestack.c | 0 .suckless/{ => dwm}/patch/movestack.h | 0 .suckless/{ => dwm}/patch/scratchpad.c | 0 .suckless/{ => dwm}/patch/scratchpad.h | 0 .suckless/{ => dwm}/patch/swallow.c | 0 .suckless/{ => dwm}/patch/swallow.h | 0 .suckless/{ => dwm}/patch/togglefullscreen.c | 0 .suckless/{ => dwm}/patch/togglefullscreen.h | 0 .suckless/{ => dwm}/patch/vanitygaps.c | 0 .suckless/{ => dwm}/patch/vanitygaps.h | 0 .suckless/{ => dwm}/patch/xrdb.c | 0 .suckless/{ => dwm}/patch/xrdb.h | 0 .suckless/slstatus/{components => }/LICENSE | 0 .suckless/slstatus/{components => }/Makefile | 0 .suckless/slstatus/{components => }/README | 0 .suckless/slstatus/{components => }/arg.h | 0 .../slstatus/{components => }/config.def.h | 0 .suckless/slstatus/{components => }/config.h | 0 .suckless/slstatus/{components => }/config.mk | 0 .suckless/slstatus/slstatus | Bin 0 -> 31832 bytes .../slstatus/{components => }/slstatus.1 | 0 .../slstatus/{components => }/slstatus.c | 0 .../slstatus/{components => }/slstatus.h | 0 .../slstatus/{components => }/slstatus.o | Bin .suckless/slstatus/{components => }/util.c | 0 .suckless/slstatus/{components => }/util.h | 0 .suckless/slstatus/{components => }/util.o | Bin .suckless/st/st | Bin 0 -> 113712 bytes .suckless/st/x.c | 2319 +++++++++++++++++ 90 files changed, 4313 insertions(+), 1 deletion(-) delete mode 100644 .suckless/README.md create mode 100644 .suckless/dmenu/LICENSE create mode 100644 .suckless/dmenu/Makefile create mode 100644 .suckless/dmenu/README create mode 100644 .suckless/dmenu/arg.h create mode 100644 .suckless/dmenu/config.def.h create mode 100644 .suckless/dmenu/config.h create mode 100644 .suckless/dmenu/config.mk create mode 100755 .suckless/dmenu/dmenu create mode 100644 .suckless/dmenu/dmenu.1 create mode 100644 .suckless/dmenu/dmenu.c create mode 100644 .suckless/dmenu/dmenu.o create mode 100644 .suckless/dmenu/dmenu_path create mode 100644 .suckless/dmenu/dmenu_run create mode 100644 .suckless/dmenu/drw.c create mode 100644 .suckless/dmenu/drw.h create mode 100644 .suckless/dmenu/drw.o create mode 100755 .suckless/dmenu/stest create mode 100644 .suckless/dmenu/stest.1 create mode 100644 .suckless/dmenu/stest.c create mode 100644 .suckless/dmenu/stest.o create mode 100644 .suckless/dmenu/util.c create mode 100644 .suckless/dmenu/util.h create mode 100644 .suckless/dmenu/util.o create mode 100755 .suckless/dwm/dwm rename .suckless/{ => dwm}/patch/attachx.c (100%) rename .suckless/{ => dwm}/patch/attachx.h (100%) rename .suckless/{ => dwm}/patch/bar.c (100%) rename .suckless/{ => dwm}/patch/bar.h (100%) rename .suckless/{ => dwm}/patch/bar_alpha.c (100%) rename .suckless/{ => dwm}/patch/bar_alpha.h (100%) rename .suckless/{ => dwm}/patch/bar_indicators.c (100%) rename .suckless/{ => dwm}/patch/bar_indicators.h (100%) rename .suckless/{ => dwm}/patch/bar_ltsymbol.c (100%) rename .suckless/{ => dwm}/patch/bar_ltsymbol.h (100%) rename .suckless/{ => dwm}/patch/bar_status.c (100%) rename .suckless/{ => dwm}/patch/bar_status.h (100%) rename .suckless/{ => dwm}/patch/bar_tagicons.c (100%) rename .suckless/{ => dwm}/patch/bar_tagicons.h (100%) rename .suckless/{ => dwm}/patch/bar_tags.c (100%) rename .suckless/{ => dwm}/patch/bar_tags.h (100%) rename .suckless/{ => dwm}/patch/bar_wintitle.c (100%) rename .suckless/{ => dwm}/patch/bar_wintitle.h (100%) rename .suckless/{ => dwm}/patch/cool_autostart.c (100%) rename .suckless/{ => dwm}/patch/cool_autostart.h (100%) rename .suckless/{ => dwm}/patch/dwm-alpha-20230401-348f655.diff (100%) rename .suckless/{ => dwm}/patch/dwmc (100%) rename .suckless/{ => dwm}/patch/dwmc.c (100%) rename .suckless/{ => dwm}/patch/dwmc.h (100%) rename .suckless/{ => dwm}/patch/fullscreen.c (100%) rename .suckless/{ => dwm}/patch/fullscreen.h (100%) rename .suckless/{ => dwm}/patch/include.c (100%) rename .suckless/{ => dwm}/patch/include.h (100%) rename .suckless/{ => dwm}/patch/ipc/IPCClient.h (100%) rename .suckless/{ => dwm}/patch/ipc/dwm-msg.c (100%) rename .suckless/{ => dwm}/patch/ipc/yajl_dumps.h (100%) rename .suckless/{ => dwm}/patch/layout_facts.c (100%) rename .suckless/{ => dwm}/patch/layout_tile.c (100%) rename .suckless/{ => dwm}/patch/layout_tile.h (100%) rename .suckless/{ => dwm}/patch/moveresize.c (100%) rename .suckless/{ => dwm}/patch/moveresize.h (100%) rename .suckless/{ => dwm}/patch/movestack.c (100%) rename .suckless/{ => dwm}/patch/movestack.h (100%) rename .suckless/{ => dwm}/patch/scratchpad.c (100%) rename .suckless/{ => dwm}/patch/scratchpad.h (100%) rename .suckless/{ => dwm}/patch/swallow.c (100%) rename .suckless/{ => dwm}/patch/swallow.h (100%) rename .suckless/{ => dwm}/patch/togglefullscreen.c (100%) rename .suckless/{ => dwm}/patch/togglefullscreen.h (100%) rename .suckless/{ => dwm}/patch/vanitygaps.c (100%) rename .suckless/{ => dwm}/patch/vanitygaps.h (100%) rename .suckless/{ => dwm}/patch/xrdb.c (100%) rename .suckless/{ => dwm}/patch/xrdb.h (100%) rename .suckless/slstatus/{components => }/LICENSE (100%) rename .suckless/slstatus/{components => }/Makefile (100%) rename .suckless/slstatus/{components => }/README (100%) rename .suckless/slstatus/{components => }/arg.h (100%) rename .suckless/slstatus/{components => }/config.def.h (100%) rename .suckless/slstatus/{components => }/config.h (100%) rename .suckless/slstatus/{components => }/config.mk (100%) create mode 100755 .suckless/slstatus/slstatus rename .suckless/slstatus/{components => }/slstatus.1 (100%) rename .suckless/slstatus/{components => }/slstatus.c (100%) rename .suckless/slstatus/{components => }/slstatus.h (100%) rename .suckless/slstatus/{components => }/slstatus.o (100%) rename .suckless/slstatus/{components => }/util.c (100%) rename .suckless/slstatus/{components => }/util.h (100%) rename .suckless/slstatus/{components => }/util.o (100%) create mode 100755 .suckless/st/st create mode 100644 .suckless/st/x.c diff --git a/.suckless/README.md b/.suckless/README.md deleted file mode 100644 index 5534256..0000000 --- a/.suckless/README.md +++ /dev/null @@ -1 +0,0 @@ -MAKE SURE YOU PUT `.suckless/patch` IN `dwm/` I UPLOADED IT WRONG AND I DONT WANNA FIX IT! \ No newline at end of file diff --git a/.suckless/dmenu/LICENSE b/.suckless/dmenu/LICENSE new file mode 100644 index 0000000..2a64b28 --- /dev/null +++ b/.suckless/dmenu/LICENSE @@ -0,0 +1,30 @@ +MIT/X Consortium License + +© 2006-2019 Anselm R Garbe +© 2006-2008 Sander van Dijk +© 2006-2007 Michał Janeczek +© 2007 Kris Maglione +© 2009 Gottox +© 2009 Markus Schnalke +© 2009 Evan Gates +© 2010-2012 Connor Lane Smith +© 2014-2022 Hiltjo Posthuma +© 2015-2019 Quentin Rameau + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/.suckless/dmenu/Makefile b/.suckless/dmenu/Makefile new file mode 100644 index 0000000..458c524 --- /dev/null +++ b/.suckless/dmenu/Makefile @@ -0,0 +1,58 @@ +# dmenu - dynamic menu +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dmenu.c stest.c util.c +OBJ = $(SRC:.c=.o) + +all: dmenu stest + +.c.o: + $(CC) -c $(CFLAGS) $< + +config.h: + cp config.def.h $@ + +$(OBJ): arg.h config.h config.mk drw.h + +dmenu: dmenu.o drw.o util.o + $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) + +stest: stest.o + $(CC) -o $@ stest.o $(LDFLAGS) + +clean: + rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz + +dist: clean + mkdir -p dmenu-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ + drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ + dmenu-$(VERSION) + tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) + gzip dmenu-$(VERSION).tar + rm -rf dmenu-$(VERSION) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + chmod 755 $(DESTDIR)$(PREFIX)/bin/stest + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ + $(DESTDIR)$(PREFIX)/bin/dmenu_path\ + $(DESTDIR)$(PREFIX)/bin/dmenu_run\ + $(DESTDIR)$(PREFIX)/bin/stest\ + $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ + $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +.PHONY: all clean dist install uninstall diff --git a/.suckless/dmenu/README b/.suckless/dmenu/README new file mode 100644 index 0000000..a8fcdfe --- /dev/null +++ b/.suckless/dmenu/README @@ -0,0 +1,24 @@ +dmenu - dynamic menu +==================== +dmenu is an efficient dynamic menu for X. + + +Requirements +------------ +In order to build dmenu you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dmenu is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dmenu +(if necessary as root): + + make clean install + + +Running dmenu +------------- +See the man page for details. diff --git a/.suckless/dmenu/arg.h b/.suckless/dmenu/arg.h new file mode 100644 index 0000000..e94e02b --- /dev/null +++ b/.suckless/dmenu/arg.h @@ -0,0 +1,49 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/.suckless/dmenu/config.def.h b/.suckless/dmenu/config.def.h new file mode 100644 index 0000000..1edb647 --- /dev/null +++ b/.suckless/dmenu/config.def.h @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +/* Default settings; can be overriden by command line. */ + +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +/* -fn option overrides fonts[0]; default X11 font or font set */ +static const char *fonts[] = { + "monospace:size=10" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, +}; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; diff --git a/.suckless/dmenu/config.h b/.suckless/dmenu/config.h new file mode 100644 index 0000000..1edb647 --- /dev/null +++ b/.suckless/dmenu/config.h @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +/* Default settings; can be overriden by command line. */ + +static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +/* -fn option overrides fonts[0]; default X11 font or font set */ +static const char *fonts[] = { + "monospace:size=10" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, +}; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; diff --git a/.suckless/dmenu/config.mk b/.suckless/dmenu/config.mk new file mode 100644 index 0000000..137f7c8 --- /dev/null +++ b/.suckless/dmenu/config.mk @@ -0,0 +1,32 @@ +# dmenu version +VERSION = 5.3 + +# paths +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# Xinerama, comment if you don't want it +XINERAMALIBS = -lXinerama +XINERAMAFLAGS = -DXINERAMA + +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = $(X11INC)/freetype2 +#MANPREFIX = ${PREFIX}/man + +# includes and libs +INCS = -I$(X11INC) -I$(FREETYPEINC) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) +LDFLAGS = $(LIBS) + +# compiler and linker +CC = cc diff --git a/.suckless/dmenu/dmenu b/.suckless/dmenu/dmenu new file mode 100755 index 0000000000000000000000000000000000000000..656bab89d05ef91e4c08f9e592538f3236578d6e GIT binary patch literal 42928 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 literal 0 HcmV?d00001 diff --git a/.suckless/dmenu/dmenu.1 b/.suckless/dmenu/dmenu.1 new file mode 100644 index 0000000..323f93c --- /dev/null +++ b/.suckless/dmenu/dmenu.1 @@ -0,0 +1,194 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-l +.IR lines ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-l " lines" +dmenu lists items vertically, with the given number of lines. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.B Escape +Exit without selecting an item, returning failure. +.TP +.B Ctrl-Left +Move cursor to the start of the current word +.TP +.B Ctrl-Right +Move cursor to the end of the current word +.TP +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/.suckless/dmenu/dmenu.c b/.suckless/dmenu/dmenu.c new file mode 100644 index 0000000..fd49549 --- /dev/null +++ b/.suckless/dmenu/dmenu.c @@ -0,0 +1,795 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef XINERAMA +#include +#endif +#include + +#include "drw.h" +#include "util.h" + +/* macros */ +#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + +/* enums */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + +struct item { + char *text; + struct item *left, *right; + int out; +}; + +static char text[BUFSIZ] = ""; +static char *embed; +static int bh, mw, mh; +static int inputw = 0, promptw; +static int lrpad; /* sum of left and right padding */ +static size_t cursor; +static struct item *items = NULL; +static struct item *matches, *matchend; +static struct item *prev, *curr, *next, *sel; +static int mon = -1, screen; + +static Atom clip, utf8; +static Display *dpy; +static Window root, parentwin, win; +static XIC xic; + +static Drw *drw; +static Clr *scheme[SchemeLast]; + +#include "config.h" + +static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; + +static unsigned int +textw_clamp(const char *str, unsigned int n) +{ + unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad; + return MIN(w, n); +} + +static void +appenditem(struct item *item, struct item **list, struct item **last) +{ + if (*last) + (*last)->right = item; + else + *list = item; + + item->left = *last; + item->right = NULL; + *last = item; +} + +static void +calcoffsets(void) +{ + int i, n; + + if (lines > 0) + n = lines * bh; + else + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); + /* calculate which items will begin the next page and previous page */ + for (i = 0, next = curr; next; next = next->right) + if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) + break; + for (i = 0, prev = curr; prev && prev->left; prev = prev->left) + if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n) + break; +} + +static void +cleanup(void) +{ + size_t i; + + XUngrabKeyboard(dpy, CurrentTime); + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); + for (i = 0; items && items[i].text; ++i) + free(items[i].text); + free(items); + drw_free(drw); + XSync(dpy, False); + XCloseDisplay(dpy); +} + +static char * +cistrstr(const char *h, const char *n) +{ + size_t i; + + if (!n[0]) + return (char *)h; + + for (; *h; ++h) { + for (i = 0; n[i] && tolower((unsigned char)n[i]) == + tolower((unsigned char)h[i]); ++i) + ; + if (n[i] == '\0') + return (char *)h; + } + return NULL; +} + +static int +drawitem(struct item *item, int x, int y, int w) +{ + if (item == sel) + drw_setscheme(drw, scheme[SchemeSel]); + else if (item->out) + drw_setscheme(drw, scheme[SchemeOut]); + else + drw_setscheme(drw, scheme[SchemeNorm]); + + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); +} + +static void +drawmenu(void) +{ + unsigned int curpos; + struct item *item; + int x = 0, y = 0, w; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); + + if (prompt && *prompt) { + drw_setscheme(drw, scheme[SchemeSel]); + x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); + } + /* draw input field */ + w = (lines > 0 || !matches) ? mw - x : inputw; + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); + + curpos = TEXTW(text) - TEXTW(&text[cursor]); + if ((curpos += lrpad / 2 - 1) < w) { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); + } + + if (lines > 0) { + /* draw vertical list */ + for (item = curr; item != next; item = item->right) + drawitem(item, x, y += bh, mw - x); + } else if (matches) { + /* draw horizontal list */ + x += inputw; + w = TEXTW("<"); + if (curr->left) { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); + } + x += w; + for (item = curr; item != next; item = item->right) + x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); + if (next) { + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); + } + } + drw_map(drw, win, 0, 0, mw, mh); +} + +static void +grabfocus(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; + Window focuswin; + int i, revertwin; + + for (i = 0; i < 100; ++i) { + XGetInputFocus(dpy, &focuswin, &revertwin); + if (focuswin == win) + return; + XSetInputFocus(dpy, win, RevertToParent, CurrentTime); + nanosleep(&ts, NULL); + } + die("cannot grab focus"); +} + +static void +grabkeyboard(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; + int i; + + if (embed) + return; + /* try to grab keyboard, we may have to wait for another process to ungrab */ + for (i = 0; i < 1000; i++) { + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, + GrabModeAsync, CurrentTime) == GrabSuccess) + return; + nanosleep(&ts, NULL); + } + die("cannot grab keyboard"); +} + +static void +match(void) +{ + static char **tokv = NULL; + static int tokn = 0; + + char buf[sizeof text], *s; + int i, tokc = 0; + size_t len, textsize; + struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + + strcpy(buf, text); + /* separate input text into tokens to be matched individually */ + for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) + if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + die("cannot realloc %zu bytes:", tokn * sizeof *tokv); + len = tokc ? strlen(tokv[0]) : 0; + + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + textsize = strlen(text) + 1; + for (item = items; item && item->text; item++) { + for (i = 0; i < tokc; i++) + if (!fstrstr(item->text, tokv[i])) + break; + if (i != tokc) /* not all tokens match */ + continue; + /* exact matches go first, then prefixes, then substrings */ + if (!tokc || !fstrncmp(text, item->text, textsize)) + appenditem(item, &matches, &matchend); + else if (!fstrncmp(tokv[0], item->text, len)) + appenditem(item, &lprefix, &prefixend); + else + appenditem(item, &lsubstr, &substrend); + } + if (lprefix) { + if (matches) { + matchend->right = lprefix; + lprefix->left = matchend; + } else + matches = lprefix; + matchend = prefixend; + } + if (lsubstr) { + if (matches) { + matchend->right = lsubstr; + lsubstr->left = matchend; + } else + matches = lsubstr; + matchend = substrend; + } + curr = sel = matches; + calcoffsets(); +} + +static void +insert(const char *str, ssize_t n) +{ + if (strlen(text) + n > sizeof text - 1) + return; + /* move existing text out of the way, insert new text, and update cursor */ + memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); + if (n > 0) + memcpy(&text[cursor], str, n); + cursor += n; + match(); +} + +static size_t +nextrune(int inc) +{ + ssize_t n; + + /* return location of next utf8 rune in the given direction (+1 or -1) */ + for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) + ; + return n; +} + +static void +movewordedge(int dir) +{ + if (dir < 0) { /* move cursor to the start of the word*/ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + } else { /* move cursor to the end of the word */ + while (text[cursor] && strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + while (text[cursor] && !strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + } +} + +static void +keypress(XKeyEvent *ev) +{ + char buf[64]; + int len; + KeySym ksym = NoSymbol; + Status status; + + len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); + switch (status) { + default: /* XLookupNone, XBufferOverflow */ + return; + case XLookupChars: /* composed string from input method */ + goto insert; + case XLookupKeySym: + case XLookupBoth: /* a KeySym and a string are returned: use keysym */ + break; + } + + if (ev->state & ControlMask) { + switch(ksym) { + case XK_a: ksym = XK_Home; break; + case XK_b: ksym = XK_Left; break; + case XK_c: ksym = XK_Escape; break; + case XK_d: ksym = XK_Delete; break; + case XK_e: ksym = XK_End; break; + case XK_f: ksym = XK_Right; break; + case XK_g: ksym = XK_Escape; break; + case XK_h: ksym = XK_BackSpace; break; + case XK_i: ksym = XK_Tab; break; + case XK_j: /* fallthrough */ + case XK_J: /* fallthrough */ + case XK_m: /* fallthrough */ + case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; + case XK_n: ksym = XK_Down; break; + case XK_p: ksym = XK_Up; break; + + case XK_k: /* delete right */ + text[cursor] = '\0'; + match(); + break; + case XK_u: /* delete left */ + insert(NULL, 0 - cursor); + break; + case XK_w: /* delete word */ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + insert(NULL, nextrune(-1) - cursor); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + insert(NULL, nextrune(-1) - cursor); + break; + case XK_y: /* paste selection */ + case XK_Y: + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + utf8, utf8, win, CurrentTime); + return; + case XK_Left: + case XK_KP_Left: + movewordedge(-1); + goto draw; + case XK_Right: + case XK_KP_Right: + movewordedge(+1); + goto draw; + case XK_Return: + case XK_KP_Enter: + break; + case XK_bracketleft: + cleanup(); + exit(1); + default: + return; + } + } else if (ev->state & Mod1Mask) { + switch(ksym) { + case XK_b: + movewordedge(-1); + goto draw; + case XK_f: + movewordedge(+1); + goto draw; + case XK_g: ksym = XK_Home; break; + case XK_G: ksym = XK_End; break; + case XK_h: ksym = XK_Up; break; + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; + default: + return; + } + } + + switch(ksym) { + default: +insert: + if (!iscntrl((unsigned char)*buf)) + insert(buf, len); + break; + case XK_Delete: + case XK_KP_Delete: + if (text[cursor] == '\0') + return; + cursor = nextrune(+1); + /* fallthrough */ + case XK_BackSpace: + if (cursor == 0) + return; + insert(NULL, nextrune(-1) - cursor); + break; + case XK_End: + case XK_KP_End: + if (text[cursor] != '\0') { + cursor = strlen(text); + break; + } + if (next) { + /* jump to end of list and position items in reverse */ + curr = matchend; + calcoffsets(); + curr = prev; + calcoffsets(); + while (next && (curr = curr->right)) + calcoffsets(); + } + sel = matchend; + break; + case XK_Escape: + cleanup(); + exit(1); + case XK_Home: + case XK_KP_Home: + if (sel == matches) { + cursor = 0; + break; + } + sel = curr = matches; + calcoffsets(); + break; + case XK_Left: + case XK_KP_Left: + if (cursor > 0 && (!sel || !sel->left || lines > 0)) { + cursor = nextrune(-1); + break; + } + if (lines > 0) + return; + /* fallthrough */ + case XK_Up: + case XK_KP_Up: + if (sel && sel->left && (sel = sel->left)->right == curr) { + curr = prev; + calcoffsets(); + } + break; + case XK_Next: + case XK_KP_Next: + if (!next) + return; + sel = curr = next; + calcoffsets(); + break; + case XK_Prior: + case XK_KP_Prior: + if (!prev) + return; + sel = curr = prev; + calcoffsets(); + break; + case XK_Return: + case XK_KP_Enter: + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); + if (!(ev->state & ControlMask)) { + cleanup(); + exit(0); + } + if (sel) + sel->out = 1; + break; + case XK_Right: + case XK_KP_Right: + if (text[cursor] != '\0') { + cursor = nextrune(+1); + break; + } + if (lines > 0) + return; + /* fallthrough */ + case XK_Down: + case XK_KP_Down: + if (sel && sel->right && (sel = sel->right) == next) { + curr = next; + calcoffsets(); + } + break; + case XK_Tab: + if (!sel) + return; + cursor = strnlen(sel->text, sizeof text - 1); + memcpy(text, sel->text, cursor); + text[cursor] = '\0'; + match(); + break; + } + +draw: + drawmenu(); +} + +static void +paste(void) +{ + char *p, *q; + int di; + unsigned long dl; + Atom da; + + /* we have been given the current selection, now insert it into input */ + if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p) + == Success && p) { + insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); + XFree(p); + } + drawmenu(); +} + +static void +readstdin(void) +{ + char *line = NULL; + size_t i, itemsiz = 0, linesiz = 0; + ssize_t len; + + /* read each line from stdin and add it to the item list */ + for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) { + if (i + 1 >= itemsiz) { + itemsiz += 256; + if (!(items = realloc(items, itemsiz * sizeof(*items)))) + die("cannot realloc %zu bytes:", itemsiz * sizeof(*items)); + } + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + if (!(items[i].text = strdup(line))) + die("strdup:"); + + items[i].out = 0; + } + free(line); + if (items) + items[i].text = NULL; + lines = MIN(lines, i); +} + +static void +run(void) +{ + XEvent ev; + + while (!XNextEvent(dpy, &ev)) { + if (XFilterEvent(&ev, win)) + continue; + switch(ev.type) { + case DestroyNotify: + if (ev.xdestroywindow.window != win) + break; + cleanup(); + exit(1); + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); + break; + case FocusIn: + /* regrab focus from parent window */ + if (ev.xfocus.window != win) + grabfocus(); + break; + case KeyPress: + keypress(&ev.xkey); + break; + case SelectionNotify: + if (ev.xselection.property == utf8) + paste(); + break; + case VisibilityNotify: + if (ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; + } + } +} + +static void +setup(void) +{ + int x, y, i, j; + unsigned int du; + XSetWindowAttributes swa; + XIM xim; + Window w, dw, *dws; + XWindowAttributes wa; + XClassHint ch = {"dmenu", "dmenu"}; +#ifdef XINERAMA + XineramaScreenInfo *info; + Window pw; + int a, di, n, area = 0; +#endif + /* init appearance */ + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(drw, colors[j], 2); + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; + lines = MAX(lines, 0); + mh = (lines + 1) * bh; +#ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { + XGetInputFocus(dpy, &w, &di); + if (mon >= 0 && mon < n) + i = mon; + else if (w != root && w != PointerRoot && w != None) { + /* find top-level window containing current input focus */ + do { + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) + XFree(dws); + } while (w != root && w != pw); + /* find xinerama screen with which the window intersects most */ + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { + area = a; + i = j; + } + } + /* no focused window is on screen, so use pointer location instead */ + if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for (i = 0; i < n; i++) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) + break; + + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; + XFree(info); + } else +#endif + { + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); + x = 0; + y = topbar ? 0 : wa.height - mh; + mw = wa.width; + } + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = mw / 3; /* input width: ~33% of monitor width */ + match(); + + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); + + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, NULL); + + XMapRaised(dpy, win); + if (embed) { + XReparentWindow(dpy, win, parentwin, x, y); + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); + if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { + for (i = 0; i < du && dws[i] != win; ++i) + XSelectInput(dpy, dws[i], FocusChangeMask); + XFree(dws); + } + grabfocus(); + } + drw_resize(drw, mw, mh); + drawmenu(); +} + +static void +usage(void) +{ + die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); +} + +int +main(int argc, char *argv[]) +{ + XWindowAttributes wa; + int i, fast = 0; + + for (i = 1; i < argc; i++) + /* these options take no arguments */ + if (!strcmp(argv[i], "-v")) { /* prints version information */ + puts("dmenu-"VERSION); + exit(0); + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ + fonts[0] = argv[++i]; + else if (!strcmp(argv[i], "-nb")) /* normal background color */ + colors[SchemeNorm][ColBg] = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ + colors[SchemeNorm][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-sb")) /* selected background color */ + colors[SchemeSel][ColBg] = argv[++i]; + else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ + colors[SchemeSel][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-w")) /* embedding window id */ + embed = argv[++i]; + else + usage(); + + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("cannot open display"); + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + if (!embed || !(parentwin = strtol(embed, NULL, 0))) + parentwin = root; + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); + drw = drw_create(dpy, screen, root, wa.width, wa.height); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + +#ifdef __OpenBSD__ + if (pledge("stdio rpath", NULL) == -1) + die("pledge"); +#endif + + if (fast && !isatty(0)) { + grabkeyboard(); + readstdin(); + } else { + readstdin(); + grabkeyboard(); + } + setup(); + run(); + + return 1; /* unreachable */ +} diff --git a/.suckless/dmenu/dmenu.o b/.suckless/dmenu/dmenu.o new file mode 100644 index 0000000000000000000000000000000000000000..e4915920c257b8588ba36d0e1a7d63156f322041 GIT binary patch literal 31968 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 literal 0 HcmV?d00001 diff --git a/.suckless/dmenu/dmenu_path b/.suckless/dmenu/dmenu_path new file mode 100644 index 0000000..3a7cda7 --- /dev/null +++ b/.suckless/dmenu/dmenu_path @@ -0,0 +1,13 @@ +#!/bin/sh + +cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" +cache="$cachedir/dmenu_run" + +[ ! -e "$cachedir" ] && mkdir -p "$cachedir" + +IFS=: +if stest -dqr -n "$cache" $PATH; then + stest -flx $PATH | sort -u | tee "$cache" +else + cat "$cache" +fi diff --git a/.suckless/dmenu/dmenu_run b/.suckless/dmenu/dmenu_run new file mode 100644 index 0000000..834ede5 --- /dev/null +++ b/.suckless/dmenu/dmenu_run @@ -0,0 +1,2 @@ +#!/bin/sh +dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & diff --git a/.suckless/dmenu/drw.c b/.suckless/dmenu/drw.c new file mode 100644 index 0000000..c41e6af --- /dev/null +++ b/.suckless/dmenu/drw.c @@ -0,0 +1,448 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD + +static int +utf8decode(const char *s_in, long *u, int *err) +{ + static const unsigned char lens[] = { + /* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */ + /* 110XX */ 2, 2, 2, 2, + /* 1110X */ 3, 3, + /* 11110 */ 4, + /* 11111 */ 0, /* invalid */ + }; + static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 }; + static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 }; + + const unsigned char *s = (const unsigned char *)s_in; + int len = lens[*s >> 3]; + *u = UTF_INVALID; + *err = 1; + if (len == 0) + return 1; + + long cp = s[0] & leading_mask[len - 1]; + for (int i = 1; i < len; ++i) { + if (s[i] == '\0' || (s[i] & 0xC0) != 0x80) + return i; + cp = (cp << 6) | (s[i] & 0x3F); + } + /* out of range, surrogate, overlong encoding */ + if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1]) + return len; + + *err = 0; + *u = cp; + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) +{ + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->h = xfont->ascent + xfont->descent; + font->dpy = drw->dpy; + + return font; +} + +static void +xfont_free(Fnt *font) +{ + if (!font) + return; + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) +{ + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); +} + +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Clr * +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; +} + +void +drw_setfontset(Drw *drw, Fnt *set) +{ + if (drw) + drw->fonts = set; +} + +void +drw_setscheme(Drw *drw, Clr *scm) +{ + if (drw) + drw->scheme = scm; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) +{ + if (!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) +{ + int ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, utf8err, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + static unsigned int nomatches[128], ellipsis_width, invalid_width; + static const char invalid[] = "�"; + + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) + return 0; + + if (!render) { + w = invert ? invert : ~invert; + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + if (w < lpad) + return x + w; + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); + if (!invalid_width && render) + invalid_width = drw_fontset_getwidth(drw, invalid); + while (1) { + ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, &utf8err); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { + text += utf8charlen; + utf8strlen += utf8err ? 0 : utf8charlen; + ew += utf8err ? 0 : tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont || utf8err) + break; + else + charexists = 0; + } + + if (utf8strlen) { + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); + } + x += ew; + w -= ew; + } + if (utf8err && (!render || invalid_width < w)) { + if (render) + drw_text(drw, x, y, w, h, 0, invalid, invert); + x += invalid_width; + w -= invalid_width; + } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); + + if (!*text || overflow) { + break; + } else if (nextfont) { + charexists = 0; + usedfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. */ + charexists = 1; + + hash = (unsigned int)utf8codepoint; + hash = ((hash >> 16) ^ hash) * 0x21F0AAAD; + hash = ((hash >> 15) ^ hash) * 0xD35A2D97; + h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches); + h1 = (hash >> 17) % LENGTH(nomatches); + /* avoid expensive XftFontMatch call when we know we won't find a match */ + if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint) + goto no_match; + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ + die("the first font in the cache must be loaded from a font string."); + } + + fcpattern = FcPatternDuplicate(drw->fonts->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; + } else { + xfont_free(usedfont); + nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint; +no_match: + usedfont = drw->fonts; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x + (render ? w : 0); +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) +{ + XGlyphInfo ext; + + if (!font || !text) + return; + + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + if (w) + *w = ext.xOff; + if (h) + *h = font->h; +} + +Cur * +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; + + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + + cur->cursor = XCreateFontCursor(drw->dpy, shape); + + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) + return; + + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/.suckless/dmenu/drw.h b/.suckless/dmenu/drw.h new file mode 100644 index 0000000..fd7631b --- /dev/null +++ b/.suckless/dmenu/drw.h @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/.suckless/dmenu/drw.o b/.suckless/dmenu/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..dbafb1662bf561b45180fe2335afc7ce9362489f GIT binary patch literal 11296 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 literal 0 HcmV?d00001 diff --git a/.suckless/dmenu/stest b/.suckless/dmenu/stest new file mode 100755 index 0000000000000000000000000000000000000000..45f7c0494f9cebae7c41eb0b7ba1f7069124d605 GIT binary patch literal 16408 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